RensaYomi6クラスで実装されているAI-COMロジックについて,説明する.


優先順位とルール

  • 1.窒息しないこと
  • 2.適切なタイミングで発火する (発火のタイミング参照)
  • 3.発火候補点で発火したと仮定したときに生じる連鎖数(NEXT〜NEXT3まで考慮) と 同色連結個数
  • 4.できるだけ下に置く
  • 5.できるだけ端の列に置く

今回の変更箇所は2,3,5である. 安定して7連鎖程度を作成し,発火することを目標とした.


各ルールの意味

2.適切なタイミングで発火する

RensaYomi4までは,危機になったら発火するというロジックだったが(下図),

今回は,危険度を判断して,

もし連鎖を伸ばす余裕がありそうであれば発火を延長するというロジックになっている. 具体的な内容については,発火のタイミングを参照.

このロジックを採用したことにより,危険度=Red3の時はNEXT3までの読み(3手読み)を行うわけだが,こいつにかなり処理時間がかかっている.

3.発火候補点で発火したと仮定したときに生じる連鎖数(NEXT〜NEXT3まで考慮)

これはRensaYomi4で使っているロジックとよく似ている.

違いは,例えば2手読みの場合,

  1. NEXTを置いた状態で,発火候補点で発火する
  2. NEXTとNEXT2を置いた状態で,発火候補点で発火する

という結果をシミュレートして, RensaYomi4の場合は,

  • 連鎖数の評価式 = max([1.の連鎖数], [2.の最大連鎖数])

であったが,RensaYomi6の場合は,

  • 連鎖数の評価式 = [2.の最大連鎖数] + [1.の連鎖数] / 2

という風に,重み付きで足し合わせるようにしている.

どうも色々試してみると,両方組み合わせた方が良い結果が得られるようだ.

連鎖数の評価式

既に少し触れたが,今回使用した連鎖数の評価式を下表にまとめる.

危険度連鎖数の評価式
Normal[NEXT2の最大連鎖数] + [NEXTの連鎖数] / 2
Red3[NEXT3の最大連鎖数] + [NEXT2の最大連鎖数] / 2 + [NEXTの連鎖数] / 4
Red2[NEXT2の最大連鎖数] + [NEXTの連鎖数] / 2
Red1[NEXTの連鎖数]

同色連結個数

実は今回ルールとしてあげていないが,連鎖数の評価式の中に,その積みを置いたときの同色連結個数も忍ばせている. これがないと,連鎖が全然できていない状態の時にバラバラでどうしようもない積みになってしまう. やはり,同色連結個数ルールは基本です.

上述の[NEXTの連鎖数]は,実際には以下の式で読み替える必要がある.

  • NEXTの連鎖数 = NEXTの連鎖数(本当の連鎖数) + 同色連結個数 / 2

同色連結個数を2で割っているのは,もしそのまま足すと,発火タイミングの判定で誤差が出てしまうことが理由. 発火タイミングの判定ではNEXT〜NEXT3間で連鎖数の比較をしているので, 余計な値が足されていてはまずい.

まぁ,発火タイミング判定用と連鎖数評価用で,別々にメモリに持たせればいいっちゃいいのですが...

発火候補点の条件

  • k個以上連結している
  • 上右左のいずれかが空白である (積みの到達可能位置である)

kはさんざん試行錯誤した結果,下表の通りとなった.

危険度k(NEXTに適用)k(NEXT2に適用)k(NEXT3に適用)
Normal33-
Red3433
Red244-
Red144-

ちなみにRensaYomi4の場合を同じ形式で表にすると,

k(NEXTに適用)k(NEXT2に適用)k(NEXT3に適用)
いつでも23-

だったということになる.

今回試した結果,どうもk=2だと積みがばらけてしまう傾向が見られたので,3または4を使うようにしている(処理速度への配慮もある).

5.できるだけ端の列に置く

そのままです. できるだけ窒息を起こりにくくするということで,今まで入れてなかったのが不思議とも言えるルール.

以下のように,中央列(X=2)との差の絶対値を評価式とする.

  • 評価式 = 絶対値([積みのX位置] - 2)


枝刈りによる高速化

できる限り,枝刈りは行っている.

1.と2.で棄却された手は,それ以降の処理をはしょっている.


総括

さんざん苦労したが,かなり安定して7連鎖程度出せるようになったと思う.

後はスピードの遅さか...難しいな.

kamolandをフォローしましょう


© 2017 KMIソフトウェア