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

原生JS战舰游戏:如何让Ship实例调用GameBoard的placeShip方法?

解决战舰游戏中Ship实例调用placeShip方法的问题

核心思路

要实现battleShip.placeShip(),需要让Ship实例与GameBoard实例建立关联——战舰的放置逻辑本质是游戏棋盘(GameBoard)的功能,Ship作为实体需要依托具体棋盘完成放置操作。我们可以通过让Ship持有GameBoard的引用,在Ship类中新增代理方法,调用GameBoard的placeShip逻辑。

修改后的代码实现

1. 调整Ship类

添加GameBoard引用存储、关联方法,以及代理的placeShip方法:

class Ship {
  constructor(name, ...args) {
    this.name = name;
    this.x = null; // 存储验证后的x坐标
    this.y = null; // 存储验证后的y坐标
    this.gameBoard = null; // 关联的GameBoard实例
  }

  // 设置当前战舰所属的游戏棋盘
  setGameBoard(board) {
    if (!(board instanceof GameBoard)) {
      throw new Error('必须传入有效的GameBoard实例');
    }
    this.gameBoard = board;
  }

  updateCoord(x, y) {
    // 原有的坐标验证逻辑示例
    const validX = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'].includes(x.toLowerCase());
    const validY = y >= 1 && y <= 10;
    if (validX && validY) {
      this.x = x.toLowerCase();
      this.y = y;
      return true;
    }
    throw new Error('坐标格式无效,请输入如{x: "a", y: 2}的格式');
  }

  // 代理调用GameBoard的placeShip方法
  placeShip() {
    if (!this.gameBoard) {
      throw new Error('请先通过setGameBoard关联游戏棋盘');
    }
    if (!this.x || !this.y) {
      throw new Error('请先通过updateCoord设置战舰坐标');
    }
    // 将当前Ship实例传入GameBoard处理放置
    return this.gameBoard.placeShip(this);
  }
}

2. 调整GameBoard类

修改placeShip方法,接收Ship实例并处理放置逻辑:

class GameBoard {
  constructor() {
    this.ships = []; // 存储已放置的战舰
    this.grid = {}; // 棋盘网格,记录坐标占用情况,示例结构:{a2: 'battleship'}
  }

  placeShip(ship) {
    if (!(ship instanceof Ship)) {
      throw new Error('只能放置Ship实例');
    }
    const coordKey = `${ship.x}${ship.y}`;
    // 检查坐标是否已被占用
    if (this.grid[coordKey]) {
      throw new Error(`坐标(${ship.x}, ${ship.y})已被占用`);
    }
    // 完成放置逻辑
    this.ships.push(ship);
    this.grid[coordKey] = ship.name;
    console.log(`${ship.name}成功放置在坐标(${ship.x}, ${ship.y})`);
    return true;
  }
}

3. 使用示例

// 创建游戏棋盘实例
const mainBoard = new GameBoard();
// 创建战舰实例
const battleShip = new Ship("BattleShip");
// 关联棋盘
battleShip.setGameBoard(mainBoard);
// 设置战舰坐标
battleShip.updateCoord("c", 2);
// 调用放置方法
battleShip.placeShip();

逻辑说明

  • Ship类的placeShip是代理方法,真正的放置逻辑由GameBoard实现,符合单一职责原则(Ship负责自身属性与状态,GameBoard负责棋盘管理)。
  • 通过setGameBoard建立关联,支持一个GameBoard关联多个Ship,或者Ship切换不同的GameBoard,灵活性更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 12:55:16