Skip to content

Commit

Permalink
fix: incorrect player set as next in game_state, improve transitions
Browse files Browse the repository at this point in the history
  • Loading branch information
TeemuKoivisto committed Jul 26, 2023
1 parent f1e4d03 commit d912d7a
Show file tree
Hide file tree
Showing 13 changed files with 353 additions and 139 deletions.
24 changes: 24 additions & 0 deletions crates/server/src/game/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,26 @@ impl Game {
&self.state.players[(self.state.player_in_turn - 1) as usize]
}

pub fn get_player_game_state(&self) -> PlayerInGameState {
if self.state.status == GameStatus::X_TURN {
PlayerInGameState::x_turn
} else if self.state.status == GameStatus::O_TURN {
PlayerInGameState::o_turn
} else if self.state.status == GameStatus::WAITING {
PlayerInGameState::waiting_player
} else {
PlayerInGameState::ended
}
}

pub fn get_board_state(&self) -> BoardState {
BoardState {
game_id: self.id.to_string(),
start_time: self.start_time,
player_in_turn: self.get_player_in_turn().id,
players: self.state.players.clone(),
cells: self.state.get_cells(),
state: self.get_player_game_state(),
}
}

Expand Down Expand Up @@ -132,6 +145,7 @@ impl Game {
game_id: self.id.to_string(),
result: self.state.status,
winner_id,
state: PlayerInGameState::ended,
}
}

Expand All @@ -149,6 +163,7 @@ impl Game {
player_id,
symbol: player.symbol.clone(),
name: player.name.clone(),
state: PlayerInGameState::waiting_player,
},
));
}
Expand All @@ -162,6 +177,7 @@ impl Game {
GamePlayerReconnected {
game_id: self.id.to_string(),
player_id,
state: self.get_player_game_state(),
},
));
}
Expand All @@ -179,18 +195,26 @@ impl Game {
next_in_turn,
x: payload.x,
y: payload.y,
state: PlayerInGameState::ended,
}),
GameToClientEvent::GameEnd(self.get_game_end()),
]);
let _ = self
.game_to_lobby_sender
.send(GameToLobbyEvent::GameEnded(self.id));
} else {
println!(
"player {} moved, next in turn {} and enum {:?}",
player_number,
next_in_turn,
self.get_player_game_state()
);
self.send(GameToClientEvent::GameUpdate(GameMove {
player_number: player_number,
next_in_turn,
x: payload.x,
y: payload.y,
state: self.get_player_game_state(),
}));
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/server/src/game/game_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub fn run_game(mut actor: Game) -> JoinHandle<()> {
actor.handle_client_event(ev).await;
},
_ = interval.tick() => {
println!("tick");
// println!("tick");
if !actor.check_if_running() {
break;
}
Expand Down
22 changes: 9 additions & 13 deletions crates/server/src/ws/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ impl Session {
let (ws_sender, ws_receiver) = socket.split();
self.ws_sender = ws_sender;
self.ws_receiver = ws_receiver;
self.state.revert_disconnected();
self.send_to_ws(ServerMsgType::player_status, &self.state.get_player_state())
.await;
}
Expand Down Expand Up @@ -80,13 +81,11 @@ impl Session {
debug!("ClientMsgType::join_lobby {:#?}", player_join);
self.state.set_player(&player_join);
self.send_to_lobby(ClientToLobbyEvent::PlayerJoinLobby(player_join));
self.state.transit(PlayerAppState::lobby);
}
}
Ok(ClientMsgType::create_lobby_game) => {
if let Ok(payload) = PlayerCreateGame::from_reader(&mut reader, &raw_buf) {
debug!("ClientMsgType::create_lobby_game {:#?}", payload);
self.state.transit(PlayerAppState::waiting_game_start);
self.send_to_lobby(ClientToLobbyEvent::PlayerCreateGame(
self.socket_id,
payload,
Expand All @@ -97,7 +96,6 @@ impl Session {
if let Ok(player_join) = PlayerJoinGame::from_reader(&mut reader, &raw_buf)
{
debug!("ClientMsgType::join_lobby_game {:#?}", player_join);
self.state.transit(PlayerAppState::waiting_game_start);
self.send_to_lobby(ClientToLobbyEvent::PlayerJoinGame(
self.socket_id,
player_join,
Expand All @@ -107,6 +105,7 @@ impl Session {
Ok(ClientMsgType::player_select_cell) => {
if let Ok(payload) = PlayerSelectCell::from_reader(&mut reader, &raw_buf) {
debug!("ClientMsgType::player_select_cell {:#?}", payload);
// @TODO use game_id
self.send_to_game(ClientToGameEvent::SelectCell(
self.socket_id,
PlayerMove {
Expand Down Expand Up @@ -157,14 +156,16 @@ impl Session {
info!("Client {} -> LobbyToClientEvent {:?}", self.socket_id, msg);
match msg {
LobbyToClientEvent::Subscribe(sender) => {
self.state.set_lobby(sender);
self.state.transit(PlayerAppState::lobby);
self.state.set_lobby(sender);
}
LobbyToClientEvent::JoinLobby(_) => todo!(),
LobbyToClientEvent::LobbyMsg(_) => todo!(),
LobbyToClientEvent::LeaveLobby(payload) => {
// let was_player = payload.iter().find(|s| s == &&self.socket_id);
// if
// if was_player.is_some() {
// println!("PLAYER LEFT LOBBY");
// }
}
LobbyToClientEvent::LobbyState(payload) => {
self.send_to_ws(ServerMsgType::lobby_state, &payload).await;
Expand Down Expand Up @@ -197,28 +198,23 @@ impl Session {
.await;
}
GameToClientEvent::PlayerReconnected(payload) => {
self.state.transit_game(payload.state);
self.send_to_ws(ServerMsgType::player_reconnected, &payload)
.await;
}
GameToClientEvent::PlayerJoin(_) => todo!(),
GameToClientEvent::PlayerLeave() => todo!(),
GameToClientEvent::GameStart(payload) => {
// @TODO use the payload
self.state.transit(PlayerAppState::in_game);
self.state.transit_game(PlayerInGameState::x_turn);
self.state.transit_game(payload.state);
self.send_to_ws(ServerMsgType::game_start, &payload).await;
}
GameToClientEvent::GameEnd(payload) => {
self.state.transit_game(PlayerInGameState::ended);
self.send_to_ws(ServerMsgType::game_end, &payload).await;
}
GameToClientEvent::GameUpdate(payload) => {
// self.state.transit_game(to);
// if self.game_state == PlayerInGameState::x_turn {
// self.game_state = PlayerInGameState::o_turn;
// } else {
// self.game_state = PlayerInGameState::x_turn;
// }
self.state.transit_game(payload.state);
self.send_to_ws(ServerMsgType::game_player_move, &payload)
.await;
}
Expand Down
68 changes: 67 additions & 1 deletion crates/server/src/ws/session_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ pub struct SessionState {
pub name: String,
pub socket_id: u32,
pub app_state: PlayerAppState,
pub prev_app_state: PlayerAppState,
pub game_state: PlayerInGameState,
pub prev_game_state: PlayerInGameState,
pub subscribed_lobby: Option<broadcast::Sender<ClientToLobbyEvent>>,
pub subscribed_games: Vec<SubscribedGame>,
}
Expand All @@ -45,7 +47,7 @@ fn is_valid_app_transition(from: &PlayerAppState, to: &PlayerAppState) -> bool {
.contains(to),
PlayerAppState::waiting_game_start => [
PlayerAppState::disconnected,
PlayerAppState::waiting_game_start,
PlayerAppState::lobby,
PlayerAppState::in_game,
]
.contains(to),
Expand All @@ -56,14 +58,60 @@ fn is_valid_app_transition(from: &PlayerAppState, to: &PlayerAppState) -> bool {
}
}

fn is_valid_game_transition(from: &PlayerInGameState, to: &PlayerInGameState) -> bool {
match from {
PlayerInGameState::not_started => [
PlayerInGameState::x_turn,
PlayerInGameState::o_turn,
PlayerInGameState::waiting_player,
PlayerInGameState::paused,
PlayerInGameState::ended,
]
.contains(to),
PlayerInGameState::x_turn => [
PlayerInGameState::waiting_player,
PlayerInGameState::o_turn,
PlayerInGameState::paused,
PlayerInGameState::ended,
]
.contains(to),
PlayerInGameState::o_turn => [
PlayerInGameState::waiting_player,
PlayerInGameState::x_turn,
PlayerInGameState::paused,
PlayerInGameState::ended,
]
.contains(to),
PlayerInGameState::waiting_player => [
PlayerInGameState::not_started,
PlayerInGameState::x_turn,
PlayerInGameState::o_turn,
PlayerInGameState::paused,
PlayerInGameState::ended,
]
.contains(to),
PlayerInGameState::paused => [
PlayerInGameState::waiting_player,
PlayerInGameState::not_started,
PlayerInGameState::x_turn,
PlayerInGameState::o_turn,
PlayerInGameState::ended,
]
.contains(to),
PlayerInGameState::ended => [].contains(to),
}
}

impl SessionState {
pub fn new(socket_id: u32) -> Self {
Self {
name: "".to_string(),
player_id: 0,
socket_id,
app_state: PlayerAppState::initializing,
prev_app_state: PlayerAppState::initializing,
game_state: PlayerInGameState::not_started,
prev_game_state: PlayerInGameState::not_started,
subscribed_lobby: None,
subscribed_games: Vec::new(),
}
Expand Down Expand Up @@ -113,17 +161,35 @@ impl SessionState {
});
}

pub fn revert_disconnected(&mut self) {
if self.app_state != PlayerAppState::disconnected {
panic!(
"Session was not in disconnected state to revert it to {:?}",
self.prev_app_state
);
}
self.app_state = self.prev_app_state;
}

pub fn transit(&mut self, to: PlayerAppState) {
if !is_valid_app_transition(&self.app_state, &to) {
panic!(
"Not valid app transition: from {:?} to {:?}",
self.app_state, to
);
}
self.prev_app_state = self.app_state;
self.app_state = to;
}

pub fn transit_game(&mut self, to: PlayerInGameState) {
// if !is_valid_game_transition(&self.game_state, &to) {
// panic!(
// "Not valid game transition: from {:?} to {:?}",
// self.game_state, to
// );
// }
self.prev_game_state = self.game_state;
self.game_state = to;
}
}
6 changes: 3 additions & 3 deletions crates/tic-tac-5/src/game_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,19 +104,19 @@ impl GameState {
}
self.board.update_cell_owner(x, y, player_number);
let did_win = self.check_win(x, y);
if player_number == self.options.players {
if player_number == 2 {
self.player_in_turn = 1;
self.status = if did_win {
GameStatus::O_WON
} else {
GameStatus::O_TURN
GameStatus::X_TURN
};
} else {
self.player_in_turn = player_number + 1;
self.status = if did_win {
GameStatus::X_WON
} else {
GameStatus::X_TURN
GameStatus::O_TURN
};
}
Ok((did_win, self.player_in_turn))
Expand Down
Loading

0 comments on commit d912d7a

Please sign in to comment.