SeaBattle/src/game.rs

71 lines
1.5 KiB
Rust

use std::sync::Arc;
use crate::data::GameRules;
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);
}
#[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 query_boats_disposition(&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<E>(pub E);
impl<E> Handler<AddPlayer<Arc<E>>> for Game
where
E: Player + 'static,
{
type Result = ();
/// Add a new player to the game
fn handle(&mut self, msg: AddPlayer<Arc<E>>, _ctx: &mut Self::Context) -> Self::Result {
assert!(self.players.len() < 2);
self.players.push(msg.0);
if self.players.len() == 2 {
self.query_boats_disposition();
}
}
}