diff --git a/packages/server/services/Game.js b/packages/server/services/Game.js index dcdae92..20dcecc 100644 --- a/packages/server/services/Game.js +++ b/packages/server/services/Game.js @@ -244,28 +244,57 @@ const Game = ({ gameData = {}, gameRecord = [] } = {}) => { }; }, + checkMove: function ({ player, pos: { x, y } }) { + // if game is over + // TODO either change logic here or add additional method for handling moves off of record + if (this.pass > 1) { + return { ...this, success: false }; + } + const point = this.boardState[`${x}-${y}`]; + const isTurn = + (this.turn === 1 && player === "black") || + (this.turn === -1 && player === "white"); + if (isTurn) { + if (point.legal) { + return { ...this, success: true, move: { player, pos: { x, y } } }; + } + } + return { ...this, success: false }; + }, + makeMove: function ({ player, pos: { x, y } }) { if (this.pass > 1) { return { ...this, success: false }; } - if (x === 0) return this.submitPass(player); - let game = this; + if (x === 0) return game.submitPass(player); + let success = false; - const point = game.boardState[`${x}-${y}`]; - const isTurn = - (game.turn === 1 && player === "black") || - (game.turn === -1 && player === "white"); - if (isTurn) { - if (point.legal) { - game.pass = 0; - game.addToRecord({ player, pos: { x, y } }); - if (this.kos.length) helper.clearKo.call(this); - point.makeMove(game); - game.turn *= -1; - success = true; - } + let game = this; + + // if checkMove has not been run, determine legality + if (!game.move) { + game = game.checkMove({ player, pos: { x, y } }); + } + if ( + // if move is legal + // ? unclear if checking move values is beneficial to prevent race conditions + game.move && + game.move.player === player && + game.move.pos.x === x && + game.move.pos.y + ) { + const point = game.boardState[`${x}-${y}`]; + game.pass = 0; + // allows for recording of prior move on game record + game.addToRecord(game.move); + if (game.kos.length) helper.clearKo.call(game); + point.makeMove(game); + game.turn *= -1; + success = true; } game.boardState = getBoardState(game); + // remove move attribute to prevent duplicate moves + delete game.move; return { ...game, legalMoves: getLegalMoves(game), success }; }, diff --git a/packages/server/services/gameServices.js b/packages/server/services/gameServices.js index d0c9d4d..f94ed1e 100644 --- a/packages/server/services/gameServices.js +++ b/packages/server/services/gameServices.js @@ -7,6 +7,29 @@ const GameService = ({ moveQueries, gameQueries }) => { }; const gamesInProgress = {}; + const storeMove = (gameId) => async ({ player, pos: { x, y } }) => { + let move = { player, pos: { x, y } }; + try { + if (moveQueries) { + const { id } = await moveQueries.addMove({ + gameId, + player, + x, + y, + gameRecord: true, + priorMove: null, + }); + move.id = id; + move.success = true; + } + } catch (e) { + console.log(e); + move.success = false; + } finally { + return move; + } + }; + return { initGame({ id, gameRecord = [], ...gameData }) { if (gamesInProgress[id]) return this.getDataForUI(id); @@ -31,6 +54,7 @@ const GameService = ({ moveQueries, gameQueries }) => { return { message: "error restoring game" }; } } + gamesInProgress[id] = await gamesInProgress[id].checkMove(move); gamesInProgress[id] = gamesInProgress[id].makeMove(move); if (gamesInProgress[id].success === false) return { message: "illegal move" }; diff --git a/packages/server/socket.js b/packages/server/socket.js index c308053..f183c37 100644 --- a/packages/server/socket.js +++ b/packages/server/socket.js @@ -1,4 +1,4 @@ -// TODO const someSocketLogic = require('./middleware/socketssockets/...'); +// TODO const someSocketLogic = require('./middleware/sockets/...'); const socketIO = require("socket.io"); const io = socketIO({ cookie: false }); @@ -24,6 +24,7 @@ io.on("connection", async (socket) => { socket.on("connect_game", (data) => { const game = `game-${data.game.id}`; socket.join(game, async () => { + // TODO move this logic into game service const gameData = await gameQueries.findGameById(data.game.id); const convertWinType = (winType) => { if (winType.includes("B")) return 1; @@ -51,7 +52,6 @@ io.on("connection", async (socket) => { socket.on("make_move", async (data) => { const { user, move, board, game, room } = data; const gameNsp = `game-${data.game.id}`; - try { const { board, message, ...meta } = await gameServices.makeMove({ id: data.game.id,