2

How can I prevent this map generator from creating touching corners like this:

-X
X-

Or

X-
-X

Here is a simplified example of the generator: http://jsfiddle.net/fDv9C/2/

4

3 に答える 3

1

ボードを作成する方法のため、生成中にこのチェックを行うことは非常に困難です。後でボードをチェックする簡単な関数を作成します。フラッドアルゴリズムを使用しています。これがフィドルhttp://jsfiddle.net/jzTEX/8/です(青い背景は元の地図、赤い背景はチェック後の地図です)

基本的に、2番目の配列を作成しますgrid2。充填後grid、再帰floodV関数を実行します

function floodV(x,y) {
    var shiftArray = [[0,1],[0,-1],[1,0],[-1,0]];
    grid2[y][x]=1;
    for(var k=0;k<4;k++) {
        var x1=x+shiftArray[k][0];
        var y1=y+shiftArray[k][1];
        if(grid[y1][x1] == 1 && grid2[y1][x1] == 0 && checkV(x1,y1)) {
            grid2[y1][x1] = 1;
            floodV(x1,y1);
        }
    }
}

チェック機能付き

function checkV(x,y) {
    var checkVarr = [[-1,-1], [-1,1], [1,1], [1,-1]];
    for(var k=0;k<4;k++) {
        if(grid[y+checkVarr[k][0]][x+checkVarr[k][1]] == 1 && grid[y+checkVarr[k][0]][x] == 0 && grid[y][x+checkVarr[k][1]] == 0 && grid2[y+checkVarr[k][0]][x+checkVarr[k][1]] == 1) 
            return false;
    }
    return true;
}

マップの大部分を破棄することがあるため、これは完全ではありませんが、新しい要素の追加を開始しようとすると、マップ全体を再度チェックする必要があります(価値のある場合)。

于 2013-02-06T21:59:41.857 に答える
1

あなたの質問はほとんど答えます。

これがフィドルです:http://jsfiddle.net/qBJVY/

if (!!grid[y][x] && !!grid[y+1][x+1] && !grid[y+1][x] && !grid[y][x+1]) {
    good=false;
    grid[y+1][x]=2;
}

不要な組み合わせをチェックし、パッチを適用するだけです。マップのどの部分も切断しないように、常にグリッドポイントを追加します。

これにより、問題が発生する可能性のある別の状況が発生する可能性がありますが、何かが変更された場合(つまり、問題が見つかった場合)は、単に再確認します。これは、たとえば、変更されたものを再帰的に調整することで最適化できますが、通常は1回または2回のパスで済みます。予期せぬ状況で修正できない場合に備えて、100回を超えるパスを許可しないリミッターがあります(ただし、そのような状況は考えられません:))。

于 2013-02-08T03:55:54.887 に答える
0

これは私がやったことです: http://jsfiddle.net/fDv9C/13/

魔法はどこで起こっていますか?53 行目から 58 行目まで下にスクロールします。

var bottom = y_next + 1;
var left = x_next - 1;
var right = x_next + 1;
var top = y_next - 1;

if (grid[top][left] || grid[top][right] ||
    grid[bottom][left] || grid[bottom][right]) continue;

要するに、接触するコーナーポイントは、計算された次の位置でのみ発生する可能性があります。したがって、次の位置の 4 つのコーナー近傍のいずれかが存在する場合は、別の次の位置を計算する必要があります。

これがたまたま可能な限り多くのパスを取得する場合は、カウンターをデクリメントすることもiできます (ただし、実際には大きな違いはありません)。

var bottom = y_next + 1;
var left = x_next - 1;
var right = x_next + 1;
var top = y_next - 1;

if (grid[top][left] || grid[top][right] ||
    grid[bottom][left] || grid[bottom][right]) {
    i--;
    continue;
}

ここでデモを参照してください: http://jsfiddle.net/fDv9C/12/

編集:抵抗できませんでした。実行をクリックし続ける必要がないように、自動マップジェネレーターを作成する必要がありました: http://jsfiddle.net/fDv9C/14/

于 2013-02-04T08:36:32.407 に答える