SeaBattle/src/game.rs

84 lines
1.8 KiB
Rust
Raw Normal View History

2022-09-11 14:48:20 +00:00
use std::sync::Arc;
use crate::data::GameRules;
use crate::human_player::HumanPlayer;
use crate::random_bot::RandomBot;
use actix::prelude::*;
use actix::{Actor, Context, Handler};
use uuid::Uuid;
pub trait Player {
fn get_name(&self) -> &str;
fn get_uid(&self) -> Uuid;
fn query_boats_layout(&self, rules: &GameRules);
}
pub enum PlayerWrapper {
Human(Arc<HumanPlayer>),
RandomBot(RandomBot),
}
impl PlayerWrapper {
fn extract(self) -> Arc<dyn Player> {
match self {
PlayerWrapper::Human(h) => h,
PlayerWrapper::RandomBot(r) => Arc::new(r),
}
}
}
#[derive(Default, Eq, PartialEq, Debug, Copy, Clone)]
enum GameStatus {
#[default]
Created,
WaitingForBoatsDisposition,
}
pub struct Game {
rules: GameRules,
players: Vec<Arc<dyn Player>>,
status: GameStatus,
}
impl Game {
pub fn new(rules: GameRules) -> Self {
Self {
rules,
players: vec![],
status: GameStatus::Created,
}
}
/// Once the two player has been registered, the game may start
fn start_game(&mut self) {
assert_eq!(self.status, GameStatus::Created);
self.status = GameStatus::WaitingForBoatsDisposition;
self.players[0].query_boats_layout(&self.rules);
self.players[1].query_boats_layout(&self.rules);
}
}
impl Actor for Game {
type Context = Context<Self>;
}
#[derive(Message)]
#[rtype(result = "()")]
pub struct AddPlayer(pub PlayerWrapper);
impl Handler<AddPlayer> for Game {
type Result = ();
/// Add a new player to the game
fn handle(&mut self, msg: AddPlayer, _ctx: &mut Self::Context) -> Self::Result {
assert!(self.players.len() < 2);
self.players.push(msg.0.extract());
if self.players.len() == 2 {
self.start_game();
}
}
}