diff --git a/2022/day-2_rock_paper_scissors/src/choice.rs b/2022/day-2_rock_paper_scissors/src/choice.rs new file mode 100644 index 0000000..2a1f462 --- /dev/null +++ b/2022/day-2_rock_paper_scissors/src/choice.rs @@ -0,0 +1,63 @@ +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 + } +} + diff --git a/2022/day-2_rock_paper_scissors/src/gameresult.rs b/2022/day-2_rock_paper_scissors/src/gameresult.rs new file mode 100644 index 0000000..6489c01 --- /dev/null +++ b/2022/day-2_rock_paper_scissors/src/gameresult.rs @@ -0,0 +1,9 @@ +use strum_macros::Display; + +/// Enum containing the possible outcomes for Rock, Paper, Scissors. +#[derive(Display, Clone, Eq, PartialEq)] +pub enum GameResult { + Win, + Loose, + Draw +} diff --git a/2022/day-2_rock_paper_scissors/src/lib.rs b/2022/day-2_rock_paper_scissors/src/lib.rs index 4c55990..7e4d20c 100644 --- a/2022/day-2_rock_paper_scissors/src/lib.rs +++ b/2022/day-2_rock_paper_scissors/src/lib.rs @@ -1,69 +1,14 @@ use common::read_file; -use strum::IntoEnumIterator; -use strum_macros::{Display, EnumIter}; use std::path::PathBuf; use tracing::{info, debug}; -#[derive(Display, Clone, Eq, PartialEq, EnumIter)] -enum Choice { - Rock, - Paper, - Scissors, -} +mod choice; +use crate::choice::Choice; -#[derive(Display, Clone, Eq, PartialEq)] -enum GameResult { - Win, - Loose, - Draw -} - -impl Choice { - 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 - } - - 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 - } - - 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 - } -} +mod gameresult; +use crate::gameresult::GameResult; +/// Calculates score for single game, given specification from part one of the task. fn calculate_result_1a(line: &str) -> u64 { debug!("Get score for 1a of game {}", line); @@ -72,7 +17,7 @@ fn calculate_result_1a(line: &str) -> u64 { Some('A') => Choice::Rock, Some('B') => Choice::Paper, Some('C') => Choice::Scissors, - _ => Choice::Rock, + _ => Choice::Rock, // Todo: Error handling, this shouldn't happen }; input.next(); @@ -81,13 +26,14 @@ fn calculate_result_1a(line: &str) -> u64 { Some('X') => Choice::Rock, Some('Y') => Choice::Paper, Some('Z') => Choice::Scissors, - _ => Choice::Rock, + _ => Choice::Rock, // Todo: Error handling, this shouldn't happen }; let result = user_choice.play(&opponent_choice); info!("Total score (1a): {}", result); result } +/// Calculates score for single game, given specification from part two of the task. fn calculate_result_1b(line: &str) -> u64 { debug!("Get score for 1b of game {}", line); @@ -96,7 +42,7 @@ fn calculate_result_1b(line: &str) -> u64 { Some('A') => Choice::Rock, Some('B') => Choice::Paper, Some('C') => Choice::Scissors, - _ => Choice::Rock, // Error handling, this shouldn't happen + _ => Choice::Rock, // Todo: Error handling, this shouldn't happen }; input.next(); @@ -105,7 +51,7 @@ fn calculate_result_1b(line: &str) -> u64 { Some('X') => GameResult::Loose, Some('Y') => GameResult::Draw, Some('Z') => GameResult::Win, - _ => GameResult::Loose, // Error handling, this shouldn't happen + _ => GameResult::Loose, // Todo: Error handling, this shouldn't happen }; let result = opponent_choice.cheat(&outcome); info!("Total score (1b): {}", result); diff --git a/README.md b/README.md index b0df77a..c196d12 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,11 @@ ``` . ├── 2022 +│   ├── common │   ├── day-1_calorie_counting -│   └── day-1_calorie_counting-alt +│   ├── day-1_calorie_counting-alt +│   ├── day-2_rock_paper_scissors +│   └── day-2_rock_paper_scissors-alt ├── create_readme.sh └── README.md ```