Created
October 25, 2016 20:12
-
-
Save markheath/303e2d7c074ee0675a02fe8cb5d4039a to your computer and use it in GitHub Desktop.
Yahtzee Kata in F#
This file contains hidden or 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
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