From d13819210680870d3a75fc8d040a2d9f3a039207 Mon Sep 17 00:00:00 2001 From: "Brady J. Garvin" <bgarvin@cse.unl.edu> Date: Tue, 22 Nov 2022 07:32:27 -0600 Subject: [PATCH] Added starter code for the homework on trees. --- boost-app/src/features/play/gameTreesSlice.js | 39 ++-- .../src/features/play/gameTreesSlice.test.js | 168 +++++++++++------- boost-app/src/features/play/scoreSheet.js | 10 ++ 3 files changed, 135 insertions(+), 82 deletions(-) diff --git a/boost-app/src/features/play/gameTreesSlice.js b/boost-app/src/features/play/gameTreesSlice.js index cccd4da..1fe05e2 100644 --- a/boost-app/src/features/play/gameTreesSlice.js +++ b/boost-app/src/features/play/gameTreesSlice.js @@ -883,27 +883,30 @@ export const selectRerootSafeties = createObjectSelector( export const selectMoveTrees = createObjectSelector( [selectTrees], (tree) => { - function createSubtree(positionEncoding) { - const children = new Map(); - for (const move of Object.getOwnPropertyNames(positionEncoding.children)) { - const child = tree.positions[positionEncoding.children[move]]; - if (child !== undefined) { - children.set(move, createSubtree(child)); - } - } - return { + function createSubtree(positionEncoding, parent = undefined, priorAdvantage = undefined) { + const result = { identity: positionEncoding.identity, ply: positionEncoding.ply, - moves: [ - ...[positionEncoding.mainLineMove].filter( - (move) => move !== undefined, - ), - ...[...children.keys()].filter( - (move) => move !== positionEncoding.mainLineMove, - ).sort(), - ], - children, + advantage: positionEncoding.advantage !== undefined && priorAdvantage !== undefined ? + (positionEncoding.advantage + priorAdvantage) / 2 : + positionEncoding.advantage, + moves: [positionEncoding.mainLineMove].filter( + (move) => move !== undefined, + ), + suggestions: positionEncoding.suggestions, + parent, + children: new Map(), }; + for (const move of Object.getOwnPropertyNames(positionEncoding.children)) { + const childEncoding = tree.positions[positionEncoding.children[move]]; + if (childEncoding !== undefined) { + result.children.set(move, createSubtree(childEncoding, result, positionEncoding.advantage)); + } + } + result.moves.push(...[...result.children.keys()].filter( + (move) => move !== positionEncoding.mainLineMove, + ).sort()); + return result; } return createSubtree(tree.positions[tree.rootIdentity]); }, diff --git a/boost-app/src/features/play/gameTreesSlice.test.js b/boost-app/src/features/play/gameTreesSlice.test.js index 5ca26fd..4aaffe8 100644 --- a/boost-app/src/features/play/gameTreesSlice.test.js +++ b/boost-app/src/features/play/gameTreesSlice.test.js @@ -571,39 +571,59 @@ describe('in the game tree slice', () => { }, }; const result = selectMoveTrees({ [gameTreesSlice.name]: state }); + const oracle = { + identity: 0, + ply: 0, + advantage: 99, + moves: ['a', 'd'], + suggestions: ['y0y0', 'z0z0'], + parent: undefined, + children: new Map([ + ['a', { + identity: 1, + ply: 1, + advantage: 99, + moves: ['b', 'c'], + suggestions: ['y0y0', 'z0z0'], + parent: undefined, + children: new Map([ + ['b', { + identity: 2, + ply: 2, + advantage: 99, + moves: [], + suggestions: ['y0y0', 'z0z0'], + parent: undefined, + children: new Map(), + }], + ['c', { + identity: 3, + ply: 2, + advantage: 99, + moves: [], + suggestions: ['y0y0', 'z0z0'], + parent: undefined, + children: new Map(), + }], + ]), + }], + ['d', { + identity: 4, + ply: 1, + advantage: 99, + moves: [], + suggestions: ['y0y0', 'z0z0'], + parent: undefined, + children: new Map(), + }], + ]), + }; + oracle.children.get('a').parent = oracle; + oracle.children.get('a').children.get('b').parent = oracle.children.get('a'); + oracle.children.get('a').children.get('c').parent = oracle.children.get('a'); + oracle.children.get('d').parent = oracle; expect(result).toEqual({ - 'def': { - identity: 0, - ply: 0, - moves: ['a', 'd'], - children: new Map([ - ['a', { - identity: 1, - ply: 1, - moves: ['b', 'c'], - children: new Map([ - ['b', { - identity: 2, - ply: 2, - moves: [], - children: new Map(), - }], - ['c', { - identity: 3, - ply: 2, - moves: [], - children: new Map(), - }], - ]), - }], - ['d', { - identity: 4, - ply: 1, - moves: [], - children: new Map(), - }], - ]), - }, + 'def': oracle, }); }); test('lists main-line moves first', () => { @@ -638,39 +658,59 @@ describe('in the game tree slice', () => { }, }; const result = selectMoveTrees({ [gameTreesSlice.name]: state }); + const oracle = { + identity: 0, + ply: 0, + advantage: 99, + moves: ['d', 'a'], + suggestions: ['y0y0', 'z0z0'], + parent: undefined, + children: new Map([ + ['a', { + identity: 1, + ply: 1, + advantage: 99, + moves: ['c', 'b'], + suggestions: ['y0y0', 'z0z0'], + parent: undefined, + children: new Map([ + ['b', { + identity: 2, + ply: 2, + advantage: 99, + moves: [], + suggestions: ['y0y0', 'z0z0'], + parent: undefined, + children: new Map(), + }], + ['c', { + identity: 3, + ply: 2, + advantage: 99, + moves: [], + suggestions: ['y0y0', 'z0z0'], + parent: undefined, + children: new Map(), + }], + ]), + }], + ['d', { + identity: 4, + ply: 1, + advantage: 99, + moves: [], + suggestions: ['y0y0', 'z0z0'], + parent: undefined, + children: new Map(), + }], + ]), + }; + oracle.children.get('a').parent = oracle; + oracle.children.get('a').children.get('b').parent = oracle.children.get('a'); + oracle.children.get('a').children.get('c').parent = oracle.children.get('a'); + oracle.children.get('d').parent = oracle; expect(result).toEqual({ - 'def': { - identity: 0, - ply: 0, - moves: ['d', 'a'], - children: new Map([ - ['a', { - identity: 1, - ply: 1, - moves: ['c', 'b'], - children: new Map([ - ['b', { - identity: 2, - ply: 2, - moves: [], - children: new Map(), - }], - ['c', { - identity: 3, - ply: 2, - moves: [], - children: new Map(), - }], - ]), - }], - ['d', { - identity: 4, - ply: 1, - moves: [], - children: new Map(), - }], - ]), - }, + 'def': oracle, }); }); test('imitates a pure function despite returning an object literal and using `new`', () => { diff --git a/boost-app/src/features/play/scoreSheet.js b/boost-app/src/features/play/scoreSheet.js index 67ff9a6..6fe316c 100644 --- a/boost-app/src/features/play/scoreSheet.js +++ b/boost-app/src/features/play/scoreSheet.js @@ -21,6 +21,16 @@ import { setPosition, } from './gameTreesSlice.js'; +// eslint-disable-next-line no-unused-vars -- remove once this function is implemented and used +function getProgress(vertex) { + return undefined; +} + +// eslint-disable-next-line no-unused-vars -- remove once this function is implemented and used +function getAnnotation(vertex) { + return undefined; +} + function Move(props) { const button = useRef(); useEffect(() => { -- GitLab