ゼロとクロスのゲームで勝利の動きを検出する最良の方法を知る必要があります. ソース コードは問題ではありません。サンプルまたは何かを開始できるものが必要なだけです。
私が思いつくことができる唯一のことは、ループを使用して、プレーヤーが行うすべての動きに対してすべての方向をテストし、たとえば 5 つ続けて検索することです。より高速で効率的な方法はありますか?
ゼロとクロスのゲームで勝利の動きを検出する最良の方法を知る必要があります. ソース コードは問題ではありません。サンプルまたは何かを開始できるものが必要なだけです。
私が思いつくことができる唯一のことは、ループを使用して、プレーヤーが行うすべての動きに対してすべての方向をテストし、たとえば 5 つ続けて検索することです。より高速で効率的な方法はありますか?
本当に簡単な解決策は、最後に行った動きからチェックすることです...明らかに、前の動きがゲームに勝つことはできなかったか、ここにいないでしょう...したがって、5つあるかどうかを確認する必要があります(または、多くの場合)配置されたばかりの移動の周りの行/列/対角線。
たとえば、ボードが次のようになり、Xが最新の動きをマークする場合:
.............
.............
.............
.............
.....X.......
.............
.............
.............
.............
.............
「C」の範囲外のものをチェックする必要はありません。
.C...C...C...
..C..C..C....
...C.C.C.....
....CCC......
.CCCCXCCCC...
....CCC......
...C.C.C.....
..C..C..C....
.C...C...C...
.............
それは役に立ちますか?(元の質問でこれをほのめかしているように見えましたが、よくわかりませんでした。)
これを超えて、単純なループがあなたの親友になるでしょう。おそらくいくつかのマイクロ最適化を行うことができますが、(実際のアプリケーションが何をしているかにもよりますが)おそらくそれだけの価値はありません。
追跡しなければならないことの1つは、この動きがストリークの途中である可能性があるため、最新の動きから5を飛び出して、連続してその数を探すことはできないということです。だから私は次のようなことをします
From the new move
left = how many in a row we have to the left of the lastest move
right = how many in a row we have to the right of the latest move
if (left + right + 1 >= 5) then you have a winner
up = how many in a row we have above the latest move
down = how many in a row we have below the latest move
if (up + down + 1 >= 5) then you have a winner
// repeat for both diagonal directions.
問題を単純化するために使用できる数学的なトリックがたくさんあるため、ゼロとクロスはプログラミングの難題です。
ゼロとクロスは通常、3 行 3 列のグリッドです。グリッドの各位置に 1 から 9 までの数字 (番号順ではない) を割り当てると、水平、垂直、斜めの各行の合計が 15 になるように数字を並べ替えることができます。
+----+----+----+
| 4 | 3 | 8 |
| | | |
+----+----+----+
| 9 | 5 | 1 |
| | | |
+----+----+----+
| 2 | 7 | 6 |
| | | |
+----+----+----+
なぜそれが役立つのですか?「O」または「X」のいずれかに属する任意の 3 つのマスを選択でき、それらの 3 つのマスの合計が 15 になる場合、そのプレイヤーがゲームに勝ったことがわかります。
3X3 ボードを検討してください
X = 1 とすると、O = -1 とし、スペースはゼロで表されます。
したがって、一番上の行がこの [X][X][X] のように見える場合、合計は 3 であるため、勝利です [O][O][O] 合計は -3 であるため、もう一方の勝利です。
[X][X][ ] は 2 なので、X ターンの場合、彼は空白に移動して勝つか、O がブロックする必要があります。
[X][O][X] が 1 であるため、勝ちはありません。
3x3 ボードでは、評価する 8 つのポジションがあります。
NXNでは数字は大きくなりますが、考え方は同じです
N=8 で、行または列の合計が 7 の場合、その行または列に X の勝ち手があることがわかります。
その方法は、高校時代の私に有効でした。
幸運をお祈りしています
悪の
ループよりも優れた方法を認識していませんが、ボードは非常に小さいため、非常に簡単です。
ちょっとした Python 疑似コード:
def get_winner(board):
if board[0][0] != EMPTY and board[0][0] == board[1][1] == board[2][2]:
return board[0][0]
if board[2][0] != EMPTY and board[2][0] == board[1][1] == board[0][2]:
return board[2][0]
for i in xrange(3):
if board[i][0] != EMPTY and board[i][0] == board[i][1] == board[i][2]:
return board[i][0]
if board[0][i] != EMPTY and board[0][i] == board[1][i] == board[2][i]:
return board[0][i]
それは表現の問題です。ゲームボードはどのように保管しますか?今、箱の外で考えてください。他にどのようにそれを保存できますか?たとえば、ボードをビットマップのペア(1つはnought用、もう1つはcross用)として表現し、数値パターンマッチングを実行して勝利条件を検出することができます。
より効率的な方法はありますが、このゲームを非常に大きなボード構成に拡張する場合にのみ重要になります。たとえば、ゼロとクロスのグループを方向オブジェクトに格納した場合 (たとえば、対角線構成を格納する)、長さwinLength-1
でソートし、これらのグループに対してのみ新しい移動をテストできます。いくつかの反復を節約できますが、多くの余分な情報をメモリに保持する必要があります。