Start using reducer to track tile locations

This commit is contained in:
Joel Therrien 2023-08-07 22:12:29 -07:00
parent 69eb2060fc
commit 44e3b97f14
2 changed files with 75 additions and 15 deletions

View file

@ -1,5 +1,7 @@
import * as React from "react"; import * as React from "react";
import {Letter as LetterData} from "word_grid"; import {GameWasm, Letter as LetterData, Tray} from "word_grid";
import {createRoot} from "react-dom/client";
import {useReducer, useState} from "react";
export enum LocationType { export enum LocationType {
GRID, GRID,
@ -13,6 +15,75 @@ export interface CoordinateData {
export type PlayableLetterData = LetterData & CoordinateData; export type PlayableLetterData = LetterData & CoordinateData;
function matchCoordinate(playerLetters: PlayableLetterData[], coords: CoordinateData): number {
for (let i=0; i<playerLetters.length; i++){
let letter = playerLetters[i];
if (letter.location === coords.location && letter.index === coords.index) {
return i;
}
}
return null; // no match
}
function movePlayableLetters(playerLetters: PlayableLetterData[], update: {start: CoordinateData, end: CoordinateData}) {
let startIndex = matchCoordinate(playerLetters, update.start);
let endIndex = matchCoordinate(playerLetters, update.end);
if(startIndex != null) {
let startLetter = playerLetters[startIndex];
startLetter.location = update.end.location;
startLetter.index = update.end.index;
}
if(endIndex != null) {
let endLetter = playerLetters[endIndex];
endLetter.location = update.start.location;
endLetter.index = update.start.index;
}
return playerLetters.slice();
}
export function Game(props: {wasm: GameWasm}) {
const [playerLetters, dispatch] = useReducer(movePlayableLetters, null, (_) => {
let tray: Tray = props.wasm.get_tray();
// initial state
let letters: PlayableLetterData[] = tray.letters.map((ld, i) => {
ld["location"] = LocationType.TRAY;
ld["index"] = i;
return ld as PlayableLetterData;
})
return letters;
})
return <>
<TileTray letters={playerLetters} trayLength={7}/>
<button onClick={(e) => {
dispatch({
"start": {
"location": LocationType.TRAY,
"index": 0
},
"end": {
"location": LocationType.TRAY,
"index": 3
},
})
}}>Swap two</button>
</>;
}
export function Letter(props: { data: LetterData }): React.JSX.Element { export function Letter(props: { data: LetterData }): React.JSX.Element {
return <div className="letter"> return <div className="letter">
<div className="text">{props.data.text}</div> <div className="text">{props.data.text}</div>

View file

@ -1,7 +1,8 @@
import init, {greet, GameWasm} from '../node_modules/word_grid/word_grid.js'; import init, {greet, GameWasm} from '../node_modules/word_grid/word_grid.js';
import {LocationType, PlayableLetterData, TileTray} from "./elements"; import {Game, LocationType, PlayableLetterData, TileTray} from "./elements";
import {createRoot} from "react-dom/client"; import {createRoot} from "react-dom/client";
import {Tray} from "word_grid"; import {Tray} from "word_grid";
import * as React from "react";
async function run() { async function run() {
// First up we need to actually load the wasm file, so we use the // First up we need to actually load the wasm file, so we use the
@ -32,22 +33,10 @@ async function run() {
// modes // modes
await init(); await init();
greet("Heyo!");
let game = new GameWasm(BigInt(1234)); let game = new GameWasm(BigInt(1234));
let tray: Tray = game.get_tray();
// initial state
let letters: PlayableLetterData[] = tray.letters.map((ld, i) => {
ld["location"] = LocationType.TRAY;
ld["index"] = i;
return ld as PlayableLetterData;
})
console.log({tray});
const root = createRoot(document.getElementById("root")); const root = createRoot(document.getElementById("root"));
root.render(<TileTray letters={letters} trayLength={7}/>); root.render(<Game wasm={game} />);
} }