diff --git a/src/lib.rs b/src/lib.rs index 1d5cf0d..598a482 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,7 +29,7 @@ impl Card { } pub fn blocks_action(self, action: Action) -> bool { matches!((self, action), - (Duke, Income) | + (Duke, ForeignAid) | (Captain, Steal) | (Ambassador, Steal) | (Contessa, Assassinate)) @@ -243,12 +243,18 @@ impl Game { target: block.target, })), ResMode::Target => match agents[block.target.unwrap()].choose_block_card(&block) { - Some(card) => Ok(Phase::BlockChallenge(phase::BlockChallenge { - blocker: block.target.unwrap(), - block_card: card, - action: block.action, - target: block.target, - })), + Some(card) => { + if card.blocks_action(block.action) { + Ok(Phase::BlockChallenge(phase::BlockChallenge { + blocker: block.target.unwrap(), + block_card: card, + action: block.action, + target: block.target, + })) + } else { + Err("Card does not block action") + } + }, None => Ok(Phase::Resolution(phase::Resolution { action: block.action, target: block.target, @@ -257,12 +263,16 @@ impl Game { ResMode::Anyone => { for id in self.turn_iterator() { if let Some(card) = agents[id].choose_block_card(&block) { - return Ok(Phase::BlockChallenge(phase::BlockChallenge { - blocker: id, - block_card: card, - action: block.action, - target: block.target, - })) + if card.blocks_action(block.action) { + return Ok(Phase::BlockChallenge(phase::BlockChallenge { + blocker: id, + block_card: card, + action: block.action, + target: block.target, + })) + } else { + return Err("Card does not block action") + } } } Ok(Phase::Resolution(phase::Resolution { @@ -512,6 +522,19 @@ mod test { })) ); } + + // Test bad block card + { + let mut game = game.clone(); + assert!( + game.block(phase::Block { + action: ForeignAid, + target: None, + }, &[&non_blocking_agent, &ambassador_block_agent, &non_blocking_agent]) + .is_err() + ); + } + } #[test]