1
0

Robot AI fixes

Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
James Ketrenos 2022-06-23 17:10:22 -07:00
parent 84c8657b55
commit 446d4d49e2
7 changed files with 92 additions and 47 deletions

View File

@ -129,7 +129,7 @@ const Activities = () => {
})); }));
}, [ws, fields]); }, [ws, fields]);
if (!timestamp || !color) { if (!timestamp) {
return <></>; return <></>;
} }

View File

@ -33,7 +33,7 @@ import { Sheep } from "./Sheep.js";
import history from "./history.js"; import history from "./history.js";
import "./App.css"; import "./App.css";
import equal from "fast-deep-equal"; import equal from "fast-deep-equal";
import { purple } from "@material-ui/core/colors";
/* /*
const Pip = () => { const Pip = () => {
<div className="Pip" <div className="Pip"

View File

@ -6,6 +6,7 @@ import ListItemText from '@material-ui/core/ListItemText';
import Moment from 'react-moment'; import Moment from 'react-moment';
import TextField from '@material-ui/core/TextField'; import TextField from '@material-ui/core/TextField';
import 'moment-timezone'; import 'moment-timezone';
import equal from "fast-deep-equal";
import "./Chat.css"; import "./Chat.css";
import { PlayerColor } from './PlayerColor.js'; import { PlayerColor } from './PlayerColor.js';
@ -30,7 +31,7 @@ const Chat = () => {
switch (data.type) { switch (data.type) {
case 'game-update': case 'game-update':
console.log(`chat - game update`); console.log(`chat - game update`);
if (data.update.chat && data.update.chat.length !== chat.length) { if (data.update.chat && !equal(data.update.chat, chat)) {
console.log(`chat - game update - ${data.update.chat.length} lines`); console.log(`chat - game update - ${data.update.chat.length} lines`);
setChat(data.update.chat); setChat(data.update.chat);
} }
@ -163,7 +164,7 @@ const Chat = () => {
} }
return ( return (
<ListItem key={`msg-${item.date}`} <ListItem key={`msg-${item.date}-${index}`}
className={item.color ? '' : 'System'}> className={item.color ? '' : 'System'}>
{ item.color && { item.color &&
<PlayerColor color={item.color}/> <PlayerColor color={item.color}/>

View File

@ -11,7 +11,7 @@ import { GlobalContext } from './GlobalContext.js';
const Player = ({ player, onClick, reverse, color, const Player = ({ player, onClick, reverse, color,
largestArmy, isSelf, longestRoad, mostPorts, mostDeveloped }) => { largestArmy, isSelf, longestRoad, mostPorts, mostDeveloped }) => {
if (!player) { if (!player) {
return <></>; return <>You are an observer.</>;
} }
const developmentCards = player.unplayed const developmentCards = player.unplayed

View File

@ -69,6 +69,7 @@ const Sheep = ({ radius, speed, size, style }) => {
return <div className={`Sheep`} return <div className={`Sheep`}
style={{ style={{
zIndex: `${Math.ceil(50 * y)}`,
top: `${Math.floor(50 + 50 * y)}%`, top: `${Math.floor(50 + 50 * y)}%`,
left: `${Math.floor(50 + 50 * x)}%`, left: `${Math.floor(50 + 50 * x)}%`,
width: `${size * 60}px`, width: `${size * 60}px`,

View File

@ -92,7 +92,7 @@ const connect = async () => {
ws.on('headers', headers); ws.on('headers', headers);
ws.on('close', close); ws.on('close', close);
ws.on('error', error); ws.on('error', error);
ws.on('message', (data) => { message(ws, data); }); ws.on('message', async (data) => { await message(ws, data); });
}); });
}; };
@ -144,7 +144,8 @@ const tryBuild = (ws) => {
ws.send(JSON.stringify(data)); ws.send(JSON.stringify(data));
}; };
let trying = false; let trying = false;
if (game.private.wood if (game.private.settlements
&& game.private.wood
&& game.private.brick && game.private.brick
&& game.private.sheep && game.private.sheep
&& game.private.wheat) { && game.private.wheat) {
@ -154,7 +155,7 @@ const tryBuild = (ws) => {
trying = true; trying = true;
} }
if (game.private.wood && game.private.brick) { if (game.private.wood && game.private.brick && game.private.roads) {
send({ send({
type: 'buy-road' type: 'buy-road'
}); });
@ -164,7 +165,14 @@ const tryBuild = (ws) => {
return trying; return trying;
}; };
const message = (ws, data) => {
const sleep = async (delay) => {
return new Promise((resolve) => {
setTimeout(resolve, delay);
});
};
const message = async (ws, data) => {
const send = (data) => { const send = (data) => {
console.log(`ws - send: ${data.type}`); console.log(`ws - send: ${data.type}`);
ws.send(JSON.stringify(data)); ws.send(JSON.stringify(data));
@ -173,14 +181,14 @@ const message = (ws, data) => {
data = JSON.parse(data); data = JSON.parse(data);
switch (data.type) { switch (data.type) {
case 'game-update': case 'game-update':
Object.assign(game, data.update);
delete data.update.chat;
delete data.update.activities;
console.log(`ws - receive - `, console.log(`ws - receive - `,
Object.assign({}, data.update, { data.update
activities: 'filtered out',
chat: 'filtered out'
})
); );
Object.assign(game, data.update);
console.log(`state - ${game.state}`); console.log(`state - ${game.state}`);
switch (game.state) { switch (game.state) {
@ -196,15 +204,16 @@ const message = (ws, data) => {
} }
console.log(`game-order - `, { console.log(`game-order - `, {
color: game.color, color: game.color,
players: game.players players: game.players
}); });
if (!game.players[game.color].orderRoll) { if (!game.players[game.color].orderRoll || game.players[game.color].tied) {
console.log(`Time to roll as ${game.color}`); console.log(`Time to roll as ${game.color}`);
send({ type: 'roll' }); send({ type: 'roll' });
} }
break; break;
case 'initial-placement': { case 'initial-placement': {
await sleep(1000 + Math.random() * 500);
console.log({ color: game.color, state: game.state, turn: game.turn }); console.log({ color: game.color, state: game.state, turn: game.turn });
if (game.turn.color !== game.color) { if (game.turn.color !== game.color) {
break; break;
@ -228,9 +237,46 @@ const message = (ws, data) => {
} break; } break;
case 'normal': case 'normal':
if (game.players[game.color].mustDiscard) {
await sleep(1000 + Math.random() * 500);
let mustDiscard = game.players[game.color].mustDiscard;
if (!mustDiscard) {
return;
}
const cards = [],
discards = {};
const types = ['wheat', 'sheep', 'stone', 'brick', 'wood'];
types.forEach(type => {
for (let i = 0; i < game.private[type]; i++) {
cards.push(type);
}
});
while (mustDiscard--) {
const type = cards[Math.floor(Math.random() * cards.length)];
if (!(type in discards)) {
discards[type] = 1;
} else {
discards[type]++;
}
}
console.log(`discarding - `, discards);
send({
type: 'discard',
discards
});
return;
}
if (game.turn.color !== game.color) {
console.log(`not ${name}'s turn.`)
return;
}
await sleep(1000 + Math.random() * 500);
if (game.turn.color !== game.color) { if (game.turn.color !== game.color) {
return; return;
} }
if (game.turn.actions && game.turn.actions.indexOf('place-road') !== -1) { if (game.turn.actions && game.turn.actions.indexOf('place-road') !== -1) {
index = game.turn.limits.roads[Math.floor( index = game.turn.limits.roads[Math.floor(
Math.random() * game.turn.limits.roads.length)]; Math.random() * game.turn.limits.roads.length)];
@ -258,32 +304,6 @@ const message = (ws, data) => {
return; return;
} }
if (game.private.mustDiscard) {
let mustDiscard = game.private.mustDiscard;
const cards = [],
discards = {};
const types = ['wheat', 'sheep', 'stone', 'brick', 'wood'];
types.forEach(type => {
for (let i = 0; i < game.private[type]; i++) {
cards.push(type);
}
});
while (mustDiscard--) {
const type = cards[Math.floor(Math.random() * cards.length)];
if (!(type in discards)) {
discards[type] = 1;
} else {
discards[type]++;
}
}
console.log(`discarding - `, discards);
send({
type: 'discard',
discards
});
return;
}
if (game.turn.actions if (game.turn.actions
&& game.turn.actions.indexOf('place-robber') !== -1) { && game.turn.actions.indexOf('place-robber') !== -1) {
console.log({ pips: game.turn.limits.pips }); console.log({ pips: game.turn.limits.pips });
@ -297,6 +317,10 @@ const message = (ws, data) => {
} }
if (game.turn.actions && game.turn.actions.indexOf('steal-resource') !== -1) { if (game.turn.actions && game.turn.actions.indexOf('steal-resource') !== -1) {
if (!game.turn.limits.players) {
console.warn(`No players in limits with steal-resource`);
return;
}
const { color } = game.turn.limits.players[Math.floor(Math.random() * game.turn.limits.players.length)]; const { color } = game.turn.limits.players[Math.floor(Math.random() * game.turn.limits.players.length)];
console.log(`stealing resouce from ${game.players[color].name}`); console.log(`stealing resouce from ${game.players[color].name}`);
send({ send({

View File

@ -970,6 +970,15 @@ const adminCommands = (game, action, value, query) => {
return `Not enough players in game to start.`; return `Not enough players in game to start.`;
} }
game.state = 'game-order'; game.state = 'game-order';
/* Delete any non-played colors from the player map; reduces all
* code that would otherwise have to filter out players by checking
* the 'Not active' state of player.status */
for (let key in game.players) {
if (game.players[key].status !== 'Active') {
delete game.players[key];
}
}
addChatMessage(game, null, `Admin requested to start the game.`);
break; break;
default: default:
@ -1128,7 +1137,7 @@ const setPlayerColor = (game, session, color) => {
/* Verify selection is not already taken */ /* Verify selection is not already taken */
if (color && game.players[color].status !== 'Not active') { if (color && game.players[color].status !== 'Not active') {
return `${game.sessions[color].name} already has ${colorToWord(color)}`; return `${game.players[color].name} already has ${colorToWord(color)}`;
} }
let active = getActiveCount(game); let active = getActiveCount(game);
@ -1218,6 +1227,9 @@ const addActivity = (game, session, message) => {
date++; date++;
} }
game.activities.push({ color: session ? session.color : '', message, date }); game.activities.push({ color: session ? session.color : '', message, date });
if (game.activities.length > 30) {
game.activities.splice(0, game.activities.length - 30);
}
} }
const addChatMessage = (game, session, message, isNormalChat) => { const addChatMessage = (game, session, message, isNormalChat) => {
@ -1244,6 +1256,9 @@ const addChatMessage = (game, session, message, isNormalChat) => {
entry.color = session.color; entry.color = session.color;
} }
game.chat.push(entry); game.chat.push(entry);
if (game.chat.length > 50) {
game.chat.splice(0, game.chat.length - 50);
}
}; };
const getColorFromName = (game, name) => { const getColorFromName = (game, name) => {
@ -2953,11 +2968,10 @@ const discard = (game, session, discards) => {
if (sum > player.mustDiscard) { if (sum > player.mustDiscard) {
return `You can not discard that many cards! You can only discard ${player.mustDiscard}.`; return `You can not discard that many cards! You can only discard ${player.mustDiscard}.`;
} }
/*
if (sum !== player.mustDiscard) { if (sum === 0) {
return `You need to discard ${player.mustDiscard} cards.`; return `You must discard at least one card.`;
} }
*/
for (let type in discards) { for (let type in discards) {
const count = parseInt(discards[type]); const count = parseInt(discards[type]);
@ -3506,11 +3520,13 @@ const saveGame = async (game) => {
/* Save per turn while debugging... */ /* Save per turn while debugging... */
game.step = game.step ? game.step : 0; game.step = game.step ? game.step : 0;
/*
await writeFile(`games/${game.id}.${game.step++}`, JSON.stringify(reducedGame, null, 2)) await writeFile(`games/${game.id}.${game.step++}`, JSON.stringify(reducedGame, null, 2))
.catch((error) => { .catch((error) => {
console.error(`${session.id} Unable to write to games/${game.id}`); console.error(`${session.id} Unable to write to games/${game.id}`);
console.error(error); console.error(error);
}); });
*/
await writeFile(`games/${game.id}`, JSON.stringify(reducedGame, null, 2)) await writeFile(`games/${game.id}`, JSON.stringify(reducedGame, null, 2))
.catch((error) => { .catch((error) => {
console.error(`${session.id} Unable to write to games/${game.id}`); console.error(`${session.id} Unable to write to games/${game.id}`);
@ -3718,6 +3734,9 @@ const getFilteredPlayers = (game) => {
const player = Object.assign({}, game.players[color]); const player = Object.assign({}, game.players[color]);
filtered[color] = player; filtered[color] = player;
if (player.status === 'Not active') { if (player.status === 'Not active') {
if (game.state !== 'lobby') {
delete filtered[color];
}
continue; continue;
} }
player.resources = 0; player.resources = 0;