initialize board for all board sizes and handicap amounts
This commit is contained in:
parent
8fb1b80cb6
commit
41e6e662e9
2 changed files with 148 additions and 40 deletions
|
@ -35,36 +35,37 @@ const HANDI_REC = {
|
||||||
// index represents handicap placement for different board-sizes, eg handiPlace['9][1] = { (3, 3), (7, 7) }
|
// 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
|
// last array in each property also used for hoshi rendering
|
||||||
const HANDI_PLACE = {
|
const HANDI_PLACE = {
|
||||||
'9' : [
|
9 : [
|
||||||
0, 0,
|
0, 0,
|
||||||
[[ 7, 3 ], [ 3, 7 ] ],
|
[ '7-3', '3-7' ], // 2
|
||||||
[ [ 7, 7 ], [ 7, 3 ], [ 3, 7 ] ],
|
[ '7-7', '7-3', '3-7' ],
|
||||||
[ [ 3, 3 ], [ 7, 7 ], [ 3, 7 ], [ 7, 3 ] ]
|
[ '3-3', '7-7', '3-7', '7-3' ]
|
||||||
],
|
],
|
||||||
'13' : [
|
13 : [
|
||||||
0, 0,
|
0, 0,
|
||||||
[ [ 4, 10 ], [ 10, 4 ] ],
|
[ '4-10', '10-4' ], // 2
|
||||||
[ [ 10, 10 ], [ 4, 10 ], [ 10, 4] ],
|
[ '10-10', '4-10', '10-4' ],
|
||||||
[ [ 4, 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-7', '4-4', '10-10', '4-10', '10-4' ],
|
||||||
[ [ 7, 4 ], [ 4, 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] ],
|
[ '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] ],
|
[ '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] ],
|
[ '7-7', '10-7', '7-4', '7-10', '4-7', '4-4', '10-10', '4-10', '10-4' ],
|
||||||
],
|
],
|
||||||
'19' : [
|
19 : [
|
||||||
0, 0,
|
0, 0,
|
||||||
[ [ 4, 16 ], [ 16, 4 ] ],
|
[ '4-16', '16-4' ], // 2
|
||||||
[ [ 16, 16 ], [ 4, 16 ], [ 16, 4] ],
|
[ '16-16', '4-16', '16-4' ],
|
||||||
[ [ 4, 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-10', '4-4', '16-16', '4-16', '16-4' ],
|
||||||
[ [ 10, 4 ], [ 4, 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] ],
|
[ '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] ],
|
[ '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] ],
|
[ '10-10', '16-10', '10-4', '10-16', '4-10', '4-4', '16-16', '4-16', '16-4' ],
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const pipeMap = (...funcs) => obj => {
|
const pipeMap = (...funcs) => obj => {
|
||||||
const arr = Object.entries(obj).reduce((acc, [key, value]) => {
|
const arr = Object.entries(obj).reduce((acc, [key, value]) => {
|
||||||
funcs.forEach(func => value = func(value));
|
funcs.forEach(func => value = func(value));
|
||||||
|
@ -76,7 +77,7 @@ const pipeMap = (...funcs) => obj => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkLegal = ({ point, Game }) => {
|
const checkLegal = ({ point, Game }) => {
|
||||||
return 'l';
|
return point.stone || 'l';
|
||||||
}
|
}
|
||||||
|
|
||||||
const getBoardState = (Game) => {
|
const getBoardState = (Game) => {
|
||||||
|
@ -84,7 +85,7 @@ const getBoardState = (Game) => {
|
||||||
return pipeMap(getLegal)(Game.boardState);
|
return pipeMap(getLegal)(Game.boardState);
|
||||||
}
|
}
|
||||||
|
|
||||||
const initBoard = boardSize => {
|
const initBoard = ({ boardSize, handicap }) => {
|
||||||
const boardState = {};
|
const boardState = {};
|
||||||
for (let i = 0; i < Math.pow(boardSize, 2); i++) {
|
for (let i = 0; i < Math.pow(boardSize, 2); i++) {
|
||||||
const point = Point({
|
const point = Point({
|
||||||
|
@ -94,21 +95,26 @@ const initBoard = boardSize => {
|
||||||
});
|
});
|
||||||
boardState[`${point.pos.x}-${point.pos.y}`] = point;
|
boardState[`${point.pos.x}-${point.pos.y}`] = point;
|
||||||
}
|
}
|
||||||
|
if (handicap) {
|
||||||
|
HANDI_PLACE[boardSize][handicap].forEach(pt => {
|
||||||
|
boardState[pt].stone = 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
return boardState;
|
return boardState;
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns Game object
|
// returns Game object
|
||||||
const Game = ({gameData, gameRecord} = {}) => ({
|
const Game = ({gameData = {}, gameRecord = []} = {}) => ({
|
||||||
winner: gameData ? gameData.winner : null,
|
winner: gameData.winner ||null,
|
||||||
turn: gameData ? gameData.turn : 1, // turn logic depends on handicap stones
|
turn: 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
|
pass: 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
|
komi: gameData.komi || 6.5, // komi depends on handicap stones + player rank
|
||||||
handicap: gameData ? gameData.handicap : 0,
|
handicap: gameData.handicap || 0,
|
||||||
boardSize: gameData ? gameData.boardSize : 19,
|
boardSize: gameData.boardSize || 19,
|
||||||
groups: {},
|
groups: {},
|
||||||
boardState: {},
|
boardState: {},
|
||||||
gameRecord: gameRecord || [],
|
gameRecord: gameRecord,
|
||||||
playerState: gameData ? gameData.playerState : {
|
playerState: gameData.playerState || {
|
||||||
bCaptures: 0,
|
bCaptures: 0,
|
||||||
wCaptures: 0,
|
wCaptures: 0,
|
||||||
bScore: 0,
|
bScore: 0,
|
||||||
|
@ -119,7 +125,8 @@ const Game = ({gameData, gameRecord} = {}) => ({
|
||||||
this.winner = null;
|
this.winner = null;
|
||||||
this.pass = 0;
|
this.pass = 0;
|
||||||
this.turn = this.handicap ? -1 : 1;
|
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);
|
return getBoardState(this);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,28 +4,129 @@ const { Game, Point } = require('../services/Game.v2');
|
||||||
|
|
||||||
describe('Game v2', () => {
|
describe('Game v2', () => {
|
||||||
it('smoke test Game', done => {
|
it('smoke test Game', done => {
|
||||||
(typeof Game()).should.eql('object');
|
(typeof Game())
|
||||||
|
.should.eql('object');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('smoke test Point', 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();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('smoke test init Game', done => {
|
it('smoke test init Game', done => {
|
||||||
(typeof Game().initGame()).should.eql('object');
|
(typeof Game().initGame())
|
||||||
|
.should.eql('object');
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Game.initGame()', () => {
|
describe('Game.initGame() returns boardState', () => {
|
||||||
it('init Game returns boardState', done => {
|
it('init Game returns default 19x19', done => {
|
||||||
Game().initGame().should.eql(emptyBoard);
|
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();
|
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 = {
|
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',
|
'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',
|
'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',
|
||||||
|
|
Loading…
Reference in a new issue