Created
December 6, 2017 07:48
-
-
Save suyash/cbb5636da94bf63a290073fb3e075df7 to your computer and use it in GitHub Desktop.
Bowling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[derive(Debug)] | |
enum State { | |
STRIKE, | |
STRIKE_PLUS_1, | |
STRIKE_PLUS_2, | |
SPARE, | |
SECOND, | |
FIRST | |
} | |
pub struct BowlingGame { | |
state: State, | |
score: usize, | |
frames: usize, | |
prev: usize, | |
} | |
impl BowlingGame { | |
pub fn new() -> BowlingGame { | |
BowlingGame { state: State::FIRST, score: 0, frames: 0, prev: 0 } | |
} | |
pub fn roll(&mut self, pins: usize) -> Result<(), ()> { | |
if pins > 10 || self.frames == 10 { | |
Err(()) | |
} else { | |
match self.state { | |
State::FIRST => { | |
if pins == 10 { | |
self.state = State::STRIKE; | |
} else { | |
self.state = State::SECOND; | |
} | |
} | |
State::SECOND => { | |
if pins == 10 { | |
self.state = State::STRIKE; | |
} else if self.prev + pins == 10 { | |
self.state = State::SPARE; | |
} else if self.prev + pins <= 10 { | |
self.score += self.prev + pins; | |
self.frames += 1; | |
self.state = State::FIRST; | |
} else { | |
return Err(()) | |
} | |
} | |
State::SPARE => { | |
self.score += 10 + pins; | |
self.frames += 1; | |
if pins == 10 { | |
self.state = State::STRIKE; | |
} else { | |
self.state = State::SECOND; | |
} | |
} | |
State::STRIKE => { | |
self.state = State::STRIKE_PLUS_2; | |
} | |
State::STRIKE_PLUS_1 => { | |
self.score += 10 + self.prev + pins; | |
self.frames += 1; | |
self.state = State::STRIKE_PLUS_2; | |
} | |
State::STRIKE_PLUS_2 => { | |
if self.prev < 10 && self.prev + pins > 10 { | |
return Err(()); | |
} | |
self.score += 10 + self.prev + pins; | |
self.frames += 1; | |
if self.prev == 10 { | |
self.state = State::STRIKE_PLUS_1; | |
} else if pins == 10 { | |
self.state = State::STRIKE; | |
} else if self.prev + pins == 10 { | |
self.state = State::SPARE; | |
} else { | |
if self.frames < 10 { // not the last roll | |
self.frames += 1; | |
self.score += self.prev + pins; | |
} | |
self.state = State::FIRST; | |
} | |
} | |
} | |
self.prev = pins; | |
Ok(()) | |
} | |
} | |
pub fn score(&self) -> Result<usize, String> { | |
if self.frames == 10 { | |
Ok(self.score) | |
} else { | |
Err(format!("incomplete game, {} frames, score {}", self.frames, self.score)) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment