refactor Game.v2 to remove side effects
This commit is contained in:
parent
a5fbeea929
commit
1a1e5121d7
2 changed files with 225 additions and 156 deletions
|
@ -63,7 +63,6 @@ const getSingleItemFromSet = set => {
|
||||||
return entry[0];
|
return entry[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const pipeMap = (...funcs) => obj => {
|
const pipeMap = (...funcs) => obj => {
|
||||||
const arr = Object.entries(obj).reduce((acc, [key, value], i, arr) => {
|
const arr = Object.entries(obj).reduce((acc, [key, value], i, arr) => {
|
||||||
funcs.forEach(func => value = func(value, i, arr));
|
funcs.forEach(func => value = func(value, i, arr));
|
||||||
|
@ -80,9 +79,10 @@ const checkLegal = ({ point, Game }) => {
|
||||||
point.legal = false;
|
point.legal = false;
|
||||||
return point;
|
return point;
|
||||||
}
|
}
|
||||||
|
const neighbors = getNeighbors({Game, point});
|
||||||
|
|
||||||
const isEmpty = point => point.stone === 0 && point.legal === true;
|
const isEmpty = point => point.stone === 0 && point.legal === true;
|
||||||
const isEmptyAdjacent = Object.values(point.neighbors).filter(isEmpty);
|
const isEmptyAdjacent = neighbors.filter(isEmpty);
|
||||||
|
|
||||||
// if empty point adjacent return true
|
// if empty point adjacent return true
|
||||||
if (!isEmptyAdjacent.length) {
|
if (!isEmptyAdjacent.length) {
|
||||||
|
@ -92,7 +92,7 @@ const checkLegal = ({ point, Game }) => {
|
||||||
const getGroupLiberties = point => Array.from(Game.groups[point.group].liberties);
|
const getGroupLiberties = point => Array.from(Game.groups[point.group].liberties);
|
||||||
const isNotSamePoint = liberty => liberty.pos.x !== point.pos.x && liberty.pos.y !== point.pos.y;
|
const isNotSamePoint = liberty => liberty.pos.x !== point.pos.x && liberty.pos.y !== point.pos.y;
|
||||||
const isInGroupWithLiberties = neighbor => getGroupLiberties(neighbor).filter(isNotSamePoint).length;
|
const isInGroupWithLiberties = neighbor => getGroupLiberties(neighbor).filter(isNotSamePoint).length;
|
||||||
const isInLiveGroup = Object.values(point.neighbors).filter(isTurnStone).filter(isInGroupWithLiberties).length;
|
const isInLiveGroup = neighbors.filter(isTurnStone).filter(isInGroupWithLiberties).length;
|
||||||
|
|
||||||
if (isInLiveGroup) {
|
if (isInLiveGroup) {
|
||||||
point.legal = true;
|
point.legal = true;
|
||||||
|
@ -123,19 +123,15 @@ const getLegalMoves = (Game) => {
|
||||||
return pipeMap(mapLegal)(Game.boardState);
|
return pipeMap(mapLegal)(Game.boardState);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getNeighbors = boardSize => (point, i, boardState) => {
|
const getNeighbors = ({ Game, point }) => {
|
||||||
const { top, btm, lft, rgt} = point.neighbors;
|
let { top = null, btm = null, lft = null, rgt = null} = point.neighbors;
|
||||||
|
const { boardState, boardSize } = Game;
|
||||||
// boardState[0] = [ '1-1', Point({x:1, y:1, boardSize}) ]
|
// boardState[0] = [ '1-1', Point({x:1, y:1, boardSize}) ]
|
||||||
point.neighbors.top = top ? boardState[i - boardSize][1] : top;
|
if (top) top = boardState[top];
|
||||||
point.neighbors.btm = btm ? boardState[i + boardSize][1] : btm;
|
if (btm) btm = boardState[btm];
|
||||||
point.neighbors.lft = lft ? boardState[i - 1][1] : lft;
|
if (lft) lft = boardState[lft];
|
||||||
point.neighbors.rgt = rgt ? boardState[i + 1][1] : rgt;
|
if (rgt) rgt = boardState[rgt];
|
||||||
for (let [direction, neighbor] of Object.entries(point.neighbors)) {
|
return [ top, btm, lft, rgt ].filter(value => value);
|
||||||
if (!neighbor) {
|
|
||||||
delete point.neighbors[direction];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return point;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const initBoard = (game) => {
|
const initBoard = (game) => {
|
||||||
|
@ -149,14 +145,14 @@ const initBoard = (game) => {
|
||||||
});
|
});
|
||||||
boardState[`${point.pos.x}-${point.pos.y}`] = point;
|
boardState[`${point.pos.x}-${point.pos.y}`] = point;
|
||||||
}
|
}
|
||||||
const boardStateWithNeighbors = pipeMap(getNeighbors(boardSize))(boardState)
|
|
||||||
if (handicap) {
|
if (handicap) {
|
||||||
HANDI_PLACE[boardSize][handicap].forEach(pt => {
|
HANDI_PLACE[boardSize][handicap].forEach(pt => {
|
||||||
boardStateWithNeighbors[pt].makeMove(game);
|
boardState[pt].makeMove({...game, boardState});
|
||||||
});
|
});
|
||||||
game.turn *= -1;
|
game.turn *= -1;
|
||||||
}
|
}
|
||||||
return boardStateWithNeighbors;
|
return boardState;
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns Game object
|
// returns Game object
|
||||||
|
@ -183,136 +179,160 @@ const Game = ({gameData = {}, gameRecord = []} = {}) => ({
|
||||||
this.turn = 1;
|
this.turn = 1;
|
||||||
this.boardState = initBoard(this);
|
this.boardState = initBoard(this);
|
||||||
this.boardState = getBoardState(this);
|
this.boardState = getBoardState(this);
|
||||||
return { ...this, legalMoves: getLegalMoves(this)};
|
this.legalMoves = getLegalMoves(this)
|
||||||
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
getMeta: function() {
|
getMeta: function() {
|
||||||
|
// cannot be chained
|
||||||
|
// does not affect game object
|
||||||
return { winner: this.winner, turn: this.turn, pass: this.pass, playerState: this.playerState, gameRecord: this.gameRecord }
|
return { winner: this.winner, turn: this.turn, pass: this.pass, playerState: this.playerState, gameRecord: this.gameRecord }
|
||||||
},
|
},
|
||||||
|
|
||||||
makeMove: function({ player, pos: {x, y}}) {
|
makeMove: function({ player, pos: {x, y}}) {
|
||||||
|
let game = this;
|
||||||
let success = false;
|
let success = false;
|
||||||
const point = this.boardState[`${x}-${y}`];
|
const point = game.boardState[`${x}-${y}`];
|
||||||
const isTurn = ( this.turn === 1 && player === 'black' )
|
const isTurn = ( game.turn === 1 && player === 'black' )
|
||||||
|| ( this.turn === -1 && player === 'white' );
|
|| ( game.turn === -1 && player === 'white' );
|
||||||
if (isTurn) {
|
if (isTurn) {
|
||||||
if (point.legal) {
|
if (point.legal) {
|
||||||
point.makeMove(this);
|
game = point.makeMove(game);
|
||||||
this.turn *= -1;
|
game.turn *= -1;
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.boardState = getBoardState(this);
|
game.boardState = getBoardState(game);
|
||||||
return {...this, legalMoves: getLegalMoves(this), success };
|
return {...game, legalMoves: getLegalMoves(game), success };
|
||||||
},
|
},
|
||||||
|
|
||||||
initGroup: function(point) {
|
initGroup: function(point) {
|
||||||
const newSymbol = Symbol(`${point.pos.x}-${point.pos.y}`);
|
const group = Symbol(`${point.pos.x}-${point.pos.y}`);
|
||||||
this.groups[newSymbol] = { stones: new Set(), liberties: new Set()};
|
this.groups[group] = { stones: new Set(), liberties: new Set()};
|
||||||
return newSymbol;
|
return { game: this, group };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const Point = ({x, y, boardSize = 19}) => ({
|
const Point = ({x, y, boardSize = 19}) => {
|
||||||
pos: {x, y},
|
let point = {
|
||||||
stone: 0, // can be 1, -1, 0, or 'k' for ko
|
pos: {x, y},
|
||||||
legal: true,
|
key: `${x}-${y}`,
|
||||||
territory: 0,
|
stone: 0, // can be 1, -1, 0, or 'k' for ko
|
||||||
capturing: {
|
legal: true,
|
||||||
'1': [],
|
territory: 0,
|
||||||
'-1': []
|
capturing: {
|
||||||
},
|
'1': [],
|
||||||
group: null,
|
'-1': []
|
||||||
neighbors: {
|
},
|
||||||
top: x > 1 ? `${ x - 1 }-${ y }` : null,
|
group: null,
|
||||||
btm: x < boardSize ? `${ x + 1 }-${ y }` : null,
|
neighbors: {
|
||||||
rgt: y < boardSize ? `${ x }-${ y + 1 }` : null,
|
top: x > 1 ? `${ x - 1 }-${ y }` : null,
|
||||||
lft: y > 1 ? `${ x }-${ y - 1 }` : null
|
btm: x < boardSize ? `${ x + 1 }-${ y }` : null,
|
||||||
},
|
rgt: y < boardSize ? `${ x }-${ y + 1 }` : null,
|
||||||
|
lft: y > 1 ? `${ x }-${ y - 1 }` : null
|
||||||
|
},
|
||||||
|
|
||||||
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].length) {
|
||||||
this.makeCaptures(game);
|
Game = this.makeCaptures(Game);
|
||||||
}
|
|
||||||
this.joinGroup({ point: this, game });
|
|
||||||
return this.checkCaptures(game);
|
|
||||||
},
|
|
||||||
|
|
||||||
joinGroup: function({ point, game }) {
|
|
||||||
if (point.group !== this.group || !point.group) {
|
|
||||||
// if point has no group set current group to new Symbol in game object
|
|
||||||
if (!point.group) {
|
|
||||||
point.group = game.initGroup(point);
|
|
||||||
}
|
}
|
||||||
|
Game = this.joinGroup({ point: this, Game });
|
||||||
|
return this.checkCaptures(Game);
|
||||||
|
},
|
||||||
|
|
||||||
// add current point to global group and override current group
|
joinGroup: function({ point, Game }) {
|
||||||
game.groups[point.group].stones.add(this);
|
if (point.group !== this.group || !point.group) {
|
||||||
this.group = point.group;
|
// if point has no group set current group to new Symbol in game object
|
||||||
this.setLiberties(game);
|
if (!point.group) {
|
||||||
for (let neighbor of Object.values(this.neighbors)) {
|
const { game, group } = Game.initGroup(point);
|
||||||
if ( neighbor.stone === this.stone
|
this.group = group;
|
||||||
// this check prevents infinite call chains
|
Game = game;
|
||||||
&& neighbor.group !== this.group
|
|
||||||
) {
|
|
||||||
neighbor.joinGroup({ point: this, game });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add current point to global group and override current group
|
||||||
|
Game.groups[point.group].stones.add(this);
|
||||||
|
if (this.group !== point.group) {
|
||||||
|
this.group = point.group;
|
||||||
|
}
|
||||||
|
Game = this.setLiberties(Game);
|
||||||
|
getNeighbors({ point:this, Game }).forEach(neighbor => {
|
||||||
|
if ( neighbor.stone === this.stone
|
||||||
|
// this check prevents infinite call chains
|
||||||
|
&& neighbor.group !== this.group
|
||||||
|
) {
|
||||||
|
Game = neighbor.joinGroup({ point: this, Game });
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
return Game;
|
||||||
},
|
},
|
||||||
|
|
||||||
setLiberties: function(game) {
|
setLiberties: function(Game) {
|
||||||
const neighbors = Object.values(this.neighbors);
|
const neighbors = getNeighbors({ point: this, Game });
|
||||||
const liberties = game.groups[this.group].liberties;
|
const liberties = Game.groups[this.group].liberties;
|
||||||
// if point is occupied remove it from liberties set of point group, else add it
|
// if point is occupied remove it from liberties set of point group, else add it
|
||||||
neighbors.forEach( pt => {
|
neighbors.forEach(neighbor => {
|
||||||
if (pt.stone) {
|
if (neighbor.stone !== 0) {
|
||||||
liberties.delete(pt);
|
liberties.delete(neighbor);
|
||||||
game.groups[pt.group].liberties.delete(this);
|
Game.groups[neighbor.group].liberties.delete(this);
|
||||||
} else {
|
}
|
||||||
liberties.add(pt)
|
if (neighbor.stone === 0) {
|
||||||
}
|
liberties.add(neighbor)
|
||||||
});
|
}
|
||||||
},
|
});
|
||||||
|
return Game;
|
||||||
|
},
|
||||||
|
|
||||||
checkCaptures: function(game) {
|
checkCaptures: function(game) {
|
||||||
// if this stone has one liberty
|
// if this stone has one liberty
|
||||||
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);
|
|
||||||
lastLiberty.capturing[this.stone * -1].push(this.group);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if neighbors have one liberty
|
|
||||||
const neighbors = Object.values(this.neighbors).filter(neighbor => neighbor.stone === -1 * this.stone)
|
|
||||||
neighbors.forEach( neighbor => {
|
|
||||||
const liberties = game.groups[neighbor.group] && game.groups[neighbor.group].liberties;
|
|
||||||
if (liberties && liberties.size === 1) {
|
|
||||||
const lastLiberty = getSingleItemFromSet(liberties);
|
const lastLiberty = getSingleItemFromSet(liberties);
|
||||||
lastLiberty.capturing[neighbor.stone * -1].push(neighbor.group);
|
lastLiberty.capturing[this.stone * -1].push(this.group);
|
||||||
}
|
}
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
makeCaptures: function(game) {
|
// if neighbors have one liberty
|
||||||
// for each group
|
const neighbors = getNeighbors({point: this, Game: game}).filter(neighbor => neighbor.stone === -1 * this.stone)
|
||||||
this.capturing[this.stone].forEach(captureGroup => {
|
neighbors.forEach( neighbor => {
|
||||||
const capturesSet = game.groups[captureGroup].stones;
|
const liberties = game.groups[neighbor.group] && game.groups[neighbor.group].liberties;
|
||||||
for (let [capture] of capturesSet.entries()) {
|
if (liberties && liberties.size === 1) {
|
||||||
capture.removeStone(game);
|
const lastLiberty = getSingleItemFromSet(liberties);
|
||||||
}
|
lastLiberty.capturing[neighbor.stone * -1].push(neighbor.group);
|
||||||
})
|
}
|
||||||
},
|
});
|
||||||
|
return game;
|
||||||
|
},
|
||||||
|
|
||||||
removeStone: function(game) {
|
makeCaptures: function(game) {
|
||||||
// reset point
|
// for each group
|
||||||
this.stone = 0;
|
this.capturing[this.stone].forEach(captureGroup => {
|
||||||
this.group = null;
|
const capturesSet = game.groups[captureGroup].stones;
|
||||||
this.capturing[game.turn] = [];
|
for (let [capture] of capturesSet.entries()) {
|
||||||
// add captures
|
game = capture.removeStone(game);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return game;
|
||||||
|
},
|
||||||
|
|
||||||
|
removeStone: function(game) {
|
||||||
|
// reset point
|
||||||
|
this.stone = 0;
|
||||||
|
this.group = null;
|
||||||
|
this.capturing[game.turn] = [];
|
||||||
|
// add captures
|
||||||
|
const player = game.turn > 0 ? 'b' : 'w';
|
||||||
|
game.playerState[`${player}Captures`] += 1;
|
||||||
|
return {...game, boardState: {...this.boardState, [this.key]: this}};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
for (let [key, value] of Object.entries(point.neighbors)) {
|
||||||
|
if (value) continue;
|
||||||
|
delete point.neighbors[key];
|
||||||
|
}
|
||||||
|
return point;
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
Game,
|
Game,
|
||||||
|
|
|
@ -30,7 +30,7 @@ describe('Game', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Game().initGame() returns boardState', () => {
|
describe('Game().initGame() returns legalMoves', () => {
|
||||||
it('initGame() returns default 19x19', done => {
|
it('initGame() returns default 19x19', done => {
|
||||||
Game().initGame()
|
Game().initGame()
|
||||||
.legalMoves.should.eql(emptyBoard);
|
.legalMoves.should.eql(emptyBoard);
|
||||||
|
@ -43,24 +43,10 @@ describe('Game().initGame() returns boardState', () => {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('initGame() returns Game with all Points having neighbors', done => {
|
it('handicap stone has proper liberties', done => {
|
||||||
const boardState = Game().initGame().boardState;
|
const game = Game({gameData: { handicap: 2 }}).initGame();
|
||||||
const oneOneNeighbors = boardState['1-1'].neighbors;
|
const group = game.boardState['4-16'].group
|
||||||
const fiveSevenNeighbors = boardState['5-7'].neighbors;
|
game.groups[group].liberties.size.should.eql(4);
|
||||||
const nineteenTenNeighbors = boardState['19-10'].neighbors;
|
|
||||||
|
|
||||||
oneOneNeighbors.rgt.pos.should.eql({x: 1, y: 2});
|
|
||||||
oneOneNeighbors.btm.pos.should.eql({x: 2, y: 1});
|
|
||||||
|
|
||||||
fiveSevenNeighbors.top.pos.should.eql({x: 4, y: 7});
|
|
||||||
fiveSevenNeighbors.btm.pos.should.eql({x: 6, y: 7});
|
|
||||||
fiveSevenNeighbors.lft.pos.should.eql({x: 5, y: 6});
|
|
||||||
fiveSevenNeighbors.rgt.pos.should.eql({x: 5, y: 8});
|
|
||||||
|
|
||||||
nineteenTenNeighbors.top.pos.should.eql({x: 18, y: 10});
|
|
||||||
nineteenTenNeighbors.lft.pos.should.eql({x: 19, y: 9});
|
|
||||||
nineteenTenNeighbors.rgt.pos.should.eql({x: 19, y: 11});
|
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -171,19 +157,29 @@ describe('Game.makeMove({ player: str, pos: { x: int, y: int } })', () => {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('makeMove next to adjacent stone of different color does not join stones as a group', done => {
|
const noGroupGame = Game({ gameData: { handicap: 2 } }).initGame() // 3 4
|
||||||
const game = Game({ gameData: { handicap: 2 } }).initGame() // 3 4
|
.makeMove({ player: 'white', pos: { x: 4, y: 15 } }) // 14 1
|
||||||
.makeMove({ player: 'white', pos: { x: 4, y: 15 } }) // 14 1
|
.makeMove({ player: 'black', pos: { x: 4, y: 14 }}) // 15 1 -1 no groups
|
||||||
.makeMove({ player: 'black', pos: { x: 4, y: 14 }}) // 15 1 -1 no groups
|
.makeMove({ player: 'white', pos: { x: 3, y: 16 } }) // 16 -1 1h
|
||||||
.makeMove({ player: 'white', pos: { x: 3, y: 16 } }) // 16 -1 1h
|
.makeMove({ player: 'black', pos: { x: 3, y: 15 }});
|
||||||
.makeMove({ player: 'black', pos: { x: 3, y: 15 }})
|
|
||||||
|
|
||||||
const hoshiGroupKey = game.boardState['4-16'].group;
|
it('makeMove next to adjacent stone of different color does not join stones as a group', done => {
|
||||||
const hoshiGroup = game.groups[hoshiGroupKey].stones;
|
const hoshiGroupKey = noGroupGame.boardState['4-16'].group;
|
||||||
hoshiGroup.has(game.boardState['4-16']).should.eql(true);
|
const hoshiGroup = noGroupGame.groups[hoshiGroupKey].stones;
|
||||||
hoshiGroup.has(game.boardState['4-15']).should.eql(false);
|
hoshiGroup.has(noGroupGame.boardState['4-16']).should.eql(true);
|
||||||
hoshiGroup.has(game.boardState['3-14']).should.eql(false);
|
hoshiGroup.has(noGroupGame.boardState['4-15']).should.eql(false);
|
||||||
hoshiGroup.has(game.boardState['3-15']).should.eql(false);
|
hoshiGroup.has(noGroupGame.boardState['3-14']).should.eql(false);
|
||||||
|
hoshiGroup.has(noGroupGame.boardState['3-15']).should.eql(false);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
|
||||||
|
it('makeMove next to adjacent stone of different color should yield proper liberties', done => {
|
||||||
|
const hoshiGroup = noGroupGame.boardState['4-16'].group;
|
||||||
|
const hoshiGroupLiberties = noGroupGame.groups[hoshiGroup].liberties;
|
||||||
|
hoshiGroupLiberties.size.should.eql(2);
|
||||||
|
const fourFifteen = noGroupGame.boardState['4-15'].group;
|
||||||
|
const fourFifteenLiberties = noGroupGame.groups[fourFifteen].liberties;
|
||||||
|
fourFifteenLiberties.size.should.eql(1);
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -211,8 +207,25 @@ describe('makeMove group join and capture logic', () => {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('stones in group have same group property', done => {
|
||||||
|
joinGame.boardState['4-16'].group.should.eql(joinGame.boardState['5-16'].group);
|
||||||
|
joinGame.boardState['4-16'].group.should.eql(joinGame.boardState['4-17'].group);
|
||||||
|
joinGame.boardState['4-17'].group.should.eql(joinGame.boardState['4-16'].group);
|
||||||
|
joinGame.boardState['4-17'].group.should.eql(joinGame.boardState['5-16'].group);
|
||||||
|
joinGame.boardState['5-16'].group.should.eql(joinGame.boardState['4-17'].group);
|
||||||
|
joinGame.boardState['5-16'].group.should.eql(joinGame.boardState['4-16'].group);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
|
||||||
|
it('stones in group should have proper liberties', done => {
|
||||||
|
const group = joinGame.boardState['4-16'].group;
|
||||||
|
joinGame.groups[group]
|
||||||
|
.liberties.size.should.eql(5);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
|
||||||
it('group with only remaining liberty at point to be played returns success: false', done => {
|
it('group with only remaining liberty at point to be played returns success: false', done => {
|
||||||
const point = Game({ gameData: { handicap: 2 } }).initGame()
|
Game({ gameData: { handicap: 2 } }).initGame()
|
||||||
.makeMove({ player: 'white', pos: { x: 4, y: 15 } }) // 3 4 5 6
|
.makeMove({ player: 'white', pos: { x: 4, y: 15 } }) // 3 4 5 6
|
||||||
.makeMove({ player: 'black', pos: { x: 4, y: 4 } }) // 15 -1 -1
|
.makeMove({ player: 'black', pos: { x: 4, y: 4 } }) // 15 -1 -1
|
||||||
.makeMove({ player: 'white', pos: { x: 5, y: 15 } }) // 16 -1 1h 0 -1
|
.makeMove({ player: 'white', pos: { x: 5, y: 15 } }) // 16 -1 1h 0 -1
|
||||||
|
@ -224,8 +237,6 @@ describe('makeMove group join and capture logic', () => {
|
||||||
.makeMove({ player: 'white', pos: { x: 4, y: 17 } })
|
.makeMove({ player: 'white', pos: { x: 4, y: 17 } })
|
||||||
.makeMove({ player: 'black', pos: { x: 10, y: 16 } })
|
.makeMove({ player: 'black', pos: { x: 10, y: 16 } })
|
||||||
.makeMove({ player: 'white', pos: { x: 5, y: 17 } })
|
.makeMove({ player: 'white', pos: { x: 5, y: 17 } })
|
||||||
console.log(point.boardState['5-16']);
|
|
||||||
point
|
|
||||||
.makeMove({ player: 'black', pos: { x: 5, y: 16 } })
|
.makeMove({ player: 'black', pos: { x: 5, y: 16 } })
|
||||||
.success.should.eql(false);
|
.success.should.eql(false);
|
||||||
done();
|
done();
|
||||||
|
@ -256,9 +267,47 @@ describe('makeMove group join and capture logic', () => {
|
||||||
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();
|
||||||
|
});
|
||||||
|
|
||||||
|
const multiCaptureGame = 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 } });
|
||||||
|
|
||||||
|
it('smoke test multi stone group capture', done => {
|
||||||
|
multiCaptureGame.makeMove({ player: 'white', pos: { x: 6, y: 16} })
|
||||||
|
.success.should.eql(true);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
|
||||||
|
it('multi stone group full group is in capturing', done => {
|
||||||
|
const group = multiCaptureGame.boardState['5-16'].group;
|
||||||
|
console.log(multiCaptureGame.groups[group].liberties)
|
||||||
|
console.log(multiCaptureGame.boardState['4-16'].capturing)
|
||||||
|
multiCaptureGame.boardState['6-16'].capturing[-1][0].should.eql(group);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
|
||||||
|
// it('multi stone group capture all points are 0', done => {
|
||||||
|
// const boardState = multiCaptureGame.makeMove({ player: 'white', pos: { x: 6, y: 16} }).boardState;
|
||||||
|
// boardState['5-16'].stone.should.eql(0)
|
||||||
|
// // boardState['4-16'].stone.should.eql(0)
|
||||||
|
// // boardState['4-17'].stone.should.eql(0)
|
||||||
// done();
|
// done();
|
||||||
// })
|
// })
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue