Some documentation

This commit is contained in:
Dane Johnson 2022-05-18 14:04:39 -05:00
parent 443e3a91c5
commit 7801eb0dd1

View File

@ -1,3 +1,5 @@
//! Coup is a game of deception for two to six players.
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
use std::fmt; use std::fmt;
@ -9,6 +11,7 @@ pub type CoupResult<T> = Result<T, &'static str>;
#[repr(u8)] #[repr(u8)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
/// Each card represents the right to perform specific actions or counteractions.
pub enum Card { pub enum Card {
Duke, Duke,
Assassin, Assassin,
@ -85,6 +88,7 @@ impl fmt::Display for Card {
#[repr(u8)] #[repr(u8)]
#[derive(Clone, Copy, PartialEq, Debug)] #[derive(Clone, Copy, PartialEq, Debug)]
/// The actions a player can perform on their turn.
pub enum Action { pub enum Action {
Income, Income,
ForeignAid, ForeignAid,
@ -96,10 +100,12 @@ pub enum Action {
} }
impl Action { impl Action {
/// If the action needs a target.
pub fn is_targeted(self) -> bool { pub fn is_targeted(self) -> bool {
matches!(self, Coup | Steal | Assassinate) matches!(self, Coup | Steal | Assassinate)
} }
/// Which players may challenge the action.
pub fn challenger_mode(self) -> ResMode { pub fn challenger_mode(self) -> ResMode {
match self { match self {
Income | ForeignAid | Coup => ResMode::None, Income | ForeignAid | Coup => ResMode::None,
@ -107,6 +113,7 @@ impl Action {
} }
} }
/// Which players may block the action.
pub fn blocker_mode(self) -> ResMode { pub fn blocker_mode(self) -> ResMode {
match self { match self {
Income | Tax | Exchange | Coup => ResMode::None, Income | Tax | Exchange | Coup => ResMode::None,
@ -115,6 +122,7 @@ impl Action {
} }
} }
/// How much the action costs to perform.
pub fn coin_cost(self) -> u8 { pub fn coin_cost(self) -> u8 {
match self { match self {
Assassinate => 3, Assassinate => 3,
@ -141,6 +149,7 @@ impl fmt::Display for Action {
#[repr(u8)] #[repr(u8)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
/// How the other players may respond to an action.
pub enum ResMode { pub enum ResMode {
None, None,
Target, Target,
@ -148,20 +157,22 @@ pub enum ResMode {
} }
#[derive(Clone)] #[derive(Clone)]
/// The cards and coins a single player possesses.
pub struct Player { pub struct Player {
pub coins: u8, pub coins: u8,
pub cards: Vec<Card>, pub cards: Vec<Card>,
} }
impl Player { impl Player {
/// If the player still possesses any cards, and thus is still in the game
pub fn is_alive(&self) -> bool { pub fn is_alive(&self) -> bool {
!self.cards.is_empty() !self.cards.is_empty()
} }
pub fn lose(&mut self, card: Card, deck: &mut Vec<Card>) { fn lose(&mut self, card: Card, deck: &mut Vec<Card>) {
self.cards.draw_first(card); self.cards.draw_first(card);
deck.push(card); deck.push(card);
} }
pub fn holds(&self, card: Card) -> bool { fn holds(&self, card: Card) -> bool {
self.cards.iter().find(|&c| *c == card).is_some() self.cards.iter().find(|&c| *c == card).is_some()
} }
} }
@ -351,7 +362,13 @@ impl Game {
Ok(Phase::Done) Ok(Phase::Done)
} }
} }
pub mod phase { pub mod phase {
//! Structures relating to game phases.
//!
//! Coup turns have 5 phases, depending on what actions are taken each phase
//! some phases might be skipped. These structures marshal information
//! between the phases.
use super::{ Card, Action }; use super::{ Card, Action };
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub enum Phase { pub enum Phase {
@ -386,10 +403,18 @@ pub mod phase {
use phase::Phase; use phase::Phase;
/// An interface to a game to make strategic decisions.
pub trait Agent : fmt::Debug { pub trait Agent : fmt::Debug {
/// 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]
fn choose_block_card(&self, block: &phase::Block) -> Option<Card>; fn choose_block_card(&self, block: &phase::Block) -> Option<Card>;
/// Should the agent challenge the block?
fn should_block_challenge(&self, block_challenge: &phase::BlockChallenge) -> bool; fn should_block_challenge(&self, block_challenge: &phase::BlockChallenge) -> bool;
/// The [Ambassador]'s exchange.
/// Given 3 or 4 [Cards](Card) the agent must return two cards to the deck.
fn exchange(&self, cards: &[Card]) -> [Card; 2]; fn exchange(&self, cards: &[Card]) -> [Card; 2];
/// The player has lost influence, and must choose a [Card] from their hand
/// to discard.
fn choose_lost_influence(&self, cards: &[Card]) -> Card; fn choose_lost_influence(&self, cards: &[Card]) -> Card;
} }