You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

战舰游戏开发:如何检测棋盘船只周边合法性并统计船只数量?

战舰棋盘校验问题解决方案

现有代码已知bug修正

  • 输入转换错误:你当前读取棋盘行时直接将char赋值给int数组,'0'和'1'的ASCII码分别为48、49,会导致后续==1判断完全失效,修改输入代码:
// 原代码
board[x][y] = temp.charAt(x);
// 修改为
board[x][y] = temp.charAt(x) - '0';
  • 循环硬编码错误:checkType方法中遍历棋盘写死了y<5和x<5,需替换为动态的size参数:
for (int y = 0; y < size; y++) {
    for (int x = 0; x < size; x++) {
  • 数组越界风险:当前代码直接访问x-1/y+1等坐标,未判断是否在棋盘边界内,会触发ArrayIndexOutOfBoundsException。

跨方法计数方案

Java为值传递,基础类型int无法直接在方法间修改原值,可用两种方案实现:

  1. 使用长度为1的int数组传递:数组为引用类型,方法内修改数组元素会同步到原变量
    // 调用方定义
    int[] shipCount = new int[1];
    // 传入各个校验方法
    horizontalBoat(board, size, x, y, shipCount);
    // 方法内计数
    shipCount[0]++;
    
  2. 将校验逻辑封装为独立类,使用成员变量存储计数,适合功能更复杂的后续迭代。

校验逻辑优化实现

你当前的方向校验逻辑存在重复识别、边界未处理的问题,推荐使用「标记已访问+全周边校验」的思路:

  1. 遍历棋盘每个格子,遇到未访问的船身(值为1)时,先识别整艘船的方向与所有点位
  2. 将该船所有点位标记为已访问,避免后续重复计数
  3. 遍历该船所有点位的8个相邻格,只要存在未访问的船身即判定为触碰,校验不通过
  4. 每识别完一艘合法船只,计数器加1
  5. 遍历完成后对比计数器值与预设船只数,一致则棋盘合法。

核心参考代码

// 8个方向偏移量,覆盖上下左右、四个对角
private static final int[][] DIRS = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};

static boolean checkBoard(int[][] board, int size, int expectShipNum) {
    int[][] visited = new int[size][size]; // 也可以直接修改原board标记为2,节省内存
    int shipCount = 0;
    for (int y = 0; y < size; y++) {
        for (int x = 0; x < size; x++) {
            if (board[x][y] == 1 && visited[x][y] == 0) {
                // 先判断船的方向,L型船不合法
                boolean hasRight = x+1 < size && board[x+1][y] == 1;
                boolean hasDown = y+1 < size && board[x][y+1] == 1;
                if (hasRight && hasDown) return false;

                // 识别整艘船的所有点位
                int len = 0;
                if (hasRight) { // 水平船
                    while (x + len < size && board[x+len][y] == 1) {
                        visited[x+len][y] = 1;
                        len++;
                    }
                } else if (hasDown) { // 垂直船
                    while (y + len < size && board[x][y+len] == 1) {
                        visited[x][y+len] = 1;
                        len++;
                    }
                } else { // 长度为1的单船
                    visited[x][y] = 1;
                    len = 1;
                }

                // 校验整艘船周边是否有其他船
                for (int i = 0; i < len; i++) {
                    int cx = hasRight ? x + i : x;
                    int cy = hasDown ? y + i : y;
                    for (int[] dir : DIRS) {
                        int nx = cx + dir[0];
                        int ny = cy + dir[1];
                        if (nx >=0 && nx < size && ny >=0 && ny < size) {
                            if (board[nx][ny] == 1 && visited[nx][ny] == 0) {
                                return false; // 周边有其他船,触碰违规
                            }
                        }
                    }
                }
                shipCount++;
            }
        }
    }
    return shipCount == expectShipNum;
}

直接在main方法中调用checkBoard(board, size, ships_num),返回true则棋盘合法,false则不合法。

内容的提问来源于stack exchange,提问作者Ceri Barnes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 08:36:04