Skip to content

Commit 78729eb

Browse files
delucisnicolodavis
andauthored
refactor(core): More Typescript conversion (#597)
* refactor(core): Convert turn-order to Typescript * refactor(core): Convert logger to Typescript * feat(core): Log errors if next or first methods don’t return numbers Closes #586 * refactor(core): Convert player-view to Typescript * refactor(core): Revert to coerce playOrder value to string Co-authored-by: Nicolo John Davis <[email protected]>
1 parent 1877268 commit 78729eb

4 files changed

Lines changed: 147 additions & 85 deletions

File tree

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ const production = process.env.NODE_ENV === 'production';
1010
const logfn = production ? () => {} : console.log;
1111
const errorfn = console.error;
1212

13-
export function info(msg) {
13+
export function info(msg: string) {
1414
logfn(`INFO: ${msg}`);
1515
}
16-
export function error(error) {
16+
export function error(error: string) {
1717
errorfn('ERROR:', error);
1818
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* https://opensource.org/licenses/MIT.
77
*/
88

9+
import { Ctx, PlayerID } from '../types';
10+
911
/**
1012
* PlayerView reducers.
1113
*/
@@ -17,7 +19,7 @@ export const PlayerView = {
1719
* removes all the keys in `players`, except for the one
1820
* corresponding to the current playerID.
1921
*/
20-
STRIP_SECRETS: (G, ctx, playerID) => {
22+
STRIP_SECRETS: (G: any, ctx: Ctx, playerID: PlayerID) => {
2123
let r = { ...G };
2224

2325
if (r.secret !== undefined) {
Lines changed: 114 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -7,88 +7,104 @@
77
*/
88

99
import * as logging from './logger';
10+
import {
11+
Ctx,
12+
StageArg,
13+
ActivePlayersArg,
14+
PlayerID,
15+
State,
16+
TurnConfig,
17+
} from '../types';
1018

1119
/**
1220
* Event to change the active players (and their stages) in the current turn.
1321
*/
14-
export function SetActivePlayersEvent(state, _playerID, arg) {
22+
export function SetActivePlayersEvent(
23+
state: State,
24+
_playerID: PlayerID,
25+
arg: ActivePlayersArg | PlayerID[]
26+
) {
1527
return { ...state, ctx: SetActivePlayers(state.ctx, arg) };
1628
}
1729

18-
export function SetActivePlayers(ctx, arg) {
30+
export function SetActivePlayers(ctx: Ctx, arg: ActivePlayersArg | PlayerID[]) {
1931
let { _prevActivePlayers } = ctx;
20-
21-
const _nextActivePlayers = arg.next || null;
22-
23-
if (arg.revert) {
24-
_prevActivePlayers = _prevActivePlayers.concat({
25-
activePlayers: ctx.activePlayers,
26-
_activePlayersMoveLimit: ctx._activePlayersMoveLimit,
27-
_activePlayersNumMoves: ctx._activePlayersNumMoves,
28-
});
29-
} else {
30-
_prevActivePlayers = [];
31-
}
32-
3332
let activePlayers = {};
33+
let _nextActivePlayers: ActivePlayersArg | null = null;
3434
let _activePlayersMoveLimit = {};
3535

3636
if (Array.isArray(arg)) {
37+
// support a simple array of player IDs as active players
3738
let value = {};
3839
arg.forEach(v => (value[v] = Stage.NULL));
3940
activePlayers = value;
40-
}
41+
} else {
42+
// process active players argument object
43+
if (arg.next) {
44+
_nextActivePlayers = arg.next;
45+
}
4146

42-
if (arg.currentPlayer !== undefined) {
43-
ApplyActivePlayerArgument(
44-
activePlayers,
45-
_activePlayersMoveLimit,
46-
ctx.currentPlayer,
47-
arg.currentPlayer
48-
);
49-
}
47+
if (arg.revert) {
48+
_prevActivePlayers = _prevActivePlayers.concat({
49+
activePlayers: ctx.activePlayers,
50+
_activePlayersMoveLimit: ctx._activePlayersMoveLimit,
51+
_activePlayersNumMoves: ctx._activePlayersNumMoves,
52+
});
53+
} else {
54+
_prevActivePlayers = [];
55+
}
56+
57+
if (arg.currentPlayer !== undefined) {
58+
ApplyActivePlayerArgument(
59+
activePlayers,
60+
_activePlayersMoveLimit,
61+
ctx.currentPlayer,
62+
arg.currentPlayer
63+
);
64+
}
65+
66+
if (arg.others !== undefined) {
67+
for (let i = 0; i < ctx.playOrder.length; i++) {
68+
const id = ctx.playOrder[i];
69+
if (id !== ctx.currentPlayer) {
70+
ApplyActivePlayerArgument(
71+
activePlayers,
72+
_activePlayersMoveLimit,
73+
id,
74+
arg.others
75+
);
76+
}
77+
}
78+
}
5079

51-
if (arg.others !== undefined) {
52-
for (let i = 0; i < ctx.playOrder.length; i++) {
53-
const id = ctx.playOrder[i];
54-
if (id !== ctx.currentPlayer) {
80+
if (arg.all !== undefined) {
81+
for (let i = 0; i < ctx.playOrder.length; i++) {
82+
const id = ctx.playOrder[i];
5583
ApplyActivePlayerArgument(
5684
activePlayers,
5785
_activePlayersMoveLimit,
5886
id,
59-
arg.others
87+
arg.all
6088
);
6189
}
6290
}
63-
}
64-
65-
if (arg.all !== undefined) {
66-
for (let i = 0; i < ctx.playOrder.length; i++) {
67-
const id = ctx.playOrder[i];
68-
ApplyActivePlayerArgument(
69-
activePlayers,
70-
_activePlayersMoveLimit,
71-
id,
72-
arg.all
73-
);
74-
}
75-
}
7691

77-
if (arg.value) {
78-
for (const id in arg.value) {
79-
ApplyActivePlayerArgument(
80-
activePlayers,
81-
_activePlayersMoveLimit,
82-
id,
83-
arg.value[id]
84-
);
92+
if (arg.value) {
93+
for (const id in arg.value) {
94+
ApplyActivePlayerArgument(
95+
activePlayers,
96+
_activePlayersMoveLimit,
97+
id,
98+
arg.value[id]
99+
);
100+
}
85101
}
86-
}
87102

88-
if (arg.moveLimit) {
89-
for (const id in activePlayers) {
90-
if (_activePlayersMoveLimit[id] === undefined) {
91-
_activePlayersMoveLimit[id] = arg.moveLimit;
103+
if (arg.moveLimit) {
104+
for (const id in activePlayers) {
105+
if (_activePlayersMoveLimit[id] === undefined) {
106+
_activePlayersMoveLimit[id] = arg.moveLimit;
107+
}
92108
}
93109
}
94110
}
@@ -119,9 +135,9 @@ export function SetActivePlayers(ctx, arg) {
119135
/**
120136
* Update activePlayers, setting it to previous, next or null values
121137
* when it becomes empty.
122-
* @param {Object} ctx
138+
* @param ctx
123139
*/
124-
export function UpdateActivePlayersOnceEmpty(ctx) {
140+
export function UpdateActivePlayersOnceEmpty(ctx: Ctx) {
125141
let {
126142
activePlayers,
127143
_activePlayersMoveLimit,
@@ -169,13 +185,13 @@ export function UpdateActivePlayersOnceEmpty(ctx) {
169185
* @param {(String|Object)} arg An active player argument
170186
*/
171187
function ApplyActivePlayerArgument(
172-
activePlayers,
173-
_activePlayersMoveLimit,
174-
playerID,
175-
arg
188+
activePlayers: Ctx['activePlayers'],
189+
_activePlayersMoveLimit: Ctx['_activePlayersMoveLimit'],
190+
playerID: PlayerID,
191+
arg: StageArg
176192
) {
177193
if (typeof arg !== 'object' || arg === Stage.NULL) {
178-
arg = { stage: arg };
194+
arg = { stage: arg as string | null };
179195
}
180196

181197
if (arg.stage !== undefined) {
@@ -189,7 +205,11 @@ function ApplyActivePlayerArgument(
189205
* @param {Array} playOrder - An array of player ID's.
190206
* @param {number} playOrderPos - An index into the above.
191207
*/
192-
function getCurrentPlayer(playOrder, playOrderPos) {
208+
function getCurrentPlayer(
209+
playOrder: Ctx['playOrder'],
210+
playOrderPos: Ctx['playOrderPos']
211+
) {
212+
// convert to string in case playOrder is set to number[]
193213
return playOrder[playOrderPos] + '';
194214
}
195215

@@ -205,15 +225,21 @@ function getCurrentPlayer(playOrder, playOrderPos) {
205225
* @param {object} ctx - The game object ctx.
206226
* @param {object} turn - A turn object for this phase.
207227
*/
208-
export function InitTurnOrderState(G, ctx, turn) {
228+
export function InitTurnOrderState(G: any, ctx: Ctx, turn: TurnConfig) {
209229
const order = turn.order;
210230

211-
let playOrder = [...new Array(ctx.numPlayers)].map((d, i) => i + '');
231+
let playOrder = [...new Array(ctx.numPlayers)].map((_, i) => i + '');
212232
if (order.playOrder !== undefined) {
213233
playOrder = order.playOrder(G, ctx);
214234
}
215235

216236
const playOrderPos = order.first(G, ctx);
237+
const posType = typeof playOrderPos;
238+
if (posType !== 'number') {
239+
logging.error(
240+
`invalid value returned by turn.order.first — expected number got ${posType}${playOrderPos}”.`
241+
);
242+
}
217243
const currentPlayer = getCurrentPlayer(playOrder, playOrderPos);
218244

219245
ctx = { ...ctx, currentPlayer, playOrderPos, playOrder };
@@ -230,7 +256,12 @@ export function InitTurnOrderState(G, ctx, turn) {
230256
* @param {string} endTurnArg - An optional argument to endTurn that
231257
may specify the next player.
232258
*/
233-
export function UpdateTurnOrderState(G, ctx, turn, endTurnArg) {
259+
export function UpdateTurnOrderState(
260+
G: any,
261+
ctx: Ctx,
262+
turn: TurnConfig,
263+
endTurnArg?: true | { remove: any; next: string }
264+
) {
234265
const order = turn.order;
235266

236267
let playOrderPos = ctx.playOrderPos;
@@ -257,6 +288,12 @@ export function UpdateTurnOrderState(G, ctx, turn, endTurnArg) {
257288
});
258289
} else {
259290
const t = order.next(G, ctx);
291+
const type = typeof t;
292+
if (type !== 'number') {
293+
logging.error(
294+
`invalid value returned by turn.order.next — expected number got ${type}${t}”.`
295+
);
296+
}
260297

261298
if (t === undefined) {
262299
endPhase = true;
@@ -293,11 +330,11 @@ export const TurnOrder = {
293330
* The default round-robin turn order.
294331
*/
295332
DEFAULT: {
296-
first: (G, ctx) =>
333+
first: (G: any, ctx: Ctx) =>
297334
ctx.turn === 0
298335
? ctx.playOrderPos
299336
: (ctx.playOrderPos + 1) % ctx.playOrder.length,
300-
next: (G, ctx) => (ctx.playOrderPos + 1) % ctx.playOrder.length,
337+
next: (G: any, ctx: Ctx) => (ctx.playOrderPos + 1) % ctx.playOrder.length,
301338
},
302339

303340
/**
@@ -307,7 +344,7 @@ export const TurnOrder = {
307344
*/
308345
RESET: {
309346
first: () => 0,
310-
next: (G, ctx) => (ctx.playOrderPos + 1) % ctx.playOrder.length,
347+
next: (G: any, ctx: Ctx) => (ctx.playOrderPos + 1) % ctx.playOrder.length,
311348
},
312349

313350
/**
@@ -316,8 +353,8 @@ export const TurnOrder = {
316353
* Similar to DEFAULT, but starts with the player who ended the last phase.
317354
*/
318355
CONTINUE: {
319-
first: (G, ctx) => ctx.playOrderPos,
320-
next: (G, ctx) => (ctx.playOrderPos + 1) % ctx.playOrder.length,
356+
first: (G: any, ctx: Ctx) => ctx.playOrderPos,
357+
next: (G: any, ctx: Ctx) => (ctx.playOrderPos + 1) % ctx.playOrder.length,
321358
},
322359

323360
/**
@@ -328,7 +365,7 @@ export const TurnOrder = {
328365
*/
329366
ONCE: {
330367
first: () => 0,
331-
next: (G, ctx) => {
368+
next: (G: any, ctx: Ctx) => {
332369
if (ctx.playOrderPos < ctx.playOrder.length - 1) {
333370
return ctx.playOrderPos + 1;
334371
}
@@ -343,10 +380,10 @@ export const TurnOrder = {
343380
*
344381
* @param {Array} playOrder - The play order.
345382
*/
346-
CUSTOM: playOrder => ({
383+
CUSTOM: (playOrder: string[]) => ({
347384
playOrder: () => playOrder,
348385
first: () => 0,
349-
next: (G, ctx) => (ctx.playOrderPos + 1) % ctx.playOrder.length,
386+
next: (G: any, ctx: Ctx) => (ctx.playOrderPos + 1) % ctx.playOrder.length,
350387
}),
351388

352389
/**
@@ -358,10 +395,10 @@ export const TurnOrder = {
358395
*
359396
* @param {string} playOrderField - Field in G.
360397
*/
361-
CUSTOM_FROM: playOrderField => ({
362-
playOrder: G => G[playOrderField],
398+
CUSTOM_FROM: (playOrderField: string) => ({
399+
playOrder: (G: any) => G[playOrderField],
363400
first: () => 0,
364-
next: (G, ctx) => (ctx.playOrderPos + 1) % ctx.playOrder.length,
401+
next: (G: any, ctx: Ctx) => (ctx.playOrderPos + 1) % ctx.playOrder.length,
365402
}),
366403
};
367404

0 commit comments

Comments
 (0)