Question

I have a big square matrix of structs which represents creatures. Each creature can move left,up,right or down. I'm checking the neighbouring matrix positions for empty cells and do the following calculation for the new coordinates:

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

This function is kind of slow, when I run the profiler it tells me that:

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

takes 36% of time and that: randomDirection = possibleMove... takes 15% of time. Is there a way I can accelerate the process?

Maybe I can take a different approach by taking from the main game board the free spots arround the coordinate of the creature immediately? If so, how do I take a submatrix if a creature is near the border of the board with out having to deal with off-boundary indexes?

Thanks, Guy.

Was it helpful?

Solution

So you have an array of structs, and move around the structs inside the array? That seems extremely inefficient to me.

Also, the reason the borderMatrix-line takes so long is because you are constructing a possibly large array.

Here's a suggestion for handling moving creatures:

Store your creatures as a nCreatures-by-mProperties numeric array. It's much easier to apply functions on a column of an array that to crawl individual fields. For example creatures = [x,y,prop1,prop2];

Move your creatures one-by-one:

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

OTHER TIPS

It is not really clear whether there are multiple highly dependant creatures, but otherwise this would be an efficient workflow:

  1. Generate 1 random number per creature
  2. Determine per creature how many possible moves it has
  3. Use the corresponding random number to make a choice

If they are dependant, but not too much you can do this several times untill you find a feasible value or include the dependance in step 2.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top