0

生き物を表す構造体の大きな正方行列があります。各クリーチャーは、左、上、右、または下に移動できます。空のセルの隣接するマトリックス位置をチェックして、新しい座標に対して次の計算を行います。

function res = Move2(worldDimension,row,col,left,up,right,down)

%In the following matrices, good moves are > 0.

%Directions pattern:
patternMatrix = [0 2 0;
                 1 5 3;
                 0 4 0];
%Possible border moves:             
borderMatrix = [0 (row>1) 0;
                (col>1) 1 (col<worldDimension);
                 0 (row<worldDimension) 0;];
%Possible neighbor moves:              
neighborsMatrix = [0 (up==0) 0 ;
                (left==0) 1 (right==0);
                 0 (down==0) 0;];             

%Matrix of possible directions including neighbors and borders
possibleMovesMatrix = ((borderMatrix).*(neighborsMatrix)).*(patternMatrix);

%Vector of possible directions:
possibleMovesVector = sort(possibleMovesMatrix(possibleMovesMatrix(:) > 0));

%Random direction:
randomDirection = possibleMovesVector(randi(length(possibleMovesVector)));

directionCoordsVector = [[row (col-1)];[(row-1) col];[row (col+1)];[(row+1) col];[row col]];                         
res = [directionCoordsVector(randomDirection,1) directionCoordsVector(randomDirection,2)];
end

この関数は少し遅いです。プロファイラーを実行すると、次のように表示されます。

borderMatrix = [0 (row>1) 0;
(col>1) 1 (col<worldDimension);
0 (row<worldDimension) 0;];

36%の時間がかかり、randomDirection =possibleMove ...は15%の時間がかかります。プロセスを加速する方法はありますか?

たぶん、メインのゲームボードからクリーチャーの座標の周りのフリースポットをすぐに取得することで、別のアプローチを取ることができますか?もしそうなら、クリーチャーが境界外のインデックスを処理する必要なしにボードの境界近くにある場合、どのようにサブマトリックスを取得しますか?

みんなありがとう。

4

2 に答える 2

1

構造体の配列があり、配列内の構造体を移動しますか?それは私には非常に非効率に思えます。

また、borderMatrix-lineに時間がかかるのは、おそらく大きな配列を作成しているためです。

動く生き物を扱うための提案は次のとおりです。

クリーチャーをnCreatures-by-mProperties数値配列として保存します。個々のフィールドをクロールする関数を配列の列に適用する方がはるかに簡単です。例えばcreatures = [x,y,prop1,prop2];

クリーチャーを1つずつ移動します。

for iCreature = 1:nCreatures
    currentPos = creatures(iCreature,1:2);

    %# initialize array of allowed moves with border conditions
    goodMoves = [currentPos(1) > 1, currentPos(2) > 1, currentPos(1) < maxX, currentPos(2) < maxY, true];

    %# check for neighbors
    if any(creatures(:,1) == currentPos(1) - 1 & creatures(:,2) == currentPos(2))
       goodMoves(1) = false;
    end
    %# etc

    %# identify remaining good moves
    if any(goodMoves(1:4))
       goodMoveIdx = find(goodMoves);
       move = goodMoveIdx(randi(length(goodMoveIdx)));
    else
       move = 5; %# remain stationary
    end
end
于 2013-01-22T16:22:20.737 に答える
0

依存度の高いクリーチャーが複数存在するかどうかは明確ではありませんが、そうでない場合は効率的なワークフローになります。

  1. クリーチャーごとに1つの乱数を生成します
  2. クリーチャーごとに、可能な動きの数を決定します
  3. 対応する乱数を使用して選択します

それらが依存しているが、あまり多くない場合は、実行可能な値が見つかるまで、またはステップ2に依存関係を含めるまで、これを数回実行できます。

于 2013-01-22T15:25:25.973 に答える