Skip to content

Instantly share code, notes, and snippets.

@markheath
Created Oct 25, 2016
Embed
What would you like to do?
Yahtzee Kata in F#
let highestRepeated dice minRepeats =
let repeats = dice |> List.countBy id |> List.filter (fun (_,n) -> n >= minRepeats) |> List.map fst
match repeats with | [] -> 0 | _ -> List.max repeats
let ofAKind n dice =
n * highestRepeated dice n
let sumOfSingle selected dice =
dice |> Seq.filter ((=) selected) |> Seq.sum
let straight target score dice =
if List.sort dice = target then score else 0
let yahtzee dice =
if Seq.length dice = 5 && Seq.length (Seq.distinct dice) = 1 then 50 else 0
//strategies
let Chance = "Chance", Seq.sum
let Ones = "Ones", sumOfSingle 1
let Twos = "Twos", sumOfSingle 2
let Threes = "Threes", sumOfSingle 3
let Fours = "Fours", sumOfSingle 4
let Fives = "Fives", sumOfSingle 5
let Sixes = "Sixes", sumOfSingle 6
let Pair = "Pair", ofAKind 2
let ThreeOfAKind = "Three of a Kind", ofAKind 3
let FourOfAKind = "Four of a Kind", ofAKind 4
let SmallStraight = "Small Straight", straight [1;2;3;4;5] 15
let LargeStraight = "Large Straight", straight [2;3;4;5;6] 20
let Yahtzee = "Yahtzee", yahtzee
let testCases = [
([1;2;3;4;5], 1, Ones)
([1;2;3;4;5], 2, Twos)
([3;2;3;4;3], 9, Threes)
([3;2;3;4;3], 4, Fours)
([5;5;5;4;3], 15, Fives)
([3;2;3;4;3], 0, Sixes)
([1;2;3;4;5], 0, Pair) // no pairs found
([1;5;3;4;5], 10, Pair) // one pair found
([2;2;6;6;4], 12, Pair) // picks highest
([2;3;1;3;3], 6, Pair) // only counts two
([2;2;6;6;6], 18, ThreeOfAKind)
([2;2;4;6;6], 0, ThreeOfAKind) // no threes found
([5;5;5;5;5], 15, ThreeOfAKind) // only counts three
([6;2;6;6;6], 24, FourOfAKind)
([2;6;4;6;6], 0, FourOfAKind) // no fours found
([5;5;5;5;5], 20, FourOfAKind) // only counts four
([1;2;5;4;3], 15, SmallStraight)
([1;2;5;1;3], 0, SmallStraight)
([6;2;5;4;3], 20, LargeStraight)
([1;2;5;1;3], 0, LargeStraight)
([5;5;5;5;5], 50, Yahtzee)
([1;5;5;5;5], 0, Yahtzee)
([1;2;3;4;5], 15, Chance)
]
let runTest (dice, expected, (name, strategy)) =
let score = strategy dice
let message = sprintf "testing with %s on %A" name dice
(expected = score), message
let runAllTests =
let results = testCases |> List.map runTest
results |> List.iter (fun (s,m) -> printf "%s %s" (if s then "PASS" else "FAIL") m)
printfn "ran %d test cases" (List.length testCases)
runAllTests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment