Skip to content

Commit

Permalink
convert turnOrder into a turn object
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolodavis committed Sep 10, 2019
1 parent 514dc1e commit 53b7ac7
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 61 deletions.
22 changes: 11 additions & 11 deletions src/core/flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
SetActionPlayersEvent,
InitTurnOrderState,
UpdateTurnOrderState,
TurnOrder,
} from './turn-order';
import * as plugins from '../plugins/main';
import { automaticGameEvent } from './action-creators';
Expand Down Expand Up @@ -176,7 +175,7 @@ export function Flow({
* @param {...object} onMove - Any code to run at the end of a move.
* (G, ctx, { type: 'moveName', args: [] }) => G
*
* @param {...object} turnOrder - Customize the turn order (see turn-order.js).
* @param {...object} turn - Customize the turn structure (see turn-order.js).
*
* @param {...object} endTurn - Set to false to disable the `endTurn` event.
*
Expand Down Expand Up @@ -238,8 +237,8 @@ export function Flow({
* // A phase-specific onMove.
* onMove - (G, ctx) => G,
*
* // A phase-specific turnOrder.
* turnOrder: TurnOrder.DEFAULT,
* // A phase-specific turn structure.
* turn: { order: TurnOrder.DEFAULT },
*
* // A phase-specific movesPerTurn.
* movesPerTurn: integer,
Expand All @@ -257,7 +256,7 @@ export function FlowWithPhases({
onTurnBegin,
onTurnEnd,
onMove,
turnOrder,
turn,
endTurn,
endPhase,
endGame,
Expand Down Expand Up @@ -292,7 +291,7 @@ export function FlowWithPhases({
if (!onTurnBegin) onTurnBegin = G => G;
if (!onTurnEnd) onTurnEnd = G => G;
if (!onMove) onMove = G => G;
if (!turnOrder) turnOrder = TurnOrder.DEFAULT;
if (!turn) turn = {};
if (undoableMoves === undefined) undoableMoves = null;

const phaseMap = game.phases || phases || {};
Expand Down Expand Up @@ -346,8 +345,8 @@ export function FlowWithPhases({
conf.onMove = onMove;
}
conf.onMove = plugins.FnWrap(conf.onMove, game);
if (conf.turnOrder === undefined) {
conf.turnOrder = turnOrder;
if (conf.turn === undefined) {
conf.turn = turn;
}
if (conf.undoableMoves === undefined) {
conf.undoableMoves = undoableMoves;
Expand All @@ -372,7 +371,7 @@ export function FlowWithPhases({
// Helper to perform start-of-phase initialization.
const startPhase = function(state, config) {
let G = config.onPhaseBegin(state.G, state.ctx);
let ctx = InitTurnOrderState(G, state.ctx, config.turnOrder);
let ctx = InitTurnOrderState(G, state.ctx, config.turn);

// Allow plugins to modify G and ctx at the beginning of a phase.
G = plugins.G.onPhaseBegin(G, ctx, game);
Expand Down Expand Up @@ -544,7 +543,7 @@ export function FlowWithPhases({
const { endPhase: a, ctx: b } = UpdateTurnOrderState(
G,
ctx,
conf.turnOrder,
conf.turn,
arg
);
endPhase = a;
Expand Down Expand Up @@ -611,7 +610,7 @@ export function FlowWithPhases({
const playerID = action.playerID;
actionPlayers = actionPlayers.filter(id => id !== playerID);

if (actionPlayers.length == 0 && conf.turnOrder.endPhaseOnceDone) {
if (actionPlayers.length == 0 && conf.turn.order.endPhaseOnceDone) {
actionPlayersOnceDone = true;
}
}
Expand Down Expand Up @@ -724,6 +723,7 @@ export function FlowWithPhases({
allPlayed: false,
phase: startingPhase,
prevPhase: 'default',
stage: {},
}),
init: state => {
return startGame(state);
Expand Down
20 changes: 11 additions & 9 deletions src/core/flow.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,12 @@ describe('phases', () => {
},
},

turnOrder: {
first: G => {
if (G.setupB && !G.cleanupB) return '1';
return '0';
turn: {
order: {
first: G => {
if (G.setupB && !G.cleanupB) return '1';
return '0';
},
},
},
});
Expand Down Expand Up @@ -202,7 +204,7 @@ describe('phases', () => {
test('movesPerTurn', () => {
{
const flow = FlowWithPhases({ movesPerTurn: 2 });
let state = { ctx: flow.ctx(2) };
let state = flow.init({ ctx: flow.ctx(2) });
expect(state.ctx.turn).toBe(0);
state = flow.processMove(state, makeMove('move', null, '0').payload);
expect(state.ctx.turn).toBe(0);
Expand All @@ -217,7 +219,7 @@ test('movesPerTurn', () => {
movesPerTurn: 2,
phases: { B: { movesPerTurn: 1 } },
});
let state = { ctx: flow.ctx(2) };
let state = flow.init({ ctx: flow.ctx(2) });
expect(state.ctx.turn).toBe(0);
state = flow.processMove(state, makeMove('move', null, '0').payload);
expect(state.ctx.turn).toBe(0);
Expand Down Expand Up @@ -349,7 +351,7 @@ test('endGameIf', () => {
{
const flow = FlowWithPhases({ endGameIf: G => G.win });

let state = { G: {}, ctx: flow.ctx(2) };
let state = flow.init({ G: {}, ctx: flow.ctx(2) });
state = flow.processGameEvent(state, gameEvent('endTurn'));
expect(state.ctx.gameover).toBe(undefined);

Expand All @@ -372,7 +374,7 @@ test('endGameIf', () => {
phases: { A: { endGameIf: G => G.win } },
});

let state = { G: {}, ctx: flow.ctx(2) };
let state = flow.init({ G: {}, ctx: flow.ctx(2) });
state = flow.processGameEvent(state, gameEvent('endTurn'));
expect(state.ctx.gameover).toBe(undefined);

Expand Down Expand Up @@ -711,7 +713,7 @@ test('endTurn is not called twice in one move', () => {
phases: { A: { endPhaseIf: G => G.endPhase, next: 'B' }, B: {} },
});

let state = { G: {}, ctx: flow.ctx(2) };
let state = flow.init({ G: {}, ctx: flow.ctx(2) });

expect(state.ctx.phase).toBe('A');
expect(state.ctx.currentPlayer).toBe('0');
Expand Down
32 changes: 20 additions & 12 deletions src/core/game.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,11 @@ test('rounds with starting player token', () => {
startingPhase: 'main',
phases: {
main: {
turnOrder: {
first: G => G.startingPlayerToken,
next: (G, ctx) => (+ctx.playOrderPos + 1) % ctx.playOrder.length,
turn: {
order: {
first: G => G.startingPlayerToken,
next: (G, ctx) => (+ctx.playOrderPos + 1) % ctx.playOrder.length,
},
},
},
},
Expand Down Expand Up @@ -99,23 +101,29 @@ test('serpentine setup phases', () => {
startingPhase: 'first setup round',
phases: {
'first setup round': {
turnOrder: {
first: () => 0,
next: (G, ctx) => (+ctx.playOrderPos + 1) % ctx.playOrder.length,
turn: {
order: {
first: () => 0,
next: (G, ctx) => (+ctx.playOrderPos + 1) % ctx.playOrder.length,
},
},
next: 'second setup round',
},
'second setup round': {
turnOrder: {
first: (G, ctx) => ctx.playOrder.length - 1,
next: (G, ctx) => (+ctx.playOrderPos - 1) % ctx.playOrder.length,
turn: {
order: {
first: (G, ctx) => ctx.playOrder.length - 1,
next: (G, ctx) => (+ctx.playOrderPos - 1) % ctx.playOrder.length,
},
},
next: 'main phase',
},
'main phase': {
turnOrder: {
first: () => 0,
next: (G, ctx) => (+ctx.playOrderPos + 1) % ctx.playOrder.length,
turn: {
order: {
first: () => 0,
next: (G, ctx) => (+ctx.playOrderPos + 1) % ctx.playOrder.length,
},
},
},
},
Expand Down
28 changes: 16 additions & 12 deletions src/core/turn-order.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,23 @@ function getCurrentPlayer(playOrder, playOrderPos) {
* Called at the start of a phase to initialize turn order state.
* @param {object} G - The game object G.
* @param {object} ctx - The game object ctx.
* @param {object} turnOrder - A turn order object for this phase.
* @param {object} turn - A turn object for this phase.
*/
export function InitTurnOrderState(G, ctx, turnOrder) {
export function InitTurnOrderState(G, ctx, turn) {
if (turn.order === undefined) {
turn.order = TurnOrder.DEFAULT;
}

let playOrder = [...new Array(ctx.numPlayers)].map((d, i) => i + '');
if (turnOrder.playOrder !== undefined) {
playOrder = turnOrder.playOrder(G, ctx);
if (turn.order.playOrder !== undefined) {
playOrder = turn.order.playOrder(G, ctx);
}

const playOrderPos = turnOrder.first(G, ctx);
const playOrderPos = turn.order.first(G, ctx);
const currentPlayer = getCurrentPlayer(playOrder, playOrderPos);

if (turnOrder.actionPlayers !== undefined) {
ctx = setActionPlayers(G, ctx, turnOrder.actionPlayers);
if (turn.order.actionPlayers !== undefined) {
ctx = setActionPlayers(G, ctx, turn.order.actionPlayers);
} else {
ctx = { ...ctx, actionPlayers: [currentPlayer] };
}
Expand All @@ -111,11 +115,11 @@ export function InitTurnOrderState(G, ctx, turnOrder) {
* Called at the end of each turn to update the turn order state.
* @param {object} G - The game object G.
* @param {object} ctx - The game object ctx.
* @param {object} turnOrder - A turn order object for this phase.
* @param {object} turn - A turn object for this phase.
* @param {string} endTurnArg - An optional argument to endTurn that
may specify the next player.
*/
export function UpdateTurnOrderState(G, ctx, turnOrder, endTurnArg) {
export function UpdateTurnOrderState(G, ctx, turn, endTurnArg) {
let playOrderPos = ctx.playOrderPos;
let currentPlayer = ctx.currentPlayer;
let actionPlayers = ctx.actionPlayers;
Expand All @@ -130,15 +134,15 @@ export function UpdateTurnOrderState(G, ctx, turnOrder, endTurnArg) {
logging.error(`invalid argument to endTurn: ${endTurnArg}`);
}
} else {
const t = turnOrder.next(G, ctx);
const t = turn.order.next(G, ctx);

if (t === undefined) {
endPhase = true;
} else {
playOrderPos = t;
currentPlayer = getCurrentPlayer(ctx.playOrder, playOrderPos);

if (turnOrder.actionPlayers === undefined) {
if (turn.order.actionPlayers === undefined) {
actionPlayers = [currentPlayer];
}
}
Expand All @@ -156,7 +160,7 @@ export function UpdateTurnOrderState(G, ctx, turnOrder, endTurnArg) {

/**
* Set of different turn orders possible in a phase.
* These are meant to be passed to the `turnOrder` setting
* These are meant to be passed to the `turn` setting
* in the flow objects.
*
* Each object defines the first player when the phase / game
Expand Down

0 comments on commit 53b7ac7

Please sign in to comment.