Use common structures for game phases
This commit is contained in:
parent
0e1381c15f
commit
1c8ffb151c
148
src/lib.rs
148
src/lib.rs
@ -258,22 +258,18 @@ impl Game {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn action_challenge(&mut self, action_challenge: phase::ActionChallenge, agents: &[&dyn Agent]) -> CoupResult<Phase> {
|
pub fn action_challenge(&mut self, move_: Move, agents: &[&dyn Agent]) -> CoupResult<Phase> {
|
||||||
let block = Phase::Block(phase::Block {
|
match move_.action.challenger_mode() {
|
||||||
action: action_challenge.action,
|
ResMode::None => Ok(Phase::Block(move_)),
|
||||||
target: action_challenge.target,
|
|
||||||
});
|
|
||||||
match action_challenge.action.challenger_mode() {
|
|
||||||
ResMode::None => Ok(block),
|
|
||||||
ResMode::Target => unreachable!(),
|
ResMode::Target => unreachable!(),
|
||||||
ResMode::Anyone => {
|
ResMode::Anyone => {
|
||||||
let challenger = self.turn_iterator().find(|&id| agents[id].should_action_challenge(self, &action_challenge));
|
let challenger = self.turn_iterator().find(|&id| agents[id].should_action_challenge(self, move_));
|
||||||
if let Some(challenger) = challenger{
|
if let Some(challenger) = challenger{
|
||||||
let current_player_wins = self.players[self.turn].wins_challenge(action_challenge.action);
|
let current_player_wins = self.players[self.turn].wins_challenge(move_.action);
|
||||||
if current_player_wins {
|
if current_player_wins {
|
||||||
// Challenger loses influence
|
// Challenger loses influence
|
||||||
self.player_lose_influence(challenger, agents)?;
|
self.player_lose_influence(challenger, agents)?;
|
||||||
Ok(block)
|
Ok(Phase::Block(move_))
|
||||||
} else {
|
} else {
|
||||||
// Player loses influence
|
// Player loses influence
|
||||||
self.player_lose_influence(self.turn, agents)?;
|
self.player_lose_influence(self.turn, agents)?;
|
||||||
@ -281,73 +277,57 @@ impl Game {
|
|||||||
Ok(Phase::Done)
|
Ok(Phase::Done)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(block)
|
Ok(Phase::Block(move_))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn block(&mut self, block: phase::Block, agents: &[&dyn Agent]) -> CoupResult<Phase> {
|
pub fn block(&mut self, move_: Move, agents: &[&dyn Agent]) -> CoupResult<Phase> {
|
||||||
match block.action.blocker_mode() {
|
match move_.action.blocker_mode() {
|
||||||
ResMode::None => Ok(Phase::Resolution(phase::Resolution {
|
ResMode::None => Ok(Phase::Resolution(move_)),
|
||||||
action: block.action,
|
ResMode::Target => match agents[move_.target.unwrap()].choose_block_card(self, move_) {
|
||||||
target: block.target,
|
|
||||||
})),
|
|
||||||
ResMode::Target => match agents[block.target.unwrap()].choose_block_card(self, &block) {
|
|
||||||
Some(card) => {
|
Some(card) => {
|
||||||
if card.blocks_action(block.action) {
|
if card.blocks_action(move_.action) {
|
||||||
Ok(Phase::BlockChallenge(phase::BlockChallenge {
|
Ok(Phase::BlockChallenge(move_, Block {
|
||||||
blocker: block.target.unwrap(),
|
blocker: move_.target.unwrap(),
|
||||||
block_card: card,
|
card,
|
||||||
action: block.action,
|
|
||||||
target: block.target,
|
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
Err("Card does not block action")
|
Err("Card does not block action")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => Ok(Phase::Resolution(phase::Resolution {
|
None => Ok(Phase::Resolution(move_)),
|
||||||
action: block.action,
|
|
||||||
target: block.target,
|
|
||||||
})),
|
|
||||||
}
|
}
|
||||||
ResMode::Anyone => {
|
ResMode::Anyone => {
|
||||||
for id in self.turn_iterator() {
|
for id in self.turn_iterator() {
|
||||||
if let Some(card) = agents[id].choose_block_card(self, &block) {
|
if let Some(card) = agents[id].choose_block_card(self, move_) {
|
||||||
if card.blocks_action(block.action) {
|
if card.blocks_action(move_.action) {
|
||||||
return Ok(Phase::BlockChallenge(phase::BlockChallenge {
|
return Ok(Phase::BlockChallenge(move_, Block {
|
||||||
blocker: id,
|
blocker: id,
|
||||||
block_card: card,
|
card,
|
||||||
action: block.action,
|
|
||||||
target: block.target,
|
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
return Err("Card does not block action")
|
return Err("Card does not block action")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Phase::Resolution(phase::Resolution {
|
Ok(Phase::Resolution(move_))
|
||||||
action: block.action,
|
|
||||||
target: block.target,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn block_challenge(&mut self, block_challenge: phase::BlockChallenge, agents: &[&dyn Agent]) -> CoupResult<Phase> {
|
pub fn block_challenge(&mut self, move_: Move, block: Block, agents: &[&dyn Agent]) -> CoupResult<Phase> {
|
||||||
if agents[self.turn].should_block_challenge(self, &block_challenge) {
|
if agents[self.turn].should_block_challenge(self, move_, block) {
|
||||||
if self.players[block_challenge.blocker].holds(block_challenge.block_card) {
|
if self.players[block.blocker].holds(block.card) {
|
||||||
// Player challenged incorrectly, loses influence and turn is forfeit
|
// Player challenged incorrectly, loses influence and turn is forfeit
|
||||||
self.player_lose_influence(self.turn, agents)?;
|
self.player_lose_influence(self.turn, agents)?;
|
||||||
Ok(Phase::Done)
|
Ok(Phase::Done)
|
||||||
} else {
|
} else {
|
||||||
// Player challenged correctly, blocker loses a card
|
// Player challenged correctly, blocker loses a card
|
||||||
self.player_lose_influence(block_challenge.blocker, agents)?;
|
self.player_lose_influence(block.blocker, agents)?;
|
||||||
// Game continues
|
// Game continues
|
||||||
Ok(Phase::Resolution(phase::Resolution {
|
Ok(Phase::Resolution(move_))
|
||||||
action: block_challenge.action,
|
|
||||||
target: block_challenge.target,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Player chose not to challenge the block, turn is forfeit
|
// Player chose not to challenge the block, turn is forfeit
|
||||||
@ -356,11 +336,11 @@ impl Game {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolution(&mut self, resolution: phase::Resolution, agents: &[&dyn Agent]) -> CoupResult<Phase> {
|
pub fn resolution(&mut self, move_: Move, agents: &[&dyn Agent]) -> CoupResult<Phase> {
|
||||||
match resolution.action {
|
match move_.action {
|
||||||
Income => self.players[self.turn].coins += 1,
|
Income => self.players[self.turn].coins += 1,
|
||||||
ForeignAid => self.players[self.turn].coins += 2,
|
ForeignAid => self.players[self.turn].coins += 2,
|
||||||
Coup | Assassinate => match resolution.target {
|
Coup | Assassinate => match move_.target {
|
||||||
Some(target) => {
|
Some(target) => {
|
||||||
// Target may have died from challenge
|
// Target may have died from challenge
|
||||||
let target_alive = self.players[target].is_alive();
|
let target_alive = self.players[target].is_alive();
|
||||||
@ -386,7 +366,7 @@ impl Game {
|
|||||||
self.players[self.turn].cards = choices;
|
self.players[self.turn].cards = choices;
|
||||||
self.deck.shuffle();
|
self.deck.shuffle();
|
||||||
}
|
}
|
||||||
Steal => match resolution.target {
|
Steal => match move_.target {
|
||||||
Some(target) => {
|
Some(target) => {
|
||||||
let val = self.players[target].coins.min(2);
|
let val = self.players[target].coins.min(2);
|
||||||
self.players[self.turn].coins += val;
|
self.players[self.turn].coins += val;
|
||||||
@ -401,61 +381,41 @@ impl Game {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod phase {
|
#[derive(PartialEq, Debug, Clone, Copy)]
|
||||||
//! Structures relating to game phases.
|
pub struct Move {
|
||||||
//!
|
pub action: Action,
|
||||||
//! Coup turns have 5 phases, depending on what actions are taken each phase
|
pub target: Option<usize>,
|
||||||
//! some phases might be skipped. These structures marshal information
|
}
|
||||||
//! between the phases.
|
|
||||||
use super::{ Card, Action };
|
#[derive(PartialEq, Debug, Clone, Copy)]
|
||||||
|
pub struct Block {
|
||||||
|
pub blocker: usize,
|
||||||
|
pub card: Card,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Phase we should move to.
|
||||||
|
///
|
||||||
|
/// Coup turns have 5 phases, depending on what actions are taken each phase
|
||||||
|
/// some phases might be skipped.
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub enum Phase {
|
pub enum Phase {
|
||||||
Action(Action),
|
Action(Move),
|
||||||
ActionChallenge(ActionChallenge),
|
ActionChallenge(Move),
|
||||||
Block(Block),
|
Block(Move),
|
||||||
BlockChallenge(BlockChallenge),
|
BlockChallenge(Move, Block),
|
||||||
Resolution(Resolution),
|
Resolution(Move),
|
||||||
Done,
|
Done,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
|
||||||
pub struct ActionChallenge {
|
|
||||||
pub action: Action,
|
|
||||||
pub target: Option<usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
|
||||||
pub struct Block {
|
|
||||||
pub action: Action,
|
|
||||||
pub target: Option<usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
|
||||||
pub struct BlockChallenge {
|
|
||||||
pub blocker: usize,
|
|
||||||
pub block_card: Card,
|
|
||||||
pub action: Action,
|
|
||||||
pub target: Option<usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
|
||||||
pub struct Resolution {
|
|
||||||
pub action: Action,
|
|
||||||
pub target: Option<usize>,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
use phase::Phase;
|
|
||||||
|
|
||||||
/// An interface to a game to make strategic decisions.
|
/// An interface to a game to make strategic decisions.
|
||||||
pub trait Agent : fmt::Debug {
|
pub trait Agent : fmt::Debug {
|
||||||
/// Should the agent challenge the action?
|
/// Should the agent challenge the action?
|
||||||
fn should_action_challenge(&self, game: &Game, action_challenge: &phase::ActionChallenge) -> bool;
|
fn should_action_challenge(&self, game: &Game, move_: Move) -> bool;
|
||||||
/// Which [card](Card) the agent wishes to use to block the current action.
|
/// Which [card](Card) the agent wishes to use to block the current action.
|
||||||
/// If the agent does not wish to block, it should return [None]
|
/// If the agent does not wish to block, it should return [None]
|
||||||
fn choose_block_card(&self, game: &Game, block: &phase::Block) -> Option<Card>;
|
fn choose_block_card(&self, game: &Game, move_: Move) -> Option<Card>;
|
||||||
/// Should the agent challenge the block?
|
/// Should the agent challenge the block?
|
||||||
fn should_block_challenge(&self, game: &Game, block_challenge: &phase::BlockChallenge) -> bool;
|
fn should_block_challenge(&self, game: &Game, move_: Move, block: Block) -> bool;
|
||||||
/// The [Ambassador]'s exchange.
|
/// The [Ambassador]'s exchange.
|
||||||
/// Given 3 or 4 [Cards](Card) the agent must return two cards to the deck.
|
/// Given 3 or 4 [Cards](Card) the agent must return two cards to the deck.
|
||||||
fn exchange(&self, game: &Game, cards: &[Card]) -> [Card; 2];
|
fn exchange(&self, game: &Game, cards: &[Card]) -> [Card; 2];
|
||||||
|
111
src/test.rs
111
src/test.rs
@ -3,13 +3,13 @@ use super::*;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct DummyAgent(Card, Option<Card>, bool);
|
struct DummyAgent(Card, Option<Card>, bool);
|
||||||
impl Agent for DummyAgent {
|
impl Agent for DummyAgent {
|
||||||
fn should_action_challenge(&self, _game: &Game, _action_challenge: &phase::ActionChallenge) -> bool {
|
fn should_action_challenge(&self, _game: &Game, _move: Move) -> bool {
|
||||||
self.2
|
self.2
|
||||||
}
|
}
|
||||||
fn choose_block_card(&self, _game: &Game, _block: &phase::Block) -> Option<Card> {
|
fn choose_block_card(&self, _game: &Game, _move: Move) -> Option<Card> {
|
||||||
self.1
|
self.1
|
||||||
}
|
}
|
||||||
fn should_block_challenge(&self, _game: &Game, _block_challenge: &phase::BlockChallenge) -> bool {
|
fn should_block_challenge(&self, _game: &Game, _move: Move, _block: Block) -> bool {
|
||||||
self.2
|
self.2
|
||||||
}
|
}
|
||||||
fn exchange(&self, _game: &Game, _cards: &[Card]) -> [Card; 2] {
|
fn exchange(&self, _game: &Game, _cards: &[Card]) -> [Card; 2] {
|
||||||
@ -42,11 +42,11 @@ fn test_action_challenge() {
|
|||||||
{
|
{
|
||||||
let mut game = game.clone();
|
let mut game = game.clone();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
game.action_challenge(phase::ActionChallenge {
|
game.action_challenge(Move {
|
||||||
action: Income,
|
action: Income,
|
||||||
target: None,
|
target: None,
|
||||||
}, &[&challenge_agent, &challenge_agent, &challenge_agent]),
|
}, &[&challenge_agent, &challenge_agent, &challenge_agent]),
|
||||||
Ok(Phase::Block(phase::Block {
|
Ok(Phase::Block(Move {
|
||||||
action: Income,
|
action: Income,
|
||||||
target: None
|
target: None
|
||||||
}))
|
}))
|
||||||
@ -57,11 +57,11 @@ fn test_action_challenge() {
|
|||||||
{
|
{
|
||||||
let mut game = game.clone();
|
let mut game = game.clone();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
game.action_challenge(phase::ActionChallenge {
|
game.action_challenge(Move {
|
||||||
action: Steal,
|
action: Steal,
|
||||||
target: Some(2),
|
target: Some(2),
|
||||||
}, &[&challenge_agent, &challenge_agent, &challenge_agent]),
|
}, &[&challenge_agent, &challenge_agent, &challenge_agent]),
|
||||||
Ok(Phase::Block(phase::Block {
|
Ok(Phase::Block(Move {
|
||||||
action: Steal,
|
action: Steal,
|
||||||
target: Some(2)
|
target: Some(2)
|
||||||
}))
|
}))
|
||||||
@ -72,7 +72,7 @@ fn test_action_challenge() {
|
|||||||
{
|
{
|
||||||
let mut game = game.clone();
|
let mut game = game.clone();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
game.action_challenge(phase::ActionChallenge {
|
game.action_challenge(Move {
|
||||||
action: Assassinate,
|
action: Assassinate,
|
||||||
target: Some(2),
|
target: Some(2),
|
||||||
}, &[&non_challenge_agent, &challenge_agent, &challenge_agent]),
|
}, &[&non_challenge_agent, &challenge_agent, &challenge_agent]),
|
||||||
@ -106,11 +106,11 @@ fn test_block() {
|
|||||||
{
|
{
|
||||||
let mut game = game.clone();
|
let mut game = game.clone();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
game.block(phase::Block {
|
game.block(Move {
|
||||||
action: Income,
|
action: Income,
|
||||||
target: None,
|
target: None,
|
||||||
}, &[&non_blocking_agent, &ambassador_block_agent, &ambassador_block_agent]),
|
}, &[&non_blocking_agent, &ambassador_block_agent, &ambassador_block_agent]),
|
||||||
Ok(Phase::Resolution(phase::Resolution {
|
Ok(Phase::Resolution(Move {
|
||||||
action: Income,
|
action: Income,
|
||||||
target: None
|
target: None
|
||||||
}))
|
}))
|
||||||
@ -121,16 +121,20 @@ fn test_block() {
|
|||||||
{
|
{
|
||||||
let mut game = game.clone();
|
let mut game = game.clone();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
game.block(phase::Block {
|
game.block(Move {
|
||||||
action: Steal,
|
action: Steal,
|
||||||
target: Some(2),
|
target: Some(2),
|
||||||
}, &[&non_blocking_agent, &ambassador_block_agent, &ambassador_block_agent]),
|
}, &[&non_blocking_agent, &ambassador_block_agent, &ambassador_block_agent]),
|
||||||
Ok(Phase::BlockChallenge(phase::BlockChallenge {
|
Ok(Phase::BlockChallenge(
|
||||||
blocker: 2,
|
Move {
|
||||||
block_card: Ambassador,
|
|
||||||
action: Steal,
|
action: Steal,
|
||||||
target: Some(2),
|
target: Some(2),
|
||||||
}))
|
},
|
||||||
|
Block {
|
||||||
|
blocker: 2,
|
||||||
|
card: Ambassador,
|
||||||
|
},
|
||||||
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,11 +142,11 @@ fn test_block() {
|
|||||||
{
|
{
|
||||||
let mut game = game.clone();
|
let mut game = game.clone();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
game.block(phase::Block {
|
game.block(Move {
|
||||||
action: Steal,
|
action: Steal,
|
||||||
target: Some(2),
|
target: Some(2),
|
||||||
}, &[&non_blocking_agent, &ambassador_block_agent, &non_blocking_agent]),
|
}, &[&non_blocking_agent, &ambassador_block_agent, &non_blocking_agent]),
|
||||||
Ok(Phase::Resolution(phase::Resolution {
|
Ok(Phase::Resolution(Move {
|
||||||
action: Steal,
|
action: Steal,
|
||||||
target: Some(2),
|
target: Some(2),
|
||||||
}))
|
}))
|
||||||
@ -153,16 +157,20 @@ fn test_block() {
|
|||||||
{
|
{
|
||||||
let mut game = game.clone();
|
let mut game = game.clone();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
game.block(phase::Block {
|
game.block(Move {
|
||||||
action: ForeignAid,
|
action: ForeignAid,
|
||||||
target: None,
|
target: None,
|
||||||
}, &[&non_blocking_agent, &non_blocking_agent, &duke_block_agent]),
|
}, &[&non_blocking_agent, &non_blocking_agent, &duke_block_agent]),
|
||||||
Ok(Phase::BlockChallenge(phase::BlockChallenge {
|
Ok(Phase::BlockChallenge(
|
||||||
blocker: 2,
|
Move {
|
||||||
block_card: Duke,
|
|
||||||
action: ForeignAid,
|
action: ForeignAid,
|
||||||
target: None,
|
target: None,
|
||||||
}))
|
},
|
||||||
|
Block {
|
||||||
|
blocker: 2,
|
||||||
|
card: Duke,
|
||||||
|
},
|
||||||
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,11 +178,11 @@ fn test_block() {
|
|||||||
{
|
{
|
||||||
let mut game = game.clone();
|
let mut game = game.clone();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
game.block(phase::Block {
|
game.block(Move {
|
||||||
action: ForeignAid,
|
action: ForeignAid,
|
||||||
target: None,
|
target: None,
|
||||||
}, &[&non_blocking_agent, &non_blocking_agent, &non_blocking_agent]),
|
}, &[&non_blocking_agent, &non_blocking_agent, &non_blocking_agent]),
|
||||||
Ok(Phase::Resolution(phase::Resolution {
|
Ok(Phase::Resolution(Move {
|
||||||
action: ForeignAid,
|
action: ForeignAid,
|
||||||
target: None,
|
target: None,
|
||||||
}))
|
}))
|
||||||
@ -185,14 +193,13 @@ fn test_block() {
|
|||||||
{
|
{
|
||||||
let mut game = game.clone();
|
let mut game = game.clone();
|
||||||
assert!(
|
assert!(
|
||||||
game.block(phase::Block {
|
game.block(Move {
|
||||||
action: ForeignAid,
|
action: ForeignAid,
|
||||||
target: None,
|
target: None,
|
||||||
}, &[&non_blocking_agent, &ambassador_block_agent, &non_blocking_agent])
|
}, &[&non_blocking_agent, &ambassador_block_agent, &non_blocking_agent])
|
||||||
.is_err()
|
.is_err()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -217,12 +224,17 @@ fn test_block_challenge() {
|
|||||||
{
|
{
|
||||||
let mut game = game.clone();
|
let mut game = game.clone();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
game.block_challenge( phase::BlockChallenge {
|
game.block_challenge(
|
||||||
blocker: 1,
|
Move {
|
||||||
block_card: Contessa,
|
|
||||||
action: Assassinate,
|
action: Assassinate,
|
||||||
target: Some(1),
|
target: Some(1),
|
||||||
}, &[&non_challenge_agent, &block_agent]),
|
},
|
||||||
|
Block {
|
||||||
|
blocker: 1,
|
||||||
|
card: Contessa,
|
||||||
|
},
|
||||||
|
&[&non_challenge_agent, &block_agent]
|
||||||
|
),
|
||||||
Ok(Phase::Done)
|
Ok(Phase::Done)
|
||||||
);
|
);
|
||||||
assert!(game.discard.is_empty());
|
assert!(game.discard.is_empty());
|
||||||
@ -232,12 +244,17 @@ fn test_block_challenge() {
|
|||||||
{
|
{
|
||||||
let mut game = game.clone();
|
let mut game = game.clone();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
game.block_challenge( phase::BlockChallenge {
|
game.block_challenge(
|
||||||
blocker: 1,
|
Move {
|
||||||
block_card: Contessa,
|
|
||||||
action: Assassinate,
|
action: Assassinate,
|
||||||
target: Some(1),
|
target: Some(1),
|
||||||
}, &[&challenge_agent, &block_agent]),
|
},
|
||||||
|
Block {
|
||||||
|
blocker: 1,
|
||||||
|
card: Contessa,
|
||||||
|
},
|
||||||
|
&[&challenge_agent, &block_agent]
|
||||||
|
),
|
||||||
Ok(Phase::Done)
|
Ok(Phase::Done)
|
||||||
);
|
);
|
||||||
assert!(!game.discard.is_empty());
|
assert!(!game.discard.is_empty());
|
||||||
@ -247,20 +264,24 @@ fn test_block_challenge() {
|
|||||||
{
|
{
|
||||||
let mut game = game.clone();
|
let mut game = game.clone();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
game.block_challenge( phase::BlockChallenge {
|
game.block_challenge(
|
||||||
blocker: 1,
|
Move {
|
||||||
block_card: Duke,
|
|
||||||
action: ForeignAid,
|
action: ForeignAid,
|
||||||
target: None,
|
target: None,
|
||||||
}, &[&challenge_agent, &block_agent]),
|
},
|
||||||
Ok(Phase::Resolution(phase::Resolution {
|
Block {
|
||||||
|
blocker: 1,
|
||||||
|
card: Duke,
|
||||||
|
},
|
||||||
|
&[&challenge_agent, &block_agent]
|
||||||
|
),
|
||||||
|
Ok(Phase::Resolution(Move {
|
||||||
action: ForeignAid,
|
action: ForeignAid,
|
||||||
target: None,
|
target: None,
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
assert!(!game.discard.is_empty());
|
assert!(!game.discard.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -283,7 +304,7 @@ fn test_resolution() {
|
|||||||
// Test income
|
// Test income
|
||||||
{
|
{
|
||||||
let mut game = game.clone();
|
let mut game = game.clone();
|
||||||
game.resolution(phase::Resolution {
|
game.resolution(Move {
|
||||||
action: Income,
|
action: Income,
|
||||||
target: None,
|
target: None,
|
||||||
}, &[&dummy_agent, &dummy_agent]).unwrap();
|
}, &[&dummy_agent, &dummy_agent]).unwrap();
|
||||||
@ -293,7 +314,7 @@ fn test_resolution() {
|
|||||||
// Test foreign aid
|
// Test foreign aid
|
||||||
{
|
{
|
||||||
let mut game = game.clone();
|
let mut game = game.clone();
|
||||||
game.resolution(phase::Resolution {
|
game.resolution(Move {
|
||||||
action: ForeignAid,
|
action: ForeignAid,
|
||||||
target: None,
|
target: None,
|
||||||
}, &[&dummy_agent, &dummy_agent]).unwrap();
|
}, &[&dummy_agent, &dummy_agent]).unwrap();
|
||||||
@ -303,7 +324,7 @@ fn test_resolution() {
|
|||||||
// Test coup / assassinate
|
// Test coup / assassinate
|
||||||
{
|
{
|
||||||
let mut game = game.clone();
|
let mut game = game.clone();
|
||||||
game.resolution(phase::Resolution {
|
game.resolution(Move {
|
||||||
action: Coup,
|
action: Coup,
|
||||||
target: Some(1),
|
target: Some(1),
|
||||||
}, &[&dummy_agent, &loser_agent]).unwrap();
|
}, &[&dummy_agent, &loser_agent]).unwrap();
|
||||||
@ -314,7 +335,7 @@ fn test_resolution() {
|
|||||||
// Test steal
|
// Test steal
|
||||||
{
|
{
|
||||||
let mut game = game.clone();
|
let mut game = game.clone();
|
||||||
game.resolution(phase::Resolution {
|
game.resolution(Move {
|
||||||
action: Steal,
|
action: Steal,
|
||||||
target: Some(1),
|
target: Some(1),
|
||||||
}, &[&dummy_agent, &dummy_agent]).unwrap();
|
}, &[&dummy_agent, &dummy_agent]).unwrap();
|
||||||
@ -325,7 +346,7 @@ fn test_resolution() {
|
|||||||
// Test exchange
|
// Test exchange
|
||||||
{
|
{
|
||||||
let mut game = game.clone();
|
let mut game = game.clone();
|
||||||
game.resolution(phase::Resolution {
|
game.resolution(Move {
|
||||||
action: Exchange,
|
action: Exchange,
|
||||||
target: Some(1),
|
target: Some(1),
|
||||||
}, &[&dummy_agent, &dummy_agent]).unwrap();
|
}, &[&dummy_agent, &dummy_agent]).unwrap();
|
||||||
|
Loading…
Reference in New Issue
Block a user