強い関数を作成する

オセロゲームでは64の升目の内、駒を置ける場所は、たかだか60箇所です。
従って、60の階乗(実際には置く箇所が制限されるのでもっと少ない)を計算できれば必勝法が見つかるはずなのですが! (^_^;)
終盤の先読みで解かるように、現在のコンピュータを持ってしても「十数手が限界」です。
そこで強い人の相手が務まるようにプログラムを強くする方法を考えてみましょう。

前田稔(Maeda Minoru)の超初心者のプログラム入門

隅を取られないようにする

  1. オセロゲームでは、序盤で四隅を取られると不利になります。
  2. ゲームの手数が少ない内は、隅を取られないように「2の2」に駒を置かないようにします。
    また、隅を取るときを除いて「2の2」に置かれた相手の駒を裏返す場合も同じです。
  3. 次に大切なのが「辺の攻防」です。
    辺のパターンを分析して「相手に隅を取られないように」プレイします。
  4. 隅に駒を置けるからと言って、何時でも隅を取って良いものではありません。
    あわてて隅をとったために、別の二隅を相手に明け渡すこともあります。
  5. 隅に石が置かれると、その隅に対応する「2の2」は意味を持たなくなります。
  6. 隅が取れたときは、そこから広がるように駒を展開するのが必勝のパターンです。
  7. これらのことを考慮してプログラムを作成して下さい。
  8. 初級を相手に勝率70%が目標です。
    乱数を使っているので、対戦回数が100回ぐらいだと運が大きく左右します。
    プログラム同士で対戦するときは、200回以上対戦して下さい。

辺の攻防

隅の争奪に関する辺の攻防のパターンを解析してみましょう。
辺を取り出すメンバー関数 Getstr() が Object Class に組み込まれています。
t[8][8] から辺を一列取り出して str[8] に格納します。
no には「0~7」の範囲で、取り出す辺と格納する方向を指示します。
左上から時計回りに0~3(及び 4~7)で取り出す起点(コーナ)を指示します。
コーナを起点にして、0~3の時は時計方向に、4~7は反時計方向に列を取り出します。
void Getstr(int no, char str[8], char t[8][8]);

先手番(●)で、自分の手番で説明していますが、逆のケースも同じように考えて下さい。
  1. 手番(●)で隅を取れるときです。
    -○●------○○●●●--
    次のように隅を取ることが出来ます。
    ●●●-----●●●●●●--
  2. 相手に手を渡しても、隅を取れるときです。
    -○●○-----○●●●○--
    最も有利なタイミングで隅を取ることができます。
    ●●●○----●●●●●○--
  3. 相手の駒を挟んで裏返せるときです。
    ---○●●--
    このパターンが現れるとゲームを有利に進めることができます。
    --●●●●--
  4. 「2の1」に駒を置くので「多少嫌味」ですが取る方が有利なことが多いようです。
    --○○●●--
    -●●●●●--
  5. 前回より「もっと嫌味」が増します。
    --○●----
    取るか否かはプレーヤの好みでしょうか?
    -●●●----
  6. ここに置けば、隅を取れることが確定する場合です。
    -○-○-----○-●●○--
    相手に手を渡しても、隅を取ることが出来ます。
    -○●○-----○●●●○--
  7. 手番(●)で相手の駒を返しても、隅を取られるときです。
    -●○-○----●○-●○--
    次の相手の手番で隅を取られます。
    -●●●○----●●●●○--
  8. 相手が駒を返しても、次の手番で隅を取ることができます。
    -○●-●----○●●-●--
    上の逆のケースです。
    -○○○●----○○○○●--
  9. 「オセロバトルゲーム」の Down Load は ゲームの Down Load とプログラムの実行 を参照して下さい。

[Previous Chapter ↑] 終盤を読み切る

超初心者のプログラム入門(Win32API C++)