6

片面戦艦ゲームを開発しようとしていますが、ほぼすべての設定が完了しています。この時点で 5, Ships オブジェクトを保持する配列を組み込むだけで済みます。船ごとに作成したクラスは Ships.java と呼ばれます。以前は配列の初期化に問題がありましたが、解決しました。

配列のインデックスから船の長さ (2、3、4、または 5) を取得しようとすると、問題が発生します。概念的に船を配置する方法がわかりません。

do-while、for ループ、if ステートメントのすべての組み合わせを試したような気がします。スイッチケースも試してみました。

目標は、コンピューターに 5 隻の船の位置を選択させ、グリッド (ROWSxCOLS) 内の各セルを NC_SHIP (クリックされていない、船) と等しくなるように設定することです。問題は、グリッド上のランダムな位置に隣接するセルの位置をチェックすることです。問題の船が適合するかどうかも確認する必要があります (ships[i].getShipLength() から取得)。

これが私がこれまでに持っているコードです:

int shipsPlaced = 0;

    for (int i = 0; i < ships.length; i++)
    {
        boolean shipPlaced = false;

        do
        {
            int randomRow = (int)(Math.random()*ROWS);
            int randomCol = (int)(Math.random()*COLS);
            int p = 0;

            if (randomRow - ships[p].getShipLength() >= 0 && gameBoard[(randomRow - p)][randomCol] == NC_EMPTY)
            {
                for (int x = 0; x < ships[x].getShipLength(); x++)
                {
                    gameBoard[(randomRow - x)][randomCol] = NC_SHIP;
                    shipsPlaced = shipsPlaced + 1;
                    if (x == ships[x].getShipLength())
                    {
                        shipPlaced = true;
                        p = p + 1;
                    }
                }
            }
        }while (shipPlaced == false);

    }

ここに表示されていない場合は、すべてが初期化および設定されています。問題は、船を「ランダムな」場所に配置するために使用される数学/ロジックに関するものです。

4

3 に答える 3

2

まず第一に、すべての船は水平になります。船の配置方向もランダム化する必要があります。

私がその問題に直面する方法は2つあります。

  1. 最初に最初の位置を合わせてから、船が収まるかどうかを確認します。
  2. 最初に利用可能なすべての位置をリストし、次にリストの長さに等しい数をランダム化します

1 - ランダムな初期位置 (x,y) の再帰的な外観を作成します (位置を再スローしない場合はfree にする必要があります)。再帰的な「lookForPos」メソッドで、randomPlacementDirectionを作成し、そこからフラグ (例: isHorizo​​ntal) を作成します。収まらない場合(開始位置から最終位置までの長さが行列のサイズをオーバーフローする)、 を再スローします。位置 (位置、位置 + 1、位置 + 2、...、位置 + n) をカバーします。ここで、「n」は船の長さ、位置は x、y ペア、+1 は枢機卿の 1 つだけに影響します。 ( isHorizo​​ntal であるかどうかに応じて) それらのいずれかが占有されている場合は、 re-throw . 最終的には、必要なものが得られます。

2 - 水平方向と垂直方向の両方に適合するすべての位置のリストを作成し ('for' 構造)、リストの長さをランダム化します。

于 2011-04-11T14:18:11.600 に答える
0

したがって、あなたの問題は、戦艦をランダムにボードに配置することです。面白い。これが私がそれを行う方法です。

Shipまず、クラスがあると仮定しましょう:

public class Ship {

    int size;

    public Ship(int size) {
        this.size = size;
    }

    public int getSize() {
        return size;
    }

}

次に、BattleshipBoard次のようなクラスを作成します。

public class BattleshipBoard {

    private final int rows;
    private final int cols;

    private char[][] board;

    public BattleshipBoard(int rows, int cols) {
        this.rows = rows;
        this.cols = cols;
        board = new char[rows][cols];
    }

    public void place(Ship[] ships) {

        Arrays.sort(ships, new Comparator<Ship>() {

            @Override
            public int compare(Ship s1, Ship s2) {
                return Integer.valueOf(s1.size).compareTo(Integer.valueOf(s2.size));
            }
        });

        for (int j = 0; j < rows; j++)
            for (int k = 0; k < cols; k++)
                board[j][k] = '-'; // Empty position

        char[][] checked = new char[rows][cols];
        Random random = new Random();
        for (int i = ships.length - 1; i >=0; i--) {
            for (int j = 0; j < rows; j++)
                for (int k = 0; k < cols; k++)
                    checked[j][k] = 'U'; // Unchecked position
            boolean placed = false;
            while (! placed) {
                int r = random.nextInt(rows);
                int c = random.nextInt(cols);
                if (checked[r][c] == 'U') {
                    checked[r][c] = 'C'; // Checked position
                    if (board[r][c] == '-') {
                        int direction = random.nextInt(4);
                        // 0 = North; 1 = East; 2 = South; 3 = West;
                        if (canPlace(ships[i], r, c, direction)) {
                            place(ships[i], r, c, direction);
                            placed = true;
                        }
                    }               
                }
            }
        }
    }

    private void place(Ship ship, int row, int col, int direction) {
        int size = ship.getSize();
        switch (direction) {
        case 0: // North
            for (int  i = row; i >= row - (size - 1); i--)
                board[i][col] = 'S';
            break;

        case 1: // East
            for (int i = col; i <= col + (size - 1); i++)
                board[row][i] = 'S';
            break;

        case 2: // South
            for (int i = row; i <= row + (size - 1); i++)
                board[i][col] = 'S';
            break;

        default: // West
            for (int i = col; i >= col - (size - 1); i--) 
                board[row][i] = 'S';
            break;
        }       
    }

    private boolean canPlace(Ship ship, int row, int col, int direction) {
        int size = ship.getSize();
        boolean thereIsRoom = true;
        switch (direction) {
        case 0: // North
            if (row - (size - 1) < 0)
                thereIsRoom = false;
            else 
                for (int  i = row; i >= row - (size - 1) && thereIsRoom; i--)
                    thereIsRoom = thereIsRoom & (board[i][col] == '-');
            break;

        case 1: // East
            if (col + (size - 1) >= cols)
                thereIsRoom = false;
            else
                for (int i = col; i <= col + (size - 1) && thereIsRoom; i++)
                    thereIsRoom = thereIsRoom & (board[row][i] == '-');
            break;

        case 2: // South
            if (row + (size - 1) >= rows)
                thereIsRoom = false;
            else
                for (int i = row; i <= row + (size - 1) && thereIsRoom; i++)
                    thereIsRoom  = thereIsRoom & (board[i][col] == '-');
            break;

        default: // West
            if (col - (size - 1) < 0) 
                thereIsRoom = false;
            else
                for (int i = col; i >= col - (size - 1) && thereIsRoom; i--) 
                    thereIsRoom = thereIsRoom & (board[row][i] == '-');
            break;
        }
        return thereIsRoom;
    }

    public void printBoard() {
        for (int i = 0; i < rows; i++)
            System.out.println(Arrays.toString(board[i]));
    }

}

次に、次のようなものがある場合:

public static void main(String[] args) {
    Ship[] ships = new Ship[] {
            new Ship(1),
            new Ship(3),
            new Ship(2),
            new Ship(3)
    };
    BattleshipBoard battleshipBoard = new BattleshipBoard(7, 7);
    battleshipBoard.place(ships);
    battleshipBoard.printBoard();
}

次の出力が得られる場合があります (Randomジェネレーターによって異なります)。

[-, -, -, -, -, -, -]
[-, -, -, -, -, -, -]
[-, -, S, -, -, -, -]
[-, -, -, -, -, -, -]
[-, S, -, S, S, -, -]
[-, S, -, -, -, -, -]
[-, S, -, -, S, S, S]

これは、サイズ 1、2、3、および 3 の 4 つの船をランダムに配置したものです。

いくつかのコメント:

  • この方法では、ランダムな開始位置とランダムなplace()位置を選択して、船をランダムに配置しようとします。(r,c)direction

  • 配列はソートされてshipsいるため、最初に最大の船から始めます (ボードの占有位置が少ないほど配置が容易になります)

  • マトリックスは、船を配置しようとするときにchecked同じランダムな位置を複数回チェックすることを避けるために使用されます(r,c)

  • 渡されたものを開始位置に配置でき、渡されたものに向かっている場合、canPlace()メソッドは true を返します。shipboard(r,c)direction

  • このplace()メソッドは、渡されたものを開始位置に配置し、渡さshipれたものに向かって進みますboard(r,c)direction

于 2011-04-11T16:23:30.383 に答える
0

私がすること:

  1. ランダムな場所に船を配置してみてください。-あなたがしたように

  2. ループでは、このポイントまで繰り返します(配列全体を通過します-2つのループが必要なようです-1つは配列の終わりまで、次は最初からそのポイントまで)

  3. メソッドを呼び出すfreeRowsInARow()と、freeColsInARow()ウィッチは、指定されたポイント (x,y) から開始して、そこに挿入できる最大の船の数を返します。

  4. あなたの船がsize <= returnedValue(上記の方法から)持っているかどうかを確認し、そうであればそこに挿入する方法を呼び出し(方法を選択 - 垂直または水平)、ループを破る(でreturn); いいえの場合 - ofc 検索を続行します。

于 2011-04-11T14:57:28.803 に答える