Impl match players via phrase

Front-end now has option to input phrase on game start.
Fixed back-end accepting empty strings (will treat empty strings as if
no phrase was given).
This commit is contained in:
Stephen Seo 2022-04-27 12:47:45 +09:00
parent f9338d4093
commit 059d0608b6
4 changed files with 144 additions and 76 deletions

View file

@ -41,7 +41,9 @@ fn handle_pairing_request(root: Value, tx: SyncSender<DBHandlerRequest>) -> Resu
let mut phrase: Option<String> = None; let mut phrase: Option<String> = None;
if let Some(phrase_text) = root.get("phrase") { if let Some(phrase_text) = root.get("phrase") {
if let Some(phrase_str) = phrase_text.as_str() { if let Some(phrase_str) = phrase_text.as_str() {
phrase = Some(phrase_str.to_owned()); if !phrase_str.is_empty() {
phrase = Some(phrase_str.to_owned());
}
} }
} }
if tx if tx

View file

@ -42,9 +42,23 @@
grid-row: 2; grid-row: 2;
grid-column: 3; grid-column: 3;
} }
button.menuMultiplayer { div.multiplayerMenu {
grid-row: 2; grid-row: 2;
grid-column: 4; grid-column: 4;
display: grid;
}
button.networkedMultiplayer {
grid-row: 1;
grid-column: 1;
}
button.NMPhrase {
grid-row: 2;
grid-column: 1;
}
input.NMPhrase {
grid-row: 3;
grid-column: 1;
} }
b.menuText { b.menuText {
color: #FFF; color: #FFF;

View file

@ -12,12 +12,12 @@ use crate::game_logic::{check_win_draw, WinType};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::cell::Cell; use std::cell::{Cell, RefCell};
use std::collections::hash_set::HashSet; use std::collections::hash_set::HashSet;
use std::fmt::Display; use std::fmt::Display;
use std::rc::Rc; use std::rc::Rc;
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub enum GameState { pub enum GameState {
MainMenu, MainMenu,
SinglePlayer(Turn, AIDifficulty), SinglePlayer(Turn, AIDifficulty),
@ -26,18 +26,20 @@ pub enum GameState {
paired: bool, paired: bool,
current_side: Option<Turn>, current_side: Option<Turn>,
current_turn: Turn, current_turn: Turn,
phrase: Option<String>,
}, },
PostGameResults(BoardState), PostGameResults(BoardState),
} }
impl GameState { impl GameState {
pub fn is_networked_multiplayer(self) -> bool { pub fn is_networked_multiplayer(&self) -> bool {
matches!( matches!(
self, *self,
GameState::NetworkedMultiplayer { GameState::NetworkedMultiplayer {
paired: _, paired: _,
current_side: _, current_side: _,
current_turn: _ current_turn: _,
phrase: _,
} }
) )
} }
@ -47,6 +49,7 @@ impl GameState {
ref mut paired, ref mut paired,
current_side: _, current_side: _,
current_turn: _, current_turn: _,
phrase: _,
} = self } = self
{ {
*paired = true; *paired = true;
@ -58,6 +61,7 @@ impl GameState {
paired: _, paired: _,
current_side, current_side,
current_turn: _, current_turn: _,
phrase: _,
} = *self } = *self
{ {
current_side current_side
@ -71,6 +75,7 @@ impl GameState {
paired: _, paired: _,
ref mut current_side, ref mut current_side,
current_turn: _, current_turn: _,
phrase: _,
} = self } = self
{ {
*current_side = side; *current_side = side;
@ -84,6 +89,7 @@ impl GameState {
paired: _, paired: _,
current_side: _, current_side: _,
current_turn, current_turn,
phrase: _,
} = *self } = *self
{ {
current_turn current_turn
@ -97,6 +103,7 @@ impl GameState {
paired: _, paired: _,
current_side, current_side,
current_turn: _, current_turn: _,
phrase: _,
} = *self } = *self
{ {
current_side current_side
@ -110,11 +117,26 @@ impl GameState {
paired: _, paired: _,
current_side: _, current_side: _,
ref mut current_turn, ref mut current_turn,
phrase: _,
} = self } = self
{ {
*current_turn = turn; *current_turn = turn;
} }
} }
pub fn get_phrase(&self) -> Option<String> {
if let GameState::NetworkedMultiplayer {
paired: _,
current_side: _,
current_turn: _,
phrase,
} = self
{
phrase.clone()
} else {
None
}
}
} }
impl Default for GameState { impl Default for GameState {
@ -128,10 +150,11 @@ impl From<MainMenuMessage> for GameState {
match msg { match msg {
MainMenuMessage::SinglePlayer(t, ai) => GameState::SinglePlayer(t, ai), MainMenuMessage::SinglePlayer(t, ai) => GameState::SinglePlayer(t, ai),
MainMenuMessage::LocalMultiplayer => GameState::LocalMultiplayer, MainMenuMessage::LocalMultiplayer => GameState::LocalMultiplayer,
MainMenuMessage::NetworkedMultiplayer => GameState::NetworkedMultiplayer { MainMenuMessage::NetworkedMultiplayer(phrase) => GameState::NetworkedMultiplayer {
paired: false, paired: false,
current_side: None, current_side: None,
current_turn: Turn::CyanPlayer, current_turn: Turn::CyanPlayer,
phrase,
}, },
} }
} }
@ -380,7 +403,7 @@ pub fn new_placed() -> PlacedType {
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct SharedState { pub struct SharedState {
pub board: BoardType, pub board: BoardType,
pub game_state: Rc<Cell<GameState>>, pub game_state: Rc<RefCell<GameState>>,
pub turn: Rc<Cell<Turn>>, pub turn: Rc<Cell<Turn>>,
pub placed: PlacedType, pub placed: PlacedType,
} }
@ -390,7 +413,7 @@ impl Default for SharedState {
Self { Self {
// cannot use [<type>; 56] because Rc does not impl Copy // cannot use [<type>; 56] because Rc does not impl Copy
board: new_empty_board(), board: new_empty_board(),
game_state: Rc::new(Cell::new(GameState::default())), game_state: Rc::new(RefCell::new(GameState::default())),
turn: Rc::new(Cell::new(Turn::CyanPlayer)), turn: Rc::new(Cell::new(Turn::CyanPlayer)),
placed: new_placed(), placed: new_placed(),
} }
@ -399,11 +422,11 @@ impl Default for SharedState {
// This enum moved from yew_components module so that this module would have no // This enum moved from yew_components module so that this module would have no
// dependencies on the yew_components module // dependencies on the yew_components module
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub enum MainMenuMessage { pub enum MainMenuMessage {
SinglePlayer(Turn, AIDifficulty), SinglePlayer(Turn, AIDifficulty),
LocalMultiplayer, LocalMultiplayer,
NetworkedMultiplayer, NetworkedMultiplayer(Option<String>),
} }
pub fn new_string_board() -> String { pub fn new_string_board() -> String {
@ -582,12 +605,15 @@ mod tests {
paired: false, paired: false,
current_side: None, current_side: None,
current_turn: Turn::CyanPlayer, current_turn: Turn::CyanPlayer,
phrase: None,
}; };
assert!(state.is_networked_multiplayer()); assert!(state.is_networked_multiplayer());
let state = GameState::NetworkedMultiplayer { let state = GameState::NetworkedMultiplayer {
paired: true, paired: true,
current_side: Some(Turn::CyanPlayer), current_side: Some(Turn::CyanPlayer),
current_turn: Turn::MagentaPlayer, current_turn: Turn::MagentaPlayer,
phrase: None,
}; };
assert!(state.is_networked_multiplayer());
} }
} }

View file

@ -13,12 +13,12 @@ use crate::constants::{
}; };
use crate::game_logic::{check_win_draw, WinType}; use crate::game_logic::{check_win_draw, WinType};
use crate::html_helper::{ use crate::html_helper::{
append_to_info_text, create_json_request, element_append_class, element_has_class, append_to_info_text, element_append_class, element_has_class, element_remove_class,
element_remove_class, get_window_document, send_to_backend, get_window_document, send_to_backend,
}; };
use crate::random_helper::get_seeded_random; use crate::random_helper::get_seeded_random;
use crate::state::{ use crate::state::{
board_from_string, BoardState, BoardType, GameState, GameStateResponse, MainMenuMessage, board_from_string, BoardState, GameState, GameStateResponse, MainMenuMessage,
NetworkedGameState, PairingRequestResponse, PairingStatusResponse, PlaceTokenResponse, NetworkedGameState, PairingRequestResponse, PairingStatusResponse, PlaceTokenResponse,
PlacedEnum, SharedState, Turn, PlacedEnum, SharedState, Turn,
}; };
@ -28,10 +28,7 @@ use std::collections::HashMap;
use std::rc::Rc; use std::rc::Rc;
use js_sys::{Function, Promise}; use js_sys::{Function, Promise};
use wasm_bindgen::JsCast; use web_sys::{AddEventListenerOptions, Document, HtmlInputElement};
use web_sys::{AddEventListenerOptions, Document, Response};
use serde_json::Value as SerdeJSONValue;
use wasm_bindgen_futures::JsFuture; use wasm_bindgen_futures::JsFuture;
@ -80,9 +77,9 @@ impl Component for MainMenu {
let onclick_networked_multiplayer = ctx let onclick_networked_multiplayer = ctx
.link() .link()
.callback(|_| MainMenuMessage::NetworkedMultiplayer); .callback(|_| MainMenuMessage::NetworkedMultiplayer(None));
let menu_class = if shared.game_state.get() == GameState::MainMenu { let menu_class = if shared.game_state.borrow().eq(&GameState::MainMenu) {
"menu" "menu"
} else { } else {
"hidden_menu" "hidden_menu"
@ -104,9 +101,19 @@ impl Component for MainMenu {
<button class={"menuLocalMultiplayer"} onclick={onclick_local_multiplayer}> <button class={"menuLocalMultiplayer"} onclick={onclick_local_multiplayer}>
{"Local Multiplayer"} {"Local Multiplayer"}
</button> </button>
<button class={"menuMultiplayer"} onclick={onclick_networked_multiplayer}> <div class={"multiplayerMenu"}>
{"Networked Multiplayer"} <button class={"networkedMultiplayer"} onclick={onclick_networked_multiplayer}>
</button> {"Networked Multiplayer"}
</button>
<button class={"NMPhrase"} onclick={ctx.link().callback(|_| {
let (_window, document) = get_window_document().expect("Should be able to get window/document");
let input = HtmlInputElement::from(wasm_bindgen::JsValue::from(document.get_element_by_id("NMPhraseText").expect("Should be able to get NMPhrase input element")));
MainMenuMessage::NetworkedMultiplayer(Some(input.value()))
})}>
{"NMultiplayer with Phrase"}
</button>
<input class={"NMPhrase"} id={"NMPhraseText"} placeholder={"input phrase here"} autofocus=true />
</div>
</div> </div>
} }
} }
@ -120,13 +127,13 @@ impl Component for MainMenu {
let document = window.document().expect("window should have a document"); let document = window.document().expect("window should have a document");
shared.game_state.replace(msg.into()); shared.game_state.replace(msg.into());
if shared.game_state.get() != GameState::MainMenu { if !shared.game_state.borrow().eq(&GameState::MainMenu) {
let mainmenu = document let mainmenu = document
.get_element_by_id("mainmenu") .get_element_by_id("mainmenu")
.expect("mainmenu should exist"); .expect("mainmenu should exist");
mainmenu.set_class_name("hidden_menu"); mainmenu.set_class_name("hidden_menu");
match shared.game_state.get() { match shared.game_state.borrow().clone() {
GameState::SinglePlayer(turn, _) => { GameState::SinglePlayer(turn, _) => {
if shared.turn.get() == turn { if shared.turn.get() == turn {
append_to_info_text( append_to_info_text(
@ -157,6 +164,7 @@ impl Component for MainMenu {
paired: _, paired: _,
current_side: _, current_side: _,
current_turn: _, current_turn: _,
phrase: _,
} => { } => {
append_to_info_text( append_to_info_text(
&document, &document,
@ -265,13 +273,14 @@ impl Component for Slot {
.context::<SharedState>(Callback::noop()) .context::<SharedState>(Callback::noop())
.expect("state to be set"); .expect("state to be set");
match shared.game_state.get() { match shared.game_state.borrow().clone() {
GameState::MainMenu => return false, GameState::MainMenu => return false,
GameState::SinglePlayer(_, _) | GameState::LocalMultiplayer => (), GameState::SinglePlayer(_, _) | GameState::LocalMultiplayer => (),
GameState::NetworkedMultiplayer { GameState::NetworkedMultiplayer {
paired, paired,
current_side, current_side,
current_turn, current_turn,
phrase: _,
} => { } => {
if paired && current_side.is_some() { if paired && current_side.is_some() {
if current_side.as_ref().unwrap() == &current_turn { if current_side.as_ref().unwrap() == &current_turn {
@ -289,7 +298,7 @@ impl Component for Slot {
} }
GameState::PostGameResults(_) => return false, GameState::PostGameResults(_) => return false,
} }
if shared.game_state.get() == GameState::MainMenu { if shared.game_state.borrow().eq(&GameState::MainMenu) {
return false; return false;
} }
@ -342,10 +351,19 @@ impl Wrapper {
} }
fn get_networked_player_id(&mut self, ctx: &Context<Self>) { fn get_networked_player_id(&mut self, ctx: &Context<Self>) {
let (shared, _) = ctx
.link()
.context::<SharedState>(Callback::noop())
.expect("state to be set");
let phrase_clone: Option<String> = shared.game_state.borrow().get_phrase();
// make a request to get the player_id // make a request to get the player_id
ctx.link().send_future(async { ctx.link().send_future(async move {
let mut json_entries = HashMap::new(); let mut json_entries = HashMap::new();
json_entries.insert("type".into(), "pairing_request".into()); json_entries.insert("type".into(), "pairing_request".into());
if let Some(phrase_string) = phrase_clone {
json_entries.insert("phrase".into(), phrase_string);
}
let send_to_backend_result = send_to_backend(json_entries).await; let send_to_backend_result = send_to_backend(json_entries).await;
if let Err(e) = send_to_backend_result { if let Err(e) = send_to_backend_result {
@ -717,7 +735,7 @@ impl Component for Wrapper {
// check if player can make a move // check if player can make a move
if !msg.is_ai_pressed() { if !msg.is_ai_pressed() {
match shared.game_state.get() { match shared.game_state.borrow().clone() {
GameState::MainMenu => (), GameState::MainMenu => (),
GameState::SinglePlayer(turn, _) => { GameState::SinglePlayer(turn, _) => {
if current_player != turn { if current_player != turn {
@ -729,6 +747,7 @@ impl Component for Wrapper {
paired, paired,
current_side, current_side,
current_turn, current_turn,
phrase: _,
} => { } => {
if paired { if paired {
if let Some(current_side) = current_side { if let Some(current_side) = current_side {
@ -796,28 +815,29 @@ impl Component for Wrapper {
// info text right of the grid // info text right of the grid
{ {
let turn = shared.turn.get(); let turn = shared.turn.get();
let output_str = let output_str = if let GameState::SinglePlayer(player_turn, _) =
if let GameState::SinglePlayer(player_turn, _) = shared.game_state.get() { shared.game_state.borrow().clone()
if shared.turn.get() == player_turn { {
format!( if shared.turn.get() == player_turn {
"<b class=\"{}\">It is {}'s (player) turn</b>",
turn.get_color(),
turn
)
} else {
format!(
"<b class=\"{}\">It is {}'s (ai) turn</b>",
turn.get_color(),
turn
)
}
} else {
format!( format!(
"<b class=\"{}\">It is {}'s Turn</b>", "<b class=\"{}\">It is {}'s (player) turn</b>",
turn.get_color(), turn.get_color(),
turn turn
) )
}; } else {
format!(
"<b class=\"{}\">It is {}'s (ai) turn</b>",
turn.get_color(),
turn
)
}
} else {
format!(
"<b class=\"{}\">It is {}'s Turn</b>",
turn.get_color(),
turn
)
};
let text_append_result = let text_append_result =
append_to_info_text(&document, "info_text1", &output_str, 1); append_to_info_text(&document, "info_text1", &output_str, 1);
@ -1179,7 +1199,7 @@ impl Component for Wrapper {
// check if it is AI's turn // check if it is AI's turn
if let GameState::SinglePlayer(player_type, _ai_difficulty) = if let GameState::SinglePlayer(player_type, _ai_difficulty) =
shared.game_state.get() shared.game_state.borrow().clone()
{ {
if shared.turn.get() != player_type { if shared.turn.get() != player_type {
ctx.link().send_message(WrapperMsg::AIChoice); ctx.link().send_message(WrapperMsg::AIChoice);
@ -1192,7 +1212,8 @@ impl Component for Wrapper {
} }
WrapperMsg::AIChoiceImpl => { WrapperMsg::AIChoiceImpl => {
// get AI's choice // get AI's choice
if let GameState::SinglePlayer(player_type, ai_difficulty) = shared.game_state.get() if let GameState::SinglePlayer(player_type, ai_difficulty) =
shared.game_state.borrow().clone()
{ {
if shared.turn.get() != player_type { if shared.turn.get() != player_type {
let choice = let choice =
@ -1228,7 +1249,9 @@ impl Component for Wrapper {
ctx.link().send_message(WrapperMsg::BackendTick); ctx.link().send_message(WrapperMsg::BackendTick);
} }
WrapperMsg::BackendTick => { WrapperMsg::BackendTick => {
if !self.do_backend_tick || !shared.game_state.get().is_networked_multiplayer() { let is_networked_multiplayer =
shared.game_state.borrow().is_networked_multiplayer();
if !self.do_backend_tick || !is_networked_multiplayer {
// disconnect id if backend tick is to be stopped // disconnect id if backend tick is to be stopped
if let Some(id) = self.player_id.take() { if let Some(id) = self.player_id.take() {
let function = Function::new_no_args(&format!( let function = Function::new_no_args(&format!(
@ -1248,12 +1271,15 @@ impl Component for Wrapper {
self.get_networked_player_id(ctx); self.get_networked_player_id(ctx);
} else if shared } else if shared
.game_state .game_state
.get() .borrow()
.get_networked_current_side() .get_networked_current_side()
.is_none() .is_none()
{ {
self.get_networked_player_type(ctx); self.get_networked_player_type(ctx);
} else if !matches!(shared.game_state.get(), GameState::PostGameResults(_)) { } else if !matches!(
shared.game_state.borrow().clone(),
GameState::PostGameResults(_)
) {
if self.place_request.is_some() { if self.place_request.is_some() {
let placement = self.place_request.take().unwrap(); let placement = self.place_request.take().unwrap();
self.send_place_request(ctx, placement); self.send_place_request(ctx, placement);
@ -1323,10 +1349,10 @@ impl Component for Wrapper {
}); });
self.player_id = Some(id); self.player_id = Some(id);
let mut game_state = shared.game_state.get(); let mut game_state = shared.game_state.borrow().clone();
game_state.set_networked_paired(); game_state.set_networked_paired();
game_state.set_networked_current_side(turn_opt); game_state.set_networked_current_side(turn_opt);
shared.game_state.set(game_state); shared.game_state.replace(game_state);
if let Some(turn_type) = turn_opt { if let Some(turn_type) = turn_opt {
append_to_info_text( append_to_info_text(
&document, &document,
@ -1356,9 +1382,9 @@ impl Component for Wrapper {
} }
} }
BREnum::GotPairing(turn_opt) => { BREnum::GotPairing(turn_opt) => {
let mut game_state = shared.game_state.get(); let mut game_state = shared.game_state.borrow().clone();
game_state.set_networked_current_side(turn_opt); game_state.set_networked_current_side(turn_opt);
shared.game_state.set(game_state); shared.game_state.replace(game_state);
if let Some(turn_type) = turn_opt { if let Some(turn_type) = turn_opt {
append_to_info_text( append_to_info_text(
&document, &document,
@ -1392,12 +1418,12 @@ impl Component for Wrapper {
self.update_board_from_string(&shared, &document, board_string); self.update_board_from_string(&shared, &document, board_string);
} }
let mut current_game_state = shared.game_state.get(); let mut current_game_state: GameState = shared.game_state.borrow().clone();
match networked_game_state { match networked_game_state {
NetworkedGameState::CyanTurn => { NetworkedGameState::CyanTurn => {
if current_game_state.get_current_turn() != Turn::CyanPlayer { if current_game_state.get_current_turn() != Turn::CyanPlayer {
current_game_state.set_networked_current_turn(Turn::CyanPlayer); current_game_state.set_networked_current_turn(Turn::CyanPlayer);
shared.game_state.set(current_game_state); shared.game_state.replace(current_game_state.clone());
append_to_info_text( append_to_info_text(
&document, &document,
"info_text1", "info_text1",
@ -1422,7 +1448,7 @@ impl Component for Wrapper {
if current_game_state.get_current_turn() != Turn::MagentaPlayer { if current_game_state.get_current_turn() != Turn::MagentaPlayer {
current_game_state current_game_state
.set_networked_current_turn(Turn::MagentaPlayer); .set_networked_current_turn(Turn::MagentaPlayer);
shared.game_state.set(current_game_state); shared.game_state.replace(current_game_state.clone());
append_to_info_text( append_to_info_text(
&document, &document,
"info_text1", "info_text1",
@ -1449,7 +1475,7 @@ impl Component for Wrapper {
.ok(); .ok();
shared shared
.game_state .game_state
.set(GameState::PostGameResults(BoardState::CyanWin)); .replace(GameState::PostGameResults(BoardState::CyanWin));
self.do_backend_tick = false; self.do_backend_tick = false;
} }
NetworkedGameState::MagentaWon => { NetworkedGameState::MagentaWon => {
@ -1462,7 +1488,7 @@ impl Component for Wrapper {
.ok(); .ok();
shared shared
.game_state .game_state
.set(GameState::PostGameResults(BoardState::MagentaWin)); .replace(GameState::PostGameResults(BoardState::MagentaWin));
self.do_backend_tick = false; self.do_backend_tick = false;
} }
NetworkedGameState::Draw => { NetworkedGameState::Draw => {
@ -1475,7 +1501,7 @@ impl Component for Wrapper {
.ok(); .ok();
shared shared
.game_state .game_state
.set(GameState::PostGameResults(BoardState::Empty)); .replace(GameState::PostGameResults(BoardState::Empty));
self.do_backend_tick = false; self.do_backend_tick = false;
} }
NetworkedGameState::Disconnected => { NetworkedGameState::Disconnected => {
@ -1495,7 +1521,7 @@ impl Component for Wrapper {
.ok(); .ok();
shared shared
.game_state .game_state
.set(GameState::PostGameResults(BoardState::Empty)); .replace(GameState::PostGameResults(BoardState::Empty));
self.do_backend_tick = false; self.do_backend_tick = false;
} }
NetworkedGameState::InternalError => { NetworkedGameState::InternalError => {
@ -1508,7 +1534,7 @@ impl Component for Wrapper {
.ok(); .ok();
shared shared
.game_state .game_state
.set(GameState::PostGameResults(BoardState::Empty)); .replace(GameState::PostGameResults(BoardState::Empty));
self.do_backend_tick = false; self.do_backend_tick = false;
} }
NetworkedGameState::NotPaired => (), NetworkedGameState::NotPaired => (),
@ -1522,7 +1548,7 @@ impl Component for Wrapper {
.ok(); .ok();
shared shared
.game_state .game_state
.set(GameState::PostGameResults(BoardState::Empty)); .replace(GameState::PostGameResults(BoardState::Empty));
self.do_backend_tick = false; self.do_backend_tick = false;
} }
} }
@ -1565,7 +1591,7 @@ impl Component for Wrapper {
.ok(); .ok();
shared shared
.game_state .game_state
.set(GameState::PostGameResults(BoardState::CyanWin)); .replace(GameState::PostGameResults(BoardState::CyanWin));
self.do_backend_tick = false; self.do_backend_tick = false;
} }
NetworkedGameState::MagentaWon => { NetworkedGameState::MagentaWon => {
@ -1576,9 +1602,9 @@ impl Component for Wrapper {
1, 1,
) )
.ok(); .ok();
shared shared.game_state.replace(GameState::PostGameResults(
.game_state BoardState::MagentaWin,
.set(GameState::PostGameResults(BoardState::MagentaWin)); ));
self.do_backend_tick = false; self.do_backend_tick = false;
} }
NetworkedGameState::Draw => { NetworkedGameState::Draw => {
@ -1591,7 +1617,7 @@ impl Component for Wrapper {
.ok(); .ok();
shared shared
.game_state .game_state
.set(GameState::PostGameResults(BoardState::Empty)); .replace(GameState::PostGameResults(BoardState::Empty));
self.do_backend_tick = false; self.do_backend_tick = false;
} }
NetworkedGameState::Disconnected => { NetworkedGameState::Disconnected => {
@ -1604,7 +1630,7 @@ impl Component for Wrapper {
.ok(); .ok();
shared shared
.game_state .game_state
.set(GameState::PostGameResults(BoardState::Empty)); .replace(GameState::PostGameResults(BoardState::Empty));
self.do_backend_tick = false; self.do_backend_tick = false;
} }
NetworkedGameState::InternalError => { NetworkedGameState::InternalError => {
@ -1617,7 +1643,7 @@ impl Component for Wrapper {
.ok(); .ok();
shared shared
.game_state .game_state
.set(GameState::PostGameResults(BoardState::Empty)); .replace(GameState::PostGameResults(BoardState::Empty));
self.do_backend_tick = false; self.do_backend_tick = false;
} }
NetworkedGameState::NotPaired => (), NetworkedGameState::NotPaired => (),
@ -1631,7 +1657,7 @@ impl Component for Wrapper {
.ok(); .ok();
shared shared
.game_state .game_state
.set(GameState::PostGameResults(BoardState::Empty)); .replace(GameState::PostGameResults(BoardState::Empty));
self.do_backend_tick = false; self.do_backend_tick = false;
} }
}, },
@ -1640,7 +1666,7 @@ impl Component for Wrapper {
} }
} }
WrapperMsg::Reset => { WrapperMsg::Reset => {
shared.game_state.set(GameState::default()); shared.game_state.replace(GameState::default());
shared.turn.set(Turn::CyanPlayer); shared.turn.set(Turn::CyanPlayer);
for idx in 0..((ROWS * COLS) as usize) { for idx in 0..((ROWS * COLS) as usize) {
shared.placed[idx].set(false); shared.placed[idx].set(false);
@ -1718,7 +1744,7 @@ impl Component for InfoText {
} }
} }
1 => { 1 => {
if shared.game_state.get() == GameState::MainMenu { if shared.game_state.borrow().eq(&GameState::MainMenu) {
html! { html! {
<div id={format!("info_text{}", ctx.props().id)} class={format!("info_text{}", ctx.props().id)}> <div id={format!("info_text{}", ctx.props().id)} class={format!("info_text{}", ctx.props().id)}>
<p> <p>