SRL Archive - SRL Snippets

GetRoom(Debug: Boolean):TPointArray;


J J

2012-08-09 07:05:24

Hello,

This snippets gets the room that you are in if there is a black outside and if the room is seperated. This is made for Dungeoneering, but should also work very well at Piramid Plunder and Stronghold of Security.

function GetRoom(Debug: Boolean): TPointArray;
var
i, j, X, Y, nearest, room: Integer;
dist: Extended;
Rooms: T2DPointArray;

begin
for i:=MMX1 to MMX2 do
for j:=MMY1 to MMY2 do
begin
dist := Pow((MMCX-i), 2) + Pow((MMCY-j), 2);
if (dist < Pow(((MMX2-MMX1)/2), 2)) then
if not(FindColorTolerance(X, Y, 0, i, j, i, j, 10)) then
begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := Point(i, j);
end;
end;

if Debug then
begin
for i:=0 to high(Result) do
SMART_DrawDot(False, Point(Result[i].x, Result[i].y+50), clYellow);
end;

nearest := 1000;
Rooms := SplitTPA(Result, 3);
if (Length(Rooms) > 0) then
for i := 0 to high(Rooms) do
begin
MiddleTPAEx(Rooms[i], X, Y)
dist := Abs(MMCX - X) + Abs(MMCY - Y);
if (dist < nearest) then
begin
nearest := Round(dist);
room := i;
end;
end;

SetLength(Result, Length(Rooms[room]));
Result := Rooms[room];

if Debug then
begin
for i:=0 to high(Result) do
SMART_DrawDot(False, Point(Result[i].x, Result[i].y+50), clGreen);
end;
end;

Works with angle compass angle.
Result w/ Debug:
Current room in green, other rooms are yellow.

The result of the function are all the points in the green area.

Takes around 650 ms to calculate, lape should push that down to around a tenth of that I hope.

eska

2012-08-09 07:21:53

The only optimisation I could see would be to not resize the TPA every single time a new non-black pixel is found. Keep in mind, I have not tested this, I do not know how the memory is allocated when you resize an array, but I'm pretty sure it's more intensive than it seems. (Ex: Maybe it makes a copy of the array, only that copy is one bigger than the original, then the original is deleted)

Instead I'd start the TPA at the maximum size the TPA could possibly be:
sizeOfTPA:= ((MMX2-MMX1) * (MMY2-MMY1))

and I would use a simple integer to keep track of the 'true' size of the TPA.
Once we're done searching the map, resize the TPA to the right size using the integer.

Edit: Did some test. My suggestion does improve performence although by not much (~10%). Here's the script I made to confirm my hypothesis:
program new;
{$i SRL/SRL.simba}
{$I SRL/SRL/Misc/Debug.simba}
function UnOptimised: TPointArray;
var
i, j, X, Y: Integer;
dist: Extended;
begin
for i:=MMX1 to MMX2 do
for j:=MMY1 to MMY2 do
begin
dist := Pow((MMCX-i), 2) + Pow((MMCY-j), 2);
if (dist < Pow(((MMX2-MMX1)/2), 2)) then
if not(FindColorTolerance(X, Y, 0, i, j, i, j, 10)) then
begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := Point(i, j);
end;
end;
end;


function Optimised: TPointArray;
var
i, j, X, Y, size: Integer;
dist: Extended;
begin
size:= 0;
SetLength(Result, ((MMX2-MMX1) * (MMY2-MMY1)));

for i:=MMX1 to MMX2 do
for j:=MMY1 to MMY2 do
begin
dist := Pow((MMCX-i), 2) + Pow((MMCY-j), 2);
if (dist < Pow(((MMX2-MMX1)/2), 2)) then
if not(FindColorTolerance(X, Y, 0, i, j, i, j, 10)) then
begin
Inc(size);
Result[size] := Point(i, j);
end;
end;
SetLength(Result, size);
end;

var
t: integer;
begin
MarkTime(t);
Optimised;
writeln(inttostr(TimeFromMark(t)));

MarkTime(t);
UnOptimised;
writeln(inttostr(TimeFromMark(t)));
end.

Output:
Compiled successfully in 640 ms.
936
1045
Successfully executed.

EDIT2: After more testing, I found out that when there is alot of black in the screen, you gain more performance than I do. If more than 2/3 of the screen is black, then your method becomes faster than mine. So in other word, don't bother.

J J

2012-08-09 09:52:26

Hm I see, increasing an integer every time or increasing the size of the result every time should take around the same time. Both methods work, but I think that it's better to have a smaller array than an extremely large one and decreasing the length afterwards. But both ways work :P

Shatterhand

2012-08-09 11:09:18

Very nice JJ! :)

Olly

2012-08-09 13:29:17

You never seem to disappoint jj :P