優勝ポジションには次の特性があります。
- すべてのターミナルポジションが勝っています。この場合、ポジション(8、8)が勝ちポジションです。
- ステップでゴールポジションに到達できるすべてのポジションが勝利ポジションです。つまり、最後の行または列のすべてのポジションが勝ちポジションです
- 次のプレーヤーはゲームに勝つことができないので、負けたポジションに移動できる場合、私たちは勝ったポジションにいます。
- 勝ちポジションにしか移動できない場合は、負けポジションになります
そのことを念頭に置いて、現在のポジションが勝ちポジションか負けポジションかを判断できるアルゴリズムを作成できます。以前に計算された結果を格納するためにテーブル(dpTable
)を使用すると、繰り返し計算を行う必要がなくなります。
boolean isWinning(int x, int y) {
if (dpTable[x][y] != null)
return dpTable[x][y];
// From the last row or the last column we can always win the game
if (x == n || y == n)
return true;
for (int i = 1; x + i <= n; i++) {
// Moving right
if (x + i <= n && !isWinning(x+i, y) {
dpTable[x][y] = true;
return true;
}
// Moving down
if (y + i <= n && !isWinning(x, y+i) {
dpTable[x][y] = true;
return true;
}
}
dpTable[x][y] = false;
return false;
}
このisWinning(x, y)
関数はtrue
、位置(x、y)から開始すると、最適にプレイしてゲームに勝つことができ、(x、y)false
から開始して勝つ方法がない場合に戻ります。