Players get live game status updates
This commit is contained in:
parent
8fac31e97b
commit
a6040fe89c
@ -34,7 +34,7 @@ pub async fn run_client(
|
||||
while let Some(chunk) = socket.next().await {
|
||||
let message = match chunk? {
|
||||
Message::Text(message) => {
|
||||
log::debug!("TEXT message from server: {}", message);
|
||||
log::trace!("TEXT message from server: {}", message);
|
||||
|
||||
let msg: ServerMessage = serde_json::from_str(&message)?;
|
||||
msg
|
||||
@ -79,8 +79,13 @@ pub async fn run_client(
|
||||
}
|
||||
ServerMessage::OtherPlayerReady => log::debug!("Other player is ready!"),
|
||||
ServerMessage::GameStarting => log::debug!("The game is starting..."),
|
||||
ServerMessage::OtherPlayerMustFire { .. } => log::debug!("Other player must fire!"),
|
||||
ServerMessage::OtherPlayerMustFire { status } => {
|
||||
assert_eq!(status.opponent_map.boats.number_of_boats(), 0);
|
||||
log::debug!("Other player must fire!")
|
||||
}
|
||||
ServerMessage::RequestFire { status } => {
|
||||
assert_eq!(status.opponent_map.boats.number_of_boats(), 0);
|
||||
|
||||
let location = status.find_valid_random_fire_location();
|
||||
log::debug!("Will fire at {:?}", location);
|
||||
socket
|
||||
@ -119,6 +124,7 @@ pub async fn run_client(
|
||||
log::warn!("Rejected boat layout: {:?}", errors);
|
||||
return Ok(ClientEndResult::InvalidBoatsLayout);
|
||||
}
|
||||
ServerMessage::SetOpponentName { name } => log::debug!("Opponent name: {}", name),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,6 +151,11 @@ impl BoatPosition {
|
||||
pub struct BoatsLayout(Vec<BoatPosition>);
|
||||
|
||||
impl BoatsLayout {
|
||||
/// Generate a new invalid (empty) boats layout
|
||||
pub fn new_invalid() -> Self {
|
||||
Self(vec![])
|
||||
}
|
||||
|
||||
/// Generate random boats layout for given game rules
|
||||
pub fn gen_random_for_rules(rules: &GameRules) -> std::io::Result<Self> {
|
||||
let mut boats = Self(Vec::with_capacity(rules.boats_list().len()));
|
||||
|
@ -1,17 +1,27 @@
|
||||
use crate::data::{Coordinates, GameRules};
|
||||
use rand::RngCore;
|
||||
|
||||
use crate::data::{BoatPosition, BoatsLayout, Coordinates, GameRules};
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct CurrentGameMapStatus {
|
||||
pub boats: BoatsLayout,
|
||||
pub successful_strikes: Vec<Coordinates>,
|
||||
pub failed_strikes: Vec<Coordinates>,
|
||||
pub sunk_boats: Vec<BoatPosition>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct CurrentGameStatus {
|
||||
pub rules: GameRules,
|
||||
//TODO
|
||||
pub your_map: CurrentGameMapStatus,
|
||||
pub opponent_map: CurrentGameMapStatus,
|
||||
}
|
||||
|
||||
impl CurrentGameStatus {
|
||||
/// Check if user can fire at a given location
|
||||
pub fn can_fire_at_location(&self, _location: Coordinates) -> bool {
|
||||
//TODO
|
||||
true
|
||||
/// Check if opponent can fire at a given location
|
||||
pub fn can_fire_at_location(&self, location: Coordinates) -> bool {
|
||||
!self.opponent_map.successful_strikes.contains(&location)
|
||||
&& !self.opponent_map.failed_strikes.contains(&location)
|
||||
}
|
||||
|
||||
/// Find valid random fire location. Loop until one is found
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::data::boats_layout::{BoatsLayout, Coordinates};
|
||||
use crate::data::{BoatPosition, EndGameMap, GameRules};
|
||||
use crate::data::{BoatPosition, CurrentGameMapStatus, EndGameMap, GameRules};
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
pub enum FireResult {
|
||||
@ -133,6 +133,18 @@ impl GameMap {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn current_map_status(&self, for_opponent: bool) -> CurrentGameMapStatus {
|
||||
CurrentGameMapStatus {
|
||||
boats: match for_opponent {
|
||||
true => BoatsLayout::new_invalid(),
|
||||
false => self.boats_config.clone(),
|
||||
},
|
||||
successful_strikes: self.successful_strikes.clone(),
|
||||
failed_strikes: self.failed_strikes.clone(),
|
||||
sunk_boats: self.sunk_boats.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn final_map(&self) -> EndGameMap {
|
||||
EndGameMap {
|
||||
boats: self.boats_config.clone(),
|
||||
|
@ -11,6 +11,8 @@ pub trait Player {
|
||||
|
||||
fn get_uid(&self) -> Uuid;
|
||||
|
||||
fn set_other_player_name(&self, name: &str);
|
||||
|
||||
fn query_boats_layout(&self, rules: &GameRules);
|
||||
|
||||
fn rejected_boats_layout(&self, errors: Vec<&'static str>);
|
||||
@ -82,6 +84,9 @@ impl Game {
|
||||
|
||||
/// Once the two player has been registered, the game may start
|
||||
fn query_boats_disposition(&mut self) {
|
||||
self.players[0].set_other_player_name(self.players[1].get_name());
|
||||
self.players[1].set_other_player_name(self.players[0].get_name());
|
||||
|
||||
log::debug!("Query boats disposition");
|
||||
assert_eq!(self.status, GameStatus::Created);
|
||||
self.status = GameStatus::WaitingForBoatsDisposition;
|
||||
@ -160,9 +165,11 @@ impl Game {
|
||||
}
|
||||
|
||||
/// Get current game status for a specific player
|
||||
fn get_game_status_for_player(&self, _id: usize) -> CurrentGameStatus {
|
||||
fn get_game_status_for_player(&self, id: usize) -> CurrentGameStatus {
|
||||
CurrentGameStatus {
|
||||
rules: self.rules.clone(),
|
||||
your_map: self.player_map(id).current_map_status(false),
|
||||
opponent_map: self.player_map(opponent(id)).current_map_status(true),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,12 @@ impl Player for HumanPlayer {
|
||||
self.uuid
|
||||
}
|
||||
|
||||
fn set_other_player_name(&self, name: &str) {
|
||||
self.player.do_send(ServerMessage::SetOpponentName {
|
||||
name: name.to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
fn query_boats_layout(&self, rules: &GameRules) {
|
||||
self.player.do_send(ServerMessage::QueryBoatsLayout {
|
||||
rules: rules.clone(),
|
||||
|
@ -41,6 +41,9 @@ pub enum ClientMessage {
|
||||
#[serde(tag = "type")]
|
||||
pub enum ServerMessage {
|
||||
WaitingForAnotherPlayer,
|
||||
SetOpponentName {
|
||||
name: String,
|
||||
},
|
||||
QueryBoatsLayout {
|
||||
rules: GameRules,
|
||||
},
|
||||
|
@ -28,6 +28,8 @@ impl Player for RandomBot {
|
||||
self.uuid
|
||||
}
|
||||
|
||||
fn set_other_player_name(&self, _name: &str) {}
|
||||
|
||||
fn query_boats_layout(&self, rules: &GameRules) {
|
||||
match BoatsLayout::gen_random_for_rules(rules) {
|
||||
Ok(layout) => self.game.do_send(SetBoatsLayout(self.uuid, layout)),
|
||||
|
Loading…
Reference in New Issue
Block a user