From 06352344fba22c92e0cde72bbdf3e9fb63aba1dc Mon Sep 17 00:00:00 2001 From: Dane Johnson Date: Fri, 20 May 2022 16:50:24 -0500 Subject: [PATCH] CLI can play some version of a whole game --- src/cli.rs | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++---- src/lib.rs | 2 ++ 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index faada8e..a8dfa27 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,5 +1,6 @@ use coup::*; use Action::*; +use Card::*; use std::io; use std::io::Write; @@ -22,6 +23,7 @@ impl HumanAgent { &[card] => println!("Your identity is {}", card), _ => unreachable!(), } + println!("You have {} coin(s)", game.players[self.turn].coins); println!("Remaining players are:"); for id in 0..game.players.len() { if id == self.turn || !game.players[id].is_alive() { @@ -52,7 +54,13 @@ impl Agent for HumanAgent { println!("Bad choice"); } }; - let target = if action.is_targeted() { Some(get_index()) } else { None }; + let target = if action.is_targeted() { + print!("Select a target: "); + flush(); + Some(get_index()) + } else { + None + }; Move { action, target } } fn should_action_challenge(&self, game: &Game, move_: Move) -> bool { @@ -74,16 +82,82 @@ impl Agent for HumanAgent { } } fn choose_block_card(&self, game: &Game, move_: Move) -> Option { - todo!(); + self.inform(game); + match move_.action { + Tax => { + print!("Will you claim Duke to block Foreign Aid?"); + match yes_or_no() { + Some(true) => Some(Duke), + _ => None, + } + }, + Assassinate => { + print!("Will you claim Contessa to block Assassination?"); + match yes_or_no() { + Some(true) => Some(Contessa), + _ => None, + } + }, + Steal => { + println!("Choose a Card to block Steal, or choose None:"); + println!(" 1) Ambassador"); + println!(" 2) Captain"); + println!(" 3) None"); + match get_index() { + 1 => Some(Ambassador), + 2 => Some(Captain), + _ => None + } + }, + _ => unreachable!(), + } + } fn should_block_challenge(&self, game: &Game, move_: Move, block: Block) -> bool { - todo!(); + self.inform(game); + loop { + print!("Will you challenge the block?"); + match yes_or_no() { + Some(b) => break b, + None => println!("Bad input"), + } + } } fn exchange(&self, game: &Game, cards: &[Card]) -> [Card; 2] { - todo!(); + self.inform(game); + let mut cards = Vec::from(cards); + while cards.len() > 2 { + println!("Choose a card to keep:"); + for (i, card) in cards.iter().enumerate() { + println!(" {}) {}", i+1, card); + } + let index = get_index() - 1; + if index < cards.len() { + cards.remove(index); + } else { + println!("Bad input"); + } + } + cards.try_into().unwrap() } fn choose_lost_influence(&self, game: &Game) -> Card { - todo!(); + match game.players[self.turn].cards.as_slice() { + &[card] => card, + &[card1, card2] => { + self.inform(game); + loop { + println!("Choose a card to lose influence"); + println!(" 1) {}", card1); + println!(" 2) {}", card2); + match get_index() { + 1 => break card1, + 2 => break card2, + _ => println!("Bad input"), + } + } + } + _ => unreachable!(), + } } } @@ -113,7 +187,7 @@ fn get_index() -> usize { fn yes_or_no() -> Option { print!(" [y/n]: "); - io::stdout().flush().unwrap(); + flush(); let mut string = String::new(); io::stdin() .read_line(&mut string) @@ -128,3 +202,7 @@ fn yes_or_no() -> Option { None } } + +fn flush() { + io::stdout().flush().unwrap(); +} diff --git a/src/lib.rs b/src/lib.rs index ba0cbac..43a6eef 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -286,6 +286,7 @@ impl Game { // Player loses influence self.player_lose_influence(self.turn, agents)?; // Turn is forfeit + self.advance(); Ok(Phase::Done) } } else { @@ -334,6 +335,7 @@ impl Game { if self.players[block.blocker].holds(block.card) { // Player challenged incorrectly, loses influence and turn is forfeit self.player_lose_influence(self.turn, agents)?; + self.advance(); Ok(Phase::Done) } else { // Player challenged correctly, blocker loses a card