Improve tray handling
Fix bugs when the tray is not fully filled, and retain custom user tray ordering between turns.
This commit is contained in:
parent
b33007d3c4
commit
4c8d27b659
2 changed files with 51 additions and 9 deletions
|
@ -2,6 +2,10 @@ import * as React from "react";
|
||||||
import {GameWasm, Letter as LetterData, MyResult, PlayedTile, PlayerAndScore, Tray, WordResult} from "word_grid";
|
import {GameWasm, Letter as LetterData, MyResult, PlayedTile, PlayerAndScore, Tray, WordResult} from "word_grid";
|
||||||
import {ChangeEvent, JSX, useEffect, useMemo, useReducer, useState} from "react";
|
import {ChangeEvent, JSX, useEffect, useMemo, useReducer, useState} from "react";
|
||||||
|
|
||||||
|
export interface Settings {
|
||||||
|
trayLength: number;
|
||||||
|
}
|
||||||
|
|
||||||
export enum LocationType {
|
export enum LocationType {
|
||||||
GRID,
|
GRID,
|
||||||
TRAY
|
TRAY
|
||||||
|
@ -63,7 +67,7 @@ function matchCoordinate(playerLetters: PlayableLetterData[], coords: Coordinate
|
||||||
for (let i=0; i<playerLetters.length; i++){
|
for (let i=0; i<playerLetters.length; i++){
|
||||||
let letter = playerLetters[i];
|
let letter = playerLetters[i];
|
||||||
|
|
||||||
if (letter.location === coords.location && letter.index === coords.index) {
|
if (letter !== undefined && letter.location === coords.location && letter.index === coords.index) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +90,7 @@ function addLogInfo(existingLog: React.JSX.Element[], newItem: React.JSX.Element
|
||||||
return existingLog.slice();
|
return existingLog.slice();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Game(props: {wasm: GameWasm}) {
|
export function Game(props: {wasm: GameWasm, settings: Settings}) {
|
||||||
|
|
||||||
const cellTypes = useMemo(() => {
|
const cellTypes = useMemo(() => {
|
||||||
return props.wasm.get_board_cell_types();
|
return props.wasm.get_board_cell_types();
|
||||||
|
@ -99,12 +103,46 @@ export function Game(props: {wasm: GameWasm}) {
|
||||||
if(update.action === TileDispatchActionType.RETRIEVE) {
|
if(update.action === TileDispatchActionType.RETRIEVE) {
|
||||||
let tray: Tray = props.wasm.get_tray("Player");
|
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<number | null>();
|
||||||
|
for (let i = 0; i<props.settings.trayLength; i++) {
|
||||||
|
freeSpots.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
playerLetters.filter((x) => {
|
||||||
|
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
|
// initial state
|
||||||
let letters: PlayableLetterData[] = tray.letters.map((ld, i) => {
|
let letters: PlayableLetterData[] = tray.letters.map((ld, i) => {
|
||||||
|
if(ld !== undefined) {
|
||||||
ld["location"] = LocationType.TRAY;
|
ld["location"] = LocationType.TRAY;
|
||||||
ld["index"] = i;
|
|
||||||
|
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 ld as PlayableLetterData;
|
||||||
})
|
});
|
||||||
|
|
||||||
return letters;
|
return letters;
|
||||||
} else if (update.action === TileDispatchActionType.MOVE) {
|
} else if (update.action === TileDispatchActionType.MOVE) {
|
||||||
|
|
||||||
|
@ -175,7 +213,7 @@ export function Game(props: {wasm: GameWasm}) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<TileTray letters={playerLetters} trayLength={7} dispatch={trayDispatch}/>
|
<TileTray letters={playerLetters} trayLength={props.settings.trayLength} dispatch={trayDispatch}/>
|
||||||
<button onClick={(e) => {
|
<button onClick={(e) => {
|
||||||
const playedTiles = playerLetters.map((i) => {
|
const playedTiles = playerLetters.map((i) => {
|
||||||
if (i === undefined) {
|
if (i === undefined) {
|
||||||
|
@ -322,7 +360,9 @@ export function TileTray(props: { letters: Array<PlayableLetterData>, trayLength
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
props.letters.forEach((letter, i) => {
|
props.letters
|
||||||
|
.filter((x) => {return x !== undefined;})
|
||||||
|
.forEach((letter, i) => {
|
||||||
if (letter.location === LocationType.TRAY) {
|
if (letter.location === LocationType.TRAY) {
|
||||||
elements[letter.index] =
|
elements[letter.index] =
|
||||||
<TileSlot
|
<TileSlot
|
||||||
|
@ -373,7 +413,9 @@ function Grid(props: {
|
||||||
</div>;
|
</div>;
|
||||||
});
|
});
|
||||||
|
|
||||||
props.playerLetters.forEach((letter, i) => {
|
props.playerLetters
|
||||||
|
.filter((letter) => {return letter !== undefined})
|
||||||
|
.forEach((letter, i) => {
|
||||||
if (letter.location === LocationType.GRID) {
|
if (letter.location === LocationType.GRID) {
|
||||||
const ct = props.cellTypes[letter.index];
|
const ct = props.cellTypes[letter.index];
|
||||||
const {className, text} = cell_type_to_details(ct);
|
const {className, text} = cell_type_to_details(ct);
|
||||||
|
|
|
@ -53,7 +53,7 @@ async function run() {
|
||||||
console.log({cellTypes});
|
console.log({cellTypes});
|
||||||
|
|
||||||
const root = createRoot(document.getElementById("root"));
|
const root = createRoot(document.getElementById("root"));
|
||||||
root.render(<Game wasm={game} />);
|
root.render(<Game wasm={game} settings={{trayLength: 7}} />);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue