use actix::Addr; use uuid::Uuid; use crate::data::{BoatsLayout, Coordinates, CurrentGameStatus, FireResult, GameRules}; use crate::game::{Fire, Game, Player, RespondRequestRematch, SetBoatsLayout}; #[derive(Clone)] pub struct IntermediateBot { game: Addr, uuid: Uuid, } impl IntermediateBot { pub fn new(game: Addr) -> Self { Self { game, uuid: Uuid::new_v4(), } } } impl Player for IntermediateBot { fn get_name(&self) -> &str { "Intermediate Bot" } fn get_uid(&self) -> Uuid { self.uuid } fn is_bot(&self) -> bool { true } 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)), Err(e) => log::error!( "Failed to use game rules to construct boats layout: {:?}", e ), } } fn rejected_boats_layout(&self, _errors: Vec<&'static str>) { unreachable!() } fn notify_other_player_ready(&self) {} fn notify_game_starting(&self) {} fn request_fire(&self, status: CurrentGameStatus) { let coordinates = status .continue_attack_boat() .unwrap_or_else(|| status.find_valid_random_fire_location()); self.game.do_send(Fire(self.uuid, coordinates)); } fn opponent_must_fire(&self, _status: CurrentGameStatus) {} fn strike_result(&self, _c: Coordinates, _res: FireResult) {} fn other_player_strike_result(&self, _c: Coordinates, _res: FireResult) {} fn lost_game(&self, _status: CurrentGameStatus) {} fn won_game(&self, _status: CurrentGameStatus) {} fn opponent_requested_rematch(&self) { self.game.do_send(RespondRequestRematch(self.uuid, true)); } fn opponent_rejected_rematch(&self) {} fn opponent_accepted_rematch(&self) {} fn opponent_left_game(&self) { // Human are not reliable lol } fn opponent_replaced_by_bot(&self) { // Not such a good idea. will panic, just in case panic!("Bot shall not play against each other (it is completely useless)"); } }