Created
August 14, 2019 23:52
-
-
Save ygrenzinger/d4f30eb9c4139abfccd65606c5bd3f0e to your computer and use it in GitHub Desktop.
Bowling Kata in Haskell
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
module ScoreCalculator ( bowlingScore ) where | |
import Data.Char | |
data Roll = Strike | Spare | PinHit Int deriving Eq | |
parseRawRolls :: String -> [Roll] -> [Roll] | |
parseRawRolls [] rolls = reverse rolls | |
parseRawRolls (' ' : rest) rolls = parseRawRolls rest rolls | |
parseRawRolls ('-':rest) rolls = parseRawRolls rest ((PinHit 0) : rolls) | |
parseRawRolls ('/':rest) rolls = parseRawRolls rest (Spare : rolls) | |
parseRawRolls ('X':rest) rolls = parseRawRolls rest (Strike : rolls) | |
parseRawRolls (r:rest) rolls = parseRawRolls rest (PinHit (digitToInt r) : rolls) | |
computeSpareScore :: [Roll] -> Int | |
computeSpareScore ((PinHit x) : _) = 10 + x | |
computeSpareScore (Strike : _) = 10 + 10 | |
computeSpareScore _ = 10 | |
computeStrikeScore :: [Roll] -> Int | |
computeStrikeScore (Strike : (Strike : _)) = 10 + 10 + 10 | |
computeStrikeScore (Strike : ((PinHit x) : _)) = 10 + 10 + x | |
computeStrikeScore ( _ : Spare : _) = 10 + 10 | |
computeStrikeScore ((PinHit first) : (PinHit second): _) = 10 + first + second | |
computeStrikeScore _ = 10 | |
computeScore :: Int -> Int -> [Roll] -> Int | |
computeScore _ score [] = score | |
computeScore 10 score _ = score | |
computeScore frameCount score (Strike:nextRolls) = computeScore (frameCount + 1) (score + computeStrikeScore nextRolls) nextRolls | |
computeScore frameCount score (_:Spare:nextRolls) = computeScore (frameCount + 1) (score + computeSpareScore nextRolls) nextRolls | |
computeScore frameCount score ((PinHit a):(PinHit b):nextRolls) = computeScore (frameCount + 1) (score + a + b) nextRolls | |
bowlingScore :: String -> Int | |
bowlingScore rolls = computeScore 0 0 (parseRawRolls rolls []) |
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
import Test.Hspec | |
import ScoreCalculator | |
main :: IO () | |
main = hspec $ do | |
describe "Bowling Score calculator" $ do | |
it "should compute 0 when all rolls are a miss" $ do | |
bowlingScore "-- -- -- -- -- -- -- -- -- --" `shouldBe` 0 | |
it "should compute 90 when always doing a first roll with 9 pins down" $ do | |
bowlingScore "9- 9- 9- 9- 9- 9- 9- 9- 9- 9-" `shouldBe` 90 | |
it "should compute 20 when all roll with 1 pin down" $ do | |
bowlingScore "11 11 11 11 11 11 11 11 11 11" `shouldBe` 20 | |
it "should compute 20 when first roll is a spare followed by a strike" $ do | |
bowlingScore "7/ X -- -- -- -- -- -- -- --" `shouldBe` 30 | |
it "should compute 12 when first roll is a spare followed by a normal hit and a miss" $ do | |
bowlingScore "7/ 1- -- -- -- -- -- -- -- --" `shouldBe` 12 | |
it "should compute 12 when first roll is a spare" $ do | |
bowlingScore "7/ 1- -- -- -- -- -- -- -- --" `shouldBe` 12 | |
it "should compute 16 when first roll is a strike" $ do | |
bowlingScore "X 12 -- -- -- -- -- -- -- --" `shouldBe` 16 | |
it "should compute 30 when first roll is a strike followed by a spare" $ do | |
bowlingScore "X 1/ -- -- -- -- -- -- -- --" `shouldBe` 30 | |
it "should compute 60 when first three rolls are a strike" $ do | |
bowlingScore "X X X -- -- -- -- -- -- --" `shouldBe` 60 | |
it "should compute 60 when first three rolls are a strike" $ do | |
bowlingScore "X X X -- -- -- -- -- -- --" `shouldBe` 60 | |
it "should compute 300 when all rolls are a strike" $ do | |
bowlingScore "X X X X X X X X X X X X" `shouldBe` 300 | |
it "should compute 300 when all frames are a spare" $ do | |
bowlingScore "5/ 5/ 5/ 5/ 5/ 5/ 5/ 5/ 5/ 5/5" `shouldBe` 150 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Better code :
https://codernub.blogspot.com/2010/03/bowling-kata-as-haskell-exercise-first.html
https://github.com/ToF-/KataBowlingHaskell/blob/master/Bowling.hs