0

我正在使用 iio 引擎在 javascript 中制作 BattleShip 游戏。

我正在尝试与计算机对战,所以我必须为船只设置一个随机位置(我希望你知道这个游戏:))。

我有 5 艘船必须放在一个网格 (10x10) 中。问题是该功能非常慢,有时页面根本没有加载。

我想知道这些功能的速度是否有一些改进,我有点新手:D

function posShips(size){
    // var size -> size of the ship
    var isOk = false; // flag var to check if the ship is in a right position
    var isOk2 = true; // flag var, become false if the cell is already fill with another ship
    var i; 
    var j;
    var side; // horizontal or vertical
    while(!isOk){
        i = iio.getRandomInt(1,11);
        j = iio.getRandomInt(1,11);
        side = iio.getRandomInt(0,2);
        if((side ? j : i)+size-1 < 11){ // Not out of the array
            for (var k = 0;  k < size; k++) { // Size of the ship
                if(side){
                    if(gridHit[i][j+k].stat == "empty"){ //If is empty put the ship
                        gridHit[i][j+k].stat = "ship";
                        gridHit[i][j+k].setFillStyle("red")
                    }else{ // If not empty
                        isOk2 = false; //Position is not good, do all the thing again.
                        for (var a = 0;  a < size; a++) { // Reset cell
                            gridHit[i][j+a].stat = "empty";
                        }
                        k = 10;
                    }
                }else{
                    if(gridHit[i+k][j].stat == "empty"){ //If is empty put the ship
                        gridHit[i+k][j].stat = "ship";
                        gridHit[i+k][j].setFillStyle("red")
                    }else{ // If not empty
                        isOk2 = false; //Position is not good, do all the thing again.
                        for (var a = 0;  a < size; a++) { // Reset cell
                            gridHit[i+a][j].stat = "empty";
                        }
                        k = 10;
                    }
                }
            };
            if(isOk2)
                isOk = true;
        }
    }
}
4

1 回答 1

4
  1. 不要选择会落在网格之外的船舶位置。先选择方向,然后根据 限制xy初始位置size。例如,如果大小为 3,则变化坐标的初始值不会超过 7。

  2. 搜索时不要更改数组。首先进行搜索,然后才更新数组。这避免了任何“清理”操作。

  3. 尽可能消除重复的深层对象引用。如果grid[y][x]重复访问不同x的,请先引用grid[y],然后将其用于后续访问。

  4. 尽早打破循环,如果前一个位置已经失败,那么继续测试一个位置是没有意义的。

  5. 首先放置您的大船 - 将小船安装在大船之间的间隙中会更容易。

有关我的实现,请参见http://jsfiddle.net/alnitak/Rp9Ke/,相当于您的函数是这样的:

this.place = function(size) {

    // faster array access
    var g = this.grid;

    // initial direction, and vector
    var dir = rand(2);  // 0 - y, 1 - x
    var dx = dir ? 1 : 0;
    var dy = dir ? 0 : 1;  // or 1 - dx

    LOOP: while (true) {
        // initial position
        var x = dir ? rand(10 - size) : rand(10);
        var y = dir ? rand(10) : rand(10 - size);

        // test points
        var n = size, tx = x, ty = y;
        while (n--) {
            if (g[ty][tx]) continue LOOP;
            tx += dx;
            ty += dy;
        }

        // fill points
        n = size;
        while (n--) {
            g[y][x] = size;
            x += dx;
            y += dy;
        }

        break;
    }
};
于 2013-07-26T08:26:28.410 回答