Skip to content

Commit

Permalink
fix: support stages and get coverage up
Browse files Browse the repository at this point in the history
  • Loading branch information
senritsu committed Aug 22, 2021
1 parent 373db50 commit 81baa16
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 8 deletions.
48 changes: 45 additions & 3 deletions src/core/flow.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ describe('stage events', () => {
test('with multiple active players', () => {
const flow = Flow({
turn: {
activePlayers: { all: 'A', moveLimit: 5 },
activePlayers: { all: 'A', minMoves: 2, moveLimit: 5 },
},
});
let state = { G: {}, ctx: flow.ctx(3) } as State;
Expand All @@ -709,7 +709,7 @@ describe('stage events', () => {
expect(state.ctx.activePlayers).toEqual({ '0': 'A', '1': 'A', '2': 'A' });
state = flow.processEvent(
state,
gameEvent('setStage', { stage: 'B', moveLimit: 1 })
gameEvent('setStage', { stage: 'B', minMoves: 1 })
);
expect(state.ctx.activePlayers).toEqual({ '0': 'B', '1': 'A', '2': 'A' });

Expand Down Expand Up @@ -737,6 +737,19 @@ describe('stage events', () => {
expect(state.ctx._activePlayersNumMoves).toMatchObject({ '0': 0 });
});

test('with min moves', () => {
const flow = Flow({});
let state = { G: {}, ctx: flow.ctx(2) } as State;
state = flow.init(state);

expect(state.ctx._activePlayersMinMoves).toBeNull();
state = flow.processEvent(
state,
gameEvent('setStage', { stage: 'A', minMoves: 1 })
);
expect(state.ctx._activePlayersMinMoves).toEqual({ '0': 1 });
});

test('with move limit', () => {
const flow = Flow({});
let state = { G: {}, ctx: flow.ctx(2) } as State;
Expand Down Expand Up @@ -858,6 +871,35 @@ describe('stage events', () => {
expect(state.ctx.activePlayers).toEqual({ '1': 'A', '2': 'A' });
});

test('with min moves', () => {
const flow = Flow({
turn: {
activePlayers: { all: 'A', minMoves: 2 },
},
});
let state = { G: {}, ctx: flow.ctx(2) } as State;
state = flow.init(state);

expect(state.ctx.activePlayers).toEqual({ '0': 'A', '1': 'A' });

state = flow.processEvent(state, gameEvent('endStage'));

// player 0 is not allowed to end the stage, they haven't made any move yet
expect(state.ctx.activePlayers).toEqual({ '0': 'A', '1': 'A' });

state = flow.processMove(state, makeMove('move', null, '0').payload);
state = flow.processEvent(state, gameEvent('endStage'));

// player 0 is still not allowed to end the stage, they haven't made the minimum number of moves
expect(state.ctx.activePlayers).toEqual({ '0': 'A', '1': 'A' });

state = flow.processMove(state, makeMove('move', null, '0').payload);
state = flow.processEvent(state, gameEvent('endStage'));

// having made 2 moves, player 0 was allowed to end the stage
expect(state.ctx.activePlayers).toEqual({ '1': 'A' });
});

test('maintains move count', () => {
const flow = Flow({
moves: { A: () => {} },
Expand Down Expand Up @@ -1936,7 +1978,7 @@ describe('hook execution order', () => {
calls.push('moves.endStage');
},
setActivePlayers: (G, ctx) => {
ctx.events.setActivePlayers({ all: 'A', moveLimit: 1 });
ctx.events.setActivePlayers({ all: 'A', minMoves: 1, moveLimit: 1 });
calls.push('moves.setActivePlayers');
},
},
Expand Down
17 changes: 16 additions & 1 deletion src/core/flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@ export function Flow({
let { ctx, _stateID } = state;
let {
activePlayers,
_activePlayersNumMoves,
_activePlayersMinMoves,
_activePlayersMoveLimit,
phase,
Expand All @@ -576,8 +577,9 @@ export function Flow({

const playerInStage = activePlayers !== null && playerID in activePlayers;

const phaseConfig = GetPhase(ctx);

if (!arg && playerInStage) {
const phaseConfig = GetPhase(ctx);
const stage = phaseConfig.turn.stages[activePlayers[playerID]];
if (stage && stage.next) arg = stage.next;
}
Expand All @@ -590,6 +592,19 @@ export function Flow({
// If player isn’t in a stage, there is nothing else to do.
if (!playerInStage) return state;

// Prevent ending the stage if minMoves haven't been reached.
const currentPlayerMoves = _activePlayersNumMoves[playerID] || 0;
if (
_activePlayersMinMoves &&
_activePlayersMinMoves[playerID] &&
currentPlayerMoves < _activePlayersMinMoves[playerID]
) {
logging.info(
`cannot end stage before making ${_activePlayersMinMoves[playerID]} moves`
);
return state;
}

// Remove player from activePlayers.
activePlayers = { ...activePlayers };
delete activePlayers[playerID];
Expand Down
41 changes: 37 additions & 4 deletions src/core/turn-order.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,7 @@ describe('setActivePlayers', () => {
_prevActivePlayers: [
{
activePlayers: { '0': 'stage1' },
_activePlayersMinMoves: null,
_activePlayersMoveLimit: null,
_activePlayersNumMoves: { '0': 1 },
},
Expand All @@ -591,6 +592,7 @@ describe('setActivePlayers', () => {
A: (G, ctx) => {
ctx.events.setActivePlayers({
currentPlayer: 'stage2',
minMoves: 1,
moveLimit: 1,
revert: true,
});
Expand All @@ -601,6 +603,7 @@ describe('setActivePlayers', () => {
turn: {
activePlayers: {
currentPlayer: 'stage1',
minMoves: 2,
moveLimit: 3,
},
},
Expand All @@ -612,6 +615,7 @@ describe('setActivePlayers', () => {
expect(state.ctx).toMatchObject({
activePlayers: { '0': 'stage1' },
_prevActivePlayers: [],
_activePlayersMinMoves: { '0': 2 },
_activePlayersMoveLimit: { '0': 3 },
_activePlayersNumMoves: {
'0': 0,
Expand All @@ -623,6 +627,7 @@ describe('setActivePlayers', () => {
expect(state.ctx).toMatchObject({
activePlayers: { '0': 'stage1' },
_prevActivePlayers: [],
_activePlayersMinMoves: { '0': 2 },
_activePlayersMoveLimit: { '0': 3 },
_activePlayersNumMoves: {
'0': 1,
Expand All @@ -637,9 +642,11 @@ describe('setActivePlayers', () => {
{
activePlayers: { '0': 'stage1' },
_activePlayersNumMoves: { '0': 2 },
_activePlayersMinMoves: { '0': 2 },
_activePlayersMoveLimit: { '0': 3 },
},
],
_activePlayersMinMoves: { '0': 1 },
_activePlayersMoveLimit: { '0': 1 },
_activePlayersNumMoves: {
'0': 0,
Expand All @@ -651,6 +658,7 @@ describe('setActivePlayers', () => {
expect(state.ctx).toMatchObject({
activePlayers: { '0': 'stage1' },
_prevActivePlayers: [],
_activePlayersMinMoves: { '0': 2 },
_activePlayersMoveLimit: { '0': 3 },
_activePlayersNumMoves: {
'0': 2,
Expand Down Expand Up @@ -721,6 +729,7 @@ describe('setActivePlayers', () => {
turn: {
activePlayers: {
all: 'play',
minMoves: 1,
moveLimit: 3,
},
stages: {
Expand All @@ -732,6 +741,12 @@ describe('setActivePlayers', () => {
const reducer = CreateGameReducer({ game });
let state = InitializeGame({ game, numPlayers: 3 });

expect(state.ctx._activePlayersMinMoves).toEqual({
'0': 1,
'1': 1,
'2': 1,
});

expect(state.ctx._activePlayersMoveLimit).toEqual({
'0': 3,
'1': 3,
Expand Down Expand Up @@ -767,7 +782,7 @@ describe('setActivePlayers', () => {
const game = {
turn: {
activePlayers: {
currentPlayer: { stage: 'play', moveLimit: 2 },
currentPlayer: { stage: 'play', minMoves: 1, moveLimit: 2 },
others: { stage: 'play', moveLimit: 1 },
},
stages: {
Expand All @@ -779,6 +794,12 @@ describe('setActivePlayers', () => {
const reducer = CreateGameReducer({ game });
let state = InitializeGame({ game, numPlayers: 3 });

expect(state.ctx._activePlayersMinMoves).toEqual({
'0': 1,
'1': undefined,
'2': undefined,
});

expect(state.ctx._activePlayersMoveLimit).toEqual({
'0': 2,
'1': 1,
Expand Down Expand Up @@ -812,14 +833,20 @@ describe('setActivePlayers', () => {
const game = {
turn: {
activePlayers: {
all: { stage: 'play', moveLimit: 2 },
all: { stage: 'play', minMoves: 2, moveLimit: 2 },
minMoves: 1,
moveLimit: 1,
},
},
};

const state = InitializeGame({ game, numPlayers: 2 });

expect(state.ctx._activePlayersMinMoves).toEqual({
'0': 2,
'1': 2,
});

expect(state.ctx._activePlayersMoveLimit).toEqual({
'0': 2,
'1': 2,
Expand All @@ -832,8 +859,8 @@ describe('setActivePlayers', () => {
activePlayers: {
value: {
'0': { stage: 'play', moveLimit: 1 },
'1': { stage: 'play', moveLimit: 2 },
'2': { stage: 'play', moveLimit: 3 },
'1': { stage: 'play', minMoves: 1, moveLimit: 2 },
'2': { stage: 'play', minMoves: 2, moveLimit: 3 },
},
},
stages: {
Expand All @@ -845,6 +872,12 @@ describe('setActivePlayers', () => {
const reducer = CreateGameReducer({ game });
let state = InitializeGame({ game, numPlayers: 3 });

expect(state.ctx._activePlayersMinMoves).toEqual({
'0': undefined,
'1': 1,
'2': 2,
});

expect(state.ctx._activePlayersMoveLimit).toEqual({
'0': 1,
'1': 2,
Expand Down

0 comments on commit 81baa16

Please sign in to comment.