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

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

Fixing Your Battleship Spawning Bug: Duplicate 4-Length Ships

Hey there! I’ve dug into your code and found two key issues causing the 4-length battleship to sometimes spawn incorrectly (either overlapping the 5-length ship or triggering repeated spawns):

1. Broken Overlap Check Selector

In your generateBoat4 function, you’re using $("#nID").hasClass("boat") to check if a cell is already occupied. The problem here is that #nID is looking for an element with the literal id "nID", not the value stored in your nID variable. You need to concatenate the variable into the selector like this: $("#" + nID).hasClass("boat"). Without this fix, your overlap check always returns false, so the 4-length ship never avoids the 5-length ship’s cells.

2. Risky Full Reset Recursion

When a ship can’t fit within the grid bounds, you’re calling generateBoats() which resets and regenerates all ships. This can lead to repeated spawns of the 5-length ship, and in worst cases, infinite recursion if random values keep picking invalid positions. Instead, you should only re-run the current ship’s generation function (e.g., generateBoat4() instead of generateBoats()).


Fixed Full Code

<!DOCTYPE html> 
<html> 
<head> 
    <title>Battle Ships</title> 
    <meta charset="UTF-8"> 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> 
    <style> 
        th, td { 
            width: 32px; 
            height: 32px; 
            background-color: grey; 
        } 
        .boat { 
            width: 32px; 
            height: 32px; 
            background-color: red; 
        } 
    </style> 
    <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; 
                } 
            } 
        }); 

        function generateBoats() { 
            console.log("Generating all battleships..."); 
            $("tr").children().removeClass("boat"); 
            generateBoat5(); 
            generateBoat4(); 
        } 

        function generateBoat5() { 
            // Spawn 5-length battleship
            var rotation = Math.floor(Math.random() * 2); 
            var randX = Math.floor(Math.random() * 11); 
            var randY = Math.floor(Math.random() * 11); 

            if (rotation === 0) { // Horizontal placement
                if (randX <= 10 - 4) { // Ensure enough space (5 cells: randX to randX+4)
                    const cells = [
                        `x=${randX}&y=${randY}`,
                        `x=${randX+1}&y=${randY}`,
                        `x=${randX+2}&y=${randY}`,
                        `x=${randX+3}&y=${randY}`,
                        `x=${randX+4}&y=${randY}`
                    ];
                    cells.forEach(cellId => $(`#${cellId}`).addClass("boat"));
                } else {
                    generateBoat5(); // Retry with new position
                } 
            } else { // Vertical placement
                if (randY <= 10 - 4) { 
                    const cells = [
                        `x=${randX}&y=${randY}`,
                        `x=${randX}&y=${randY+1}`,
                        `x=${randX}&y=${randY+2}`,
                        `x=${randX}&y=${randY+3}`,
                        `x=${randX}&y=${randY+4}`
                    ];
                    cells.forEach(cellId => $(`#${cellId}`).addClass("boat"));
                } else {
                    generateBoat5();
                } 
            } 
        } 

        function generateBoat4() { 
            // Spawn 4-length battleship
            var rotation = Math.floor(Math.random() * 2); 
            var randX = Math.floor(Math.random() * 11); 
            var randY = Math.floor(Math.random() * 11); 
            let cells = [];

            if (rotation === 0) { // Horizontal
                if (randX <= 10 - 3) { // 4 cells: randX to randX+3
                    cells = [
                        `x=${randX}&y=${randY}`,
                        `x=${randX+1}&y=${randY}`,
                        `x=${randX+2}&y=${randY}`,
                        `x=${randX+3}&y=${randY}`
                    ];
                } else {
                    generateBoat4();
                    return; // Stop current function execution after retry
                }
            } else { // Vertical
                if (randY <= 10 - 3) { 
                    cells = [
                        `x=${randX}&y=${randY}`,
                        `x=${randX}&y=${randY+1}`,
                        `x=${randX}&y=${randY+2}`,
                        `x=${randX}&y=${randY+3}`
                    ];
                } else {
                    generateBoat4();
                    return;
                }
            }

            // Check if any cell is already occupied by another ship
            const isOverlapping = cells.some(cellId => $(`#${cellId}`).hasClass("boat"));

            if (isOverlapping) {
                generateBoat4(); // Retry if overlapping
            } else {
                cells.forEach(cellId => $(`#${cellId}`).addClass("boat"));
            }
        }

        // Missing click handler (prevents console errors)
        function koord(cellId) {
            console.log(`Clicked cell: ${cellId}`);
        }
    </script> 
</head> 
<body onload="generateBoats()"> 
    <table id="tabela"></table> 
</body> 
</html>

Extra Improvements I Added

  • Template Literals: Used backticks ` for cleaner string concatenation (e.g., `x=${randX}&y=${randY}` instead of "x=" + randX + "&y=" + randY).
  • Array-Based Cell Handling: Stored ship cells in arrays to avoid repetitive code and make updates easier.
  • Explicit Boundary Logic: Changed randX < 7 to randX <= 10 - 4 to make the grid space check more intuitive (10 is the maximum cell index, subtract (ship length - 1) for valid starting positions).
  • Early Return Statements: Added return after recursive calls to prevent leftover code from running.
  • Fixed Missing koord Function: The original code had a click event bound but no function implementation, which caused console errors. I added a basic version to fix this.

内容的提问来源于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:11:26