2017-03-17 8 views
1

私はGomoku AIをアレイビットボードで実装しています。私は8アレイボード(行、列、対角線/、対角線\)人間4とコンピュータ4です。各配列は整数、各行は行、列、または対角線のいずれかを表し、その上にビット単位の演算を実行できます。Gomoku AI:ビットボードを使って接続がブロックされているかどうかを調べる方法は?

public int[] humanRows = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 

人間のプレーヤーまたはコンピュータが移動を選択するたびに、そのプレーヤーに属する4つのボードがすべて更新されます。このようにして、5行で簡単にチェックすることができます。これは素晴らしい方法です。

for(int row: humanDiagonals){ 
     if ((row & (row>>1) & (row>>2) & (row>>3) & (row>>4)) != 0){ 
      return humanPiece; 
     } 
    } 

今は問題が発生します。私はすべてのパターン(open-4,4-one-end-blockedなど)を私の評価関数に与えることができるようにしたいと考えています。しかし、ビットボードを使用して正方形の3つの状態(空のX塗りつぶし、O塗りつぶし)を表現できないため、connect-4がすでにブロックされているかどうかを確認できません。 &演算子を使用してビットボードをマージすると、塗りつぶされた四角はすべて1として表され、それらを区別することはできません。 私は以下のようなメソッドを持っていますが、見ての通り、ブロックされた終了点は考慮されていません。

public int comboCount(String combo, int[] board) { 
    int count = 0; 
    int len = combo.length(); 
    for (int row : board) { 
     if (row != 0) { // if the row is not empty 
      int shiftedRow = row; 
      for (int i = 0; i < len; i++) { 
       int temp = row >> i; 
       shiftedRow &= temp; 
      } 
      String rowString = Integer.toBinaryString(shiftedRow); 
      for (int k = 0; k < rowString.length(); k++) { 
       if (rowString.charAt(k) == '1') { 
        count += 1; 
       } 
      } 
     } 
    } 
    return count; 
} 

解決策を見つけるのに役立つ人がいますか?私は、問題には単純な解決策があると感じていますが、私はそれの周りに頭を包むことができませんでした。これは初めてのことですので、可能であれば、解決策を簡単にしてください。

答えて

1

最初に片方の行に4行(ただし長くはありません)をチェックしてから、マージしたボードで長い行を確認するだけです。これらの便利な機能を使用して

...

private static boolean hasFourInRow(int row){ 
    return (row & (row >> 1) & (row >> 2) & (row >> 3)) != 0; 
} 

private static boolean hasFiveInRow(int row){ 
    return (row & (row >> 1) & (row >> 2) & (row >> 3) & (row >> 4)) != 0; 
} 

private static boolean hasSixInRow(int row){ 
    return (row & (row >> 1) & (row >> 2) & (row >> 3) & 
      (row >> 4) & (row >> 5)) != 0; 
} 

これは、あなたが簡単にあなたが言及したケースを検出する方法である。

public static void main(String[] args) { 
    int humanRow = 0b00011110; 
    int computerRow = 0b00100001; 

    if (hasFourInRow(humanRow) && !hasFiveInRow(humanRow)){ 
     int combinedRow = humanRow | computerRow; 

     if (!hasFiveInRow(combinedRow)){ 
      System.out.println("Open 4!"); 
     } else if (!hasSixInRow(combinedRow)){ 
      System.out.println("4-one-end-blocked!"); 
     } else { 
      System.out.println("4-both-ends-blocked!"); 
     } 
    }  
} 
+0

は、あなたの答えをありがとう、それは本当に私に答えていません。問題。私はボードの中で人間のためにすべての4-one-end-blockedを言うとしましょうの総数を探しています。あなたのソリューションは、各行がこのようなパターンを1つだけ表示するとうまく動作しますが、このOXXXX-OOOOXXXXOのようなケースでは機能しません。数多くの部分がすでに数えられたパターンを追加することなくマージボードを数えにくくなります。 –

+0

あなたの言っていることが分かります。そのような行の予想される出力は何でしょうか? – Junuxx

+0

上記のケースでは、4-one-end-blocked、0 4-in-a-row、および1-four-both-end-blockedの出力を得たいです –

関連する問題