WIP Add Grid

This commit is contained in:
Joel Therrien 2023-08-09 20:00:14 -07:00
parent 1fb5235f2b
commit 5dc11de37d
6 changed files with 122 additions and 10 deletions

View file

@ -91,7 +91,7 @@ impl Letter {
} }
} }
#[derive(Debug)] #[derive(Debug, Copy, Clone, Serialize)]
pub enum CellType { pub enum CellType {
Normal, Normal,
DoubleWord, DoubleWord,
@ -104,13 +104,13 @@ pub enum CellType {
#[derive(Debug)] #[derive(Debug)]
pub struct Cell { pub struct Cell {
pub value: Option<Letter>, pub value: Option<Letter>,
cell_type: CellType, pub cell_type: CellType,
coordinates: Coordinates, pub coordinates: Coordinates,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Board { pub struct Board {
cells: Vec<Cell>, pub cells: Vec<Cell>,
} }
pub struct Word<'a> { pub struct Word<'a> {

View file

@ -1,7 +1,7 @@
use rand::rngs::SmallRng; use rand::rngs::SmallRng;
use rand::SeedableRng; use rand::SeedableRng;
use wasm_bindgen::prelude::wasm_bindgen; use wasm_bindgen::prelude::wasm_bindgen;
use crate::board::Letter; use crate::board::{Board, Letter};
use crate::constants::{standard_tile_pool, TRAY_LENGTH}; use crate::constants::{standard_tile_pool, TRAY_LENGTH};
use crate::player_interaction::ai::Difficulty; use crate::player_interaction::ai::Difficulty;
use crate::player_interaction::Tray; use crate::player_interaction::Tray;
@ -21,7 +21,8 @@ pub struct PlayerState {
} }
pub struct Game { pub struct Game {
tiles: Vec<Letter>, tile_pool: Vec<Letter>,
board: Board,
player: PlayerState, player: PlayerState,
} }
@ -51,7 +52,8 @@ impl Game {
}; };
Game { Game {
tiles: letters, tile_pool: letters,
board: Board::new(),
player, player,
} }
} }
@ -64,4 +66,6 @@ impl Game {
&mut self.player.tray &mut self.player.tray
} }
pub fn get_board(&self) -> &Board {&self.board}
} }

View file

@ -1,6 +1,7 @@
use serde_wasm_bindgen::Error; use serde_wasm_bindgen::Error;
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
use wasm_bindgen::prelude::wasm_bindgen; use wasm_bindgen::prelude::wasm_bindgen;
use crate::board::CellType;
use crate::game::Game; use crate::game::Game;
#[wasm_bindgen] #[wasm_bindgen]
@ -19,4 +20,14 @@ impl GameWasm {
serde_wasm_bindgen::to_value(tray) serde_wasm_bindgen::to_value(tray)
} }
pub fn get_board_cell_types(&self) -> Result<JsValue, Error> {
let board = self.0.get_board();
let cell_types: Vec<CellType> = board.cells.iter().map(|cell| -> CellType {
cell.cell_type.clone()
}).collect();
serde_wasm_bindgen::to_value(&cell_types)
}
} }

View file

@ -1,13 +1,22 @@
import * as React from "react"; import * as React from "react";
import {GameWasm, Letter as LetterData, Tray} from "word_grid"; import {GameWasm, Letter as LetterData, Tray} from "word_grid";
import {createRoot} from "react-dom/client"; import {createRoot} from "react-dom/client";
import {Children, useReducer, useState} from "react"; import {Children, useMemo, useReducer, useState} from "react";
export enum LocationType { export enum LocationType {
GRID, GRID,
TRAY TRAY
} }
enum CellType {
Normal = "Normal",
DoubleWord = "DoubleWord",
DoubleLetter = "DoubleLetter",
TripleLetter = "TripleLetter",
TripleWord = "TripleWord",
Start = "Start",
}
export interface CoordinateData { export interface CoordinateData {
location: LocationType; location: LocationType;
index: number; index: number;
@ -53,6 +62,10 @@ function movePlayableLetters(playerLetters: PlayableLetterData[], update: {start
export function Game(props: {wasm: GameWasm}) { export function Game(props: {wasm: GameWasm}) {
const cellTypes = useMemo(() => {
return props.wasm.get_board_cell_types();
}, []);
const [playerLetters, dispatch] = useReducer(movePlayableLetters, null, (_) => { const [playerLetters, dispatch] = useReducer(movePlayableLetters, null, (_) => {
let tray: Tray = props.wasm.get_tray(); let tray: Tray = props.wasm.get_tray();
@ -67,7 +80,10 @@ export function Game(props: {wasm: GameWasm}) {
}) })
return <> return <>
<Grid cellTypes={cellTypes} />
<TileTray letters={playerLetters} trayLength={7} dispatch={dispatch}/> <TileTray letters={playerLetters} trayLength={7} dispatch={dispatch}/>
<button onClick={(e) => { <button onClick={(e) => {
dispatch({ dispatch({
@ -86,6 +102,8 @@ export function Game(props: {wasm: GameWasm}) {
} }
export function TileSlot(props: { tile: React.JSX.Element | undefined, location: CoordinateData, dispatch: TileDispatch }): React.JSX.Element { export function TileSlot(props: { tile: React.JSX.Element | undefined, location: CoordinateData, dispatch: TileDispatch }): React.JSX.Element {
let isDraggable = props.tile !== undefined; let isDraggable = props.tile !== undefined;
@ -101,7 +119,12 @@ export function TileSlot(props: { tile: React.JSX.Element | undefined, location:
props.dispatch({start: startLocation, end: thisLocation}); props.dispatch({start: startLocation, end: thisLocation});
} }
return <div className="tileSpot" let className = "tileSpot";
if (props.location.location === LocationType.GRID) {
className += " ephemeral";
}
return <div className={className}
draggable={isDraggable} draggable={isDraggable}
onDragStart={onDragStart} onDragStart={onDragStart}
onDrop={onDrop} onDrop={onDrop}
@ -152,3 +175,36 @@ export function TileTray(props: { letters: Array<PlayableLetterData>, trayLength
) )
} }
function Grid(props: {cellTypes: CellType[]}) {
const elements = props.cellTypes.map((ct, i) => {
let className: string;
switch (ct) {
case CellType.Normal:
className = "grid-spot-normal"
break;
case CellType.DoubleWord:
className = "grid-spot-double-word"
break;
case CellType.DoubleLetter:
className = "grid-spot-double-letter"
break;
case CellType.TripleLetter:
className = "grid-spot-triple-letter"
break;
case CellType.TripleWord:
className = "grid-spot-triple-word"
break;
case CellType.Start:
className = "grid-spot-start"
break;
}
return <div key={i} className={className}></div>;
});
return <div className="board-grid">
{elements}
</div>
}

View file

@ -35,6 +35,9 @@ async function run() {
let game = new GameWasm(BigInt(1234)); let game = new GameWasm(BigInt(1234));
const cellTypes = game.get_board_cell_types();
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} />);

View file

@ -1,5 +1,7 @@
@tile-width: 55px; @tile-width: 55px;
@tile-font-size: 35px; @tile-font-size: 35px;
@board-length: 15;
@tile-star-size: 45px;
.tray { .tray {
display: grid; display: grid;
@ -11,6 +13,42 @@
margin: 10px; margin: 10px;
} }
.board-grid {
//grid-area: grid;
display: grid;
grid-template-columns: repeat(@board-length, @tile-width);
grid-template-rows: repeat(@board-length, @tile-width);
justify-content: center;
grid-gap: 1px;
user-select: none;
}
.grid-spot-normal{
}
.grid-spot-double-word {
background-color: #f9b4a5;
}
.grid-spot-double-letter {
background-color: #c0d1d0;
}
.grid-spot-triple-letter {
background-color: #349eb9;
}
.grid-spot-triple-word {
background-color: #f65f4c;
}
.grid-spot-start {
background-color: #f9b4a5;
font-size: @tile-star-size;
}
.tileSpot { .tileSpot {
height: 100%; height: 100%;
width: 100%; width: 100%;