小时候,曾经玩一种2人的纸牌优秀,洗牌之后,一人一半,然后轮流出1张牌,压在牌桌上,越压越高,如果有人出的牌和前面某张相同的点,就把这两张牌中间的牌一起赢取,收回到自己的牌下面。这样下去直到有一方手中无牌认输。
其实,洗牌之后,就已经注定输赢了。
-module(cards). -export([shuffle/0]). -include("card.hrl"). rand_list(L1, L2)-> case length(L2) of 0 -> L1; N-> Nth = random:uniform(N), Elem = lists:nth(Nth,L2), L3 = lists:delete(Elem,L2), rand_list([Elem|L1], L3) end. create_rand_list()-> L0 = lists:seq(1,4*13,1), random:seed(), rand_list([],L0). create_times4_list(L)-> lists:map(fun (X)->lists:map(fun(Y)->#card{value=X,suit=Y} end,?suit_set) end, L). make_deck([H|Lpos],L2)-> if length(Lpos) == 0 ->[lists:nth(H, L2)]; true->[lists:nth(H, L2)|make_deck(Lpos, L2)] end. shuffle()-> L0 = lists:seq(1,13,1), L1 = create_times4_list(L0), L2 = lists:flatten(L1), L3=create_rand_list(), make_deck(L3,L2).
-module(game). -export([play_game/0,dealer/0,player/2]). -include("card.hrl"). play_game() -> P0=spawn(game, dealer, []), io:format("spawn dealer ~p~n",[P0]). dealer() -> random:seed(now()), DealerPid = self(), Deck = cards:shuffle(), {P1Cards, P2Cards} = lists:split(trunc(length(Deck) / 2), Deck), P1 = spawn(game, player, [DealerPid, P1Cards]), io:format("spawn player ~p with ~p~n",[P1, P1Cards]), P2 = spawn(game, player, [DealerPid, P2Cards]), io:format("spawn player ~p with ~p~n",[P2, P2Cards]), P2!{show_card}, dealer([P1, P2], await_card, P2, []). loc(Card, [H|NCards]) -> if Card#card.value == H#card.value -> 1; length(NCards) == 0 -> error_logger:warning_msg("no same card!~n"), -1024; true -> loc(Card, NCards) + 1 end. win_card(H,NCards) -> Nth = loc(H, NCards), if Nth > 0 -> {First, Second} = lists:split(Nth, NCards), {[H|First], Second}; true -> [] end. opponent(Pids, Pid)-> [P1, P2] = Pids, if P1 == Pid -> P2; true -> P1 end. dealer(Pids, State, Pid, NCards) -> io:format("~p ~p~n",[State, NCards]), case State of await_card -> receive {accept, Pid, Card} -> dealer(Pids, check_cards, Pid, [Card|NCards]); {give_up, Pid} -> io:format("~p give up! ~p is the winner~n", [Pid, opponent(Pids, Pid)]), end_game(Pids) after 2000 -> io:format("~p timeout! ~p is the winner~n", [Pid, opponent(Pids, Pid)]), end_game(Pids) end; check_cards -> [TopCard|RemCards] = NCards, case lists:member(TopCard#card.value, lists:map(fun(X)->X#card.value end,RemCards)) of true -> {WinnedCards, RemtainedCards} = win_card(TopCard, RemCards), Pid ! {give_card, WinnedCards}, dealer(Pids, await_card, Pid, RemtainedCards); false -> opponent(Pids,Pid)! {show_card}, dealer(Pids, await_card, opponent(Pids,Pid), NCards) end end. end_game(Pids) -> lists:foreach(fun(Process) -> exit(Process, kill) end, Pids), io:format("Game finished.~n"). player(Dealer, Cards) -> receive {show_card} -> if length(Cards) =< 0 -> Dealer!{give_up, self()}; true -> [H|RemCards] = Cards, Dealer!{accept, self(), H}, player(Dealer, RemCards) end; {give_card, GivenCards} -> [H|RemCards] = Cards++GivenCards, Dealer!{accept, self(), H}, player(Dealer, RemCards) end.
card.hrl:
-define(suit_set, ["Clubs","Diamonds","Hearts","Spades"]). -record(card, {value, suit}).
>erlc cards.erl
>erlc games.erl
>erl
game:play_game().
<0.322.0> give up! <0.323.0> is the winner
Game finished