initialize board for all board sizes and handicap amounts

This commit is contained in:
Sorrel Bri 2020-04-19 15:02:09 -07:00
parent 8fb1b80cb6
commit 41e6e662e9
2 changed files with 148 additions and 40 deletions

View file

@ -35,36 +35,37 @@ const HANDI_REC = {
// 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' : [
9 : [
0, 0,
[[ 7, 3 ], [ 3, 7 ] ],
[ [ 7, 7 ], [ 7, 3 ], [ 3, 7 ] ],
[ [ 3, 3 ], [ 7, 7 ], [ 3, 7 ], [ 7, 3 ] ]
[ '7-3', '3-7' ], // 2
[ '7-7', '7-3', '3-7' ],
[ '3-3', '7-7', '3-7', '7-3' ]
],
'13' : [
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] ],
[ '4-10', '10-4' ], // 2
[ '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' : [
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] ],
[ '4-16', '16-4' ], // 2
[ '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));
@ -76,7 +77,7 @@ const pipeMap = (...funcs) => obj => {
}
const checkLegal = ({ point, Game }) => {
return 'l';
return point.stone || 'l';
}
const getBoardState = (Game) => {
@ -84,7 +85,7 @@ const getBoardState = (Game) => {
return pipeMap(getLegal)(Game.boardState);
}
const initBoard = boardSize => {
const initBoard = ({ boardSize, handicap }) => {
const boardState = {};
for (let i = 0; i < Math.pow(boardSize, 2); i++) {
const point = Point({
@ -94,21 +95,26 @@ const initBoard = boardSize => {
});
boardState[`${point.pos.x}-${point.pos.y}`] = point;
}
if (handicap) {
HANDI_PLACE[boardSize][handicap].forEach(pt => {
boardState[pt].stone = 1;
});
}
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,
const Game = ({gameData = {}, gameRecord = []} = {}) => ({
winner: gameData.winner ||null,
turn: gameData.turn || 1, // turn logic depends on handicap stones
pass: gameData.pass || 0, // -1 represents state in which resignation has been submitted, not confirmed
komi: gameData.komi || 6.5, // komi depends on handicap stones + player rank
handicap: gameData.handicap || 0,
boardSize: gameData.boardSize || 19,
groups: {},
boardState: {},
gameRecord: gameRecord || [],
playerState: gameData ? gameData.playerState : {
gameRecord: gameRecord,
playerState: gameData.playerState || {
bCaptures: 0,
wCaptures: 0,
bScore: 0,
@ -119,7 +125,8 @@ const Game = ({gameData, gameRecord} = {}) => ({
this.winner = null;
this.pass = 0;
this.turn = this.handicap ? -1 : 1;
this.boardState = initBoard(this.boardSize)
this.boardState = initBoard({ boardSize: this.boardSize, handicap: this.handicap})
// return this.boardState
return getBoardState(this);
}
});

View file

@ -4,28 +4,129 @@ const { Game, Point } = require('../services/Game.v2');
describe('Game v2', () => {
it('smoke test Game', done => {
(typeof Game()).should.eql('object');
(typeof Game())
.should.eql('object');
done();
});
it('smoke test Point', done => {
(typeof Point({x: 1, y: 1})).should.eql('object');
(typeof Point({x: 1, y: 1}))
.should.eql('object');
done();
});
it('smoke test init Game', done => {
(typeof Game().initGame()).should.eql('object');
(typeof Game().initGame())
.should.eql('object');
done();
})
});
describe('Game.initGame()', () => {
it('init Game returns boardState', done => {
Game().initGame().should.eql(emptyBoard);
describe('Game.initGame() returns boardState', () => {
it('init Game returns default 19x19', done => {
Game().initGame()
.should.eql(emptyBoard);
done();
});
it('init Game with 2 handicap returns boardState with stones', done => {
Game({gameData: { handicap: 2 }}).initGame()
.should.eql({...emptyBoard, '4-16': 1, '16-4': 1});
done();
});
it('init 19x19 Game with all levels of handicap returns boardState with stones', done => {
Game({gameData: { boardSize: 19, handicap: 2 }}).initGame()
.should.eql({...emptyBoard, '4-16': 1, '16-4': 1 });
Game({gameData: { boardSize: 19, handicap: 3 }}).initGame()
.should.eql({...emptyBoard, '16-16': 1, '4-16': 1, '16-4': 1 });
Game({gameData: { boardSize: 19, handicap: 4 }}).initGame()
.should.eql({...emptyBoard, '4-4': 1, '16-16': 1, '4-16': 1, '16-4': 1 });
Game({gameData: { boardSize: 19, handicap: 5 }}).initGame()
.should.eql({...emptyBoard, '10-10': 1, '4-4': 1, '16-16': 1, '4-16': 1, '16-4': 1 });
Game({gameData: { boardSize: 19, handicap: 6 }}).initGame()
.should.eql({...emptyBoard, '10-4': 1, '4-10': 1, '4-4': 1, '16-16': 1, '4-16': 1, '16-4': 1 });
Game({gameData: { boardSize: 19, handicap: 7 }}).initGame()
.should.eql({...emptyBoard, '10-10': 1, '10-4': 1, '4-10': 1, '4-4': 1, '16-16': 1, '4-16': 1, '16-4': 1 });
Game({gameData: { boardSize: 19, handicap: 8 }}).initGame()
.should.eql({...emptyBoard, '16-10': 1, '10-4': 1, '10-16': 1, '4-10': 1, '4-4': 1, '16-16': 1, '4-16': 1, '16-4': 1 });
Game({gameData: { boardSize: 19, handicap: 9 }}).initGame()
.should.eql({...emptyBoard, '10-10': 1, '16-10': 1, '10-4': 1, '10-16': 1, '4-10': 1, '4-4': 1, '16-16': 1, '4-16': 1, '16-4': 1 });
done();
})
it('init 13x13 Game returns boardState', done => {
Game({gameData: { boardSize: 13 }}).initGame()
.should.eql(emptyBoard13);
done();
});
it('init 13x13 Game with all levels of handicap returns boardState with stones', done => {
Game({gameData: { boardSize: 13, handicap: 2 }}).initGame()
.should.eql({...emptyBoard13, '4-10': 1, '10-4': 1 });
Game({gameData: { boardSize: 13, handicap: 3 }}).initGame()
.should.eql({...emptyBoard13, '10-10': 1, '4-10': 1, '10-4': 1 });
Game({gameData: { boardSize: 13, handicap: 4 }}).initGame()
.should.eql({...emptyBoard13, '4-4': 1, '10-10': 1, '4-10': 1, '10-4': 1 });
Game({gameData: { boardSize: 13, handicap: 5 }}).initGame()
.should.eql({...emptyBoard13, '7-7': 1, '4-4': 1, '10-10': 1, '4-10': 1, '10-4': 1 });
Game({gameData: { boardSize: 13, handicap: 6 }}).initGame()
.should.eql({...emptyBoard13, '7-4': 1, '4-7': 1, '4-4': 1, '10-10': 1, '4-10': 1, '10-4': 1 });
Game({gameData: { boardSize: 13, handicap: 7 }}).initGame()
.should.eql({...emptyBoard13, '7-7': 1, '7-4': 1, '4-7': 1, '4-4': 1, '10-10': 1, '4-10': 1, '10-4': 1 });
Game({gameData: { boardSize: 13, handicap: 8 }}).initGame()
.should.eql({...emptyBoard13, '10-7': 1, '7-4': 1, '7-10': 1, '4-7': 1, '4-4': 1, '10-10': 1, '4-10': 1, '10-4': 1 });
Game({gameData: { boardSize: 13, handicap: 9 }}).initGame()
.should.eql({...emptyBoard13, '7-7': 1, '10-7': 1, '7-4': 1, '7-10': 1, '4-7': 1, '4-4': 1, '10-10': 1, '4-10': 1, '10-4': 1 });
done();
});
it('init 9x9 Game returns boardState', done => {
Game({gameData: { boardSize: 9 }}).initGame()
.should.eql(emptyBoard9);
done();
});
it('init 9x9 Game with all levels of handicap returns boardState with stones', done => {
Game({gameData: { boardSize: 9, handicap: 2 }}).initGame()
.should.eql({...emptyBoard9, '3-7': 1, '7-3': 1 });
Game({gameData: { boardSize: 9, handicap: 3 }}).initGame()
.should.eql({...emptyBoard9, '7-7': 1, '3-7': 1, '7-3': 1 });
Game({gameData: { boardSize: 9, handicap: 4 }}).initGame()
.should.eql({...emptyBoard9, '3-3': 1, '7-7': 1, '3-7': 1, '7-3': 1 });
done();
});
})
const emptyBoard9 = {
'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',
'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',
'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',
'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',
'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',
'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',
'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',
'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',
'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'
}
const emptyBoard13 = {
'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',
'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',
'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',
'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',
'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',
'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',
'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',
'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',
'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',
'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',
'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',
'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',
'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'
}
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',