1

私は約4か月間Javaを学んでいます。これは、私が学ぶ最初のプログラミング言語です。学校では、コンソールベースのゲームであるプロジェクトを実行する必要があります。私はBoggleを選びました。

私はサイコロを持ったArrayListを持っていて、それぞれがランダムな「サイドアップ」を取得し、次にArrayListがシャッフルされ、2次元配列が各サイドアップの値で満たされます。現時点では、配列は文字列で埋められています。文字の方が適している場合もありますが、変更はかなり簡単です。

私が直面している問題は、配列内の単語を見つけることができる必要があるということです。Boggleの単語は任意の方向に進むことができ、各一意のブロックは単語ごとに1回だけ使用できますが、パスは交差する可能性があり、斜めに検索することもできます。最初の文字が配列に存在するかどうかをなんとか見つけました。検索を中止できる場合、それが存在する場合は、単語の2番目の文字を検索する検索を開始する必要があります。これは、最初の文字のブロックの周囲にある必要があります。

計算を行ったところ、周囲のブロックの左上隅が常に「i-1とj-1」であることがわかりました。私はこれを解決しましたが、単語を見つけることができないようです...また、2つの「e」が周囲にある場合、それぞれの「e」を試して単語を検索する方法がわかりません。これまでの私のコードは次のとおりです。

これは現時点で私の最も重要なクラス、クラスゲームボードです

public class Gameboard {

private List<Dice> dices = new ArrayList<Dice>();
private final int boardSize;
private String[][] board;
private boolean [][] blocksAvailable;
private Random random = new Random();

public GameBoard() {
    // Making the board with a given size (will be changeable later but is "4" for now)
    boardSize = 4;
    board = new String[boardSize][boardSize];
    blocksAvailable = new boolean[boardSize][boardSize];
    for(int i = 0; i < boardSize; i++) {
        for(int j = 0; j < boardSize; j++) {
            blocksAvailable[i][j] = true;
        }
    }
}

public String[][] getBoard() {
    return board;
}

public int getFullSize() {
    return boardSize*boardSize;
}

public void makeBoard() {
    //random "side up" for each dice
    for(int i = 0; i < dices.size(); i++) {
        dices.get(i).setSideUp();
    }

    // Shuffle all dices
    Collections.shuffle(dices);

    // Fill the board with the values of the dices
    int counter = 0;
    for(int i = 0; i < boardSize; i++) {
        for(int j = 0; j < boardSize; j++) {
            board[i][j] = dices.get(counter++).getSideUp();
        }
    }


}

public String showBoard() {
    //Show the board, each block divided by "|"
    String str = "";
    for(int i = 0; i < boardSize; i++) {
        for(int j = 0; j < boardSize; j++) {
            str += String.format("|%s|", board[i][j].toString());
            if(j == 3) {
                str += "\n";
            }
        }
    }
    return str;
}

public void addDices() {
    dices.add(new dice("R", "I", "F", "O", "B", "X"));
    dices.add(new dice("I", "F", "E", "H", "E", "Y"));
    dices.add(new dice("D", "E", "N", "O", "W", "S"));
    dices.add(new dice("U", "T", "O", "K", "N", "D"));
    dices.add(new dice("H", "M", "S", "R", "A", "O"));
    dices.add(new dice("L", "U", "P", "E", "T", "S"));
    dices.add(new dice("A", "C", "I", "T", "O", "A"));
    dices.add(new dice("Y", "L", "G", "K", "U", "E"));
    dices.add(new dice("Q", "B", "M", "J", "O", "A"));
    dices.add(new dice("E", "H", "I", "S", "P", "N"));
    dices.add(new dice("V", "E", "T", "I", "G", "N"));
    dices.add(new dice("B", "A", "L", "I", "Y", "T"));
    dices.add(new dice("E", "Z", "A", "V", "N", "D"));
    dices.add(new dice("R", "A", "L", "E", "S", "C"));
    dices.add(new dice("U", "W", "I", "L", "R", "G"));
    dices.add(new dice("P", "A", "C", "E", "M", "D"));
}

public boolean searchWord(String word) {
    String wordUp = woord.toUpperCase();
    String firstLetter = Character.toString(wordUp.charAt(0));


    for(int i = 0; i < boardSize;i++) {
        for(int j = 0; j < boardSize;j++) {
            if(firstLetter.equals(board[i][j]) == true) {

                int a = i;
                int b = j;
                String theLetter = "";
                // First letter found, continue search
                for(int h = 1; h < hetWoord.length(); h++) {
                    theLetter = Character.toString(wordUp.charAt(h));
                    int[] values = searchLetter(theLetter, a, b);
                    if(values[0] > -1) {
                        a = values[0];
                        b = values[1];
                    } else {
                        return false;
                    }
                }
                return true;

            }
        }
    }
    return false;
}

public int[] searchLetter(String letter, int i, int j) {
    int[] values = new int[2];

    try{if(board[i-1][j-1].equals(letter) && blocksAvailable[i-1][j-1] == true) {
        values[0] = i-1;
        values[1] = j-1;
        blocksAvailable[i-1][j-1] = false;
    }  else if(board[i-1][j].equals(letter) && blocksAvailable[i-1][j] == true) {
        values[0] = i-1;
        values[1] = j;
        blocksAvailable[i-1][j] = false;
    } else if(board[i-1][j+1].equals(letter) && blocksAvailable[i-1][j+1] == true) {
        values[0] = i-1;
        values[1] = j+1;
        blocksAvailable[i-1][j+1] = false;
    } else if(board[i][j-1].equals(letter) && blocksAvailable[i][j-1] == true) {
        values[0] = i;
        values[1] = j-1;
        blocksAvailable[i][j-1] = false;
    } else if(board[i][j+1].equals(letter) && blocksAvailable[i][j+1] == true) {
        values[0] = i;
        values[1] = j+1;
        blocksAvailable[i][j+1] = false;
    } else if(board[i+1][j-1].equals(letter) && blocksAvailable[i+1][j-1] == true) {
        values[0] = i+1;
        values[1] = j-1;
        blocksAvailable[i+1][j+1] = false;
    } else if(board[i+1][j].equals(letter) && blocksAvailable[i+1][j] == true) {
        values[0] = i+1;
        values[1] = j;
        blocksAvailable[i+1][j] = false;
    } else if(board[i+1][j+1].equals(letter) && blocksAvailable[i+1][j+1] == true) {
        values[0] = i+1;
        values[1] = j+1;
        blocksAvailable[i+1][j+1] = false;
    } else {
        values[0] = -1;  // If not found, negative values, easy to check in searchWord if letter was found
        values[1] = -1;
    }}catch (ArrayIndexOutOfBoundsException e) {

    }

    return values;
}
}
4

5 に答える 5

7

私はあなたの質問に答えるつもりはないので、これは削除されるかもしれません。しかし、どうぞ、かなりお願いします、使用してください:

// instead of: board[i-1][j-1]

public String getBoardValue(int x, int y) {
  if (x<0 || x>=boardSize) return "";
  if (y<0 || y>=boardSize) return "";
  return board[x][y];
}

そのようなヘルパーメソッドを使用すると、

  • IndexArrayOutOfBoundsExceptionがスローされないことを確認してください
  • 常にnull以外のボード値を持つ
于 2013-01-21T13:11:11.983 に答える
0

さて、あなたが尋ねたことは少し複雑です。あなたはあなたの単語のすべての可能な方向を見る必要がありますArray。私はあなたがミニプロジェクトを見てそれらlogicの評価を見る必要があることをお勧めします。あなたはグーグルで多くのプロジェクトを見つけることができます。例http://1000projects.org/java-projects-gaming.html

私はあなたにコピーペーストを求めているのではなく、適切な方法で物事を行うためのアイデアを得るためだけです。数年前に私はXOゲームを作成しc/c++、xとoの組み合わせをチェックするコード(必要に応じて)を提供できます(コード、構文はそれほど変わりません)。

于 2013-01-21T13:56:55.533 に答える
0

メソッドsearchLetterは、より理解しやすいように書き直すことができます。

public boolean isValid(int x, int y) {
   return x>= 0 && x < boardSize && y >=0 && y < boardSize;
}

public int[] searchLetter(String letter, int i, int j) {

   int[] values = new int[2];
  //initialization as not found.
   values[0] = -1;
   values[1] = -1; 
   for(int ix = i-1; ix <= i+1 ; ix++){
      for(int jx = j-1; jx <= j+1 ; jx++){
         if(i == ix && j == jx)
            //skip the cell from were the search is performed
            continue;

         if(isValid(ix,jx)
            && board[ix][jx].equals(letter) 
            && blocksAvailable[ix][jx] == true) {
              values[0] = ix;
              values[1] = jx;
              blocksAvailable[ix][jx] = false;
              //early return 
              return values;
         }
      }
    return values;
}

コメントがなくても、読者はこれが何らかの隣接検索であるというヒントを持っています。

実際のところ、アルゴリズムは可能な次の位置のリストを返す必要があります。上記のコードは最初の出現を返します。インデックスの各ペアを最初のインデックスを返すのではなくリストに入れると、単語のすべての候補文字が表示されます。その際、 Breath優先探索のgetNeighbourまたはadjancentVertexesを実装します。

于 2013-01-21T15:19:43.390 に答える
0

ヒント:最初の文字を見つけたら、次の文字を1つずつ探すのではなく、その時点から取得できる同じ長さの8つの可能な単語を計算するだけです。ボード上のその文字の位置によっては、8未満になる場合があります。これを1つの方向について理解できれば、そのロジックを残りの可能な方向に変換するのが簡単になります。次に、それらの単語を比較する必要があります。一致するものがない場合は、最初の文字を見つけて同じプロセスを繰り返します。

于 2016-01-28T22:08:07.937 に答える
0

面接で聞かれたのですが、時間があまりなかったので、面接官にこの問題への取り組み方を説明しました。彼は私の答えに問題がないようで、コーディングを試みるように私に頼むことさえしませんでした。おそらく、この問題は見た目ほど簡単ではなく、十分な時間がなかったためです。インタビューが終わった後、自宅で試してみましたが、解決策にいくつかのバグがありました。それについて考え続け、以前に投稿したアイデアを思いついたのですが、この投稿が3年前のものであることに気付いたので、コーディングすることにしました。このソリューションは機能しますが、改善の余地があります。

import java.util.LinkedHashSet;
import java.util.Set;


public class StringsArrays {

    public static void main(String[] args) {
        final char[][] matrix = new char[4][4];
        matrix[0] = new char[] { 'G', 'A', 'B', 'C' };
        matrix[1] = new char[] { 'O', 'O', 'E', 'F' };
        matrix[2] = new char[] { 'O', 'H', 'O', 'I' };
        matrix[3] = new char[] { 'J', 'K', 'L', 'D' };


        System.out.println(search("JOOG", matrix)); //N
        System.out.println(search("BEOL", matrix)); //S
        System.out.println(search("AB", matrix));   //E
        System.out.println(search("FE", matrix));   //W
        System.out.println(search("HEC", matrix));  //NE
        System.out.println(search("DOOG", matrix)); //NW
        System.out.println(search("GOOD", matrix)); //SE
        System.out.println(search("FOK", matrix));  //SW        
        System.out.println(search("HO", matrix));

    }

    public static boolean search(final String word, char[][] matrix) {

        final char firstLetter = word.charAt(0);
        for (int y = 0; y < matrix.length; y++) {
            for (int x = 0; x < matrix[y].length; x++) {
                if (matrix[y][x] == firstLetter) {
                    final Set<String> words = readInAllDirections(word.length(), x, y, matrix);
                    if (words.contains(word)) {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    enum Direction {
        NORTH, SOUTH,
        EAST, WEST,
        NORTH_EAST, NORTH_WEST,
        SOUTH_EAST, SOUTH_WEST
    }

    private static Set<String> readInAllDirections(final int length, final int x, final int y, final char[][] matrix) {
        final Set<String> words = new LinkedHashSet<>();
        for (final Direction direction : Direction.values()) {
            words.add(readWord(length, x, y, matrix, direction));
        }
        return words;
    }

    private static String readWord(final int length, final int xBegin, final int yBegin, final char[][] matrix, final Direction direction) {
        final int xEnd = getXEnd(xBegin, length, direction);
        final int yEnd = getYEnd(yBegin, length, direction);
        int x;
        int y;

        final StringBuilder matrixWord = new StringBuilder();

        if (direction == Direction.SOUTH) {
            if (yEnd > matrix.length-1) {
                return null;
            }
            for (y = yBegin; y <= yEnd; y++) {
                matrixWord.append(matrix[y][xBegin]);
            }
        }
        if (direction == Direction.NORTH) {
            if (yEnd < 0) {
                return null;
            }
            for (y = yBegin; y >= yEnd; y--) {
                matrixWord.append(matrix[y][xBegin]);
            }
        }
        if (direction == Direction.EAST) {
            if (xEnd > matrix[yBegin].length-1) {
                return null;
            }
            for (x = xBegin; x <= xEnd; x++) {
                matrixWord.append(matrix[yBegin][x]);
            }
        }
        if (direction == Direction.WEST) {
            if (xEnd < 0) {
                return null;
            }
            for (x = xBegin; x >= xEnd; x--) {
                matrixWord.append(matrix[yBegin][x]);
            }
        }
        if (direction == Direction.SOUTH_EAST) {
            if (yEnd > matrix.length-1 || xEnd > matrix[yBegin].length-1) {
                return null;
            }
            x = xBegin;
            y = yBegin;
            while (y <= yEnd && x <= xEnd) {
                matrixWord.append(matrix[y][x]);
                y++;
                x++;
            }
        }
        if (direction == Direction.SOUTH_WEST) {
            if (yEnd > matrix.length-1 || xEnd < 0) {
                return null;
            }
            x = xBegin;
            y = yBegin;
            while (y <= yEnd && x >= xEnd) {
                matrixWord.append(matrix[y][x]);
                y++;
                x--;
            }
        }
        if (direction == Direction.NORTH_EAST) {
            if (yEnd < 0 || xEnd > matrix[yBegin].length-1) {
                return null;
            }
            x = xBegin;
            y = yBegin;
            while (y >= yEnd && x <= xEnd) {
                matrixWord.append(matrix[y][x]);
                y--;
                x++;
            }
        }
        if (direction == Direction.NORTH_WEST) {
            if (yEnd < 0 || xEnd < 0) {
                return null;
            }
            x = xBegin;
            y = yBegin;
            while (y >= yEnd && x >= xEnd) {
                matrixWord.append(matrix[y][x]);
                y--;
                x--;
            }
        }

        return matrixWord.toString();
    }

    private static int getYEnd(final int y, final int length, final Direction direction) {
        if (direction == Direction.SOUTH || direction == Direction.SOUTH_EAST || direction == Direction.SOUTH_WEST) {
            // y0 + length + ? = y1
            return y + length - 1;
        }
        if (direction == Direction.NORTH || direction == Direction.NORTH_EAST || direction == Direction.NORTH_WEST) {
            // y0 - length + ? = y1
            return y - length + 1; 
        }

        // direction == Direction.EAST || direction == Direction.WEST)
        return y;
    }

    private static int getXEnd(final int x, final int length, final Direction direction) {
        if (direction == Direction.EAST || direction == Direction.NORTH_EAST || direction == Direction.SOUTH_EAST) {
            // x0 + length + ? = x1
            return x + length - 1;
        }
        if (direction == Direction.WEST || direction == Direction.NORTH_WEST || direction == Direction.SOUTH_WEST) {
            // x0 - length + ? = x1
            return x - length + 1;
        }

        // direction == Direction.NORTH || direction == Direction.SOUTH)
        return x;
    }
}
于 2016-01-29T01:10:33.987 に答える