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::OtherPlayerReady => log::debug!("Other player is ready!"),
|
||||||
ServerMessage::GameStarting => log::debug!("The game is starting..."),
|
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 boats_layout::*;
|
||||||
|
pub use current_game_status::*;
|
||||||
pub use game_map::*;
|
pub use game_map::*;
|
||||||
pub use game_rules::*;
|
pub use game_rules::*;
|
||||||
pub use play_config::*;
|
pub use play_config::*;
|
||||||
|
|
||||||
mod boats_layout;
|
mod boats_layout;
|
||||||
|
mod current_game_status;
|
||||||
mod game_map;
|
mod game_map;
|
||||||
mod game_rules;
|
mod game_rules;
|
||||||
mod play_config;
|
mod play_config;
|
||||||
|
43
src/game.rs
43
src/game.rs
@ -4,7 +4,7 @@ use actix::prelude::*;
|
|||||||
use actix::{Actor, Context, Handler};
|
use actix::{Actor, Context, Handler};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::data::{BoatsLayout, GameMap, GameRules};
|
use crate::data::*;
|
||||||
|
|
||||||
pub trait Player {
|
pub trait Player {
|
||||||
fn get_name(&self) -> &str;
|
fn get_name(&self) -> &str;
|
||||||
@ -16,6 +16,10 @@ pub trait Player {
|
|||||||
fn notify_other_player_ready(&self);
|
fn notify_other_player_ready(&self);
|
||||||
|
|
||||||
fn notify_game_starting(&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 {
|
fn opponent(index: usize) -> usize {
|
||||||
@ -40,6 +44,7 @@ pub struct Game {
|
|||||||
status: GameStatus,
|
status: GameStatus,
|
||||||
map_0: Option<GameMap>,
|
map_0: Option<GameMap>,
|
||||||
map_1: Option<GameMap>,
|
map_1: Option<GameMap>,
|
||||||
|
turn: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Game {
|
impl Game {
|
||||||
@ -50,6 +55,7 @@ impl Game {
|
|||||||
status: GameStatus::Created,
|
status: GameStatus::Created,
|
||||||
map_0: None,
|
map_0: None,
|
||||||
map_1: None,
|
map_1: None,
|
||||||
|
turn: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +81,22 @@ impl Game {
|
|||||||
/// Start fires exchange
|
/// Start fires exchange
|
||||||
fn start_fire_exchanges(&mut self) {
|
fn start_fire_exchanges(&mut self) {
|
||||||
self.status = GameStatus::Started;
|
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
|
/// Receive game configuration of a player
|
||||||
fn handle(&mut self, msg: SetBoatsLayout, _ctx: &mut Self::Context) -> Self::Result {
|
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);
|
let player_index = self.player_id_by_uuid(msg.0);
|
||||||
log::debug!("Got boat disposition for player {}", player_index);
|
log::debug!("Got boat disposition for player {}", player_index);
|
||||||
match 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 actix::Addr;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::data::GameRules;
|
use crate::data::{CurrentGameStatus, GameRules};
|
||||||
use crate::game::{Game, Player, SetBoatsLayout};
|
use crate::game::{Fire, Game, Player, SetBoatsLayout};
|
||||||
use crate::human_player_ws::{ClientMessage, HumanPlayerWS, ServerMessage};
|
use crate::human_player_ws::{ClientMessage, HumanPlayerWS, ServerMessage};
|
||||||
|
|
||||||
pub struct HumanPlayer {
|
pub struct HumanPlayer {
|
||||||
@ -34,6 +34,15 @@ impl Player for HumanPlayer {
|
|||||||
fn notify_game_starting(&self) {
|
fn notify_game_starting(&self) {
|
||||||
self.player.do_send(ServerMessage::GameStarting);
|
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 {
|
impl HumanPlayer {
|
||||||
@ -45,6 +54,7 @@ impl HumanPlayer {
|
|||||||
ClientMessage::BoatsLayout { layout } => {
|
ClientMessage::BoatsLayout { layout } => {
|
||||||
self.game.do_send(SetBoatsLayout(self.uuid, 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 actix_web_actors::ws::{CloseCode, CloseReason, Message, ProtocolError, WebsocketContext};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::data::{BoatsLayout, BotType, GameRules};
|
use crate::data::{BoatsLayout, BotType, Coordinates, CurrentGameStatus, GameRules};
|
||||||
use crate::game::{AddPlayer, Game};
|
use crate::game::{AddPlayer, Game};
|
||||||
use crate::human_player::HumanPlayer;
|
use crate::human_player::HumanPlayer;
|
||||||
use crate::random_bot::RandomBot;
|
use crate::random_bot::RandomBot;
|
||||||
@ -24,6 +24,7 @@ pub enum StartMode {
|
|||||||
pub enum ClientMessage {
|
pub enum ClientMessage {
|
||||||
StopGame,
|
StopGame,
|
||||||
BoatsLayout { layout: BoatsLayout },
|
BoatsLayout { layout: BoatsLayout },
|
||||||
|
Fire { location: Coordinates },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Message)]
|
#[derive(Message)]
|
||||||
@ -36,6 +37,8 @@ pub enum ServerMessage {
|
|||||||
WaitingForOtherPlayerConfiguration,
|
WaitingForOtherPlayerConfiguration,
|
||||||
OtherPlayerReady,
|
OtherPlayerReady,
|
||||||
GameStarting,
|
GameStarting,
|
||||||
|
OtherPlayerMustFire { status: CurrentGameStatus },
|
||||||
|
RequestFire { status: CurrentGameStatus },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use actix::Addr;
|
use actix::Addr;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::data::{BoatsLayout, GameRules};
|
use crate::data::{BoatsLayout, CurrentGameStatus, GameRules};
|
||||||
use crate::game::{Game, Player, SetBoatsLayout};
|
use crate::game::{Fire, Game, Player, SetBoatsLayout};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct RandomBot {
|
pub struct RandomBot {
|
||||||
@ -42,4 +42,11 @@ impl Player for RandomBot {
|
|||||||
fn notify_other_player_ready(&self) {}
|
fn notify_other_player_ready(&self) {}
|
||||||
|
|
||||||
fn notify_game_starting(&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