0

iio エンジンを使用して JavaScript で戦艦ゲームを実行しています。

私はコンピューターと対戦しようとしているので、船の位置をランダムに設定する必要があります (ゲームを知っていることを願っています:))。

グリッド (10x10) に配置する必要がある 5 つの船があります。問題は、関数が非常に遅く、ページがまったく読み込まれない場合があることです。

これらの機能の速度に改善があるかどうか知りたいです。私は少し初心者です: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. グリッドの外にある船の位置を選択しないでください。最初に方向を選択してから、 に基づいてxと初期位置を制限します。たとえば、サイズが 3 の場合、可変座標の初期値が 7 を超えるポイントはありません。ysize

  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 に答える