mirror of
https://github.com/correl/riichi.git
synced 2024-11-14 19:19:31 +00:00
Improved hand and meld records
This commit is contained in:
parent
44e9beeca3
commit
15860dfdad
3 changed files with 46 additions and 59 deletions
|
@ -1,21 +1,21 @@
|
||||||
|
-type wind() :: east | south | west | north.
|
||||||
|
-type dragon() :: green | red | white.
|
||||||
|
|
||||||
-record(tile, {
|
-record(tile, {
|
||||||
suit,
|
suit :: pin | man | sou | wind | dragon,
|
||||||
value
|
value :: integer() | wind() | dragon(),
|
||||||
|
from=draw :: draw | wind()
|
||||||
}).
|
}).
|
||||||
|
-type tile() :: #tile{}.
|
||||||
|
|
||||||
|
-record(meld, {
|
||||||
|
type :: pair | chii | pon | kan,
|
||||||
|
tiles :: [tile()]
|
||||||
|
}).
|
||||||
|
-type meld() :: #meld{}.
|
||||||
|
|
||||||
-record(hand, {
|
-record(hand, {
|
||||||
tiles=[],
|
tiles=[] :: [tile()],
|
||||||
sets=[],
|
melds=[] :: [meld()]
|
||||||
seqs=[]
|
|
||||||
}).
|
|
||||||
|
|
||||||
-record(set, {
|
|
||||||
count,
|
|
||||||
tile,
|
|
||||||
open=true
|
|
||||||
}).
|
|
||||||
|
|
||||||
-record(seq, {
|
|
||||||
tiles,
|
|
||||||
open=true
|
|
||||||
}).
|
}).
|
||||||
|
-type hand() :: #hand{}.
|
||||||
|
|
|
@ -10,21 +10,16 @@ find(Tiles) ->
|
||||||
find([], Hand, Possible) ->
|
find([], Hand, Possible) ->
|
||||||
[Hand|Possible];
|
[Hand|Possible];
|
||||||
|
|
||||||
find(Tiles, Hand = #hand{tiles=HT, sets=HS}, Possible) ->
|
find(Tiles, Hand = #hand{tiles=HT, melds=HM}, Possible) ->
|
||||||
case Tiles of
|
|
||||||
[T, T, T, T|Rest] ->
|
|
||||||
find(Rest, Hand#hand{sets=[#set{count=4, tile=T, open=false}|HS]}, Possible);
|
|
||||||
_ -> []
|
|
||||||
end ++
|
|
||||||
case Tiles of
|
case Tiles of
|
||||||
[T, T, T|Rest] ->
|
[T, T, T|Rest] ->
|
||||||
find(Rest, Hand#hand{sets=[#set{count=3, tile=T, open=false}|HS]}, Possible);
|
find(Rest, Hand#hand{melds=[#meld{type=pon, tiles=[T, T, T]}|HM]}, Possible);
|
||||||
_ ->
|
_ ->
|
||||||
[]
|
[]
|
||||||
end ++
|
end ++
|
||||||
case Tiles of
|
case Tiles of
|
||||||
[T, T|Rest] ->
|
[T, T|Rest] ->
|
||||||
find(Rest, Hand#hand{sets=[#set{count=2, tile=T, open=false}|HS]}, Possible);
|
find(Rest, Hand#hand{melds=[#meld{type=pair, tiles=[T, T]}|HM]}, Possible);
|
||||||
_ ->
|
_ ->
|
||||||
[]
|
[]
|
||||||
end ++
|
end ++
|
||||||
|
@ -32,7 +27,7 @@ find(Tiles, Hand = #hand{tiles=HT, sets=HS}, Possible) ->
|
||||||
[T1 = #tile{value=V1, suit=S}, T2 = #tile{value=V2, suit=S}, T3 = #tile{value=V3, suit=S}|_] when
|
[T1 = #tile{value=V1, suit=S}, T2 = #tile{value=V2, suit=S}, T3 = #tile{value=V3, suit=S}|_] when
|
||||||
is_integer(V1) andalso
|
is_integer(V1) andalso
|
||||||
[V1, V2, V3] =:= [V1, V1 + 1, V1 + 2] ->
|
[V1, V2, V3] =:= [V1, V1 + 1, V1 + 2] ->
|
||||||
find(Tiles -- [T1, T2, T3], Hand#hand{sets=[#seq{tiles=[T1, T2, T3], open=false}|HS]}, Possible);
|
find(Tiles -- [T1, T2, T3], Hand#hand{melds=[#meld{type=chii, tiles=[T1, T2, T3]}|HM]}, Possible);
|
||||||
_ ->
|
_ ->
|
||||||
[]
|
[]
|
||||||
end ++
|
end ++
|
||||||
|
@ -41,12 +36,12 @@ find(Tiles, Hand = #hand{tiles=HT, sets=HS}, Possible) ->
|
||||||
find(Rest, Hand#hand{tiles=[T|HT]}, Possible)
|
find(Rest, Hand#hand{tiles=[T|HT]}, Possible)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
is_complete(#hand{tiles=[], sets=Sets}) ->
|
is_complete(#hand{tiles=[], melds=Melds}) ->
|
||||||
Pairs = [S || S <- Sets, S#set.count =:= 2],
|
Pairs = [M || M <- Melds, M#meld.type =:= pair],
|
||||||
case length(Pairs) of
|
case length(Pairs) of
|
||||||
1 ->
|
1 ->
|
||||||
% Four mentsu + 1 pair = 5 sets
|
% Four mentsu + 1 pair = 5 sets
|
||||||
length(Sets) =:= 5;
|
length(Melds) =:= 5;
|
||||||
7 ->
|
7 ->
|
||||||
% Must be seven *unique* pairs
|
% Must be seven *unique* pairs
|
||||||
sets:size(sets:from_list(Pairs)) =:= 7;
|
sets:size(sets:from_list(Pairs)) =:= 7;
|
||||||
|
@ -57,9 +52,9 @@ is_complete(#hand{}=Hand) ->
|
||||||
kokushi_musou(Hand).
|
kokushi_musou(Hand).
|
||||||
|
|
||||||
% 13 Orphans
|
% 13 Orphans
|
||||||
kokushi_musou(#hand{tiles=Tiles, sets=Sets}) when
|
kokushi_musou(#hand{tiles=Tiles, melds=Melds}) when
|
||||||
length(Tiles) =:= 13
|
length(Tiles) =:= 13
|
||||||
andalso length(Sets) =:= 0 ->
|
andalso length(Melds) =:= 0 ->
|
||||||
not lists:any(fun(#tile{value=V}) ->
|
not lists:any(fun(#tile{value=V}) ->
|
||||||
lists:member(V, lists:seq(2,8))
|
lists:member(V, lists:seq(2,8))
|
||||||
end,
|
end,
|
||||||
|
|
50
src/yaku.erl
50
src/yaku.erl
|
@ -5,21 +5,23 @@
|
||||||
-compile([export_all]).
|
-compile([export_all]).
|
||||||
|
|
||||||
|
|
||||||
yakuhai(#hand{sets=Sets}) ->
|
yakuhai(#hand{melds=Melds}) ->
|
||||||
length(lists:filter(fun(T = #tile{}) ->
|
length(lists:filter(fun(#meld{type=Type, tiles=[T|_]}) ->
|
||||||
case T#tile.suit of
|
case {Type, T} of
|
||||||
wind ->
|
{pair, _} ->
|
||||||
|
false;
|
||||||
|
{chii, _} ->
|
||||||
|
false;
|
||||||
|
{_, #tile{suit=wind}} ->
|
||||||
% TODO: Round/Seat Winds
|
% TODO: Round/Seat Winds
|
||||||
false;
|
false;
|
||||||
dragon ->
|
{_, #tile{suit=dragon}} ->
|
||||||
true;
|
true
|
||||||
_ ->
|
|
||||||
false
|
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
Sets)).
|
Melds)).
|
||||||
|
|
||||||
tanyao(#hand{sets=Sets}) ->
|
tanyao(#hand{melds=Melds}) ->
|
||||||
not lists:any(fun(T = #tile{}) ->
|
not lists:any(fun(T = #tile{}) ->
|
||||||
case T#tile.suit of
|
case T#tile.suit of
|
||||||
dragon ->
|
dragon ->
|
||||||
|
@ -30,32 +32,22 @@ tanyao(#hand{sets=Sets}) ->
|
||||||
lists:member(T#tile.value, [1,9])
|
lists:member(T#tile.value, [1,9])
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
Sets).
|
lists:flatten([Tiles || #meld{tiles=Tiles} <- Melds])).
|
||||||
|
|
||||||
pinfu(#hand{sets=Sets}) ->
|
pinfu(#hand{melds=Melds}) ->
|
||||||
% TODO: Verify closed, open wait, pair not round/seat wind
|
% TODO: Verify closed, open wait, pair not round/seat wind
|
||||||
lists:all(fun(S) ->
|
length([M || M = #meld{type=T} <- Melds, T =:= chii]) =:= 4.
|
||||||
case S of
|
|
||||||
#seq{} ->
|
|
||||||
true;
|
|
||||||
_ ->
|
|
||||||
false
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
[S || S <- Sets]).
|
|
||||||
|
|
||||||
% 7 Pairs
|
% 7 Pairs
|
||||||
chiitoitsu(#hand{tiles=[], sets=Sets})
|
chiitoitsu(#hand{tiles=[], melds=Melds})
|
||||||
when length(Sets) =:= 7 ->
|
when length(Melds) =:= 7 ->
|
||||||
Pairs = [S || S <- Sets, S#set.count =:= 2],
|
Pairs = [S || S <- Melds, S#meld.type =:= pair],
|
||||||
length(Pairs) =:= 7 andalso sets:size(sets:from_list(Pairs)) =:= 7.
|
length(Pairs) =:= 7 andalso sets:size(sets:from_list(Pairs)) =:= 7.
|
||||||
|
|
||||||
% 13 Orphans
|
% 13 Orphans
|
||||||
kokushi_musou(#hand{tiles=Tiles, sets=Sets})
|
kokushi_musou(#hand{tiles=Tiles, melds=[#meld{type=pair, tiles=[T,T]}]}) ->
|
||||||
when length(Tiles) =:= 13
|
|
||||||
andalso length(Sets) =:= 0 ->
|
|
||||||
not lists:any(fun(#tile{value=V}) ->
|
not lists:any(fun(#tile{value=V}) ->
|
||||||
lists:member(V, lists:seq(2,8))
|
lists:member(V, lists:seq(2,8))
|
||||||
end,
|
end,
|
||||||
Tiles)
|
[T|Tiles])
|
||||||
andalso sets:size(sets:from_list(Tiles)) =:= 13.
|
andalso sets:size(sets:from_list([T|Tiles])) =:= 13.
|
||||||
|
|
Loading…
Reference in a new issue