6

我正在尝试开发一款单面战舰游戏,并且我几乎已经完成了所有设置。我只需要合并一个此时包含 5 个 Ships 对象的数组。我为每艘船创建的类称为 Ships.java。早些时候我在初始化数组时遇到了问题,但已经解决了。

当我尝试从数组中的索引中提取船的长度(2、3、4 或 5)时,就会出现问题。我不确定如何在概念上放置船只。

我觉得我已经尝试了 do-while、for 循环和 if 语句的所有组合。甚至尝试了一个开关盒。

目标是让计算机为五艘船选择位置,并将网格中的每个单元格 (ROWSxCOLS) 设置为等于 NC_SHIP(未单击,加上船)。问题是让它检查与网格上随机位置相邻的单元格的位置。还必须检查有问题的船是否适合(从 ship[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

首先:你所有的船都是水平的,你还应该随机化船的放置方向。

有两种方法可以解决这个问题:

  1. 首先适合初始位置,然后查看船舶是否适合。
  2. 首先列出所有可用位置,然后随机化一个等于列表长度的数字

1 - 对随机初始位置 (x,y) 进行递归查找(如果不是重新抛出位置,则应该是自由的)。在递归“ lookForPos ”方法中,创建一个randomPlacementDirection,并从中创建一个标志(例如 isHorizo​​ntal)。如果不合适(从开始到最终位置的长度溢出矩阵的大小),重新抛出. 覆盖位置(位置,位置+1,位置+2,...,位置+n),其中'n'是你的船的长度,位置是x,y对,+1只影响一个红衣主教(取决于是否 isHorizo​​ntal )如果它们中的任何一个也被占用re-throw。最终你会得到你需要的东西。

2 - 列出所有适合的位置(“for”结构),水平和垂直,然后随机化列表的长度。

于 2011-04-11T14:18:11.600 回答
0

我会做什么:

  1. 找个随机的地方尝试把你的船放在那里。- 就像你一样

  2. 在一个循环中迭代直到这一点(遍历整个数组 - 似乎你需要 2 个循环 - 一个直到数组结束,下一个从开始到那个点)

  3. 调用方法freeRowsInARow()freeColsInARow()返回从给定点 (x,y) 开始可以插入的最大船的数量

  4. 检查您的船是否有size <= returnedValue(通过上述方法),如果有 - 调用插入它的方法(选择方式 - 垂直或水平)并中断循环(使用return);如果没有 - ofc 继续搜索。

于 2011-04-11T14:57:28.803 回答
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 的船的随机放置。

几点评论:

  • place()方法尝试通过选择随机起始位置(r,c)和随机direction

  • 数组已排序,因此我们首先从ships最大的船开始(当我们的棋盘占用位置较少时,放置它们更容易)

  • checked矩阵用于避免(r,c)在尝试放置船只时多次检查相同的随机位置

  • 如果传递的可以放在起始位置并朝向传递的位置,则该canPlace()方法返回trueshipboard(r,c)direction

  • place()方法将传递ship的位置放在board起始位置(r,c)并朝向传递direction

于 2011-04-11T16:23:30.383 回答