Robot AI fixes
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
parent
84c8657b55
commit
446d4d49e2
@ -129,7 +129,7 @@ const Activities = () => {
|
|||||||
}));
|
}));
|
||||||
}, [ws, fields]);
|
}, [ws, fields]);
|
||||||
|
|
||||||
if (!timestamp || !color) {
|
if (!timestamp) {
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
@ -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}/>
|
||||||
|
@ -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
|
||||||
|
@ -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`,
|
||||||
|
@ -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':
|
||||||
console.log(`ws - receive - `,
|
|
||||||
Object.assign({}, data.update, {
|
|
||||||
activities: 'filtered out',
|
|
||||||
chat: 'filtered out'
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
Object.assign(game, data.update);
|
Object.assign(game, data.update);
|
||||||
|
delete data.update.chat;
|
||||||
|
delete data.update.activities;
|
||||||
|
console.log(`ws - receive - `,
|
||||||
|
data.update
|
||||||
|
);
|
||||||
|
|
||||||
console.log(`state - ${game.state}`);
|
console.log(`state - ${game.state}`);
|
||||||
|
|
||||||
switch (game.state) {
|
switch (game.state) {
|
||||||
@ -198,13 +206,14 @@ const message = (ws, data) => {
|
|||||||
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({
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user