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

战舰游戏开发Bug求助:4格战舰重复生成问题

解决战舰游戏中4格战舰重复/重叠的问题

嘿,我看了你的代码,找到几个导致4格战舰有时看起来重复的关键问题,咱们一步步来解决:

核心问题分析

  1. 重叠判断的语法错误:你在generateBoat4里用$("#nID")检查元素是否有boat类,但这里的nID是变量,你实际是在找ID为字符串"nID"的元素(根本不存在),导致重叠判断完全失效,所以4格战舰经常和5格战舰重叠,看起来就像重复了。
  2. 递归调用的不合理性:当生成位置不合适时,你直接调用generateBoats(),这会清空所有已生成的战舰并重新整个流程,不仅效率低,还可能因为重复触发导致意外生成多艘战舰。
  3. 无位置占用记录:每次生成都是随机碰运气,没有记录哪些格子已经被占用,判断起来效率低还容易出错。

分步修复方案

1. 修复重叠判断的语法错误

把generateBoat4里的判断语句改成用变量拼接选择器,比如:

// 原来的错误写法
if (($("#nID").hasClass("boat")) || ($("#nID2").hasClass("boat"))...)

// 正确写法
if ($("#" + nID).hasClass("boat") || $("#" + nID2).hasClass("boat")...)

2. 优化递归逻辑,避免重复生成整个舰队

当位置不合适时,只重新生成当前战舰,而不是整个舰队。比如generateBoat5里的错误分支:

// 原来的写法
} else {
  generateBoats(); // 清空所有战舰重新来
}

// 改成
} else {
  generateBoat5(); // 只重新生成5格战舰
}

generateBoat4里同理,改成调用generateBoat4()而不是generateBoats()。

3. 推荐:用集合记录已占用位置(更高效)

创建一个全局Set来存储已被战舰占用的格子ID,这样可以快速判断位置是否可用,不用每次去DOM里查找:

// 全局变量存储已占用的格子ID
const occupiedCells = new Set();

function generateBoats() {
  console.log("func");
  $("tr").children().removeClass("boat");
  occupiedCells.clear(); // 清空集合
  generateBoat5();
  generateBoat4();
}

然后在generateBoat5和generateBoat4里,先生成所有需要的格子ID,检查是否在集合中,再决定是否生成或重新尝试。

完整修复后的代码

替换你原来的<script>部分即可:

<script>
$(document).ready(function(){
  for (var vr = 0; vr < 11; vr++) {
    var vrsta = document.getElementById('tabela').insertRow(vr);
    for (var st = 0; st < 11; st++) {
      var okvir = vrsta.insertCell(st);
      okvir.id = "x=" + st + "&y=" + vr;
      okvir.setAttribute("onclick", "koord(this.id)");
      okvir.innerHTML = "x-" + st + " y-" + vr;
    }
  }
});

const occupiedCells = new Set();

function generateBoats() {
  console.log("func");
  $("tr").children().removeClass("boat");
  occupiedCells.clear();
  generateBoat5();
  generateBoat4();
}

function generateBoat5() {
  var rotation = Math.floor((Math.random() * 2));
  var randX = Math.floor((Math.random() * 11));
  var randY = Math.floor((Math.random() * 11));
  const cells = [];

  if (rotation == 0) {
    if (randX > 6) {
      generateBoat5();
      return;
    }
    for (let i=0; i<5; i++) {
      cells.push(`x=${randX+i}&y=${randY}`);
    }
  } else if (rotation == 1) {
    if (randY > 6) {
      generateBoat5();
      return;
    }
    for (let i=0; i<5; i++) {
      cells.push(`x=${randX}&y=${randY+i}`);
    }
  }

  // 检查是否已被占用
  for (const cell of cells) {
    if (occupiedCells.has(cell)) {
      generateBoat5();
      return;
    }
  }

  // 标记占用并添加样式
  cells.forEach(cell => {
    occupiedCells.add(cell);
    $(`#${cell}`).addClass("boat");
  });
}

function generateBoat4() {
  var rotation = Math.floor((Math.random() * 2));
  var randX = Math.floor((Math.random() * 11));
  var randY = Math.floor((Math.random() * 11));
  const cells = [];

  if (rotation == 0) {
    if (randX > 7) {
      generateBoat4();
      return;
    }
    for (let i=0; i<4; i++) {
      cells.push(`x=${randX+i}&y=${randY}`);
    }
  } else if (rotation == 1) {
    if (randY > 7) {
      generateBoat4();
      return;
    }
    for (let i=0; i<4; i++) {
      cells.push(`x=${randX}&y=${randY+i}`);
    }
  }

  // 检查是否已被占用
  for (const cell of cells) {
    if (occupiedCells.has(cell)) {
      generateBoat4();
      return;
    }
  }

  // 标记占用并添加样式
  cells.forEach(cell => {
    occupiedCells.add(cell);
    $(`#${cell}`).addClass("boat");
  });
}

function koord(id) {
  // 可以在这里添加点击后的逻辑,比如判断是否击中
  console.log("Clicked cell:", id);
}
</script>

这样修改后,4格战舰就不会再和5格战舰重叠,也不会出现看起来重复的情况啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:07:35