初歩的なように見えて、これで状態遷移とか、対話型とか、アルゴリズムの優先順位とか、後で応用が利きそうなテーマも含まれていたりする。
■ 状態遷移
ゲームの状態遷移は下図のようになる。ひとたび Java コードから fireAllRules() して開始したら、勝敗が決まるか引分けになるまで、遷移に関しては Drools に一任したい。
■ 対話型
ユーザの番のとき、マス目の番号をコンソールから受け付ける入力ロジックを、RHS (ルールのアクション部分) で実行する。non-deterministic な(実行のたびに異なる)要素をルールの実行に組み入れてみたいというのが趣旨。
■ アルゴリズムの優先順位付け
wikipedia のこのエントリを参考にした。
高優先順位の順に、以下のようなマス目の選び方になる。
- 後一手で列が完成する盤面なら、その列を完成して終了。
- ユーザが後一手で一列完成できる盤面なら、それをブロックする。
- 後一手で二方向の王手が作れる盤面なら、それを作る。
- ユーザが後一手で二方向の王手が作れる盤面なら、ブロックする。
- 中央が空いていたら、そこに置く。
- 相手が角を取っていて対角が空いていたら、そこに置く。
- 角が空いていたらそこに置く。
- 空いているマスがあったら、そこに置く。
こういうのは手続き型とは大幅に違うコーディングになるので、面白い。Prolog みたいな宣言型論理プログラミングとも、やっぱり違っていてなんか独特。
■ 実行
実行は Eclipse 3.5 Galileo + Drools plugin 5.0.1でやってみた。ユーザ入力は Eclipse のコンソールビューを用いている。
(ちなみに Drools プラグインのデバッグ機能の Working Memory ビューを使おうとすると、実行時にエラーが出てさっぱり動かないが、これは Drools が Eclipse 3.5 に対応していないかららしい。Drools 5.1 では 直っているらしいが、まだ update サイトにないので、今回は見送った。[参考URL])
こんな感じの実行結果になる。
first player? (y/n)
y
<user> input cell number(0-8): 5
- - -
- - u
- - -
<machine> strategy = Center
- - -
- m u
- - -
<user> input cell number(0-8): 1
- u -
- m u
- - -
<machine> strategy = Block Opponent^s Fork
- u m
- m u
- - -
<user> input cell number(0-8): 6
- u m
- m u
u - -
<machine> strategy = Empty Corner
- u m
- m u
u - m
<user> input cell number(0-8): 0
u u m
- m u
u - m
<machine> strategy = Block
u u m
m m u
u - m
<user> input cell number(0-8): 7
== draw!
u u m
m m u
u u m
次ポストでは、コードをさらしてみる。
0 件のコメント:
コメントを投稿