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