2016-08-21 2 views
1

私はスペース、XまたはOのいずれかが入力された6 * 7 2D char配列のConnect Four "ボード"を持っています。 4つのXまたは4つのOsを縦方向、横方向または斜め方向に一列に並べる。投げずに、Java:対角線をチェックする方法Connect 4が2D配列で勝利

private char CheckVerticalWinner(char[][] currentBoard) { 
    // check vertical (move down one row, same column) 
    char vWinner = ' '; 
    for (int col=0; col<7; col++) { 
     int vCount = 0; 
     for (int row=0; row<5; row++) { 
      if (currentBoard[row][col]!=' ' && 
       currentBoard[row][col] == currentBoard[row+1][col]) { 
       vCount++; 
       System.out.println("VERT "+vCount); //test 
      } else { 
       vCount = 1; 
      } 

      if (vCount>=4) { 
       vWinner = currentBoard[row][col]; 
      } 
     } 
    } 
    return vWinner; 
} 


private char CheckHorizontalWinner(char[][] currentBoard) { 
    // check horizontal (move across one column, same row) 
    char hWinner = ' '; 
    for (int row=0; row<6; row++) { 
     int hCount = 0; 
     for (int col=0; col<6; col++) { 
      if (currentBoard[row][col]!=' ' && 
       currentBoard[row][col] == currentBoard[row][col+1]) { 
       hCount++; 
       System.out.println("HORIZ "+hCount); //test 
      } else { 
       hCount = 1; 
      } 

      if (hCount>= 4) { 
       hWinner = currentBoard[row][col]; 
      } 
     } 
    } 
    return hWinner; 
} 

私はちょうど対角線の勝利のためにチェックする方法にこだわって:私は勝利条件が勝利charは以下のようにいくつかのメソッドによって返される場合、垂直方向と水平方向のため、正常にチェックを得ることができましたArrayIndexOutOfBoundsException

Diagonals to be checked diagram基本的に

、どのようになります:私は、私は下の図のように、4つの正方形長いか以上ある後方対角線に一度、前方対角線用と1回、2回、2次元配列を反復処理する必要があります知っています私は勝利のチャーを返すためにこのメソッドを記入しますか?

private char CheckDiagonalWinner(char[][] currentBoard) { 

    // some iteration here 

    return dWinner; 
} 

ご協力いただければ幸いです。

+0

はそれがボードの範囲を超えてから自分を防止する簡単な問題ではないですか? N x M板の場合、右対角線の場合は '(0,0)'の部分行列を '(N-4、M-4)'とみなし、左から右下。 –

+0

推奨として、グリッドの開始行と列を受け入れ、少なくとも4つの値に対して特定の方向に「スキャン」するメソッドを作成することをお勧めします。行に4つの値がある場合のブール値を返すことができます。 –

+1

ヒント:より意味のある抽象を思いついてみてください:文字の2次元配列を使うことは、あなたの目的にとって非常に低レベルの抽象です。代わりに、列挙型を使用してボード内のセルを表すことができます。言い換えれば、行列が2次元配列でなければならないという「即時」の考え方には向かないでください。あなたの細胞を整理する別の形が他のことをはるかに容易にするかもしれないと思ったら、少し時間を費やしていました。 – GhostCat

答えて

4

最も単純なアルゴリズムは、おそらくです:コード内

for every direction 
    for every coordinate 
     check whether the next 3 elements in this direction exist and are the same 

final int maxx = 7; 
final int maxy = 6; 

char winner(char[][] board) { 
    int[][] directions = {{1,0}, {1,-1}, {1,1}, {0,1}}; 
    for (int[] d : directions) { 
     int dx = d[0]; 
     int dy = d[1]; 
     for (int x = 0; x < maxx; x++) { 
      for (int y = 0; y < maxy; y++) { 
       int lastx = x + 3*dx; 
       int lasty = y + 3*dy; 
       if (0 <= lastx && lastx < maxx && 0 <= lasty && lasty < maxy) { 
        char w = board[x][y]; 
        if (w != ' ' && w == board[x+dx][y+dy] 
           && w == board[x+2*dx][y+2*dy] 
           && w == board[lastx][lasty]) { 
         return w; 
        } 
       } 
      } 
     } 
    } 
    return ' '; // no winner 
} 
+0

簡単な解決に感謝します。私はちょうどそれを試したが、ArrayIndexOutOfBoundsExceptionsの束をそのまま投げる。あなたがどこに行ったのか分かりますが、これを修正するためにどのループを修正するのか分かりにくいだけです... –

+0

私に例外を投げかけません。私たちはボードの大きさに同意していますか? (私が仮定したようにボード[7] [6]ですか、ボード[6] [7] ')ですか? – meriton

+0

ああ、ちょうど私の質問の誤植を実現しました。私のコードでは、実際には 'board [6] [7]'です。それを指摘してくれてありがとう、そして解決のために! –

2

まず、ボード全体をいつでも確認する必要はありません。あなたのコードで実行されていると思います。

ボードの任意の方向を確認する前に、まずボードにユーザー入力を入力してください。コードを最適化してユーザーとコンピューターの両方で簡単にすることができます。つまり、新しい入力を得るたびに、その入力を使用してマトリックスを更新することです。こうして私たちは常に行列を更新し、次に行うことを実行できます:

ユーザーからの入力のxとyを取得します。つまり、ユーザーが2行目を選択すると、2行目と4列目に行列が設定されます。これらの座標はどうしますか? THEMを使用して行列を4行でチェックするメソッドに送ります。これにより、行列全体をチェックするのではなく、入力された行列のみをチェックすることができます。垂直方向のチェックで

、あなたは今、たとえば、それらの座標からだけダウンチェックすることができます:水平方向、水平方向のチェックのために

boolean winner = false; 

count = 1; 

if (x > 3) 

for (i = 0; i < 3; i++) { 

    if (A[x][y-i] == 'X') 

     count ++; 

    if (count == 4) { 

     winner = true; 

     return; 

    } 

同じことを行うが、。左と右を確認するには、2つのループが必要です。

対角線のチェックでは、セット座標を含む対角をチェックするだけで済みます。たとえば、ユーザーが行4と列5を入力した場合、左の対角線について、(5,4)、(6,3)および(7,2)をチェックする必要があります。

座標を使用して勝者を確認する方がはるかに簡単です。これにより、行列の人口部分だけを確認することができます。

ご不便をおかけして申し訳ありませんが、お電話でこれを書いて、後で必要に応じていくつかの例を追加して追加できます。

+0

挿入された最後の要素が4の中央にある場合はどうなりますか? (左側の2つの要素と右側の要素が等しい場合は、勝者もあります...) – meriton

+0

ループのために左と右の両方に++を数えるだけで終わりの文字に達したら、ループ。このコードはちょっとした作業が必要ですが、私は完全に動作する例を与えませんでした。しかし、OPのコードは、誤解がなければO(n^2 + n^2 + 4n)の複雑さを持ちます.nは7×6です。 – leonz

関連する問題