85 lines
1.8 KiB
Rust
85 lines
1.8 KiB
Rust
|
#[derive(PartialEq, Debug)]
|
||
|
pub enum Choice {
|
||
|
Rock,
|
||
|
Paper,
|
||
|
Scissors,
|
||
|
}
|
||
|
|
||
|
impl Choice {
|
||
|
pub fn score(&self) -> u32 {
|
||
|
match self {
|
||
|
Choice::Rock => 1,
|
||
|
Choice::Paper => 2,
|
||
|
Choice::Scissors => 3,
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
pub struct Round {
|
||
|
opponent: Choice,
|
||
|
own: Choice,
|
||
|
}
|
||
|
|
||
|
pub enum RoundResult {
|
||
|
Win,
|
||
|
Draw,
|
||
|
Loss,
|
||
|
}
|
||
|
|
||
|
impl Round {
|
||
|
pub fn result(&self) -> RoundResult {
|
||
|
let win = match self.own {
|
||
|
Choice::Rock => Choice::Scissors,
|
||
|
Choice::Paper => Choice::Rock,
|
||
|
Choice::Scissors => Choice::Paper,
|
||
|
};
|
||
|
|
||
|
if self.opponent == win {
|
||
|
RoundResult::Win
|
||
|
} else if self.opponent == self.own {
|
||
|
RoundResult::Draw
|
||
|
} else {
|
||
|
RoundResult::Loss
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn score(&self) -> u32 {
|
||
|
let choice_score = self.own.score();
|
||
|
let result_score = match self.result() {
|
||
|
RoundResult::Win => 6,
|
||
|
RoundResult::Draw => 3,
|
||
|
RoundResult::Loss => 0,
|
||
|
};
|
||
|
|
||
|
choice_score + result_score
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn parse_choice(choice_str: &str) -> Choice {
|
||
|
match choice_str.chars().next().unwrap() {
|
||
|
'A' => Choice::Rock,
|
||
|
'B' => Choice::Paper,
|
||
|
'C' => Choice::Scissors,
|
||
|
'X' => Choice::Rock,
|
||
|
'Y' => Choice::Paper,
|
||
|
'Z' => Choice::Scissors,
|
||
|
_ => panic!("Unknown choice {}", choice_str),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn parse_rounds(input: &String) -> Vec<Round> {
|
||
|
let lines = input.lines();
|
||
|
let mut rounds = Vec::new();
|
||
|
|
||
|
for line in lines {
|
||
|
let (opponent, own) = line.split_once(' ').unwrap();
|
||
|
rounds.push(Round {
|
||
|
opponent: parse_choice(opponent),
|
||
|
own: parse_choice(own),
|
||
|
});
|
||
|
}
|
||
|
|
||
|
rounds
|
||
|
}
|