use strum::IntoEnumIterator; use strum_macros::{Display, EnumIter}; use tracing::{info, debug}; use crate::gameresult::GameResult; /// Enum containing the possible choices for Rock, Paper, Scissors. #[derive(Display, Clone, Eq, PartialEq, EnumIter)] pub enum Choice { Rock, Paper, Scissors, } impl Choice { /// Returns the outcome of the game from `i`s perspective, playing against `other`. fn win(i: &Choice, other: &Choice) -> GameResult { debug!("Get GameResult based on {}, {}", i, other); let result = match (i, other) { (Choice::Rock, Choice::Scissors) => GameResult::Win, (Choice::Paper, Choice::Rock) => GameResult::Win, (Choice::Scissors, Choice::Paper) => GameResult::Win, _ if i == other => GameResult::Draw, _ => GameResult::Loose }; info!("GameResult: {}", &result); result } /// Calculate score based on `self`s and `other`s =Rock, Paper, Scissors=-choice and the resulting outcome. pub fn play(&self, other: &Choice) -> u64 { debug!("Get score based on {}, {}", &self, other); let hand_value = match self { Choice::Rock => 1, Choice::Paper => 2, Choice::Scissors => 3, }; let game_value = match Choice::win(self, other) { GameResult::Win => 6, GameResult::Draw => 3, GameResult::Loose => 0, }; let result = hand_value + game_value; info!("Score: {}", &result); result } /// Calculates the score based on the wished upon `outcome` when `self` is the opponents choice. pub fn cheat(&self, outcome: &GameResult) -> u64 { debug!("Get score by cheating based on {}, {}", &self, outcome); let user_choice = Choice::iter().filter(|c| &Choice::win(&c, &self) == outcome).next(); let result =user_choice.unwrap().play(&self); info!("Score: {}", result); result } }