From 823dc072ab1752283c57047a1e7c2c3bac366964 Mon Sep 17 00:00:00 2001 From: Stefan Hanke Date: Tue, 6 Mar 2018 18:58:11 +0100 Subject: [PATCH 1/3] set seed before calling setup() --- src/core/reducer.js | 8 +++++++- src/core/reducer.test.js | 12 ++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/core/reducer.js b/src/core/reducer.js index ffbc726f9..6d4a2ed51 100644 --- a/src/core/reducer.js +++ b/src/core/reducer.js @@ -22,6 +22,12 @@ export function createGameReducer({ game, numPlayers, multiplayer }) { numPlayers = 2; } + // need to init PRNGState here, otherwise calls to + // Random inside setup() are using undefined + if (game !== undefined) { + PRNGState.set(game.seed); + } + const initial = { // User managed state. G: game.setup(numPlayers), @@ -50,7 +56,7 @@ export function createGameReducer({ game, numPlayers, multiplayer }) { }; // Initialize PRNG seed. - initial.ctx._random = { seed: game.seed }; + initial.ctx._random = { seed: PRNGState.get() }; const state = game.flow.init({ G: initial.G, ctx: initial.ctx }); diff --git a/src/core/reducer.test.js b/src/core/reducer.test.js index 7d99c19fb..0e3b61216 100644 --- a/src/core/reducer.test.js +++ b/src/core/reducer.test.js @@ -9,6 +9,7 @@ import Game from './game'; import { createGameReducer } from './reducer'; import { makeMove, gameEvent, restore } from './action-creators'; +import { Random } from './random'; const game = Game({ moves: { @@ -151,3 +152,14 @@ test('log', () => { state = reducer(state, actionC); expect(state.log).toEqual([actionA, actionB, actionC.payload]); }); + +test('using Random inside setup()', () => { + const game = Game({ + setup: () => Random.Shuffle([...Array(5).keys()]), + }); + const reducer = createGameReducer({ game }); + + const state = reducer(undefined, makeMove('moveA')); + console.log(JSON.stringify(state, null, 3)); + expect(state.G).toMatchObject([2, 3, 0, 1, 4]); +}); From f536c1d245e64cddb15a44825a483c95f6db7f58 Mon Sep 17 00:00:00 2001 From: Stefan Hanke Date: Tue, 6 Mar 2018 19:05:42 +0100 Subject: [PATCH 2/3] drop console.log; drop unnecessary condition --- src/core/reducer.js | 4 +--- src/core/reducer.test.js | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/reducer.js b/src/core/reducer.js index 6d4a2ed51..c419dab53 100644 --- a/src/core/reducer.js +++ b/src/core/reducer.js @@ -24,9 +24,7 @@ export function createGameReducer({ game, numPlayers, multiplayer }) { // need to init PRNGState here, otherwise calls to // Random inside setup() are using undefined - if (game !== undefined) { - PRNGState.set(game.seed); - } + PRNGState.set(game.seed); const initial = { // User managed state. diff --git a/src/core/reducer.test.js b/src/core/reducer.test.js index 0e3b61216..7644ea4b1 100644 --- a/src/core/reducer.test.js +++ b/src/core/reducer.test.js @@ -157,9 +157,9 @@ test('using Random inside setup()', () => { const game = Game({ setup: () => Random.Shuffle([...Array(5).keys()]), }); + const reducer = createGameReducer({ game }); const state = reducer(undefined, makeMove('moveA')); - console.log(JSON.stringify(state, null, 3)); expect(state.G).toMatchObject([2, 3, 0, 1, 4]); }); From b44af728685e523ad1038f0da9c26e7cc57a72bc Mon Sep 17 00:00:00 2001 From: Nicolo Davis Date: Fri, 9 Mar 2018 15:38:34 +0800 Subject: [PATCH 3/3] fix PRNGState initialization --- src/core/reducer.js | 8 ++++---- src/core/reducer.test.js | 28 +++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/core/reducer.js b/src/core/reducer.js index c419dab53..54b35e00b 100644 --- a/src/core/reducer.js +++ b/src/core/reducer.js @@ -22,9 +22,9 @@ export function createGameReducer({ game, numPlayers, multiplayer }) { numPlayers = 2; } - // need to init PRNGState here, otherwise calls to - // Random inside setup() are using undefined - PRNGState.set(game.seed); + // Need to init PRNGState here, otherwise calls to + // Random inside setup() are using undefined. + PRNGState.set({ seed: game.seed }); const initial = { // User managed state. @@ -54,7 +54,7 @@ export function createGameReducer({ game, numPlayers, multiplayer }) { }; // Initialize PRNG seed. - initial.ctx._random = { seed: PRNGState.get() }; + initial.ctx._random = PRNGState.get(); const state = game.flow.init({ G: initial.G, ctx: initial.ctx }); diff --git a/src/core/reducer.test.js b/src/core/reducer.test.js index 7644ea4b1..99dedad99 100644 --- a/src/core/reducer.test.js +++ b/src/core/reducer.test.js @@ -154,12 +154,30 @@ test('log', () => { }); test('using Random inside setup()', () => { - const game = Game({ - setup: () => Random.Shuffle([...Array(5).keys()]), + const game1 = Game({ + seed: 'seed1', + setup: () => ({ n: Random.D6() }), }); - const reducer = createGameReducer({ game }); + const game2 = Game({ + seed: 'seed2', + setup: () => ({ n: Random.D6() }), + }); + + const game3 = Game({ + seed: 'seed2', + setup: () => ({ n: Random.D6() }), + }); + + const reducer1 = createGameReducer({ game: game1 }); + const state1 = reducer1(undefined, makeMove()); + + const reducer2 = createGameReducer({ game: game2 }); + const state2 = reducer2(undefined, makeMove()); + + const reducer3 = createGameReducer({ game: game3 }); + const state3 = reducer3(undefined, makeMove()); - const state = reducer(undefined, makeMove('moveA')); - expect(state.G).toMatchObject([2, 3, 0, 1, 4]); + expect(state1.G.n).not.toBe(state2.G.n); + expect(state2.G.n).toBe(state3.G.n); });