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

Java战舰游戏:实现打击方法与舰船沉没判断

实现战舰游戏的击中处理与舰船沉没判断

嘿,针对你开发的Java战舰游戏,我来一步步帮你搞定getBoardStrike方法,以及核心的舰船沉没判断逻辑!

一、先明确现有数据结构的定义

首先假设你的数组定义大概是这样(方便后续代码对应):

// gameBoard:0代表无舰船,非0值代表对应舰船的ID(比如1=航母,2=战列舰,3=巡洋舰1,4=巡洋舰2,5=驱逐舰)
private int[][] gameBoard = new int[10][10];
// BoardHits:true表示该位置已被击中,false表示未击中
private boolean[][] BoardHits = new boolean[10][10];

二、实现getBoardStrike方法

这个方法需要完成几个核心动作:校验位置有效性、标记击中状态、判断是否击中舰船、进一步判断舰船是否沉没。这里我让方法返回是否击沉了舰船(你也可以根据需求调整返回值,比如返回是否是有效击中)。

public boolean getBoardStrike(int[] hit) {
    // 1. 校验输入位置的合法性(防止数组越界)
    if (hit == null || hit.length != 2 || hit[0] < 0 || hit[0] >= 10 || hit[1] < 0 || hit[1] >= 10) {
        throw new IllegalArgumentException("Invalid hit position!");
    }
    
    int x = hit[0];
    int y = hit[1];
    
    // 2. 检查该位置是否已经被击中过
    if (BoardHits[x][y]) {
        System.out.println("This position has already been hit!");
        return false; // 已击中过,返回false表示未击沉(或未产生有效打击)
    }
    
    // 3. 标记该位置为已击中
    BoardHits[x][y] = true;
    
    // 4. 判断是否击中了舰船
    int shipId = gameBoard[x][y];
    if (shipId == 0) {
        // 没击中舰船,返回false
        return false;
    }
    
    // 5. 击中舰船,判断该舰船是否已全部沉没
    boolean isShipSunk = isShipSunk(shipId);
    if (isShipSunk) {
        System.out.println("You sunk a ship!");
    }
    return isShipSunk;
}

三、核心:舰船沉没判断逻辑isShipSunk方法

这个方法的思路是:遍历整个游戏棋盘,找到所有属于该舰船ID的位置,然后检查这些位置是否都已经被标记为击中。如果所有位置都被击中,说明舰船沉没。

private boolean isShipSunk(int shipId) {
    // 遍历整个10x10棋盘
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
            // 如果当前位置属于该舰船,但未被击中,说明舰船还没沉没
            if (gameBoard[i][j] == shipId && !BoardHits[i][j]) {
                return false;
            }
        }
    }
    // 所有该舰船的位置都被击中了,返回true表示沉没
    return true;
}

四、优化建议:用Ship类管理舰船状态

上面的方法虽然能工作,但每次判断沉没都要遍历整个棋盘,效率有点低。如果想更高效,可以定义一个Ship类来封装每艘舰船的信息:

class Ship {
    private int id;
    private int length;
    // 存储舰船所有的位置坐标,比如每个坐标是int[]{x,y}
    private List<int[]> positions;
    private boolean isSunk;

    public Ship(int id, int length, List<int[]> positions) {
        this.id = id;
        this.length = length;
        this.positions = positions;
        this.isSunk = false;
    }

    // 判断该舰船是否沉没的方法
    public boolean isSunk(boolean[][] boardHits) {
        for (int[] pos : positions) {
            int x = pos[0];
            int y = pos[1];
            if (!boardHits[x][y]) {
                return false;
            }
        }
        this.isSunk = true;
        return true;
    }

    // getter方法
    public int getId() { return id; }
    public boolean isSunk() { return isSunk; }
}

然后在你的游戏类里维护一个List<Ship>来管理所有舰船:

private List<Ship> ships = new ArrayList<>();

这样,当击中某个位置时,拿到舰船ID后,直接找到对应的Ship对象调用isSunk方法,不用遍历整个棋盘,效率更高。修改后的getBoardStrike里的沉没判断部分可以改成:

// 找到对应的舰船
Ship hitShip = ships.stream().filter(s -> s.getId() == shipId).findFirst().orElse(null);
boolean isShipSunk = hitShip != null && hitShip.isSunk(BoardHits);

这种方式更面向对象,也更易于维护,比如后续要添加舰船的其他状态(比如类型、颜色)都很方便。


内容的提问来源于stack exchange,提问作者Lee Yaan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:55:20