Set and sequence detection

This commit is contained in:
Correl Roush 2012-07-02 22:05:05 -04:00
parent 6390496db4
commit c13705c2c2
3 changed files with 72 additions and 0 deletions

View file

@ -13,3 +13,8 @@
tile, tile,
open=true open=true
}). }).
-record(seq, {
tiles,
open=true
}).

43
src/riichi_hand.erl Normal file
View file

@ -0,0 +1,43 @@
-module(riichi_hand).
-include("riichi.hrl").
-compile([export_all]).
find_sets(Tiles) ->
Unique = sets:to_list(sets:from_list(Tiles)),
[#set{count=length(lists:filter(fun(X) -> X == T end, Tiles)), tile=T, open=false}
|| T <- Unique].
reorder_seqs(Tiles) ->
Unique = sets:to_list(sets:from_list(Tiles)),
lists:sort(Unique) ++ (Tiles -- Unique).
find_seqs(Tiles) ->
find_seqs(reorder_seqs(Tiles), {[], []}).
find_seqs([], {Seqs, Rest}) ->
{lists:sort(Seqs), lists:sort(Rest)};
find_seqs([T1 = #tile{suit=Suit}, T2 = #tile{suit=Suit}, T3 = #tile{suit=Suit} | Tiles], {Seqs, Rest})
when T2#tile.value =:= (T1#tile.value + 1)
andalso T3#tile.value =:= (T2#tile.value + 1) ->
find_seqs(reorder_seqs(Tiles), {[#seq{tiles=[T1, T2, T3], open=false} | Seqs], Rest});
find_seqs([T | Tiles], {Seqs, Rest}) ->
find_seqs(Tiles, {Seqs, [T | Rest]}).
perms([]) -> [[]];
perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].
combinations(0, _) -> [[]];
combinations(_, []) -> [];
combinations(N, [X|XS]) -> [[X|YS] || YS <- combinations(N-1, XS)] ++ combinations(N, XS).
find_hands(Tiles) ->
find_hands(Tiles, []).
find_hands([], Hands) ->
Hands;
find_hands([_T | _Remaining] = Tiles, Hands) ->
[#hand{tiles=Tiles} | Hands].

View file

@ -0,0 +1,24 @@
-module(riichi_hand_tests).
-include("riichi.hrl").
-include_lib("eunit/include/eunit.hrl").
find_sets_test() ->
Tiles = [#tile{suit=man, value=V} || V <- lists:seq(1,8)],
Expected = {[
#seq{tiles=[#tile{suit=man, value=V} || V <- lists:seq(1,3)], open=false},
#seq{tiles=[#tile{suit=man, value=V} || V <- lists:seq(4,6)], open=false}
],
[#tile{suit=man, value=V} || V <- lists:seq(7,8)]
},
?assertEqual(Expected, riichi_hand:find_seqs(Tiles)).
find_duplicate_sets_test() ->
Tiles = [#tile{suit=man, value=V} || V <- lists:seq(1,3), _ <- lists:seq(1,3)] ++
[#tile{suit=man, value=4} || _ <- [1,2]],
Expected = {[
#seq{tiles=[#tile{suit=man, value=V} || V <- lists:seq(1,3)], open=false}
|| _ <- [1,2,3]
],
[#tile{suit=man, value=4} || _ <- [1,2]]
},
?assertEqual(Expected, riichi_hand:find_seqs(Tiles)).