From 8c2714b0dda16cf4377badfdaf348f0b2ffc8765 Mon Sep 17 00:00:00 2001 From: Joel Therrien Date: Sun, 22 Dec 2024 16:27:13 -0800 Subject: [PATCH] WIP Add api game events --- server/src/main.rs | 100 ++++++++++++++++++++++++++++++++++--------- wasm/src/lib.rs | 4 +- wordgrid/src/api.rs | 4 +- wordgrid/src/game.rs | 2 +- 4 files changed, 83 insertions(+), 27 deletions(-) diff --git a/server/src/main.rs b/server/src/main.rs index 17c9b5d..4f103c4 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -15,7 +15,7 @@ use tokio::select; use uuid::Uuid; use word_grid::api::{APIGame, ApiState}; use word_grid::dictionary::{Dictionary, DictionaryImpl}; -use word_grid::game::Game; +use word_grid::game::{Error, Game, PlayedTile}; use word_grid::player_interaction::ai::Difficulty; use ws::stream::DuplexStream; use ws::Message; @@ -73,17 +73,29 @@ enum RoomEvent { #[serde(tag = "type")] enum ServerToClientMessage { RoomChange { event: RoomEvent, info: PartyInfo }, - GameEvent { state: ApiState }, + GameEvent { state: ApiState, committed: bool }, + GameError { error: Error }, Invalid { reason: String }, } +#[derive(Deserialize, Debug)] +enum GameMove { + Pass, + Exchange { + tiles: Vec, + }, + Play { + played_tiles: Vec>, + commit_move: bool, + }, +} + #[derive(Deserialize, Debug)] #[serde(tag = "type")] enum ClientToServerMessage { - RoomChange, Load, StartGame, - GameMove, + GameMove { r#move: GameMove }, AddAI { difficulty: Difficulty }, RemoveAI { index: usize }, } @@ -146,8 +158,9 @@ async fn incoming_message_handler( // TODO println!("Received {message:#?} from client {}", player.id); match message { - ClientToServerMessage::RoomChange => {} - ClientToServerMessage::Load => {} + ClientToServerMessage::Load => { + return !game_load(player, room, stream).await + } ClientToServerMessage::StartGame => { let mut room = room.write().await; if room.game.is_some() { @@ -176,7 +189,47 @@ async fn incoming_message_handler( sender.send(InnerRoomMessage::GameEvent).unwrap(); } } - ClientToServerMessage::GameMove => {} + ClientToServerMessage::GameMove { r#move } => { + let mut room = room.write().await; + if room.game.is_none() { + let event = ServerToClientMessage::Invalid { + reason: format!("Game hasn't been started yet"), + }; + let event = serde_json::to_string(&event).unwrap(); + let _ = stream.send(event.into()).await; + } else { + let game = room.game.as_mut().unwrap(); + let result = match r#move { + GameMove::Pass => game.pass(&player.name), + GameMove::Exchange { tiles } => { + game.exchange(&player.name, tiles) + } + GameMove::Play { + played_tiles, + commit_move, + } => { + let result = game.play(&player.name, played_tiles, commit_move); + if result.is_ok() & !commit_move { + let event = ServerToClientMessage::GameEvent {state: result.unwrap(), committed: false}; + let event = serde_json::to_string(&event).unwrap(); + let _ = stream.send(event.into()).await; + return false; + } + result + }, + }; + match result { + Ok(_) => { + sender.send(InnerRoomMessage::GameEvent).unwrap(); + } + Err(error) => { + let event = ServerToClientMessage::GameError { error }; + let event = serde_json::to_string(&event).unwrap(); + let _ = stream.send(event.into()).await; + } + } + } + } ClientToServerMessage::AddAI { difficulty } => { let mut room = room.write().await; room.party_info.ais.push(difficulty.clone()); @@ -216,6 +269,19 @@ async fn incoming_message_handler( false } +async fn game_load(player: &Player, room: &Arc>, stream: &mut DuplexStream) -> bool { + // The game object was modified; we need to trigger a load from this player's perspective + let mut room = room.write().await; + + let state = room.game.as_mut().unwrap().load(&player.name).unwrap(); + let event = ServerToClientMessage::GameEvent { state, committed: true }; + + let text = serde_json::to_string(&event).unwrap(); + let x = stream.send(text.into()).await; + + x.is_ok() +} + async fn outgoing_message_handler( message: Result, _sender: &Sender, @@ -225,22 +291,14 @@ async fn outgoing_message_handler( ) -> bool { let message = message.unwrap(); println!("Inner room message - {:#?}", message); - let message = match message { - InnerRoomMessage::PassThrough(event) => serde_json::to_string(&event).unwrap(), - InnerRoomMessage::GameEvent => { - // The game object was modified; we need to trigger a load from this player's perspective - let mut room = room.write().await; - - let state = room.game.as_mut().unwrap().load(&player.name).unwrap(); - let event = ServerToClientMessage::GameEvent { state }; - - serde_json::to_string(&event).unwrap() + return match message { + InnerRoomMessage::PassThrough(event) => { + let text = serde_json::to_string(&event).unwrap(); + let x = stream.send(text.into()).await; + x.is_err() } + InnerRoomMessage::GameEvent => !game_load(player, room, stream).await, }; - - let _ = stream.send(message.into()).await; - - false } #[get("/room/?")] diff --git a/wasm/src/lib.rs b/wasm/src/lib.rs index 0faa7dd..f647451 100644 --- a/wasm/src/lib.rs +++ b/wasm/src/lib.rs @@ -46,9 +46,7 @@ impl WasmAPI { let tray_tile_locations: Vec> = serde_wasm_bindgen::from_value(tray_tile_locations).unwrap(); - let result = self - .0 - .play("Player".to_string(), tray_tile_locations, commit_move); + let result = self.0.play("Player", tray_tile_locations, commit_move); serde_wasm_bindgen::to_value(&result).unwrap() } diff --git a/wordgrid/src/api.rs b/wordgrid/src/api.rs index efb62dd..6e6f324 100644 --- a/wordgrid/src/api.rs +++ b/wordgrid/src/api.rs @@ -180,7 +180,7 @@ impl APIGame { pub fn play( &mut self, - player: String, + player: &str, tray_tile_locations: Vec>, commit_move: bool, ) -> Result { @@ -190,7 +190,7 @@ impl APIGame { let tray = self.0.player_states.get_tray(&player).unwrap().clone(); let update = Update { r#type: turn_action, - player, + player: player.to_string(), }; if commit_move { self.1.push(update.clone()) diff --git a/wordgrid/src/game.rs b/wordgrid/src/game.rs index 2da2277..d926b0b 100644 --- a/wordgrid/src/game.rs +++ b/wordgrid/src/game.rs @@ -20,7 +20,7 @@ pub enum Player { }, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum Error { InvalidPlayer(String), WrongTurn(String),