From 7af8d028025f81ae138bddfcbf2c7c72d57f6b7e Mon Sep 17 00:00:00 2001 From: James Ketrenos Date: Wed, 2 Feb 2022 20:33:23 -0800 Subject: [PATCH] Game now sets up correct tile and pip order! Signed-off-by: James Ketrenos --- client/src/Board.js | 119 +++++++--------------------- client/src/Table.js | 13 ++-- server/routes/games.js | 173 ++++++++++++++++++++++++----------------- 3 files changed, 137 insertions(+), 168 deletions(-) diff --git a/client/src/Board.js b/client/src/Board.js index e9ee008..058e16f 100644 --- a/client/src/Board.js +++ b/client/src/Board.js @@ -3,95 +3,13 @@ import "./Board.css"; const base = process.env.PUBLIC_URL; 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 [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 [signature, setSignature] = useState(""); + const [pips, setPips] = useState(<>); + const [borders, setBorders] = useState(<>); + const [tiles, setTiles] = useState(<>); const generatePips = () => { let row = 0, rowCount = 0; @@ -104,7 +22,7 @@ const Board = ({ game }) => { : String.fromCharCode(65 + i); divs.push(
{ let y = center.y - rows.length * 0.5 * 67, 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; switch (type) { case "robber": @@ -162,7 +80,7 @@ const Board = ({ game }) => { for (let i = 0; i < count; i++) { divs.push(
{ let prev = (side == 0) ? 6 : side; const file = `borders-${side+1}.${prev}.png`; divs.push(
{ return divs; }; - const tiles = generateTiles(), - pips = generatePips(), - borders = generateBorders(); + const updateBorders = () => { + for (let i = 0; i < 6; i++) { + + } + } + 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 (
diff --git a/client/src/Table.js b/client/src/Table.js index 0527042..06fde2c 100755 --- a/client/src/Table.js +++ b/client/src/Table.js @@ -360,6 +360,9 @@ const Players = ({ table }) => { const players = []; + if (!table.game) { + return (<>); + } for (let color in table.game.players) { const item = table.game.players[color], inLobby = table.game.state === 'lobby'; if (!inLobby && item.status === 'Not active') { @@ -788,19 +791,19 @@ class Table extends React.Component { return ""; } const signature = - game.borders.map(border => border.file.replace(/borders-(.).*/, "$1")).join('') + - game.pips.map(pip => pip.roll.toString()).join('') + - game.tiles.map(tile => tile.type.charAt(0)).join(''); + game.borderOrder.map(border => Number(border).toString(16)).join('') + '-' + + game.pipOrder.map(pip => Number(pip).toString(16)).join('') + '-' + + game.tileOrder.map(tile => Number(tile).toString(16)).join(''); return signature; }; updateGame(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); + this.setState( { game: game }); this.game = game; } diff --git a/server/routes/games.js b/server/routes/games.js index 4a83a4c..cf5770e 100755 --- a/server/routes/games.js +++ b/server/routes/games.js @@ -36,54 +36,54 @@ function shuffle(array) { const assetData = { tiles: [ - { type: "wood", y: 0. / 4. }, - { type: "wood", y: 1. / 4. }, - { type: "wood", y: 2. / 4. }, - { type: "wood", y: 3. / 4. }, - { type: "wheat", y: 0. / 4. }, - { type: "wheat", y: 1. / 4. }, - { type: "wheat", y: 2. / 4. }, - { type: "wheat", y: 3. / 4. }, - { type: "stone", y: 0. / 4. }, - { type: "stone", y: 1. / 4. }, - { type: "stone", y: 2. / 4. }, - { type: "sheep", y: 0. / 4. }, - { type: "sheep", y: 1. / 4. }, - { type: "sheep", y: 2. / 4. }, - { type: "sheep", y: 3. / 4. }, - { type: "brick", y: 0. / 4. }, - { type: "brick", y: 1. / 4. }, - { type: "brick", y: 2. / 4. }, - { type: "robber", y: 0 } + "wood", + "wood", + "wood", + "wood", + "wheat", + "wheat", + "wheat", + "wheat", + "stone", + "stone", + "stone", + "sheep", + "sheep", + "sheep", + "sheep", + "brick", + "brick", + "brick", + "robber" ], pips: [ - { roll: 7, pips: 0, y: 3. / 6., x: 0. / 6. }, - { roll: 5, pips: 4, y: 0. / 6., x: 0. / 6. }, - { roll: 2, pips: 1, y: 0. / 6., x: 1. / 6. }, - { roll: 6, pips: 5, y: 0. / 6., x: 2. / 6. }, - { roll: 3, pips: 2, y: 0. / 6., x: 3. / 6. }, - { roll: 8, pips: 5, y: 0. / 6., x: 4. / 6. }, - { roll: 10, pips: 3, y: 0. / 6., x: 5. / 6. }, - { roll: 9, pips: 4, y: 1. / 6., x: 0. / 6. }, - { roll: 12, pips: 1, y: 1. / 6., x: 1. / 6. }, - { roll: 11, pips: 2, y: 1. / 6., x: 2. / 6. }, - { roll: 4, pips: 3, y: 1. / 6., x: 3. / 6. }, - { roll: 8, pips: 5, y: 1. / 6., x: 4. / 6. }, - { roll: 10, pips: 3, y: 1. / 6., x: 5. / 6. }, - { roll: 9, pips: 4, y: 2. / 6., x: 0. / 6. }, - { roll: 4, pips: 3, y: 2. / 6., x: 1. / 6. }, - { roll: 5, pips: 4, y: 2. / 6., x: 2. / 6. }, - { roll: 6, pips: 6, y: 2. / 6., x: 3. / 6. }, - { roll: 3, pips: 2, y: 2. / 6., x: 4. / 6. }, - { roll: 11, pips: 2, y: 2. / 6., x: 5. / 6. } + { roll: 7, pips: 0 }, + { roll: 5, pips: 4 }, + { roll: 2, pips: 1 }, + { roll: 6, pips: 5 }, + { roll: 3, pips: 2 }, + { roll: 8, pips: 5 }, + { roll: 10, pips: 3 }, + { roll: 9, pips: 4 }, + { roll: 12, pips: 1 }, + { roll: 11, pips: 2 }, + { roll: 4, pips: 3 }, + { roll: 8, pips: 5 }, + { roll: 10, pips: 3 }, + { roll: 9, pips: 4 }, + { roll: 4, pips: 3 }, + { roll: 5, pips: 4 }, + { roll: 6, pips: 6 }, + { roll: 3, pips: 2 }, + { roll: 11, pips: 2 } ], borders: [ - { file: 'borders-1.6.png', left: "sheep", right: "bank" }, - { file: 'borders-2.1.png', center: "sheep" }, - { file: 'borders-3.2.png', left: "wheat", right: "bank" }, - { file: 'borders-4.3.png', center: "wood" }, - { file: 'borders-5.4.png', left: "sheep", right: "bank" }, - { file: 'borders-6.5.png', center: "bank" } + { left: "sheep", right: "bank" }, + { center: "sheep" }, + { left: "wheat", right: "bank" }, + { center: "wood" }, + { left: "sheep", right: "bank" }, + { center: "bank" } ], 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 */ for (let id in game.sessions) { const session = game.sessions[id]; @@ -590,9 +601,6 @@ const createGame = (id) => { startTime: Date.now(), turns: 0, state: "lobby", /* lobby, active, finished */ - tiles: [], - pips: [], - borders: [], tokens: [], players: { R: getPlayer(), @@ -612,6 +620,11 @@ const createGame = (id) => { chat: [ { date: Date.now(), message: `New game started for ${id}` } ], id: id }; + + [ "pips", "borders", "tiles" ].forEach((field) => { + game[field] = assetData[field] + }); + games[game.id] = game; shuffleBoard(game); console.log(`New game created: ${game.id}`); @@ -633,32 +646,52 @@ router.post("/:id?", (req, res/*, next*/) => { }); const shuffleBoard = (game) => { - [ "tiles", "pips", "borders" ].forEach((field) => { - game[field] = [] - for (let i = 0; i < assetData[field].length; i++) { - game[field].push(i); - } - /* Shuffle an array of indexes */ - shuffle(game[field]); - /* Convert from an index array to a full array */ - for (let i = 0; i < assetData[field].length; i++) { - game[field][i] = assetData[field][game[field][i]]; - } - }); + const seq = []; + for (let i = 0; i < 6; i++) { + seq.push(i); + } + shuffle(seq); + game.borderOrder = seq.slice(); + for (let i = 6; i < 19; i++) { + seq.push(i); + } + shuffle(seq); + game.tileOrder = seq.slice(); - /* Walk through the board looking for the robber and - * if it isn't on the desert, swap with the desert to - * be under the robber */ - const robberIndex = game.pips.findIndex((pip) => pip.roll === 7), - desertIndex = game.tiles.findIndex((tile) => tile.type === 'robber'); - - if (robberIndex !== desertIndex) { - let tmp = game.tiles[desertIndex]; - game.tiles[desertIndex] = game.tiles[robberIndex]; - game.tiles[robberIndex] = tmp; + /* Pip order is from one of the random corners, then rotate around + * and skip over the desert (robber) */ + + /* Board: + * 0 1 2 + * 3 4 5 6 + * 7 8 9 10 11 + * 12 13 14 15 + * 16 17 18 + */ + 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) } /*