diff options
Diffstat (limited to 'rust/bowling/src/lib.rs')
| -rw-r--r-- | rust/bowling/src/lib.rs | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/rust/bowling/src/lib.rs b/rust/bowling/src/lib.rs new file mode 100644 index 0000000..bd517a5 --- /dev/null +++ b/rust/bowling/src/lib.rs | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | #[derive(Debug, PartialEq)] | ||
| 2 | pub enum Error { | ||
| 3 | NotEnoughPinsLeft, | ||
| 4 | GameComplete, | ||
| 5 | } | ||
| 6 | |||
| 7 | #[derive(Debug, Default)] | ||
| 8 | pub struct BowlingGame { | ||
| 9 | throws: Vec<u16>, | ||
| 10 | prev: u16 | ||
| 11 | } | ||
| 12 | |||
| 13 | impl BowlingGame { | ||
| 14 | pub fn new() -> Self { | ||
| 15 | Default::default() | ||
| 16 | } | ||
| 17 | |||
| 18 | pub fn roll(&mut self, pins: u16) -> Result<(), Error> { | ||
| 19 | if pins + self.prev > 10 { | ||
| 20 | Err(Error::NotEnoughPinsLeft) | ||
| 21 | } else if self.score().is_some() { | ||
| 22 | Err(Error::GameComplete) | ||
| 23 | } else { | ||
| 24 | self.throws.push(pins); | ||
| 25 | self.prev = if self.prev + pins == 10 { 0 } else { pins }; | ||
| 26 | Ok(()) | ||
| 27 | } | ||
| 28 | } | ||
| 29 | |||
| 30 | pub fn score(&self) -> Option<u16> { | ||
| 31 | let mut score = 0; | ||
| 32 | let mut stage = 0; | ||
| 33 | for _ in 1..=10 { | ||
| 34 | let first = self.throws.get(stage)?; | ||
| 35 | let second = self.throws.get(stage+1)?; | ||
| 36 | score += first + second; | ||
| 37 | if first + second >= 10 { | ||
| 38 | let third = self.throws.get(stage+2)?; | ||
| 39 | score += third; | ||
| 40 | } | ||
| 41 | stage += if *first == 10 { 1 } else { 2 }; | ||
| 42 | } | ||
| 43 | Some(score) | ||
| 44 | } | ||
| 45 | } | ||
