1
0

Game now sets up correct tile and pip order!

Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
James Ketrenos 2022-02-02 20:33:23 -08:00
parent 27cf10ad48
commit 7af8d02802
3 changed files with 137 additions and 168 deletions

View File

@ -3,95 +3,13 @@ import "./Board.css";
const base = process.env.PUBLIC_URL; const base = process.env.PUBLIC_URL;
const assetsPath = `${base}/assets`; const assetsPath = `${base}/assets`;
const images = {};
const getPlayerColors = (color) => {
switch (color) {
case "O":
return {
strokeStyle: "white",
fillStyle: "#ff5722"
}
case "R":
return {
strokeStyle: "white",
fillStyle: "#f44336"
}
case "W":
return {
strokeStyle: "black",
fillStyle: "#9e9e9e"
}
case "B":
return {
strokeStyle: "black",
fillStyle: "#03a9f4"
}
default:
return {
strokeStyle: "rgb(16, 16, 16)",
fillStyle: "rgb(64, 64, 64)"
}
};
};
const hexagonRatio = 1.1547005,
tileHeight = 0.16,
tileWidth = tileHeight * hexagonRatio,
roadSize = tileHeight * 0.5 * (5. / 8.),
settlementSize = tileHeight * 0.5 - roadSize;
const imageLoaded = (event) => {
const image = event.target;
console.log(`Done loading ${image.src}`);
image.removeEventListener("load", imageLoaded);
image.removeEventListener("error", imageLoadError);
try {
if (image.drawFrame) {
window.requestAnimationFrame(image.drawFrame);
}
} catch (error) {
image.board = null;
}
};
const imageLoadError = (event) => {
const image = event.target;
console.log(`Error loading ${image.src}`);
image.removeEventListener("load", imageLoaded);
image.removeEventListener("error", imageLoadError);
console.log(`Error loading ${image.src}`);
}
const loadImage = (file, drawFrame) => {
if (file in images) {
images[file].drawFrame = drawFrame;
return images[file];
}
const image = new Image();
image.drawFrame = drawFrame;
images[file] = image;
image.addEventListener("load", imageLoaded);
image.addEventListener("error", imageLoadError);
image.src = `${assetsPath}/gfx/${file}`;
return image;
}
const Board = ({ game }) => { const Board = ({ game }) => {
const [closest, setClosest] = useState({
info: {},
tile: null,
road: null,
tradeToken: null,
settlement: null
});
const center = { x: 300, y: 350 }, rows = [3, 4, 5, 4, 3]; const center = { x: 300, y: 350 }, rows = [3, 4, 5, 4, 3];
const [signature, setSignature] = useState("");
const [pips, setPips] = useState(<></>);
const [borders, setBorders] = useState(<></>);
const [tiles, setTiles] = useState(<></>);
const generatePips = () => { const generatePips = () => {
let row = 0, rowCount = 0; let row = 0, rowCount = 0;
@ -104,7 +22,7 @@ const Board = ({ game }) => {
: String.fromCharCode(65 + i); : String.fromCharCode(65 + i);
divs.push( divs.push(
<div <div
key={`pip-${code}`} key={`pip-${(i).toString(16)}`}
className="Pip" className="Pip"
style={{ style={{
top: `${y}px`, top: `${y}px`,
@ -132,7 +50,7 @@ const Board = ({ game }) => {
let y = center.y - rows.length * 0.5 * 67, let y = center.y - rows.length * 0.5 * 67,
x = center.x - (rows[row] - 1) * 0.5 * 77.5; x = center.x - (rows[row] - 1) * 0.5 * 77.5;
return [ "robber", "brick", "wood", "sheep", "stone", "wheat" ].map((type) => { return [ "wood", "wheat", "stone", "sheep", "brick", "robber" ].map((type) => {
let count; let count;
switch (type) { switch (type) {
case "robber": case "robber":
@ -162,7 +80,7 @@ const Board = ({ game }) => {
for (let i = 0; i < count; i++) { for (let i = 0; i < count; i++) {
divs.push( divs.push(
<div <div
key={`${type}-${i}`} key={`${type}-${(i).toString(16)}`}
className="Tile" className="Tile"
style={{ style={{
top: `${y}px`, top: `${y}px`,
@ -196,7 +114,7 @@ const Board = ({ game }) => {
let prev = (side == 0) ? 6 : side; let prev = (side == 0) ? 6 : side;
const file = `borders-${side+1}.${prev}.png`; const file = `borders-${side+1}.${prev}.png`;
divs.push(<div divs.push(<div
key={`border-${side}`} key={`border-${side.toString(16)}`}
className="Border" className="Border"
style={{ style={{
top: `${y}px`, top: `${y}px`,
@ -208,9 +126,24 @@ const Board = ({ game }) => {
return divs; return divs;
}; };
const tiles = generateTiles(), const updateBorders = () => {
pips = generatePips(), for (let i = 0; i < 6; i++) {
borders = generateBorders();
}
}
useEffect(() => {
if (game && game.signature != signature) {
console.log(`Generate for ${game.signature}`);
setPips(generatePips);
setBorders(generateBorders);
setTiles(generateTiles);
setSignature(game.signature);
} else {
if (!game) {
console.log(`No game in Board`);
}
}
}, [ setPips, setBorders, setTiles, setSignature, game]);
return ( return (
<div className="Board" style={{backgroundImage: `url(${assetsPath}/gfx/tabletop.png)`}}> <div className="Board" style={{backgroundImage: `url(${assetsPath}/gfx/tabletop.png)`}}>

View File

@ -360,6 +360,9 @@ const Players = ({ table }) => {
const players = []; const players = [];
if (!table.game) {
return (<></>);
}
for (let color in table.game.players) { for (let color in table.game.players) {
const item = table.game.players[color], inLobby = table.game.state === 'lobby'; const item = table.game.players[color], inLobby = table.game.state === 'lobby';
if (!inLobby && item.status === 'Not active') { if (!inLobby && item.status === 'Not active') {
@ -788,19 +791,19 @@ class Table extends React.Component {
return ""; return "";
} }
const signature = const signature =
game.borders.map(border => border.file.replace(/borders-(.).*/, "$1")).join('') + game.borderOrder.map(border => Number(border).toString(16)).join('') + '-' +
game.pips.map(pip => pip.roll.toString()).join('') + game.pipOrder.map(pip => Number(pip).toString(16)).join('') + '-' +
game.tiles.map(tile => tile.type.charAt(0)).join(''); game.tileOrder.map(tile => Number(tile).toString(16)).join('');
return signature; return signature;
}; };
updateGame(game) { updateGame(game) {
if (this.state.signature !== this.gameSignature(game)) { if (this.state.signature !== this.gameSignature(game)) {
this.setState({ signature: this.gameSignature(game), game: game }); game.signature = this.gameSignature(game);
} }
// console.log("Update Game", game); // console.log("Update Game", game);
this.setState( { game: game });
this.game = game; this.game = game;
} }

View File

@ -36,54 +36,54 @@ function shuffle(array) {
const assetData = { const assetData = {
tiles: [ tiles: [
{ type: "wood", y: 0. / 4. }, "wood",
{ type: "wood", y: 1. / 4. }, "wood",
{ type: "wood", y: 2. / 4. }, "wood",
{ type: "wood", y: 3. / 4. }, "wood",
{ type: "wheat", y: 0. / 4. }, "wheat",
{ type: "wheat", y: 1. / 4. }, "wheat",
{ type: "wheat", y: 2. / 4. }, "wheat",
{ type: "wheat", y: 3. / 4. }, "wheat",
{ type: "stone", y: 0. / 4. }, "stone",
{ type: "stone", y: 1. / 4. }, "stone",
{ type: "stone", y: 2. / 4. }, "stone",
{ type: "sheep", y: 0. / 4. }, "sheep",
{ type: "sheep", y: 1. / 4. }, "sheep",
{ type: "sheep", y: 2. / 4. }, "sheep",
{ type: "sheep", y: 3. / 4. }, "sheep",
{ type: "brick", y: 0. / 4. }, "brick",
{ type: "brick", y: 1. / 4. }, "brick",
{ type: "brick", y: 2. / 4. }, "brick",
{ type: "robber", y: 0 } "robber"
], ],
pips: [ pips: [
{ roll: 7, pips: 0, y: 3. / 6., x: 0. / 6. }, { roll: 7, pips: 0 },
{ roll: 5, pips: 4, y: 0. / 6., x: 0. / 6. }, { roll: 5, pips: 4 },
{ roll: 2, pips: 1, y: 0. / 6., x: 1. / 6. }, { roll: 2, pips: 1 },
{ roll: 6, pips: 5, y: 0. / 6., x: 2. / 6. }, { roll: 6, pips: 5 },
{ roll: 3, pips: 2, y: 0. / 6., x: 3. / 6. }, { roll: 3, pips: 2 },
{ roll: 8, pips: 5, y: 0. / 6., x: 4. / 6. }, { roll: 8, pips: 5 },
{ roll: 10, pips: 3, y: 0. / 6., x: 5. / 6. }, { roll: 10, pips: 3 },
{ roll: 9, pips: 4, y: 1. / 6., x: 0. / 6. }, { roll: 9, pips: 4 },
{ roll: 12, pips: 1, y: 1. / 6., x: 1. / 6. }, { roll: 12, pips: 1 },
{ roll: 11, pips: 2, y: 1. / 6., x: 2. / 6. }, { roll: 11, pips: 2 },
{ roll: 4, pips: 3, y: 1. / 6., x: 3. / 6. }, { roll: 4, pips: 3 },
{ roll: 8, pips: 5, y: 1. / 6., x: 4. / 6. }, { roll: 8, pips: 5 },
{ roll: 10, pips: 3, y: 1. / 6., x: 5. / 6. }, { roll: 10, pips: 3 },
{ roll: 9, pips: 4, y: 2. / 6., x: 0. / 6. }, { roll: 9, pips: 4 },
{ roll: 4, pips: 3, y: 2. / 6., x: 1. / 6. }, { roll: 4, pips: 3 },
{ roll: 5, pips: 4, y: 2. / 6., x: 2. / 6. }, { roll: 5, pips: 4 },
{ roll: 6, pips: 6, y: 2. / 6., x: 3. / 6. }, { roll: 6, pips: 6 },
{ roll: 3, pips: 2, y: 2. / 6., x: 4. / 6. }, { roll: 3, pips: 2 },
{ roll: 11, pips: 2, y: 2. / 6., x: 5. / 6. } { roll: 11, pips: 2 }
], ],
borders: [ borders: [
{ file: 'borders-1.6.png', left: "sheep", right: "bank" }, { left: "sheep", right: "bank" },
{ file: 'borders-2.1.png', center: "sheep" }, { center: "sheep" },
{ file: 'borders-3.2.png', left: "wheat", right: "bank" }, { left: "wheat", right: "bank" },
{ file: 'borders-4.3.png', center: "wood" }, { center: "wood" },
{ file: 'borders-5.4.png', left: "sheep", right: "bank" }, { left: "sheep", right: "bank" },
{ file: 'borders-6.5.png', center: "bank" } { center: "bank" }
], ],
developmentCards: [] developmentCards: []
}; };
@ -201,6 +201,17 @@ const loadGame = async (id) => {
} }
} }
if (!game.pipOrder || !game.borderOrder || !game.tileOrder) {
console.log("Shuffling old save file");
shuffleBoard(game);
}
if (!game.pips || !game.borders || !game.tiles) {
[ "pips", "borders", "tiles" ].forEach((field) => {
game[field] = assetData[field]
});
}
/* Reconnect session player colors to the player objects */ /* Reconnect session player colors to the player objects */
for (let id in game.sessions) { for (let id in game.sessions) {
const session = game.sessions[id]; const session = game.sessions[id];
@ -590,9 +601,6 @@ const createGame = (id) => {
startTime: Date.now(), startTime: Date.now(),
turns: 0, turns: 0,
state: "lobby", /* lobby, active, finished */ state: "lobby", /* lobby, active, finished */
tiles: [],
pips: [],
borders: [],
tokens: [], tokens: [],
players: { players: {
R: getPlayer(), R: getPlayer(),
@ -612,6 +620,11 @@ const createGame = (id) => {
chat: [ { date: Date.now(), message: `New game started for ${id}` } ], chat: [ { date: Date.now(), message: `New game started for ${id}` } ],
id: id id: id
}; };
[ "pips", "borders", "tiles" ].forEach((field) => {
game[field] = assetData[field]
});
games[game.id] = game; games[game.id] = game;
shuffleBoard(game); shuffleBoard(game);
console.log(`New game created: ${game.id}`); console.log(`New game created: ${game.id}`);
@ -633,32 +646,52 @@ router.post("/:id?", (req, res/*, next*/) => {
}); });
const shuffleBoard = (game) => { const shuffleBoard = (game) => {
[ "tiles", "pips", "borders" ].forEach((field) => { const seq = [];
game[field] = [] for (let i = 0; i < 6; i++) {
for (let i = 0; i < assetData[field].length; i++) { seq.push(i);
game[field].push(i); }
} shuffle(seq);
/* Shuffle an array of indexes */ game.borderOrder = seq.slice();
shuffle(game[field]); for (let i = 6; i < 19; i++) {
/* Convert from an index array to a full array */ seq.push(i);
for (let i = 0; i < assetData[field].length; i++) { }
game[field][i] = assetData[field][game[field][i]]; shuffle(seq);
} game.tileOrder = seq.slice();
});
/* Walk through the board looking for the robber and /* Pip order is from one of the random corners, then rotate around
* if it isn't on the desert, swap with the desert to * and skip over the desert (robber) */
* be under the robber */
const robberIndex = game.pips.findIndex((pip) => pip.roll === 7), /* Board:
desertIndex = game.tiles.findIndex((tile) => tile.type === 'robber'); * 0 1 2
* 3 4 5 6
if (robberIndex !== desertIndex) { * 7 8 9 10 11
let tmp = game.tiles[desertIndex]; * 12 13 14 15
game.tiles[desertIndex] = game.tiles[robberIndex]; * 16 17 18
game.tiles[robberIndex] = tmp; */
const order = [
[ 0, 1, 2, 6, 11, 15, 18, 17, 16, 12, 7, 3, 4, 5, 10, 14, 13, 8, 9 ],
[ 2, 6, 11, 15, 18, 17, 16, 12, 7, 3, 0, 1, 5, 10, 14, 13, 8, 4, 9 ],
[ 11, 15, 18, 17, 16, 12, 7, 3, 0, 1, 2, 6, 10, 14, 13, 8, 4, 5, 9 ],
[ 18, 17, 16, 12, 7, 3, 0, 1, 2, 6, 11, 15, 14, 13, 8, 4, 5, 10, 9 ],
[ 16, 12, 7, 3, 0, 1, 2, 6, 11, 15, 18, 17, 13, 8, 4, 5, 10, 14, 9 ],
[ 7, 3, 0, 1, 2, 6, 11, 15, 18, 17, 16, 12, 8, 4, 5, 10, 14, 13, 9 ]
]
const sequence = order[Math.floor(Math.random() * order.length)];
game.pipOrder = [];
for (let i = 0, p = 0; i < sequence.length; i++) {
const target = sequence[i];
/* If the target tile is the desert (18), then set the
* pip value to the robber (0) otherwise set
* the target pip value to the currently incremeneting
* pip value. */
if (game.tileOrder[target] === 18) {
game.pipOrder[target] = 0;
} else {
game.pipOrder[target] = p++;
}
} }
shuffle(game.developmentCards) shuffle(game.developmentCards)
} }
/* /*