Can fire
This commit is contained in:
parent
54f7566016
commit
a0eae4c93d
@ -67,6 +67,16 @@ pub async fn run_client(server: &str, rules: &GameRules) -> Result<(), Box<dyn E
|
||||
}
|
||||
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::RequestFire { status } => {
|
||||
let location = status.find_valid_random_fire_location();
|
||||
log::debug!("Will fire at {:?}", location);
|
||||
socket
|
||||
.send(Message::Text(serde_json::to_string(
|
||||
&ClientMessage::Fire { location },
|
||||
)?))
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
30
src/data/current_game_status.rs
Normal file
30
src/data/current_game_status.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use crate::data::{Coordinates, GameRules};
|
||||
use rand::RngCore;
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct CurrentGameStatus {
|
||||
pub rules: GameRules,
|
||||
// TODO
|
||||
}
|
||||
|
||||
impl CurrentGameStatus {
|
||||
/// Check if user can fire at a given location
|
||||
pub fn can_fire_at_location(&self, _location: Coordinates) -> bool {
|
||||
// TODO
|
||||
true
|
||||
}
|
||||
|
||||
/// Find valid random fire location. Loop until one is found
|
||||
pub fn find_valid_random_fire_location(&self) -> Coordinates {
|
||||
let mut rng = rand::thread_rng();
|
||||
loop {
|
||||
let coordinates = Coordinates::new(
|
||||
(rng.next_u32() % self.rules.map_width as u32) as i32,
|
||||
(rng.next_u32() % self.rules.map_height as u32) as i32,
|
||||
);
|
||||
if coordinates.is_valid(&self.rules) && self.can_fire_at_location(coordinates) {
|
||||
return coordinates;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
pub use boats_layout::*;
|
||||
pub use current_game_status::*;
|
||||
pub use game_map::*;
|
||||
pub use game_rules::*;
|
||||
pub use play_config::*;
|
||||
|
||||
mod boats_layout;
|
||||
mod current_game_status;
|
||||
mod game_map;
|
||||
mod game_rules;
|
||||
mod play_config;
|
||||
|
43
src/game.rs
43
src/game.rs
@ -4,7 +4,7 @@ use actix::prelude::*;
|
||||
use actix::{Actor, Context, Handler};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::data::{BoatsLayout, GameMap, GameRules};
|
||||
use crate::data::*;
|
||||
|
||||
pub trait Player {
|
||||
fn get_name(&self) -> &str;
|
||||
@ -16,6 +16,10 @@ pub trait Player {
|
||||
fn notify_other_player_ready(&self);
|
||||
|
||||
fn notify_game_starting(&self);
|
||||
|
||||
fn request_fire(&self, status: CurrentGameStatus);
|
||||
|
||||
fn other_player_must_fire(&self, status: CurrentGameStatus);
|
||||
}
|
||||
|
||||
fn opponent(index: usize) -> usize {
|
||||
@ -40,6 +44,7 @@ pub struct Game {
|
||||
status: GameStatus,
|
||||
map_0: Option<GameMap>,
|
||||
map_1: Option<GameMap>,
|
||||
turn: usize,
|
||||
}
|
||||
|
||||
impl Game {
|
||||
@ -50,6 +55,7 @@ impl Game {
|
||||
status: GameStatus::Created,
|
||||
map_0: None,
|
||||
map_1: None,
|
||||
turn: 0,
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,7 +81,22 @@ impl Game {
|
||||
/// Start fires exchange
|
||||
fn start_fire_exchanges(&mut self) {
|
||||
self.status = GameStatus::Started;
|
||||
log::debug!("Start fire exchanges");
|
||||
log::debug!(
|
||||
"Start fire exchanges. Player {}#{} goes first",
|
||||
self.players[self.turn].get_name(),
|
||||
self.turn
|
||||
);
|
||||
|
||||
self.players[self.turn].request_fire(self.get_game_status_for_player(self.turn));
|
||||
self.players[opponent(self.turn)]
|
||||
.request_fire(self.get_game_status_for_player(opponent(self.turn)));
|
||||
}
|
||||
|
||||
/// Get current game status for a specific player
|
||||
fn get_game_status_for_player(&self, _id: usize) -> CurrentGameStatus {
|
||||
CurrentGameStatus {
|
||||
rules: self.rules.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,7 +134,11 @@ impl Handler<SetBoatsLayout> for Game {
|
||||
|
||||
/// Receive game configuration of a player
|
||||
fn handle(&mut self, msg: SetBoatsLayout, _ctx: &mut Self::Context) -> Self::Result {
|
||||
assert_eq!(self.status, GameStatus::WaitingForBoatsDisposition);
|
||||
if self.status != GameStatus::WaitingForBoatsDisposition {
|
||||
log::error!("Player attempted to set boat configuration on invalid step!");
|
||||
return;
|
||||
}
|
||||
|
||||
let player_index = self.player_id_by_uuid(msg.0);
|
||||
log::debug!("Got boat disposition for player {}", player_index);
|
||||
match player_index {
|
||||
@ -130,3 +155,15 @@ impl Handler<SetBoatsLayout> for Game {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Message, Debug)]
|
||||
#[rtype(result = "()")]
|
||||
pub struct Fire(pub Uuid, pub Coordinates);
|
||||
|
||||
impl Handler<Fire> for Game {
|
||||
type Result = ();
|
||||
|
||||
fn handle(&mut self, msg: Fire, _ctx: &mut Self::Context) -> Self::Result {
|
||||
log::debug!("FIRE ===> {:?}", msg);
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
use actix::Addr;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::data::GameRules;
|
||||
use crate::game::{Game, Player, SetBoatsLayout};
|
||||
use crate::data::{CurrentGameStatus, GameRules};
|
||||
use crate::game::{Fire, Game, Player, SetBoatsLayout};
|
||||
use crate::human_player_ws::{ClientMessage, HumanPlayerWS, ServerMessage};
|
||||
|
||||
pub struct HumanPlayer {
|
||||
@ -34,6 +34,15 @@ impl Player for HumanPlayer {
|
||||
fn notify_game_starting(&self) {
|
||||
self.player.do_send(ServerMessage::GameStarting);
|
||||
}
|
||||
|
||||
fn request_fire(&self, status: CurrentGameStatus) {
|
||||
self.player.do_send(ServerMessage::RequestFire { status });
|
||||
}
|
||||
|
||||
fn other_player_must_fire(&self, status: CurrentGameStatus) {
|
||||
self.player
|
||||
.do_send(ServerMessage::OtherPlayerMustFire { status });
|
||||
}
|
||||
}
|
||||
|
||||
impl HumanPlayer {
|
||||
@ -45,6 +54,7 @@ impl HumanPlayer {
|
||||
ClientMessage::BoatsLayout { layout } => {
|
||||
self.game.do_send(SetBoatsLayout(self.uuid, layout))
|
||||
}
|
||||
ClientMessage::Fire { location } => self.game.do_send(Fire(self.uuid, location)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use actix_web_actors::ws;
|
||||
use actix_web_actors::ws::{CloseCode, CloseReason, Message, ProtocolError, WebsocketContext};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::data::{BoatsLayout, BotType, GameRules};
|
||||
use crate::data::{BoatsLayout, BotType, Coordinates, CurrentGameStatus, GameRules};
|
||||
use crate::game::{AddPlayer, Game};
|
||||
use crate::human_player::HumanPlayer;
|
||||
use crate::random_bot::RandomBot;
|
||||
@ -24,6 +24,7 @@ pub enum StartMode {
|
||||
pub enum ClientMessage {
|
||||
StopGame,
|
||||
BoatsLayout { layout: BoatsLayout },
|
||||
Fire { location: Coordinates },
|
||||
}
|
||||
|
||||
#[derive(Message)]
|
||||
@ -36,6 +37,8 @@ pub enum ServerMessage {
|
||||
WaitingForOtherPlayerConfiguration,
|
||||
OtherPlayerReady,
|
||||
GameStarting,
|
||||
OtherPlayerMustFire { status: CurrentGameStatus },
|
||||
RequestFire { status: CurrentGameStatus },
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -1,8 +1,8 @@
|
||||
use actix::Addr;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::data::{BoatsLayout, GameRules};
|
||||
use crate::game::{Game, Player, SetBoatsLayout};
|
||||
use crate::data::{BoatsLayout, CurrentGameStatus, GameRules};
|
||||
use crate::game::{Fire, Game, Player, SetBoatsLayout};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct RandomBot {
|
||||
@ -42,4 +42,11 @@ impl Player for RandomBot {
|
||||
fn notify_other_player_ready(&self) {}
|
||||
|
||||
fn notify_game_starting(&self) {}
|
||||
|
||||
fn request_fire(&self, status: CurrentGameStatus) {
|
||||
self.game
|
||||
.do_send(Fire(self.uuid, status.find_valid_random_fire_location()));
|
||||
}
|
||||
|
||||
fn other_player_must_fire(&self, _status: CurrentGameStatus) {}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user