From 8fb1b80cb6d32a778645992baa6ad31ed14efcb8 Mon Sep 17 00:00:00 2001 From: Sorrel Bri Date: Sat, 18 Apr 2020 20:04:00 -0700 Subject: [PATCH] add initGame to v2 Game logic service --- packages/server/services/Game.js | 7 -- packages/server/services/Game.v2.js | 145 +++++++++++++++++++++++++++ packages/server/test/Game.v2.spec.js | 49 +++++++++ 3 files changed, 194 insertions(+), 7 deletions(-) create mode 100644 packages/server/services/Game.v2.js create mode 100644 packages/server/test/Game.v2.spec.js diff --git a/packages/server/services/Game.js b/packages/server/services/Game.js index 3d255ff..c2f9834 100644 --- a/packages/server/services/Game.js +++ b/packages/server/services/Game.js @@ -6,12 +6,6 @@ const STONES_DATA = { 'k': 'ko' } -const DOTS_DATA = { - '-1': 'white', - '0': 'none', - '1': 'black', - 'd': 'dame', -} // index corresponds to difference in player rank const KOMI_REC = { @@ -138,7 +132,6 @@ class Game { makeMove = (move) => { const player = move.player === 'white' ? -1 : 1; const point = this.findPointFromIdx([move.pos.x, move.pos.y]) - console.log([move.pos.x, move.pos.y]) if ( !checkLegal(point, this) ) throw Error('illegal move'); clearKo(this); clearPass(this); diff --git a/packages/server/services/Game.v2.js b/packages/server/services/Game.v2.js new file mode 100644 index 0000000..bd99b85 --- /dev/null +++ b/packages/server/services/Game.v2.js @@ -0,0 +1,145 @@ +/*----- constants -----*/ +const STONES_DATA = { + '-1': 'white', + '0': 'none', + '1': 'black', + 'k': 'ko' +} + + +// index corresponds to difference in player rank +const KOMI_REC = { + '9': [ + 5.5, 2.5, -0.5, -3.5, -6.5, -9.5, 12.5, 15.5, 18.5, 21.5 + ], + '13': [ + 5.5, 0.5, -5.5, 0.5, -5.5, 0.5, -5.5, 0.5, -5.5, 0.5 + ], + '19': [ + 7.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5 + ] +} + +const HANDI_REC = { + '9': [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ], + '13': [ + 0, 0, 0, 2, 2, 3, 3, 4, 4, 5 + ], + '19': [ + 0, 0, 2, 3, 4, 5, 6, 7, 8, 9 + ] +} + +// index represents handicap placement for different board-sizes, eg handiPlace['9][1] = { (3, 3), (7, 7) } +// last array in each property also used for hoshi rendering +const HANDI_PLACE = { + '9' : [ + 0, 0, + [[ 7, 3 ], [ 3, 7 ] ], + [ [ 7, 7 ], [ 7, 3 ], [ 3, 7 ] ], + [ [ 3, 3 ], [ 7, 7 ], [ 3, 7 ], [ 7, 3 ] ] + ], + '13' : [ + 0, 0, + [ [ 4, 10 ], [ 10, 4 ] ], + [ [ 10, 10 ], [ 4, 10 ], [ 10, 4] ], + [ [ 4, 4 ], [ 10, 10 ], [ 4, 10 ], [ 10, 4] ], + [ [ 7, 7 ], [ 4, 4 ], [ 10, 10 ], [ 4, 10 ], [ 10, 4] ], + [ [ 7, 4 ], [ 4, 7 ], [ 4, 4 ], [ 10, 10 ], [ 4, 10 ], [ 10, 4] ], + [ [ 7, 7 ], [ 7, 4 ], [ 4, 7 ], [ 4, 4 ], [ 10, 10 ], [ 4, 10 ], [ 10, 4] ], + [ [ 10, 7 ], [ 7, 4 ], [ 7, 10 ], [ 4, 7 ], [ 4, 4 ], [ 10, 10 ], [ 4, 10 ], [ 10, 4] ], + [ [ 7, 7 ], [ 10, 7 ], [ 7, 4 ], [ 7, 10 ], [ 4, 7 ], [ 4, 4 ], [ 10, 10 ], [ 4, 10 ], [ 10, 4] ], + ], + '19' : [ + 0, 0, + [ [ 4, 16 ], [ 16, 4 ] ], + [ [ 16, 16 ], [ 4, 16 ], [ 16, 4] ], + [ [ 4, 4 ], [ 16, 16 ], [ 4, 16 ], [ 16, 4] ], + [ [ 10, 10 ], [ 4, 4 ], [ 16, 16 ], [ 4, 16 ], [ 16, 4] ], + [ [ 10, 4 ], [ 4, 10 ], [ 4, 4 ], [ 16, 16 ], [ 4, 16 ], [ 16, 4] ], + [ [ 10, 10 ], [ 10, 4 ], [ 4, 10 ], [ 4, 4 ], [ 16, 16 ], [ 4, 16 ], [ 16, 4] ], + [ [ 16, 10 ], [ 10, 4 ], [ 10, 16 ], [ 4, 10 ], [ 4, 4 ], [ 16, 16 ], [ 4, 16 ], [ 16, 4] ], + [ [ 10, 10 ], [ 16, 10 ], [ 10, 4 ], [ 10, 16 ], [ 4, 10 ], [ 4, 4 ], [ 16, 16 ], [ 4, 16 ], [ 16, 4] ], + ] +}; + +const pipeMap = (...funcs) => obj => { + const arr = Object.entries(obj).reduce((acc, [key, value]) => { + funcs.forEach(func => value = func(value)); + return [...acc, [key, value]]; + },[]); + return arr.reduce((acc, [key, value]) => { + return { ...acc, [key]: value } + }, {}); +} + +const checkLegal = ({ point, Game }) => { + return 'l'; +} + +const getBoardState = (Game) => { + const getLegal = point => checkLegal({ point, Game }); + return pipeMap(getLegal)(Game.boardState); +} + +const initBoard = boardSize => { + const boardState = {}; + for (let i = 0; i < Math.pow(boardSize, 2); i++) { + const point = Point({ + x: Math.floor(i / boardSize) + 1, + y: i % boardSize + 1, + boardSize + }); + boardState[`${point.pos.x}-${point.pos.y}`] = point; + } + return boardState; +} + +// returns Game object +const Game = ({gameData, gameRecord} = {}) => ({ + winner: gameData ? gameData.winner : null, + turn: gameData ? gameData.turn : 1, // turn logic depends on handicap stones + pass: gameData ? gameData.pass : 0, // -1 represents state in which resignation has been submitted, not confirmed + komi: gameData ? gameData.komi : 6.5, // komi depends on handicap stones + player rank + handicap: gameData ? gameData.handicap : 0, + boardSize: gameData ? gameData.boardSize : 19, + groups: {}, + boardState: {}, + gameRecord: gameRecord || [], + playerState: gameData ? gameData.playerState : { + bCaptures: 0, + wCaptures: 0, + bScore: 0, + wScore: 0 + }, + + initGame: function() { + this.winner = null; + this.pass = 0; + this.turn = this.handicap ? -1 : 1; + this.boardState = initBoard(this.boardSize) + return getBoardState(this); + } +}); + +const Point = ({x, y, boardSize = 19}) => ({ + pos: {x, y}, + stone: 0, // can be 1, -1, 0, or 'k' for ko + legal: 0, + territory: 0, + capturing: [], + groupMembers: [ this ], + neighbors: { + top: x > 1 ? `${ x - 1 }-${ y }` : null, + btm: x < boardSize ? `${ x + 1 }-${ y }` : null, + rgt: y < boardSize ? `${ x }-${ y + 1 }` : null, + lft: y > 1 ? `${ x }-${ y - 1 }` : null + } +}); + +module.exports = { + Game, + Point +} \ No newline at end of file diff --git a/packages/server/test/Game.v2.spec.js b/packages/server/test/Game.v2.spec.js new file mode 100644 index 0000000..43122c2 --- /dev/null +++ b/packages/server/test/Game.v2.spec.js @@ -0,0 +1,49 @@ +const chai = require('chai'); +const should = chai.should(); +const { Game, Point } = require('../services/Game.v2'); + +describe('Game v2', () => { + it('smoke test Game', done => { + (typeof Game()).should.eql('object'); + done(); + }); + + it('smoke test Point', done => { + (typeof Point({x: 1, y: 1})).should.eql('object'); + done(); + }); + + it('smoke test init Game', done => { + (typeof Game().initGame()).should.eql('object'); + done(); + }) +}); + +describe('Game.initGame()', () => { + it('init Game returns boardState', done => { + Game().initGame().should.eql(emptyBoard); + done(); + }) +}) + +const emptyBoard = { + '1-1': 'l','1-2': 'l','1-3': 'l','1-4': 'l','1-5': 'l','1-6': 'l','1-7': 'l','1-8': 'l','1-9': 'l','1-10': 'l','1-11': 'l','1-12': 'l','1-13': 'l','1-14': 'l','1-15': 'l','1-16': 'l','1-17': 'l','1-18': 'l','1-19': 'l', + '2-1': 'l','2-2': 'l','2-3': 'l','2-4': 'l','2-5': 'l','2-6': 'l','2-7': 'l','2-8': 'l','2-9': 'l','2-10': 'l','2-11': 'l','2-12': 'l','2-13': 'l','2-14': 'l','2-15': 'l','2-16': 'l','2-17': 'l','2-18': 'l','2-19': 'l', + '3-1': 'l','3-2': 'l','3-3': 'l','3-4': 'l','3-5': 'l','3-6': 'l','3-7': 'l','3-8': 'l','3-9': 'l','3-10': 'l','3-11': 'l','3-12': 'l','3-13': 'l','3-14': 'l','3-15': 'l','3-16': 'l','3-17': 'l','3-18': 'l','3-19': 'l', + '4-1': 'l','4-2': 'l','4-3': 'l','4-4': 'l','4-5': 'l','4-6': 'l','4-7': 'l','4-8': 'l','4-9': 'l','4-10': 'l','4-11': 'l','4-12': 'l','4-13': 'l','4-14': 'l','4-15': 'l','4-16': 'l','4-17': 'l','4-18': 'l','4-19': 'l', + '5-1': 'l','5-2': 'l','5-3': 'l','5-4': 'l','5-5': 'l','5-6': 'l','5-7': 'l','5-8': 'l','5-9': 'l','5-10': 'l','5-11': 'l','5-12': 'l','5-13': 'l','5-14': 'l','5-15': 'l','5-16': 'l','5-17': 'l','5-18': 'l','5-19': 'l', + '6-1': 'l','6-2': 'l','6-3': 'l','6-4': 'l','6-5': 'l','6-6': 'l','6-7': 'l','6-8': 'l','6-9': 'l','6-10': 'l','6-11': 'l','6-12': 'l','6-13': 'l','6-14': 'l','6-15': 'l','6-16': 'l','6-17': 'l','6-18': 'l','6-19': 'l', + '7-1': 'l','7-2': 'l','7-3': 'l','7-4': 'l','7-5': 'l','7-6': 'l','7-7': 'l','7-8': 'l','7-9': 'l','7-10': 'l','7-11': 'l','7-12': 'l','7-13': 'l','7-14': 'l','7-15': 'l','7-16': 'l','7-17': 'l','7-18': 'l','7-19': 'l', + '8-1': 'l','8-2': 'l','8-3': 'l','8-4': 'l','8-5': 'l','8-6': 'l','8-7': 'l','8-8': 'l','8-9': 'l','8-10': 'l','8-11': 'l','8-12': 'l','8-13': 'l','8-14': 'l','8-15': 'l','8-16': 'l','8-17': 'l','8-18': 'l','8-19': 'l', + '9-1': 'l','9-2': 'l','9-3': 'l','9-4': 'l','9-5': 'l','9-6': 'l','9-7': 'l','9-8': 'l','9-9': 'l','9-10': 'l','9-11': 'l','9-12': 'l','9-13': 'l','9-14': 'l','9-15': 'l','9-16': 'l','9-17': 'l','9-18': 'l','9-19': 'l', + '10-1': 'l','10-2': 'l','10-3': 'l','10-4': 'l','10-5': 'l','10-6': 'l','10-7': 'l','10-8': 'l','10-9': 'l','10-10': 'l','10-11': 'l','10-12': 'l','10-13': 'l','10-14': 'l','10-15': 'l','10-16': 'l','10-17': 'l','10-18': 'l','10-19': 'l', + '11-1': 'l','11-2': 'l','11-3': 'l','11-4': 'l','11-5': 'l','11-6': 'l','11-7': 'l','11-8': 'l','11-9': 'l','11-10': 'l','11-11': 'l','11-12': 'l','11-13': 'l','11-14': 'l','11-15': 'l','11-16': 'l','11-17': 'l','11-18': 'l','11-19': 'l', + '12-1': 'l','12-2': 'l','12-3': 'l','12-4': 'l','12-5': 'l','12-6': 'l','12-7': 'l','12-8': 'l','12-9': 'l','12-10': 'l','12-11': 'l','12-12': 'l','12-13': 'l','12-14': 'l','12-15': 'l','12-16': 'l','12-17': 'l','12-18': 'l','12-19': 'l', + '13-1': 'l','13-2': 'l','13-3': 'l','13-4': 'l','13-5': 'l','13-6': 'l','13-7': 'l','13-8': 'l','13-9': 'l','13-10': 'l','13-11': 'l','13-12': 'l','13-13': 'l','13-14': 'l','13-15': 'l','13-16': 'l','13-17': 'l','13-18': 'l','13-19': 'l', + '14-1': 'l','14-2': 'l','14-3': 'l','14-4': 'l','14-5': 'l','14-6': 'l','14-7': 'l','14-8': 'l','14-9': 'l','14-10': 'l','14-11': 'l','14-12': 'l','14-13': 'l','14-14': 'l','14-15': 'l','14-16': 'l','14-17': 'l','14-18': 'l','14-19': 'l', + '15-1': 'l','15-2': 'l','15-3': 'l','15-4': 'l','15-5': 'l','15-6': 'l','15-7': 'l','15-8': 'l','15-9': 'l','15-10': 'l','15-11': 'l','15-12': 'l','15-13': 'l','15-14': 'l','15-15': 'l','15-16': 'l','15-17': 'l','15-18': 'l','15-19': 'l', + '16-1': 'l','16-2': 'l','16-3': 'l','16-4': 'l','16-5': 'l','16-6': 'l','16-7': 'l','16-8': 'l','16-9': 'l','16-10': 'l','16-11': 'l','16-12': 'l','16-13': 'l','16-14': 'l','16-15': 'l','16-16': 'l','16-17': 'l','16-18': 'l','16-19': 'l', + '17-1': 'l','17-2': 'l','17-3': 'l','17-4': 'l','17-5': 'l','17-6': 'l','17-7': 'l','17-8': 'l','17-9': 'l','17-10': 'l','17-11': 'l','17-12': 'l','17-13': 'l','17-14': 'l','17-15': 'l','17-16': 'l','17-17': 'l','17-18': 'l','17-19': 'l', + '18-1': 'l','18-2': 'l','18-3': 'l','18-4': 'l','18-5': 'l','18-6': 'l','18-7': 'l','18-8': 'l','18-9': 'l','18-10': 'l','18-11': 'l','18-12': 'l','18-13': 'l','18-14': 'l','18-15': 'l','18-16': 'l','18-17': 'l','18-18': 'l','18-19': 'l', + '19-1': 'l','19-2': 'l','19-3': 'l','19-4': 'l','19-5': 'l','19-6': 'l','19-7': 'l','19-8': 'l','19-9': 'l','19-10': 'l','19-11': 'l','19-12': 'l','19-13': 'l','19-14': 'l','19-15': 'l','19-16': 'l','19-17': 'l','19-18': 'l','19-19': 'l' +}; \ No newline at end of file