WIP Add Grid
This commit is contained in:
parent
1fb5235f2b
commit
5dc11de37d
6 changed files with 122 additions and 10 deletions
|
@ -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> {
|
||||||
|
|
12
src/game.rs
12
src/game.rs
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,5 +65,7 @@ impl Game {
|
||||||
pub fn get_tray_mut(&mut self) -> &mut Tray {
|
pub fn get_tray_mut(&mut self) -> &mut Tray {
|
||||||
&mut self.player.tray
|
&mut self.player.tray
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_board(&self) -> &Board {&self.board}
|
||||||
|
|
||||||
}
|
}
|
11
src/wasm.rs
11
src/wasm.rs
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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}
|
||||||
|
@ -151,4 +174,37 @@ export function TileTray(props: { letters: Array<PlayableLetterData>, trayLength
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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>
|
||||||
}
|
}
|
|
@ -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} />);
|
||||||
|
|
||||||
|
|
|
@ -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%;
|
||||||
|
|
Loading…
Reference in a new issue