Refactored receive_play from wasm into Game

This commit is contained in:
Joel Therrien 2023-08-18 18:14:27 -07:00
parent cd8a4b73a9
commit cb10d97724
2 changed files with 86 additions and 87 deletions

View file

@ -1,7 +1,9 @@
use rand::prelude::SliceRandom; use rand::prelude::SliceRandom;
use rand::rngs::SmallRng; use rand::rngs::SmallRng;
use rand::SeedableRng; use rand::SeedableRng;
use crate::board::{Board, Letter}; use serde::{Deserialize, Serialize};
use tsify::Tsify;
use crate::board::{Board, Coordinates, Letter};
use crate::constants::{standard_tile_pool, TRAY_LENGTH}; use crate::constants::{standard_tile_pool, TRAY_LENGTH};
use crate::dictionary::{Dictionary, DictionaryImpl}; use crate::dictionary::{Dictionary, DictionaryImpl};
use crate::player_interaction::ai::Difficulty; use crate::player_interaction::ai::Difficulty;
@ -31,6 +33,20 @@ pub struct PlayerState {
pub tray: Tray pub tray: Tray
} }
#[derive(Deserialize, Tsify, Copy, Clone)]
#[tsify(from_wasm_abi)]
pub struct PlayedTile {
index: usize,
character: Option<char>,
}
#[derive(Debug, Serialize, Deserialize, Tsify)]
#[tsify(from_wasm_abi)]
pub struct WordResult {
word: String,
score: u32,
}
pub struct Game{ pub struct Game{
pub tile_pool: Vec<Letter>, pub tile_pool: Vec<Letter>,
board: Board, board: Board,
@ -120,5 +136,61 @@ impl Game {
&self.dictionary &self.dictionary
} }
pub fn receive_play(&mut self, player: &str, tray_tile_locations: Vec<Option<PlayedTile>>, commit_move: bool) -> Result<Vec<WordResult>, String> {
let mut board_instance = self.get_board().clone();
let mut tray = self.get_tray(player).unwrap().clone();
let mut played_letters: Vec<(Letter, Coordinates)> = Vec::new();
for (i, played_tile) in tray_tile_locations.iter().enumerate() {
if played_tile.is_some() {
let played_tile = played_tile.unwrap();
let mut letter: Letter = tray.letters.get(i).unwrap().unwrap();
*tray.letters.get_mut(i).unwrap() = None;
let coord = Coordinates::new_from_index(played_tile.index);
if letter.is_blank {
match played_tile.character {
None => {
panic!("You can't play a blank character without providing a letter value")
}
Some(x) => {
// TODO - I should check that the character is a valid letter
letter.text = x;
}
}
}
played_letters.push((letter, coord));
}
}
board_instance.receive_play(played_letters)?;
let x = board_instance.calculate_scores(self.get_dictionary())?;
let words: Vec<WordResult> = x.0.iter()
.map(|(word, score)| {
WordResult {
word: word.to_string(),
score: *score
}
})
.collect();
if commit_move {
let mut player_state = self.get_player_state_mut(player).unwrap();
player_state.score += x.1;
player_state.tray = tray;
board_instance.fix_tiles();
self.set_board(board_instance);
self.fill_trays()
}
Ok(words)
}
} }

View file

@ -3,8 +3,8 @@ use serde_wasm_bindgen::Error;
use tsify::Tsify; use tsify::Tsify;
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
use wasm_bindgen::prelude::wasm_bindgen; use wasm_bindgen::prelude::wasm_bindgen;
use crate::board::{Board, CellType, Coordinates, Letter}; use crate::board::{CellType, Letter};
use crate::game::Game; use crate::game::{Game, PlayedTile};
#[wasm_bindgen] #[wasm_bindgen]
pub struct GameWasm(Game); pub struct GameWasm(Game);
@ -18,17 +18,12 @@ pub enum ResponseType {
#[derive(Serialize, Deserialize, Tsify)] #[derive(Serialize, Deserialize, Tsify)]
#[tsify(from_wasm_abi)] #[tsify(from_wasm_abi)]
pub struct MyResult<E> { pub struct MyResult<E: Serialize> {
response_type: ResponseType, response_type: ResponseType,
value: E, value: E,
} }
#[derive(Deserialize, Tsify, Copy, Clone)]
#[tsify(from_wasm_abi)]
pub struct PlayedTile {
index: usize,
character: Option<char>,
}
#[wasm_bindgen] #[wasm_bindgen]
impl GameWasm { impl GameWasm {
@ -64,94 +59,26 @@ impl GameWasm {
serde_wasm_bindgen::to_value(&letters) serde_wasm_bindgen::to_value(&letters)
} }
pub fn receive_play(&mut self, player: &str, tray_tile_locations: JsValue, commit_move: bool) -> Result<JsValue, JsValue> { pub fn receive_play(&mut self, player: &str, tray_tile_locations: JsValue, commit_move: bool) -> Result<JsValue, Error> {
let tray_tile_locations: Vec<Option<PlayedTile>> = serde_wasm_bindgen::from_value(tray_tile_locations)?; let tray_tile_locations: Vec<Option<PlayedTile>> = serde_wasm_bindgen::from_value(tray_tile_locations)?;
let mut board_instance = self.0.get_board().clone(); let result = self.0.receive_play(player, tray_tile_locations, commit_move);
let mut tray = self.0.get_tray(player).unwrap().clone();
let mut played_letters: Vec<(Letter, Coordinates)> = Vec::new(); match result {
for (i, played_tile) in tray_tile_locations.iter().enumerate() {
if played_tile.is_some() {
let played_tile = played_tile.unwrap();
let mut letter: Letter = tray.letters.get(i).unwrap().unwrap();
*tray.letters.get_mut(i).unwrap() = None;
let coord = Coordinates::new_from_index(played_tile.index);
if letter.is_blank {
match played_tile.character {
None => {
panic!("You can't play a blank character without providing a letter value")
}
Some(x) => {
// TODO - I should check that the character is a valid letter
letter.text = x;
}
}
}
played_letters.push((letter, coord));
}
}
match board_instance.receive_play(played_letters) {
Err(e) => {
return Ok(serde_wasm_bindgen::to_value(
&MyResult {
response_type: ResponseType::ERR,
value: e
}).unwrap());
},
Ok(_) => {}
}
#[derive(Debug, Serialize, Deserialize, Tsify)]
#[tsify(from_wasm_abi)]
struct WordResult {
word: String,
score: u32,
}
let result = board_instance.calculate_scores(self.0.get_dictionary());
let result = match result {
Ok(x) => { Ok(x) => {
let words: Vec<WordResult> = x.0.iter() serde_wasm_bindgen::to_value(&MyResult {
.map(|(word, score)| {
WordResult {
word: word.to_string(),
score: *score
}
})
.collect();
if commit_move {
let mut player_state = self.0.get_player_state_mut(player).unwrap();
player_state.score += x.1;
player_state.tray = tray;
board_instance.fix_tiles();
self.0.set_board(board_instance);
self.0.fill_trays()
}
serde_wasm_bindgen::to_value(
&MyResult {
response_type: ResponseType::OK, response_type: ResponseType::OK,
value: words value: x
}).unwrap() })
}, },
Err(e) => { Err(e) => {
serde_wasm_bindgen::to_value( serde_wasm_bindgen::to_value(&MyResult {
&MyResult {
response_type: ResponseType::ERR, response_type: ResponseType::ERR,
value: e value: e
}).unwrap() })
} }
}; }
Ok(result)
} }