1

現在、掃海艇プログラムに取り組んでおり、その中の隣人を明らかにするために少し助けが必要です. 現在、私のプログラムが明らかにするためにできることは次のとおりです

1 は選択されたボタンで、行は入力する必要があるものです。現在、選択したボタンの周りのボタンは、入力できるものです。

必要に応じてコードを投稿できます。

事前に助けてくれてありがとう。 ここに画像の説明を入力

1 は地雷、4 はアレイ上のフラグ付きスポット

public int findneighbors(int row, int col) {
      int count = 0;
    if (board[row][col] == 2)
        try {
            if (board[row][col + 1] == 1 || board[row][col + 1] == 4)
                count ++;
        }

            catch( ArrayIndexOutOfBoundsException e)
            {
            }
        try {
        if (board[row + 1][col + 1] == 1 || board[row + 1][col + 1] == 4)
            count ++;
            }
        catch( ArrayIndexOutOfBoundsException e)
        {
        }
        try {
        if (board[row + 1][col - 1] == 1 || board[row + 1][col - 1] == 4)
            count ++;
            }
        catch( ArrayIndexOutOfBoundsException e)
        {
        }
        try {
            if (board[row - 1][col - 1] == 1 || board[row - 1][col - 1] == 4)
                count ++;
                }
            catch( ArrayIndexOutOfBoundsException e)
            {
            }
        try {
            if (board[row][col + 1] == 1 || board[row][col + 1] == 4)
                count ++;
                }
            catch( ArrayIndexOutOfBoundsException e)
            {
            }
        try {
            if (board[row + 1][col] == 1 || board[row + 1][col] == 4)
                count ++;
                }
            catch( ArrayIndexOutOfBoundsException e)
            {
            }
        try {
            if (board[row - 1][col] == 1 || board[row - 1][col] == 4)
                count ++;
                }
            catch( ArrayIndexOutOfBoundsException e)
            {
            }
        try {
            if (board[row][col - 1] == 1 || board[row][col - 1] == 4)
                count ++;
                }
            catch( ArrayIndexOutOfBoundsException e)
            {
            }
        try {
            if (board[row - 1][col + 1] == 1 || board[row - 1][col + 1] == 4)
                count ++;
                }
            catch( ArrayIndexOutOfBoundsException e)
            {
            }

    return count;
  }
public int buttonFloodFill(int r, int c)
{
    int loopCount = 0;
    int rowCount = 1;
    int colCount = 1;
    while (loopCount < 1)
    {
        try {
    if (g.getFloodValue(r,c + colCount) == true) {
        board[r][c + colCount].setText(Integer.toString(g.findneighbors(r,c + colCount)));
        board[r][c + colCount].setEnabled(false);
    }
        }
    catch( ArrayIndexOutOfBoundsException e)
    {
    }
    try {
    if (g.getFloodValue(r,c - colCount) == true) {
        board[r][c - colCount].setText(Integer.toString(g.findneighbors(r,c - colCount)));
        board[r][c - colCount].setEnabled(false);
    }
    }
catch( ArrayIndexOutOfBoundsException e)
{
}
    try {
    if (g.getFloodValue(r + rowCount,c + colCount) == true) {
        board[r + rowCount][c + colCount].setText(Integer.toString(g.findneighbors(r + rowCount,c + colCount)));
        board[r + rowCount][c + colCount].setEnabled(false);
    }
    }
catch( ArrayIndexOutOfBoundsException e)
{
}
    try {
    if (g.getFloodValue(r + rowCount,c - colCount) == true) {
        board[r + rowCount][c - colCount].setText(Integer.toString(g.findneighbors(r + rowCount,c - colCount)));
        board[r + rowCount][c - colCount].setEnabled(false);
    }
    }
catch( ArrayIndexOutOfBoundsException e)
{
}
    try {
    if (g.getFloodValue(r - rowCount,c - colCount) == true) {
        board[r - rowCount][c - colCount].setText(Integer.toString(g.findneighbors(r - rowCount,c - colCount)));
        board[r - rowCount][c - colCount].setEnabled(false);
        }
    }
catch( ArrayIndexOutOfBoundsException e)
{
}
    try {
    if (g.getFloodValue(r - rowCount,c + colCount) == true) {
        board[r - rowCount][c + colCount].setText(Integer.toString(g.findneighbors(r - rowCount,c + colCount)));
        board[r - rowCount][c + colCount].setEnabled(false);
    }
    }
catch( ArrayIndexOutOfBoundsException e)
{
}
    try {
    if (g.getFloodValue(r - rowCount,c) == true) {
        board[r - rowCount][c].setText(Integer.toString(g.findneighbors(r - rowCount,c)));
        board[r - rowCount][c].setEnabled(false);
    }
    }
catch( ArrayIndexOutOfBoundsException e)
{
}
    try {
    if (g.getFloodValue(r + rowCount,c) == true) {
        board[r + rowCount][c].setText(Integer.toString(g.findneighbors(r+ rowCount,c)));
        board[r + rowCount][c].setEnabled(false);
    }
    }
catch( ArrayIndexOutOfBoundsException e)
{
}
    rowCount ++;
    colCount ++;
    loopCount ++;

    }
    return 0;
}
4

3 に答える 3

3

私はあなたのコードを読んでいませんが、ループや小さなヘルパー関数を使用したリファクタリングなどの基本的なテクニックを学ぶ必要があるようです。例外処理には興味がないことがわかります。これは、この規模のプログラムでは今のところ問題ありませんが、連続した try-catch ブロックを1つまたは単に関数を宣言して、おそらくスローします。

あなたの質問に関しては、再帰が答えです。隣人、隣人の隣人、およびその隣人などをチェックし続けることはできません。繰り返しパターンを考え出す必要があります。フラッド フィルが実際の答えですが、再帰に慣れ、再帰によって解決される可能性のある問題を特定する方法を学ぶ必要があります。

于 2012-02-16T23:09:01.037 に答える
1

あなたのコードを見た後、この特定の問題を修正しようとするよりも、いくつかの一般的なガイドラインを提供するのが最善だと思います。

Java は、オブジェクト指向プログラミング用に設計された言語です。あなたが行ったことは、より手続き的なアプローチであり、もちろんこれも機能しますが、Java を使用しているため、言語機能を有利に使用したいと考えています。

プロジェクトでどのような「オブジェクト」を見つけることができるか見てみましょう。すでにボード、セルの配列があります。あなたが示したコードはこのボードの一部であり、ボードとは関係のないコードから分離できます。

現在、ボードはそのセルの状態を表す整数で構成されています。では、cell もオブジェクトにするのは興味深いことではないでしょうか。そうすれば、ボードは状態を持つセルの配列を持つことになります。これは、推論しなければならないレベルの数を増やすだけだと言えます。ある意味ではこれも真実ですが、これらの各レベルは明確に定義された概念であり、個別に推論することができます. コード例を見てみましょう。

class Cell {
    private int state; //whatever your default is

    public Cell(int state) {
        this.state = state;
    }

これで、状態を検査するメソッドをいくつか追加できます。

    public boolean hasMine() {
         return state == 1;
    }
    public boolean isFlagged() {
         return state == 4;
    }

同様に、状態を変更するメソッドを追加できます。

    public void flag() {
        state = 4;
    }

私はいくつかのメソッドをリストしただけですが、それ以上のメソッドを書く方法は明らかだと思います。(また、私は今のところ状態を整数のままにしています。オブジェクト指向プログラミングに慣れたら、Java 列挙型または状態パターンを見たいと思うかもしれません)

ではボードを見てみましょう。現在、隣接する地雷の数を返す findneighbours というメソッドがあります。個人的には、getAdjecentMineCount のように、このメソッドをより明確なものと呼びます。ただし、セルのすべての隣接セルを返す getNeighbours メソッドも存在すると思います。次に、この getNeighbours メソッドを使用して、次のように隣接する地雷の数を簡単に見つけることができます。

public int getAdjecentMineCount(int row, int col) {
    int count=0;
    for (Cell c : getNeighbours(row, col)) //this iterates over the neighbours that are returned by the getNeighbours function
        if (c.hasMine())
             count++;
    return count;
}

次に、セルの表示を見てみましょう。難しく考えずに、revealCell というメソッドを作成しましょう。

public void revealCell(int row, int col) {
    if (board[row][col].hasMine())
        System.out.println("BOOM"); //whatever has to happen when you click on a bomb
    //now we also want to reveil any non-diagonal neighbour that doesn't have a mine
    for (Cell c : getNonDiagonalNeighbours(row, col))
        if (!c.hasMine() && !c.isRevealed())
             reveilCell(rowOf(c), columnOf(c));
}

同じメソッドへの再帰呼び出しに注目してください。これにより、セルのチェーンが明らかになります。

隣人を見つけるメソッドなど、意図的にコードにいくつかの穴を残しました。私の説明があなたを正しい方向に導き、あなた自身でこの言語についてもっと理解できるようになることを願っています. さらに問題がある場合は、お気軽にお問い合わせください。

(免責事項: ここで提供するソリューションが理想的なソリューションであるとは決して主張しません。私が目指しているのは、よりクリーンでオブジェクト指向のコードを書くように導くことだけです。)

于 2012-02-16T23:07:58.347 に答える
0

コード全体を再実装して申し訳ありませんが、それはあなたのコードを理解しようとするよりも速いです...

public class Minefield {

    int mx, my;

    /** whether a mine is present */
    boolean[][] mined;

    /** the number of mines in neighboring cells */
    int[][] mines;

    /** whether this cell is revealed */
    boolean[][] revealed;

    public Minefield() {
        Random chaos = new Random();

        mx = 10;
        my = 10;
        for (int x = 0; x < mx; x++) {
            for (int y = 0; y < my; y++) {
                mined[x][y] = chaos.nextFloat() < 0.2;
            }
        }

        for (int x = 0; x < mx; x++) {
            for (int y = 0; y < my; y++) {
                mines[x][y] = 0;
                for (int nx = max(x - 1, 0); nx < mx && nx <= x + 1; nx++) {
                    for (int ny = max(y - 1, 0); ny < my && ny <= y + 1; ny++) {
                        if (mined[nx][ny]) {
                            mines[x][y]++;
                        }
                    }
                }
            }
        }
    }

    void stepOn(int x, int y) {
        reveal(x, y);
        if (mined[x][y]) {
            throw new GameOverException();
        }
    }

    void reveal(int x, int y) {
        if (!revealed[x][y]) {
            revealed[x][y] = true;
            if (mines[x][y] == 0) {
                for (int nx = max(x - 1, 0); nx < mx && nx <= x + 1; nx++) {
                    for (int ny = max(y - 1, 0); ny < my && ny <= y + 1; ny++) {
                        reveal(nx, ny);
                    }
                }
            }
        }
    }

注: このコードはまだテストしていませんが、理解していただければ幸いです。

于 2012-02-16T23:25:03.807 に答える