aboutsummaryrefslogtreecommitdiff
path: root/rust/bowling/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/bowling/src/lib.rs')
-rw-r--r--rust/bowling/src/lib.rs45
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)]
2pub enum Error {
3 NotEnoughPinsLeft,
4 GameComplete,
5}
6
7#[derive(Debug, Default)]
8pub struct BowlingGame {
9 throws: Vec<u16>,
10 prev: u16
11}
12
13impl 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}