//Bowling Game Kata Implementation

open StateMonad

let AllPins = 10

let ZeroPins = 0

let IsStrike(roll, _) = roll = AllPins

let IsSpare(roll, nextRoll) = (roll + nextRoll) = AllPins

let SpareBonus rolls = match rolls with

| (rollA, rollB)::rolls' -> rollA

| [] -> 0

let StrikeBonus rolls = match rolls with

| (rollA,rollB)::rolls' -> rollA + if rollA = AllPins then rollA else rollB

| [] -> 0

let frames rolls =

let rec frames' rolls =

match rolls with

| rollA::rollB::[] -> [(rollA,rollB)]

| rollA::rollB::rolls' -> if (IsStrike(rollA, rollB)) then

(rollA, ZeroPins) :: frames' (rollB::rolls')

else

(rollA, rollB) :: frames' rolls'

| rollA::[] -> [(rollA, ZeroPins)]

frames' rolls

let NextScoreNoBonus prevScore rollA rollB = prevScore + rollA + rollB

let rec totals xs score =

match xs with

| (x,y)::[] when x < AllPins -> (NextScoreNoBonus score x y)

| (_,_)::[] -> score

| (x,y)::xs ->

if (IsStrike(x,y)) then

totals xs (score + x + StrikeBonus xs)

else

if (IsSpare(x,y)) then

totals xs ((NextScoreNoBonus score x y) + SpareBonus xs)

else

totals xs (NextScoreNoBonus score x y)

| [] -> score

let Score m = Execute (state { do! m

let! score = GetState

return score }) []

let Total xs = (totals (frames xs) 0)

let Roll(pins) = state { let! s = GetState

do! SetState(s @ [pins]) }

let RollList xs = state { let! xs' = MMap (fun s -> state { do! Roll s }) xs

return () }

let RollMany t s = state { do! RollList (List.map (fun _ -> s) [1..t]) }

let RollSpare = state { do! Roll 5

do! Roll 5 }

let RollStrike = state { do! Roll 10 }

## Monday, 2 March 2009

### Bowling Game Kata Implementation

Subscribe to:
Post Comments (Atom)

## No comments:

Post a Comment