refact: BotStrategy dyn trait
This commit is contained in:
parent
4ee2b02a41
commit
5762187b04
|
|
@ -1,10 +1,8 @@
|
||||||
mod bot;
|
mod bot;
|
||||||
|
|
||||||
use store::{
|
use store::{CheckerMove, Color, GameEvent, GameState, PlayerId, PointsRules, TurnStage};
|
||||||
CheckerMove, Color, Dice, GameEvent, GameState, Player, PlayerId, PointsRules, Stage, TurnStage,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub trait BotStrategy {
|
pub trait BotStrategy: std::fmt::Debug {
|
||||||
fn get_game(&self) -> &GameState;
|
fn get_game(&self) -> &GameState;
|
||||||
fn get_mut_game(&mut self) -> &mut GameState;
|
fn get_mut_game(&mut self) -> &mut GameState;
|
||||||
fn calculate_points(&self) -> u8;
|
fn calculate_points(&self) -> u8;
|
||||||
|
|
@ -27,18 +25,11 @@ pub struct DefaultStrategy {
|
||||||
impl Default for DefaultStrategy {
|
impl Default for DefaultStrategy {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let game = GameState::default();
|
let game = GameState::default();
|
||||||
let mut strategy = Self {
|
Self {
|
||||||
game,
|
game,
|
||||||
player_id: 2,
|
player_id: 2,
|
||||||
color: Color::Black,
|
color: Color::Black,
|
||||||
};
|
|
||||||
strategy
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl DefaultStrategy {
|
|
||||||
fn new() -> Self {
|
|
||||||
Self::default()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,35 +86,34 @@ impl BotStrategy for DefaultStrategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Bot<BotStrategy> {
|
pub struct Bot {
|
||||||
pub player_id: PlayerId,
|
pub player_id: PlayerId,
|
||||||
strategy: BotStrategy,
|
strategy: Box<dyn BotStrategy>,
|
||||||
color: Color,
|
// color: Color,
|
||||||
schools_enabled: bool,
|
// schools_enabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Bot<DefaultStrategy> {
|
impl Default for Bot {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
let strategy = DefaultStrategy::default();
|
||||||
Self {
|
Self {
|
||||||
player_id: 2,
|
player_id: 2,
|
||||||
strategy: DefaultStrategy::default(),
|
strategy: Box::new(strategy),
|
||||||
color: Color::Black,
|
// color: Color::Black,
|
||||||
schools_enabled: false,
|
// schools_enabled: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<BS> Bot<BS>
|
impl Bot {
|
||||||
where
|
|
||||||
BS: BotStrategy,
|
|
||||||
{
|
|
||||||
/// new initialize a bot
|
/// new initialize a bot
|
||||||
/// # Examples
|
/// # Examples
|
||||||
/// ```let mut bot = Bot::new(Color::Black);
|
/// ```let mut bot = Bot::new(Color::Black);
|
||||||
/// assert_eq!(bot.game.stage, Stage::PreGame);
|
/// assert_eq!(bot.game.stage, Stage::PreGame);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn new(mut strategy: BS, color: Color, schools_enabled: bool) -> Self {
|
// pub fn new(mut strategy: Box<dyn BotStrategy>, color: Color, schools_enabled: bool) -> Self {
|
||||||
let game = strategy.get_mut_game();
|
pub fn new(mut strategy: Box<dyn BotStrategy>, color: Color) -> Self {
|
||||||
|
// let game = strategy.get_mut_game();
|
||||||
strategy.init_players();
|
strategy.init_players();
|
||||||
let player_id = match color {
|
let player_id = match color {
|
||||||
Color::White => 1,
|
Color::White => 1,
|
||||||
|
|
@ -133,8 +123,8 @@ where
|
||||||
Self {
|
Self {
|
||||||
player_id,
|
player_id,
|
||||||
strategy,
|
strategy,
|
||||||
color,
|
// color,
|
||||||
schools_enabled: false,
|
// schools_enabled: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -174,16 +164,19 @@ where
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use store::{Dice, Stage};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_new() {
|
fn test_new() {
|
||||||
let bot = Bot::new(DefaultStrategy::new(), Color::Black, false);
|
let bot = Bot::new(Box::new(DefaultStrategy::default()), Color::Black);
|
||||||
|
// let bot = Bot::new(Box::new(DefaultStrategy::default()), Color::Black, false);
|
||||||
assert_eq!(bot.get_state().stage, Stage::PreGame);
|
assert_eq!(bot.get_state().stage, Stage::PreGame);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_consume() {
|
fn test_consume() {
|
||||||
let mut bot = Bot::new(DefaultStrategy::new(), Color::Black, false);
|
let mut bot = Bot::new(Box::new(DefaultStrategy::default()), Color::Black);
|
||||||
|
// let mut bot = Bot::new(Box::new(DefaultStrategy::default()), Color::Black, false);
|
||||||
let mut event = bot.handle_event(&GameEvent::BeginGame { goes_first: 2 });
|
let mut event = bot.handle_event(&GameEvent::BeginGame { goes_first: 2 });
|
||||||
assert_eq!(event, Some(GameEvent::Roll { player_id: 2 }));
|
assert_eq!(event, Some(GameEvent::Roll { player_id: 2 }));
|
||||||
assert_eq!(bot.get_state().active_player_id, 2);
|
assert_eq!(bot.get_state().active_player_id, 2);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use crate::game_runner::Game;
|
use crate::game_runner::Game;
|
||||||
use bot::BotStrategy;
|
use store::{CheckerMove, GameEvent, GameState, Stage, TurnStage};
|
||||||
use store::{CheckerMove, GameEvent, GameState, PointsRules, Stage, TurnStage};
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct AppArgs {
|
pub struct AppArgs {
|
||||||
|
|
@ -73,15 +72,15 @@ impl App {
|
||||||
let dice = self.game.dice_roller.roll();
|
let dice = self.game.dice_roller.roll();
|
||||||
|
|
||||||
// get correct points for these board and dice
|
// get correct points for these board and dice
|
||||||
let points_rules = PointsRules::new(
|
// let points_rules = PointsRules::new(
|
||||||
&self
|
// &self
|
||||||
.game
|
// .game
|
||||||
.state
|
// .state
|
||||||
.player_color_by_id(&self.game.player_id.unwrap())
|
// .player_color_by_id(&self.game.player_id.unwrap())
|
||||||
.unwrap(),
|
// .unwrap(),
|
||||||
&self.game.state.board,
|
// &self.game.state.board,
|
||||||
dice,
|
// dice,
|
||||||
);
|
// );
|
||||||
self.game.handle_event(&GameEvent::RollResult {
|
self.game.handle_event(&GameEvent::RollResult {
|
||||||
player_id: self.game.player_id.unwrap(),
|
player_id: self.game.player_id.unwrap(),
|
||||||
dice,
|
dice,
|
||||||
|
|
@ -191,10 +190,10 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use pretty_assertions::assert_eq;
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_display() {
|
fn test_display() {
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,14 @@
|
||||||
use bot::{Bot, BotStrategy, DefaultStrategy};
|
use bot::{Bot, DefaultStrategy};
|
||||||
use store::{CheckerMove, DiceRoller, GameEvent, GameState, PlayerId, TurnStage};
|
use store::{CheckerMove, DiceRoller, GameEvent, GameState, PlayerId, TurnStage};
|
||||||
|
|
||||||
// Application Game
|
// Application Game
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Game {
|
pub struct Game {
|
||||||
pub state: GameState,
|
pub state: GameState,
|
||||||
pub dice_roller: DiceRoller,
|
pub dice_roller: DiceRoller,
|
||||||
pub first_move: Option<CheckerMove>,
|
pub first_move: Option<CheckerMove>,
|
||||||
pub player_id: Option<PlayerId>,
|
pub player_id: Option<PlayerId>,
|
||||||
bot: Bot<DefaultStrategy>,
|
bot: Bot,
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Game {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
state: GameState::default(),
|
|
||||||
dice_roller: DiceRoller::default(),
|
|
||||||
first_move: None,
|
|
||||||
player_id: None,
|
|
||||||
bot: Bot::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Game {
|
impl Game {
|
||||||
|
|
@ -32,8 +20,9 @@ impl Game {
|
||||||
// bot
|
// bot
|
||||||
let bot_id: PlayerId = state.init_player("bot").unwrap();
|
let bot_id: PlayerId = state.init_player("bot").unwrap();
|
||||||
let bot_color = state.player_color_by_id(&bot_id).unwrap();
|
let bot_color = state.player_color_by_id(&bot_id).unwrap();
|
||||||
let bot_strategy = DefaultStrategy::default();
|
let bot_strategy = Box::new(DefaultStrategy::default());
|
||||||
let bot: Bot<DefaultStrategy> = Bot::new(bot_strategy, bot_color, schools_enabled);
|
// let bot: Bot = Bot::new(bot_strategy, bot_color, schools_enabled);
|
||||||
|
let bot: Bot = Bot::new(bot_strategy, bot_color);
|
||||||
|
|
||||||
let mut game = Self {
|
let mut game = Self {
|
||||||
state,
|
state,
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,6 @@ pub fn render(app: &mut App, f: &mut Frame) {
|
||||||
)
|
)
|
||||||
.style(Style::default().fg(Color::Yellow))
|
.style(Style::default().fg(Color::Yellow))
|
||||||
.alignment(Alignment::Center),
|
.alignment(Alignment::Center),
|
||||||
f.size(),
|
f.area(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -310,7 +310,7 @@ impl Board {
|
||||||
/// Check if a field is blocked for a player
|
/// Check if a field is blocked for a player
|
||||||
pub fn blocked(&self, color: &Color, field: Field) -> Result<bool, Error> {
|
pub fn blocked(&self, color: &Color, field: Field) -> Result<bool, Error> {
|
||||||
// the square is blocked on the opponent rest corner
|
// the square is blocked on the opponent rest corner
|
||||||
let opp_corner_field = if color == &Color::White { 13 } else { 12 };
|
// let opp_corner_field = if color == &Color::White { 13 } else { 12 };
|
||||||
self.passage_blocked(color, field)
|
self.passage_blocked(color, field)
|
||||||
// .map(|blocked| blocked || opp_corner_field == field)
|
// .map(|blocked| blocked || opp_corner_field == field)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
use crate::Error;
|
|
||||||
use rand::distributions::{Distribution, Uniform};
|
use rand::distributions::{Distribution, Uniform};
|
||||||
use rand::{rngs::StdRng, SeedableRng};
|
use rand::{rngs::StdRng, SeedableRng};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
@ -76,12 +75,6 @@ impl Dice {
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait to roll the dices
|
|
||||||
pub trait Roll {
|
|
||||||
/// Roll the dices
|
|
||||||
fn roll(&mut self) -> &mut Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue