diff --git a/ui/src/elements.tsx b/ui/src/elements.tsx index 1f3b69b..049f929 100644 --- a/ui/src/elements.tsx +++ b/ui/src/elements.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import {GameWasm, Letter as LetterData, MyResult, PlayedTile, PlayerAndScore, Tray, WordResult} from "word_grid"; import {ChangeEvent, JSX, useEffect, useMemo, useReducer, useRef, useState} from "react"; import {Modal} from "./Modal"; -import {addNTimes} from "./utils"; +import {addNTimes, mergeTrays} from "./utils"; export interface Settings { trayLength: number; @@ -82,6 +82,7 @@ enum TileDispatchActionType { MOVE, RETRIEVE, SET_BLANK, + RETURN, } type TileDispatchAction = {action: TileDispatchActionType, start?: CoordinateData, end?: CoordinateData, newBlankValue?: string, blankIndex?: number}; type TileDispatch = React.Dispatch; @@ -103,49 +104,10 @@ export function Game(props: {wasm: GameWasm, settings: Settings}) { function movePlayableLetters(playerLetters: PlayableLetterData[], update: TileDispatchAction) { if(update.action === TileDispatchActionType.RETRIEVE) { + let tray: Tray = props.wasm.get_tray("Player"); - - // we may need to check against the existing tray to retain whatever user reorderings there are - const freeSpots = new Array(); - for (let i = 0; i { - return x !== undefined && x !== null; - }).forEach((x) => { - if (x.location === LocationType.TRAY) { - freeSpots[x.index] = null; - } - }); - - const firstNotNull = (): number => { - for (let i of freeSpots) { - if (i !== null) { - freeSpots[i] = null; - return i; - } - } - - return null; - } - - // initial state - let letters: PlayableLetterData[] = tray.letters.map((ld, i) => { - if(ld !== undefined) { - ld["location"] = LocationType.TRAY; - - if (playerLetters[i] !== undefined && playerLetters[i] !== null && playerLetters[i].location === LocationType.TRAY) { - ld["index"] = playerLetters[i].index; - } else { - ld["index"] = firstNotNull(); - } - } - return ld as PlayableLetterData; - }); - - return letters; + return mergeTrays(playerLetters, tray.letters); } else if (update.action === TileDispatchActionType.MOVE) { let startIndex = matchCoordinate(playerLetters, update.start); @@ -175,6 +137,8 @@ export function Game(props: {wasm: GameWasm, settings: Settings}) { } } return playerLetters.slice(); + } else if (update.action === TileDispatchActionType.RETURN) { + return mergeTrays(playerLetters, playerLetters); } else { console.error("Unknown tray update"); console.error({update}); @@ -182,6 +146,8 @@ export function Game(props: {wasm: GameWasm, settings: Settings}) { } + + const [playerLetters, trayDispatch] = useReducer(movePlayableLetters, []); const [logInfo, logDispatch] = useReducer(addLogInfo, []); @@ -302,6 +268,9 @@ export function Game(props: {wasm: GameWasm, settings: Settings}) { + ; diff --git a/ui/src/utils.ts b/ui/src/utils.ts index bc070f3..f33640c 100644 --- a/ui/src/utils.ts +++ b/ui/src/utils.ts @@ -1,6 +1,52 @@ +import {Letter} from "word_grid"; +import {LocationType, PlayableLetterData} from "./elements"; export function addNTimes(array: T[], toAdd: T, times: number) { for (let i=0; i(); + for (let i = 0; i { + return x !== undefined && x !== null; + }).forEach((x) => { + if (x.location === LocationType.TRAY) { + freeSpots[x.index] = null; + } + }); + + const firstNotNull = (): number => { + for (let i of freeSpots) { + if (i !== null) { + freeSpots[i] = null; + return i; + } + } + + return null; + } + + return newer.map((ld, i) => { + if (ld !== undefined) { + + if (existing[i] !== undefined && existing[i] !== null && existing[i].location === LocationType.TRAY) { + ld["index"] = existing[i].index; + } else { + ld["index"] = firstNotNull(); + } + ld["location"] = LocationType.TRAY; + } + return ld as PlayableLetterData; + }); + } \ No newline at end of file