roll bot dice
This commit is contained in:
parent
dff9f7f3e1
commit
6ceefe01ab
|
|
@ -5,7 +5,7 @@ use store::{CheckerMove, Color, Dice, GameEvent, GameState, Player, PlayerId, St
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Bot {
|
pub struct Bot {
|
||||||
pub game: GameState,
|
pub game: GameState,
|
||||||
player_id: PlayerId,
|
pub player_id: PlayerId,
|
||||||
color: Color,
|
color: Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,7 +46,8 @@ impl Bot {
|
||||||
|
|
||||||
pub fn consume(&mut self, event: &GameEvent) -> Option<GameEvent> {
|
pub fn consume(&mut self, event: &GameEvent) -> Option<GameEvent> {
|
||||||
self.game.consume(event);
|
self.game.consume(event);
|
||||||
// println!("{:?}", self.game);
|
println!("bot game {:?}", self.game);
|
||||||
|
println!("bot player_id {:?}", self.player_id);
|
||||||
if self.game.active_player_id == self.player_id {
|
if self.game.active_player_id == self.player_id {
|
||||||
return match self.game.turn_stage {
|
return match self.game.turn_stage {
|
||||||
TurnStage::RollDice => Some(GameEvent::Roll {
|
TurnStage::RollDice => Some(GameEvent::Roll {
|
||||||
|
|
@ -60,6 +61,7 @@ impl Bot {
|
||||||
player_id: self.player_id,
|
player_id: self.player_id,
|
||||||
moves: self.choose_move(),
|
moves: self.choose_move(),
|
||||||
}),
|
}),
|
||||||
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use bot::Bot;
|
use bot::Bot;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use store::{CheckerMove, Color, Dice, DiceRoller, GameEvent, GameState, PlayerId};
|
use store::{CheckerMove, Color, Dice, DiceRoller, GameEvent, GameState, PlayerId, TurnStage};
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct AppArgs {
|
pub struct AppArgs {
|
||||||
|
|
@ -43,15 +43,31 @@ impl Game {
|
||||||
|
|
||||||
pub fn consume(&mut self, event: &GameEvent) -> Option<GameEvent> {
|
pub fn consume(&mut self, event: &GameEvent) -> Option<GameEvent> {
|
||||||
if self.state.validate(event) {
|
if self.state.validate(event) {
|
||||||
|
println!("consuming {:?}", event);
|
||||||
self.state.consume(event);
|
self.state.consume(event);
|
||||||
return self
|
// chain all successive bot actions
|
||||||
|
let bot_event = self
|
||||||
.bot
|
.bot
|
||||||
.consume(event)
|
.consume(event)
|
||||||
.map(|evt| self.consume(&evt))
|
.map(|evt| self.consume(&evt))
|
||||||
.flatten();
|
.flatten();
|
||||||
|
// roll dice for bot if needed
|
||||||
|
if self.bot_needs_dice_roll() {
|
||||||
|
let dice = self.dice_roller.roll();
|
||||||
|
return self.consume(&GameEvent::RollResult {
|
||||||
|
player_id: self.bot.player_id,
|
||||||
|
dice,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return bot_event;
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bot_needs_dice_roll(&self) -> bool {
|
||||||
|
self.state.active_player_id == self.bot.player_id
|
||||||
|
&& self.state.turn_stage == TurnStage::RollWaiting
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Application.
|
// Application.
|
||||||
|
|
@ -167,7 +183,7 @@ Rolled dice : 0 & 0
|
||||||
| | | X |
|
| | | X |
|
||||||
| | | X |
|
| | | X |
|
||||||
| | | 15 |
|
| | | 15 |
|
||||||
|----------------------------- | | ------------------------------|
|
|------------------------------ | | -----------------------------|
|
||||||
| | | 15 |
|
| | | 15 |
|
||||||
| | | O |
|
| | | O |
|
||||||
| | | O |
|
| | | O |
|
||||||
|
|
@ -187,11 +203,12 @@ Rolled dice : 0 & 0
|
||||||
#[test]
|
#[test]
|
||||||
fn test_move() {
|
fn test_move() {
|
||||||
let expected = "-------------------------------
|
let expected = "-------------------------------
|
||||||
Rolled dice : 2 & 3
|
Rolled dice : 4 & 6
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
13 14 15 16 17 18 19 20 21 22 23 24
|
13 14 15 16 17 18 19 20 21 22 23 24
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
|
| X | | X X |
|
||||||
| | | X |
|
| | | X |
|
||||||
| | | X |
|
| | | X |
|
||||||
| | | X |
|
| | | X |
|
||||||
|
|
@ -199,9 +216,8 @@ Rolled dice : 2 & 3
|
||||||
| | | X |
|
| | | X |
|
||||||
| | | X |
|
| | | X |
|
||||||
| | | X |
|
| | | X |
|
||||||
| | | X |
|
| | | 13 |
|
||||||
| | | 15 |
|
|------------------------------ | | -----------------------------|
|
||||||
|----------------------------- | | ------------------------------|
|
|
||||||
| | | 13 |
|
| | | 13 |
|
||||||
| | | O |
|
| | | O |
|
||||||
| | | O |
|
| | | O |
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,10 @@ impl CheckerMove {
|
||||||
return Err(Error::FieldInvalid);
|
return Err(Error::FieldInvalid);
|
||||||
}
|
}
|
||||||
// check that the destination is after the origin field
|
// check that the destination is after the origin field
|
||||||
if to < from && to != 0 {
|
// --> not applicable for black moves
|
||||||
return Err(Error::MoveInvalid);
|
// if to < from && to != 0 {
|
||||||
}
|
// return Err(Error::MoveInvalid);
|
||||||
|
// }
|
||||||
Ok(Self { from, to })
|
Ok(Self { from, to })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -188,13 +189,13 @@ impl Board {
|
||||||
.to_owned();
|
.to_owned();
|
||||||
for mut line in upper {
|
for mut line in upper {
|
||||||
// add middle bar
|
// add middle bar
|
||||||
line.replace_range(30..30, "| |");
|
line.replace_range(31..31, "| |");
|
||||||
output = output + " |" + &line + " |\n";
|
output = output + " |" + &line + " |\n";
|
||||||
}
|
}
|
||||||
output = output + " |----------------------------- | | ------------------------------|\n";
|
output = output + " |------------------------------ | | -----------------------------|\n";
|
||||||
for mut line in lower {
|
for mut line in lower {
|
||||||
// add middle bar
|
// add middle bar
|
||||||
line.replace_range(30..30, "| |");
|
line.replace_range(31..31, "| |");
|
||||||
output = output + " |" + &line + " |\n";
|
output = output + " |" + &line + " |\n";
|
||||||
}
|
}
|
||||||
output = output
|
output = output
|
||||||
|
|
@ -345,7 +346,11 @@ impl Board {
|
||||||
if Some(color) != checker_color {
|
if Some(color) != checker_color {
|
||||||
return Err(Error::FieldInvalid);
|
return Err(Error::FieldInvalid);
|
||||||
}
|
}
|
||||||
self.positions[field - 1] -= 1;
|
let unit = match color {
|
||||||
|
Color::White => 1,
|
||||||
|
Color::Black => -1,
|
||||||
|
};
|
||||||
|
self.positions[field - 1] -= unit;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -355,7 +360,11 @@ impl Board {
|
||||||
if None != checker_color && Some(color) != checker_color {
|
if None != checker_color && Some(color) != checker_color {
|
||||||
return Err(Error::FieldInvalid);
|
return Err(Error::FieldInvalid);
|
||||||
}
|
}
|
||||||
self.positions[field - 1] += 1;
|
let unit = match color {
|
||||||
|
Color::White => 1,
|
||||||
|
Color::Black => -1,
|
||||||
|
};
|
||||||
|
self.positions[field - 1] += unit;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ pub enum Stage {
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
pub enum TurnStage {
|
pub enum TurnStage {
|
||||||
RollDice,
|
RollDice,
|
||||||
|
RollWaiting,
|
||||||
MarkPoints,
|
MarkPoints,
|
||||||
Move,
|
Move,
|
||||||
}
|
}
|
||||||
|
|
@ -102,9 +103,10 @@ impl GameState {
|
||||||
|
|
||||||
// step -> 2 bits
|
// step -> 2 bits
|
||||||
let step_bits = match self.turn_stage {
|
let step_bits = match self.turn_stage {
|
||||||
|
TurnStage::RollWaiting => "00",
|
||||||
TurnStage::RollDice => "01",
|
TurnStage::RollDice => "01",
|
||||||
TurnStage::MarkPoints => "01",
|
TurnStage::MarkPoints => "10",
|
||||||
TurnStage::Move => "10",
|
TurnStage::Move => "11",
|
||||||
};
|
};
|
||||||
pos_bits.push_str(step_bits);
|
pos_bits.push_str(step_bits);
|
||||||
|
|
||||||
|
|
@ -288,8 +290,8 @@ impl GameState {
|
||||||
fn moves_follows_dices(&self, color: &Color, moves: &(CheckerMove, CheckerMove)) -> bool {
|
fn moves_follows_dices(&self, color: &Color, moves: &(CheckerMove, CheckerMove)) -> bool {
|
||||||
let (dice1, dice2) = self.dice.values;
|
let (dice1, dice2) = self.dice.values;
|
||||||
let (move1, move2): &(CheckerMove, CheckerMove) = moves.into();
|
let (move1, move2): &(CheckerMove, CheckerMove) = moves.into();
|
||||||
let dist1 = (move1.get_to() - move1.get_from()) as u8;
|
let dist1 = (move1.get_to() as i8 - move1.get_from() as i8).abs() as u8;
|
||||||
let dist2 = (move2.get_to() - move2.get_from()) as u8;
|
let dist2 = (move2.get_to() as i8 - move2.get_from() as i8).abs() as u8;
|
||||||
print!("{}, {}, {}, {}", dist1, dist2, dice1, dice2);
|
print!("{}, {}, {}, {}", dist1, dist2, dice1, dice2);
|
||||||
// basic : same number
|
// basic : same number
|
||||||
if cmp::min(dist1, dist2) != cmp::min(dice1, dice2)
|
if cmp::min(dist1, dist2) != cmp::min(dice1, dice2)
|
||||||
|
|
@ -415,7 +417,9 @@ impl GameState {
|
||||||
PlayerDisconnected { player_id } => {
|
PlayerDisconnected { player_id } => {
|
||||||
self.players.remove(player_id);
|
self.players.remove(player_id);
|
||||||
}
|
}
|
||||||
Roll { player_id: _ } => {}
|
Roll { player_id: _ } => {
|
||||||
|
self.turn_stage = TurnStage::RollWaiting;
|
||||||
|
}
|
||||||
RollResult { player_id: _, dice } => {
|
RollResult { player_id: _, dice } => {
|
||||||
self.dice = *dice;
|
self.dice = *dice;
|
||||||
self.turn_stage = TurnStage::MarkPoints;
|
self.turn_stage = TurnStage::MarkPoints;
|
||||||
|
|
@ -436,6 +440,7 @@ impl GameState {
|
||||||
.find(|id| *id != player_id)
|
.find(|id| *id != player_id)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone();
|
.clone();
|
||||||
|
self.turn_stage = TurnStage::RollDice;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -585,6 +590,13 @@ mod tests {
|
||||||
CheckerMove::new(6, 9).unwrap(),
|
CheckerMove::new(6, 9).unwrap(),
|
||||||
);
|
);
|
||||||
assert!(!state.moves_possible(&Color::White, &moves));
|
assert!(!state.moves_possible(&Color::White, &moves));
|
||||||
|
|
||||||
|
// black moves
|
||||||
|
let moves = (
|
||||||
|
CheckerMove::new(24, 20).unwrap(),
|
||||||
|
CheckerMove::new(20, 19).unwrap(),
|
||||||
|
);
|
||||||
|
assert!(state.moves_possible(&Color::Black, &moves));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue