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
相关产品推荐
相关产品推荐

