diff --git a/include/riichi.hrl b/include/riichi.hrl index 719a458..9b45447 100644 --- a/include/riichi.hrl +++ b/include/riichi.hrl @@ -2,3 +2,14 @@ suit, value }). + +-record(hand, { + tiles=[], + sets=[] +}). + +-record(set, { + count, + tile, + open=true +}). diff --git a/src/riichi.erl b/src/riichi.erl index f6ad0c3..ad36006 100644 --- a/src/riichi.erl +++ b/src/riichi.erl @@ -6,7 +6,10 @@ is_valid_tile/1, dora/1, nearest/2, - score/3 + score/3, + score_hand/1, + score_hand/2, + score_hand/3 ]). is_valid_tile(#tile{suit=dragon, value=Value}) -> @@ -71,3 +74,26 @@ score(Fu, Han, Limit) -> true -> Score end. + +score_hand(#hand{}=H) -> + score_hand(H, 20). + +score_hand(#hand{}=H, Fu) -> + score_hand(H, Fu, true). + +score_hand(#hand{tiles=T, sets=_S}=_H, BaseFu, Limit) -> + Fu = [ + BaseFu + ], + Han = [ + _DaiSanGen = case sets:is_subset(sets:from_list([{3, #tile{suit=dragon, value=red}}, {3, #tile{suit=dragon, value=white}}, {3, #tile{suit=dragon, value=green}}]), sets:from_list(find_sets(T))) of + true -> 13; + _ -> 0 + end + ], + score(lists:sum(Fu), lists:sum(Han), Limit). + +find_sets(Tiles) -> + Unique = sets:to_list(sets:from_list(Tiles)), + [{length(lists:filter(fun(X) -> X == T end, Tiles)), T} + || T <- Unique]. diff --git a/test/riichi_tests.erl b/test/riichi_tests.erl index 3ac0e24..a602b65 100644 --- a/test/riichi_tests.erl +++ b/test/riichi_tests.erl @@ -82,3 +82,14 @@ score_fu_limit_test() -> score_rounded_test() -> ?assertEqual(riichi:score(20, 1, true), 200). % 160 rounded up + +score_hand_dai_san_gan_test() -> + Hand = #hand{ + tiles = lists:flatten([ + lists:duplicate(3, #tile{suit=dragon, value=red}), + lists:duplicate(3, #tile{suit=dragon, value=white}), + lists:duplicate(3, #tile{suit=dragon, value=green}), + lists:duplicate(3, #tile{suit=wind, value=east}), + lists:duplicate(2, #tile{suit=wind, value=north})]) + }, + ?assertEqual(riichi:score_hand(Hand, 30), 8000).