diff --git a/packages/server/services/Game.v2.js b/packages/server/services/Game.v2.js index 66cf15c..02a4ea2 100644 --- a/packages/server/services/Game.v2.js +++ b/packages/server/services/Game.v2.js @@ -164,6 +164,7 @@ const Game = ({gameData = {}, gameRecord = []} = {}) => ({ boardSize: gameData.boardSize || 19, groups: {}, boardState: {}, + ko: [], gameRecord: gameRecord, playerState: gameData.playerState || { bCaptures: 0, @@ -216,7 +217,8 @@ const Point = ({x, y, boardSize = 19}) => { let point = { pos: {x, y}, key: `${x}-${y}`, - stone: 0, // can be 1, -1, 0, or 'k' for ko + stone: 0, // can be 1, -1, 0, + ko: false, legal: true, territory: 0, capturing: { @@ -311,7 +313,14 @@ const Point = ({x, y, boardSize = 19}) => { const capturesSet = game.groups[captureGroup].stones; for (let [capture, _] of capturesSet.entries()) { game = capture.removeStone(game); + if (capturesSet.size === 1) { + const liberties = getNeighbors({ point: this, Game: game }).filter(neighbor => neighbor.stone === 0); + if (liberties.length === 1) { + capture.ko = true; + } + } } + } // points with stones cannot be played to capture this.capturing = { '1': new Set(), '-1': new Set() } @@ -344,3 +353,12 @@ module.exports = { Point } +Game().initGame() + .makeMove({ player: 'black', pos: { x: 4, y: 4 } }) // 3 4 5 6 + .makeMove({ player: 'white', pos: { x: 4, y: 5 } }) // 4 1 -1 + .makeMove({ player: 'black', pos: { x: 5, y: 3 } }) // 5 1 -1 1 -1 + .makeMove({ player: 'white', pos: { x: 5, y: 6 } }) // 6 1 -1 + .makeMove({ player: 'black', pos: { x: 6, y: 4 } }) + .makeMove({ player: 'white', pos: { x: 6, y: 5 } }) + .makeMove({ player: 'black', pos: { x: 5, y: 5 } }) + .makeMove({ player: 'white', pos: { x: 5, y: 4 } }) \ No newline at end of file diff --git a/packages/server/test/Game.v2.spec.js b/packages/server/test/Game.v2.spec.js index 945b7a2..253e08b 100644 --- a/packages/server/test/Game.v2.spec.js +++ b/packages/server/test/Game.v2.spec.js @@ -336,11 +336,11 @@ describe('capture logic: snapback, ko and playing in eyes', () => { }); const snapbackGame = () => Game().initGame() - .makeMove({ player: 'black', pos: { x: 4, y: 4 } }) // 3 4 5 6 7 - .makeMove({ player: 'white', pos: { x: 5, y: 4 } }) // 4 1. 1. -1. - .makeMove({ player: 'black', pos: { x: 5, y: 6 } }) // 5 1. -1. -1. 1. -1. - .makeMove({ player: 'white', pos: { x: 5, y: 7 } }) // 6 1. 1. -1. - .makeMove({ player: 'black', pos: { x: 4, y: 5 } }) // (13) at {5,6} . + .makeMove({ player: 'black', pos: { x: 4, y: 4 } }) // 3 4 5 6 7 + .makeMove({ player: 'white', pos: { x: 5, y: 4 } }) // 4 1 1 -1 + .makeMove({ player: 'black', pos: { x: 5, y: 6 } }) // 5 1 -1 -1 1 -1 + .makeMove({ player: 'white', pos: { x: 5, y: 7 } }) // 6 1 1 -1 + .makeMove({ player: 'black', pos: { x: 4, y: 5 } }) // (13) at {5,6} .makeMove({ player: 'white', pos: { x: 4, y: 6 } }) .makeMove({ player: 'black', pos: { x: 5, y: 3 } }) .makeMove({ player: 'white', pos: { x: 6, y: 6 } }) @@ -350,18 +350,31 @@ describe('capture logic: snapback, ko and playing in eyes', () => { .makeMove({ player: 'white', pos: { x: 5, y: 5 } }) .makeMove({ player: 'black', pos: { x: 5, y: 6 } }) - it('snapback functions properly', done => { snapbackGame() - .success.should.eql(true); + .success.should.eql(true); done(); }); + + const koGame = () => Game().initGame() + .makeMove({ player: 'black', pos: { x: 4, y: 4 } }) // 3 4 5 6 + .makeMove({ player: 'white', pos: { x: 4, y: 5 } }) // 4 1 -1 + .makeMove({ player: 'black', pos: { x: 5, y: 3 } }) // 5 1 -1 1 -1 + .makeMove({ player: 'white', pos: { x: 5, y: 6 } }) // 6 1 -1 + .makeMove({ player: 'black', pos: { x: 6, y: 4 } }) + .makeMove({ player: 'white', pos: { x: 6, y: 5 } }) + .makeMove({ player: 'black', pos: { x: 5, y: 5 } }) + .makeMove({ player: 'white', pos: { x: 5, y: 4 } }) - // it('ko recognized properly', done => { - // snapbackGame() - // .makeMove({ player: 'white', pos: { x: 5, y: 5 } }) - // done(); - // }) + it('ko recognized properly on point', done => { + koGame() + .boardState['5-5'].ko.should.eql(true); + done(); + }) + + // ko marked on game object + // ko marked in legalMoves object + // ko cleared after move })