Erlangとジャンケン
SequenceableCollection >> #after: を使ってジャンケンの勝敗判定経由でPrologの話をしよう - CROSS2012・言語CROSSにあるジャンケン判定をErlangで真似てみました。
-module(janken). -compile(export_all). win(goo, choki) -> true; win(choki, par) -> true; win(par, goo) -> true; win(_, _) -> false. judge(P, P) -> even; judge(P1, P2) -> J1 = win(P1, P2), J2 = win(P2, P1), if J1 -> winner_is_p1; J2 -> winner_is_p2; end.
実際に動かしてみます…
3> janken:judge(goo, choki). winner_is_p1 4> janken:judge(goo, goo). even 5> janken:judge(goo, par). winner_is_p2
よいようです。しかし単にパターンマッチングをしているだけなので面白くないですね…。
オリジナルのPrologソースを少しいじってみました。
win(goo, choki). win(choki, par). win(par, goo). even(goo, goo). even(choki, choki). even(par, par). judge(P1, P2, winner_is_p1) :- win(P1, P2). judge(P1, P2, winner_is_p2) :- win(P2, P1). judge(P1, P2, even) :- even(P1, P2).
zinnia@tulip:/tmp[5]% gprolog GNU Prolog 1.3.0 By Daniel Diaz Copyright (C) 1999-2007 Daniel Diaz | ?- ['janken.pl']. compiling /tmp/janken.pl for byte code... /tmp/janken.pl compiled, 11 lines read - 1144 bytes written, 18 ms (1 ms) yes | ?- judge(goo, par, Result). Result = winner_is_p2 ? a % グー対パーではパーが勝つ。 no | ?- judge(par, par, Result). Result = even % パー対パーは引き分け。 yes | ?- judge(P1, par, winner_is_p1). % 相手(P2)がパーを出したときに勝てる手は? P1 = choki ? a % チョキ no | ?- judge(P1, P2, winner_is_p2). % 相手(P2)が勝つ手をすべて挙げる。 P1 = choki P2 = goo ? a P1 = par P2 = choki P1 = goo P2 = par no | ?- judge(P1, P2, Result). % すべての手と勝敗を挙げる。 P1 = goo P2 = choki Result = winner_is_p1 ? a P1 = choki P2 = par Result = winner_is_p1 P1 = par P2 = goo Result = winner_is_p1 P1 = choki P2 = goo Result = winner_is_p2 P1 = par P2 = choki Result = winner_is_p2 P1 = goo P2 = par Result = winner_is_p2 P1 = goo P2 = goo Result = even P1 = choki P2 = choki Result = even P1 = par P2 = par Result = even yes
こういう柔軟な問い合わせができるのはやっぱりPrologならではですね。