8

私は現在、自分で基本的な 4 行ゲームに取り組んでいますが、その背後にあるロジックにかなりこだわっています。

現在、ボードを表すこの多次元配列があります

[
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0]
]

0は空のスロットを表し、12はプレーヤーを表します。しばらくすると、次の配列が得られるとしましょう。

[
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 1, 1, 0, 0],
    [0, 0, 0, 1, 1, 0, 0],
    [0, 0, 1, 2, 2, 2, 0],
    [0, 1, 2, 2, 1, 2, 0]
]

4 つ連続しているかどうかをチェックするロジックを作成するにはどうすればよいですか? 水平線と垂直線の計算はかなり簡単に思えますが (まだ最善の方法を考え出していますが)、対角線の場合はどうすればよいでしょうか?

4

2 に答える 2

16

最善の策は、おそらく検索スペースを 4 つに分割することです。

  • 垂直;
  • 水平;
  • 右と下;
  • 右と上。

次に、方向に基づいて開始座標と終了座標を制限します。

たとえば、配列が左上にあるboard[row=0-5][col=0-6]としましょう。board[0][0]

最初の垂直方向 (ループはこの疑似コードの両端に含まれます) :

for row = 0 to 2:
    for col = 0 to 6:
        if board[row][col] != 0 and
           board[row][col] == board[row+1][col] and
           board[row][col] == board[row+2][col] and
           board[row][col] == board[row+3][col]:
               return board[row][col]

これにより、可能性がボードの端からはみ出さないものだけに制限されます。これは、各セルをチェックし、そこからすべての方向に進むことから単純化して開始する場合に、ほとんどのソリューションが抱える問題です。つまり、開始行 3 をチェックしても意味がないということです。これは、行 3、4、5、および 6 (後者は存在しません) が含まれるからです。

同様に、水平の場合:

for row = 0 to 5:
    for col = 0 to 3:
        if board[row][col] != 0 and
           board[row][col] == board[row][col+1] and
           board[row][col] == board[row][col+2] and
           board[row][col] == board[row][col+3]:
               return board[row][col]

右と下の場合、右と上が続きます。

for row = 0 to 2:
    for col = 0 to 3:
        if board[row][col] != 0 and
           board[row][col] == board[row+1][col+1] and
           board[row][col] == board[row+2][col+2] and
           board[row][col] == board[row+3][col+3]:
               return board[row][col]

for row = 3 to 5:
    for col = 0 to 3:
        if board[row][col] != 0 and
           board[row][col] == board[row-1][col+1] and
           board[row][col] == board[row-2][col+2] and
           board[row][col] == board[row-3][col+3]:
               return board[row][col]

さて、外側のループを作成して 2 回ではなく 1 回だけ実行することで、これら 2 つを実際に組み合わせることができますが、実際には、理解しやすいように (適切なコメントを付けて) 別々にしておくことを好みます。for col = 0 to 3ただし、パフォーマンスに夢中になっている場合は、次のことを試すことができます。

for col = 0 to 3:
    for row = 0 to 2:
        if board[row][col] != 0 and
           board[row][col] == board[row+1][col+1] and
           board[row][col] == board[row+2][col+2] and
           board[row][col] == board[row+3][col+3]:
               return board[row][col]
    for row = 3 to 5:
        if board[row][col] != 0 and
           board[row][col] == board[row-1][col+1] and
           board[row][col] == board[row-2][col+2] and
           board[row][col] == board[row-3][col+3]:
               return board[row][col]

次に、4 つの可能な方向で勝利が見つからない場合0は、勝者1またはの代わりに単純に戻り2ます。

たとえば、サンプル ボードは次のようになります。

row
 0   [0, 0, 0, 0, 0, 0, 0]
 1   [0, 0, 0, 0, 0, 0, 0]
 2   [0, 0, 0, 1, 1, 0, 0]
 3   [0, 0, 0, 1, 1, 0, 0]
 4   [0, 0, 1, 2, 2, 2, 0]
 5 > [0, 1, 2, 2, 1, 2, 0]
         ^
      0  1  2  3  4  5  6 <- col

、、およびがすべて に設定されている{5,1}ため、開始セルが であった右および上ループで勝者を検出します。{5,1}{4,2}{3,3}{2,4}1

于 2013-03-17T05:27:47.237 に答える
2

しばらく前に、4 連続ゲームを開発しました。以下は、4 連続条件である勝利条件をチェックするためのコード スニペットです: (これは C 言語です)

int checkWinOrLose(int grid[][7],int result,int rowNum) {
//  For checking whether any win or lose condition is reached. Returns 1 if win or lose is reached. else returns 0
//  grid[][] is the 6X7 matrix
//  result is the column number where the last coin was placed
//  rowNum is the row number where the last coin was placed

    int player=grid[rowNum][result];
    if(rowNum<=2 && grid[rowNum+1][result]==player && grid[rowNum+2][result]==player && grid[rowNum+3][result]==player) // 4 in a row vertically
        return 1;
    else {
        int count=1,i,j;
        for(i=result+1;i<7;i++) { // 4 in a row horizontally
            if(grid[rowNum][i]!=player)
                break;
            count++;
        }
        for(i=result-1;i>=0;i--) { // 4 in a row horizontally
            if(grid[rowNum][i]!=player)
                break;
            count++;
        }
        if(count>=4)
            return 1;
        count=1;
        for(i=result+1,j=rowNum+1;i<7 && j<6;i++,j++) { // 4 in a row diagonally
            if(grid[j][i]!=player)
                break;
            count++;
        }
        for(i=result-1,j=rowNum-1;i>=0 && j>=0;i--,j--) { // 4 in a row diagonally
            if(grid[j][i]!=player)
                break;
            count++;
        }
        if(count>=4)
            return 1;
        count=1;
        for(i=result+1,j=rowNum-1;i<7 && j>=0;i++,j--) { // 4 in a row diagonally
            if(grid[j][i]!=player)
                break;
            count++;
        }
        for(i=result-1,j=rowNum+1;i>=0 && j<6;i--,j++) { // 4 in a row diagonally
            if(grid[j][i]!=player)
                break;
            count++;
        }
        if(count>=4)
            return 1;
    }
    return 0;
}
于 2013-03-17T05:44:39.413 に答える