add setLiberties to Point and refactor groups object to include liberties for each group
This commit is contained in:
parent
e553601af7
commit
089783c82d
2 changed files with 53 additions and 40 deletions
|
@ -1,12 +1,3 @@
|
||||||
/*----- constants -----*/
|
|
||||||
const STONES_DATA = {
|
|
||||||
'-1': 'white',
|
|
||||||
'0': 'none',
|
|
||||||
'1': 'black',
|
|
||||||
'k': 'ko'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// index corresponds to difference in player rank
|
// index corresponds to difference in player rank
|
||||||
const KOMI_REC = {
|
const KOMI_REC = {
|
||||||
'9': [
|
'9': [
|
||||||
|
@ -77,11 +68,21 @@ const pipeMap = (...funcs) => obj => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkLegal = ({ point, Game }) => {
|
const checkLegal = ({ point, Game }) => {
|
||||||
return point.stone || 'l';
|
// if stone (includes ko) return false
|
||||||
|
let legal = false;
|
||||||
|
if (point.stone) {
|
||||||
|
return { ...point, legal };
|
||||||
|
}
|
||||||
|
// if liberties return true
|
||||||
|
// if group has liberties return true
|
||||||
|
// if move would capture opposing group
|
||||||
|
// set capturing object and return true
|
||||||
|
point.legal = !point.stone ? true : false;
|
||||||
|
return point;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getBoardState = (Game) => {
|
const getBoardState = (Game) => {
|
||||||
const getLegal = point => checkLegal({ point, Game });
|
const getLegal = point => checkLegal({ point, Game }).legal ? 'l' : point.stone;
|
||||||
return pipeMap(getLegal)(Game.boardState);
|
return pipeMap(getLegal)(Game.boardState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +164,7 @@ const Game = ({gameData = {}, gameRecord = []} = {}) => ({
|
||||||
|
|
||||||
initGroup: function(point) {
|
initGroup: function(point) {
|
||||||
const newSymbol = Symbol(`${point.pos.x}-${point.pos.y}`);
|
const newSymbol = Symbol(`${point.pos.x}-${point.pos.y}`);
|
||||||
this.groups[newSymbol] = new Set();
|
this.groups[newSymbol] = { stones: new Set(), liberties: new Set()};
|
||||||
return newSymbol;
|
return newSymbol;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -195,17 +196,26 @@ const Point = ({x, y, boardSize = 19}) => ({
|
||||||
point.group = game.initGroup(point);
|
point.group = game.initGroup(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add current point to global group
|
// add current point to global group and override current group
|
||||||
game.groups[point.group].add(this);
|
game.groups[point.group].stones.add(this);
|
||||||
this.group = point.group;
|
this.group = point.group;
|
||||||
|
this.setLiberties(game);
|
||||||
for (let neighbor of Object.values(this.neighbors)) {
|
for (let neighbor of Object.values(this.neighbors)) {
|
||||||
if ( neighbor.stone === this.stone
|
if ( neighbor.stone === this.stone
|
||||||
&& neighbor.group !== this.group) {
|
// this check prevents infinite call chains
|
||||||
|
&& neighbor.group !== this.group
|
||||||
|
) {
|
||||||
neighbor.joinGroup({ point: this, game });
|
neighbor.joinGroup({ point: this, game });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setLiberties: function(game) {
|
||||||
|
const neighbors = Object.values(this.neighbors);
|
||||||
|
const liberties = game.groups[this.group].liberties;
|
||||||
|
// if point is occupied remove it from liberties set of point group, else add it
|
||||||
|
neighbors.forEach( pt => pt ? liberties.delete(pt) : liberties.add(pt) );
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -158,14 +158,16 @@ describe('Game.makeMove({ player: str, pos: { x: int, y: int } })', () => {
|
||||||
.makeMove({ player: 'black', pos: { x: 4, y: 14 }})
|
.makeMove({ player: 'black', pos: { x: 4, y: 14 }})
|
||||||
.makeMove({ player: 'white', pos: { x: 4, y: 5 }})
|
.makeMove({ player: 'white', pos: { x: 4, y: 5 }})
|
||||||
|
|
||||||
const blackGroup = game.boardState['4-14'].group;
|
const blackGroupKey = game.boardState['4-14'].group;
|
||||||
game.groups[blackGroup].has(game.boardState['4-14']).should.eql(true);
|
const blackGroup = game.groups[blackGroupKey].stones;
|
||||||
game.groups[blackGroup].has(game.boardState['4-15']).should.eql(true);
|
blackGroup.has(game.boardState['4-14']).should.eql(true);
|
||||||
game.groups[blackGroup].has(game.boardState['4-16']).should.eql(true);
|
blackGroup.has(game.boardState['4-15']).should.eql(true);
|
||||||
const whiteGroup = game.boardState['4-4'].group;
|
blackGroup.has(game.boardState['4-16']).should.eql(true);
|
||||||
game.groups[whiteGroup].has(game.boardState['4-4']).should.eql(true);
|
const whiteGroupKey = game.boardState['4-4'].group;
|
||||||
game.groups[whiteGroup].has(game.boardState['3-4']).should.eql(true);
|
const whiteGroup = game.groups[whiteGroupKey].stones;
|
||||||
game.groups[whiteGroup].has(game.boardState['4-5']).should.eql(true);
|
whiteGroup.has(game.boardState['4-4']).should.eql(true);
|
||||||
|
whiteGroup.has(game.boardState['3-4']).should.eql(true);
|
||||||
|
whiteGroup.has(game.boardState['4-5']).should.eql(true);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -176,23 +178,24 @@ describe('Game.makeMove({ player: str, pos: { x: int, y: int } })', () => {
|
||||||
.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 hoshiGroup = game.boardState['4-16'].group;
|
const hoshiGroupKey = game.boardState['4-16'].group;
|
||||||
game.groups[hoshiGroup].has(game.boardState['4-16']).should.eql(true);
|
const hoshiGroup = game.groups[hoshiGroupKey].stones;
|
||||||
game.groups[hoshiGroup].has(game.boardState['4-15']).should.eql(false);
|
hoshiGroup.has(game.boardState['4-16']).should.eql(true);
|
||||||
game.groups[hoshiGroup].has(game.boardState['3-14']).should.eql(false);
|
hoshiGroup.has(game.boardState['4-15']).should.eql(false);
|
||||||
game.groups[hoshiGroup].has(game.boardState['3-15']).should.eql(false);
|
hoshiGroup.has(game.boardState['3-14']).should.eql(false);
|
||||||
|
hoshiGroup.has(game.boardState['3-15']).should.eql(false);
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
|
|
||||||
// it('makeMove returns success: false when move is made in point with no liberties', done => {
|
it('makeMove returns success: false when move is made in point with no liberties', done => {
|
||||||
// Game({ gameData: { handicap: 2 } }).initGame()
|
Game({ gameData: { handicap: 2 } }).initGame()
|
||||||
// .makeMove({ player: 'white', pos: { x: 4, y: 4 } }).makeMove({ player: 'black', pos: { x: 6, y: 16 } })
|
.makeMove({ player: 'white', pos: { x: 4, y: 4 } }).makeMove({ player: 'black', pos: { x: 6, y: 16 } })
|
||||||
// .makeMove({ player: 'white', pos: { x: 16, y: 16 }}).makeMove({ player: 'black', pos: { x: 5, y: 15 } })
|
.makeMove({ player: 'white', pos: { x: 16, y: 16 }}).makeMove({ player: 'black', pos: { x: 5, y: 15 } })
|
||||||
// .makeMove({ player: 'white', pos: { x: 16, y: 10 }}).makeMove({ player: 'black', pos: { x: 5, y: 17 } })
|
.makeMove({ player: 'white', pos: { x: 16, y: 10 }}).makeMove({ player: 'black', pos: { x: 5, y: 17 } })
|
||||||
// .makeMove({ player: 'white', pos: { x: 5, y: 16 }})
|
.makeMove({ player: 'white', pos: { x: 5, y: 16 }})
|
||||||
// .success.should.eql(false);
|
.success.should.eql(false);
|
||||||
// done();
|
done();
|
||||||
// })
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
const initialMeta = {
|
const initialMeta = {
|
||||||
|
|
Loading…
Reference in a new issue