Skip to content

Instantly share code, notes, and snippets.

@markheath

markheath/yahtzee.fs

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
You can’t perform that action at this time.