refactor Point.capturing to Set to handle adjascent stones in same group

This commit is contained in:
Sorrel Bri 2020-04-30 23:45:19 -07:00
parent e9d94d1fad
commit 1142c1d448
2 changed files with 85 additions and 54 deletions

View file

@ -221,8 +221,8 @@ const Point = ({x, y, boardSize = 19}) => {
legal: true, legal: true,
territory: 0, territory: 0,
capturing: { capturing: {
'1': [], '1': new Set(),
'-1': [] '-1': new Set()
}, },
group: null, group: null,
neighbors: { neighbors: {
@ -235,7 +235,7 @@ const Point = ({x, y, boardSize = 19}) => {
makeMove: function(Game) { makeMove: function(Game) {
this.stone = Game.turn; this.stone = Game.turn;
this.legal = false; this.legal = false;
if (this.capturing[this.stone].length) { if (this.capturing[this.stone].size) {
Game = this.makeCaptures(Game); Game = this.makeCaptures(Game);
} }
Game = this.joinGroup({ point: this, Game }); Game = this.joinGroup({ point: this, Game });
@ -290,7 +290,7 @@ const Point = ({x, y, boardSize = 19}) => {
const liberties = game.groups[this.group].liberties; const liberties = game.groups[this.group].liberties;
if (liberties.size === 1) { if (liberties.size === 1) {
const lastLiberty = getSingleItemFromSet(liberties); const lastLiberty = getSingleItemFromSet(liberties);
lastLiberty.capturing[this.stone * -1].push(this.group); lastLiberty.capturing[this.stone * -1].add(this.group);
} }
// if neighbors have one liberty // if neighbors have one liberty
@ -299,7 +299,7 @@ const Point = ({x, y, boardSize = 19}) => {
const liberties = game.groups[neighbor.group] && game.groups[neighbor.group].liberties; const liberties = game.groups[neighbor.group] && game.groups[neighbor.group].liberties;
if (liberties && liberties.size === 1) { if (liberties && liberties.size === 1) {
const lastLiberty = getSingleItemFromSet(liberties); const lastLiberty = getSingleItemFromSet(liberties);
lastLiberty.capturing[neighbor.stone * -1].push(neighbor.group); lastLiberty.capturing[neighbor.stone * -1].add(neighbor.group);
} }
}); });
return game; return game;
@ -307,24 +307,28 @@ const Point = ({x, y, boardSize = 19}) => {
makeCaptures: function(game) { makeCaptures: function(game) {
// for each group // for each group
this.capturing[this.stone].forEach(captureGroup => { for (let [captureGroup, _] of this.capturing[this.stone].entries()) {
const capturesSet = game.groups[captureGroup].stones; const capturesSet = game.groups[captureGroup].stones;
for (let [capture] of capturesSet.entries()) { for (let [capture, _] of capturesSet.entries()) {
game = capture.removeStone(game); game = capture.removeStone(game);
} }
}); }
return game; return game;
}, },
removeStone: function(game) { removeStone: function(game) {
if (this.stone = 0) {
return game;
}
// reset point // reset point
this.stone = 0; this.stone = 0;
this.group = null; this.group = null;
this.capturing[game.turn] = []; this.capturing[game.turn] = new Set();
// add captures // add captures
const player = game.turn > 0 ? 'b' : 'w'; const player = game.turn > 0 ? 'b' : 'w';
game.playerState[`${player}Captures`] += 1; game.playerState[`${player}Captures`] += 1;
return {...game, boardState: {...this.boardState, [this.key]: this}}; return {...game, boardState: {...game.boardState, [this.key]: this}};
} }
} }
for (let [key, value] of Object.entries(point.neighbors)) { for (let [key, value] of Object.entries(point.neighbors)) {
@ -338,3 +342,21 @@ module.exports = {
Game, Game,
Point Point
} }
Game().initGame()
.makeMove({ player: 'black', pos: { x: 4, y: 17 } })
.makeMove({ player: 'white', pos: { x: 3, y: 16 } })
.makeMove({ player: 'black', pos: { x: 5, y: 16 } })
.makeMove({ player: 'white', pos: { x: 4, y: 15 } })
.makeMove({ player: 'black', pos: { x: 4, y: 16 } })
.makeMove({ player: 'black', pos: { x: 4, y: 10 } }) // 3 4 5 6
.makeMove({ player: 'white', pos: { x: 3, y: 17 } }) // 15 -1 -1
.makeMove({ player: 'black', pos: { x: 10, y: 4 } }) // 16 -1 1 1 -1
.makeMove({ player: 'white', pos: { x: 5, y: 15 } }) // 17 -1 1 -1
.makeMove({ player: 'black', pos: { x: 10, y: 8 } }) // 18 -1
.makeMove({ player: 'white', pos: { x: 4, y: 18} })
.makeMove({ player: 'black', pos: { x: 3, y: 6 } })
.makeMove({ player: 'white', pos: { x: 5, y: 17} })
.makeMove({ player: 'black', pos: { x: 6, y: 3 } })
.makeMove({ player: 'white', pos: { x: 6, y: 16} })

View file

@ -194,7 +194,7 @@ describe('Game.makeMove({ player: str, pos: { x: int, y: int } })', () => {
}); });
}); });
describe('makeMove group join and capture logic', () => { describe('makeMove group join and basic capture logic', () => {
const joinGame = Game().initGame() const joinGame = Game().initGame()
.makeMove({ player: 'black', pos: { x: 4, y: 17 } }) // 3 4 5 .makeMove({ player: 'black', pos: { x: 4, y: 17 } }) // 3 4 5
.makeMove({ player: 'white', pos: { x: 3, y: 16 } }) // 15 -1 .makeMove({ player: 'white', pos: { x: 3, y: 16 } }) // 15 -1
@ -250,30 +250,30 @@ describe('makeMove group join and capture logic', () => {
.makeMove({ player: 'white', pos: { x: 5, y: 16 } }) // 4,16 captured .makeMove({ player: 'white', pos: { x: 5, y: 16 } }) // 4,16 captured
.makeMove({ player: 'black', pos: { x: 10, y: 4 } }) .makeMove({ player: 'black', pos: { x: 10, y: 4 } })
it('makeMove capture smoke test', done => { it('makeMove capture smoke test', done => {
captureGame.makeMove({ player: 'white', pos: { x: 4, y: 17 } }) captureGame.makeMove({ player: 'white', pos: { x: 4, y: 17 } })
.success.should.eql(true); .success.should.eql(true);
done(); done();
}); });
it('makeMove assesses captures', done => { it('makeMove assesses captures', done => {
captureGame.boardState['4-17'].capturing[-1].length.should.eql(1); captureGame.boardState['4-17'].capturing[-1].size.should.eql(1);
done(); done();
}) })
it('makeMove capture removes captured stone', done => { it('makeMove capture removes captured stone', done => {
captureGame.makeMove({ player: 'white', pos: { x: 4, y: 17 } }) captureGame.makeMove({ player: 'white', pos: { x: 4, y: 17 } })
.boardState['4-16'].stone.should.eql(0); .boardState['4-16'].stone.should.eql(0);
done(); done();
}); });
it('makeMove capture increases capturing players captures', done => { it('makeMove capture increases capturing players captures', done => {
captureGame.makeMove({ player: 'white', pos: { x: 4, y: 17 } }) captureGame.makeMove({ player: 'white', pos: { x: 4, y: 17 } })
.playerState.wCaptures.should.eql(1); .playerState.wCaptures.should.eql(1);
done(); done();
}); });
const multiCaptureGame = () => Game().initGame() const multiCaptureGame = () => Game().initGame()
.makeMove({ player: 'black', pos: { x: 4, y: 17 } }) .makeMove({ player: 'black', pos: { x: 4, y: 17 } })
.makeMove({ player: 'white', pos: { x: 3, y: 16 } }) .makeMove({ player: 'white', pos: { x: 3, y: 16 } })
.makeMove({ player: 'black', pos: { x: 5, y: 16 } }) .makeMove({ player: 'black', pos: { x: 5, y: 16 } })
@ -288,29 +288,38 @@ describe('makeMove group join and capture logic', () => {
.makeMove({ player: 'black', pos: { x: 3, y: 6 } }) .makeMove({ player: 'black', pos: { x: 3, y: 6 } })
.makeMove({ player: 'white', pos: { x: 5, y: 17} }) .makeMove({ player: 'white', pos: { x: 5, y: 17} })
.makeMove({ player: 'black', pos: { x: 6, y: 3 } }); .makeMove({ player: 'black', pos: { x: 6, y: 3 } });
it('smoke test multi stone group capture', done => { it('smoke test multi stone group capture', done => {
multiCaptureGame().makeMove({ player: 'white', pos: { x: 6, y: 16} }) multiCaptureGame().makeMove({ player: 'white', pos: { x: 6, y: 16} })
.success.should.eql(true); .success.should.eql(true);
done(); done();
}) });
it('multi stone group full group is in capturing', done => { it('multi stone group full group is in capturing', done => {
const game = multiCaptureGame() const game = multiCaptureGame()
const group = game.boardState['4-16'].group; const group = game.boardState['4-16'].group;
game.boardState['6-16'].capturing[-1][0].should.eql(group); game.boardState['6-16'].capturing[-1].has(group).should.eql(true);
done(); done();
}) });
it('multi stone group capture all points are 0', done => { it('multi stone group capture all points are 0', done => {
const game = multiCaptureGame(); const game = multiCaptureGame();
game.makeMove({ player: 'white', pos: { x: 6, y: 16} }); game.makeMove({ player: 'white', pos: { x: 6, y: 16} });
game.boardState['5-16'].stone.should.eql(0) game.boardState['5-16'].stone.should.eql(0)
game.boardState['4-16'].stone.should.eql(0) game.boardState['4-16'].stone.should.eql(0)
game.boardState['4-17'].stone.should.eql(0) game.boardState['4-17'].stone.should.eql(0)
done(); done();
}) });
})
it('multi stone group capture scores points properly', done => {
const game = multiCaptureGame();
game.makeMove({ player: 'white', pos: { x: 6, y: 16} });
game.playerState.wCaptures.should.eql(3);
done();
})
});
// describe('capture logic: snapback')
const initialMeta = { const initialMeta = {