-module(cribbage). -export([points/1]). points([]) -> 0; points(L) -> Hand = lists:sort(L), fifteens(Hand, 0) + runs(Hand, 0, 0) + pairs(Hand, 1, 0). cardval(C) when C > 9 -> 10; cardval(C) -> C. fifteens(_L, Total) when Total > 15 -> 0; fifteens(_Hand, Total) when Total =:= 15 -> 2; fifteens([], _Total) -> 0; fifteens([H | T], Total) when Total < 15 -> fifteens(T, Total) + fifteens(T, Total + cardval(H)). run(3) -> 3; run(4) -> 6; run(5) -> 12; run(_Length) -> 0. %% two cases for runs %% 1. A straight run - 4,5,6,7 %% 2. A run with a double in the sequence - 4,4,5,6 or 4,5,5,6 runs([], _Curr, Len) -> run(Len); runs([H | T], Curr, Len) when H =:= (Curr+1) -> runs(T, H, Len + 1); runs([H | T], Curr, Len) when H =:= Curr -> runs(T, Curr, Len, {H, 2}); runs([H | T], _Curr, Len) -> run(Len) + runs(T, H, 1). runs([], _Curr, Len, {_Card, Mult}) -> Mult * run(Len); runs([H | T], Curr, Len, {Card, Mult}) when H =:= (Curr+1) -> runs(T, H, (Len+1), {Card, Mult}); %% needed for special cases where multiple cards are doubled up %% like 3,4,4,5,5 runs([H | T], Curr, Len, {Card, Mult}) when H =:= Curr, H > Card -> runs(T, Curr, Len, {H, (Mult*2)}); %% handles a triple carding, like 2,2,2,3,4 runs([H | T], Curr, Len, {Card, Mult}) when H =:= Curr -> runs(T, Curr, Len, {Card, (Mult+1)}); runs([H | T], _Curr, Len, {_Card, Mult}) -> (Mult * run(Len)) + runs(T, H, 1). pairs([], Pairs, _Curr) -> pair(Pairs); pairs([H | T], Pairs, Curr) when H =:= Curr -> pairs(T, Pairs+1, Curr); pairs([H | T], Pairs, _Curr) -> pair(Pairs) + pairs(T, 1, H). pair(2) -> 2; pair(3) -> 6; pair(4) -> 12; pair(_Length) -> 0.