SRL Archive - Test corner

AutoColorWall test (very accurate)


marpis

2009-05-13 00:46:22

This function is extremely accurate, but very slow. It might take over 10 seconds to find the color, but it still does find it. It looks like it doesn't get confused of other players very easily.

It ignores colors found on the borders of the MM, like white color on the compass etc.

I wonder if the same thing could be done a faster way without making it any more inaccurate?

PS. I noticed that walls don't have just 1 color at the same time on MM, if you pick the colors of walls around MM you can find them different.

EDIT: I did some testing with various different tolerances and things, and came to this conclusion:
Browsing through RGB values is the best option to do this. Why? because high tolerances sometimes pick the color of grass etc, and if they fail they may pick almost black colors. My function returns either some almost white color, or total black (color 0) so its easier to check if AutoColor has been successful. I bet no tolerancemonster can get more accurate than this. (Im going to take some pictures that show where this function has found the right color, and i also post if it has given an invalid color)


test program:

program New;
{.include SRL/SRL.scar}

var
gATPA: T2DPointArray;

Function DebugATPA(aPoints: Array Of TPointArray; BmpName: String): Boolean;

Var
Width, Height, ClientBMP, I, L, C, Col: Integer;
xs, ys, xe, ye: Integer;
OuterPoints: TPointArray;

Begin
For I := 0 To High(aPoints) Do
L := L + Length(aPoints[i]);
SetLength(OuterPoints, L + 1);
C := 0;
For I := 0 To High(aPoints) Do
For L := 0 To High(aPoints[i]) Do
Begin
C := C + 1;
OuterPoints[C] := aPoints[i][L];
End;

Try
Begin
xe := xs xor xs;
ye := ys xor ys;
xs := 1 shl 20;
ys := 1 shl 20;

For I := 0 To High(OuterPoints) Do
Begin
xs := Min(xs, OuterPoints[i].X);
ys := Min(ys, OuterPoints[i].Y);

xe := Max(xe, OuterPoints[i].X);
ye := Max(ye, OuterPoints[i].Y);
End;

Width := xe - xs;
Height := ye - ys;

DisplayDebugImgWindow(0, 0);
DisplayDebugImgWindow(Width, Height);
ClientBMP := BitmapFromString(Width, Height, '');

CopyClientToBitmap(ClientBMP, xs, ys, xe, ye)
For I := 0 To High(aPoints) Do
Begin
Col := RGBtoColor(0, 255, 0);
For L := 0 To High(aPoints[i]) Do
FastSetPixel(ClientBMP, aPoints[i][L].X - xs, aPoints[i][L].Y - ys, Col);
End;

SafeDrawBitmap(ClientBMP, GetDebugCanvas, 0, 0);
DisplayDebugImgWindow(Width, Height);
If BmpName <> '' Then
SaveBitmap(ClientBMP, ScriptPath + BmpName + '.bmp');

FreeBitmap(ClientBMP);
End
Except
FreeBitmap(ClientBMP);
End;
Result := True;
End;

function AutoColorWall: integer;
var
TPA: TPointArray;
R, G, B, R2, G2, B2, hi, i, ii, DTM, x, y, hi: integer;
angle: extended;
dtmMainPoint: TDTMPointDef;
dtmSubPoints: Array [0..4] of TDTMPointDef;
TempTDTM: TDTM;
begin
writeln('AutoColoring Walls...');
for R:= 83 downto 73 do
for G:= 83 downto 73 do
for B:= 83 downto 73 do
begin
R2:= R*3;
G2:= G*3;
B2:= B*3;
if not FindColorTolerance(x, y, RGBToColor(R2, G2, B2), MMX1, MMY1, MMX2, MMY2, 2) then Continue;
FindColorsTolerance(TPA, RGBtoColor(R2, G2, B2), MMX1, MMY1, MMX2, MMY2, 2);
if Length(TPA) < 30 then continue;
hi := High(TPA);

for i:= 0 to hi do
begin
dtmMainPoint.x := TPA[i].x;
dtmMainPoint.y := TPA[i].y;
dtmMainPoint.AreaSize := 0;
dtmMainPoint.AreaShape := 0;
dtmMainPoint.Color := RGBToColor(R2, G2, B2);
dtmMainPoint.Tolerance := 2;

for ii:= 1 to 5 do
begin
dtmSubPoints[ii-1].x := dtmMainPoint.x;
dtmSubPoints[ii-1].y := dtmMainPoint.y-ii;
dtmSubPoints[ii-1].AreaSize := 0;
dtmSubPoints[ii-1].AreaShape := 0;
dtmSubPoints[ii-1].Color := RGBToColor(R2, G2, B2);
dtmSubPoints[ii-1].Tolerance := 2;
end;

TempTDTM.MainPoint := dtmMainPoint;
TempTDTM.SubPoints := dtmSubPoints;
DTM:= AddDTM(TempTDTM);

if FindDTMRotated(DTM, x, y, MMX1, MMY1, MMX2, MMY2, 0, Pi, 0.01, angle) then
if InCircle(MMCX, MMCY, x, y, 72) then
begin
result:= GetColor(x, y);
exit;
end else
continue;
end;
end;
writeln('AutoColorWall Failed! Result = 0');
end;

var
t, c: integer;

begin
SetupSRL;
SetLength(gATPA, 1);
MarkTime(t);
c:= AutoColorWall;
writeln('Time elapsed: '+inttostr(TimeFromMark(t))+' ms');
writeln('Wallcolor = '+inttostr(c));
FindColorsTolerance(gATPA[0], c, mmx1, mmy1, mmx2, mmy2, 10);
DebugATPA(gATPA, '');
end.

i tested more than 6 times but here are some shots:

edit: minor bugfix
edit: major bug, will be fixing it tomorroow
edit: final conclusion: i took the old function back (the slow one)
edit: minor bugfix

Naum

2009-05-13 00:52:27

ACA2 AnyOne?

Like the function though, but ACA makes ones 20 times faster and is alot less code :)

senrath

2009-05-13 00:55:45

I'm confused. Why set xs and ys to 1 shl 20? Wouldn't it be faster just to set them to 1048576?

footballjds

2009-05-13 00:59:59

2 things
i made one b4 using a 2*1 dtm and it did it in 16 ms with perfect accuarcy.
the difference in colors in sensible as:
if you face north all the lines that are vertical or horizontal are one color.
all the lines that are slanted are another ;)
go to lumby and try it. :D

but the walls are always only 2 different colors

Naum

2009-05-13 01:06:24

From: senrath
I'm confused. Why set xs and ys to 1 shl 20? Wouldn't it be faster just to set them to 1048576?


Thats Wizzup?'s, he knows best my friend ;)

marpis

2009-05-13 01:10:07

From: NaumanAkhlaQ
ACA2 AnyOne?

Like the function though, but ACA makes ones 20 times faster and is alot less code :)

try it and see how it fails


From: footballjds

i made one b4 using a 2*1 dtm and it did it in 16 ms with perfect accuarcy.

i tried it, it doesn't work. it occasionally moves the mouse outside the MM circle, and it also gives wrong colors.
my function makes a 1*5 DTM with almost perfect colors, so mine is like more advanced version of your function :)
i got the idea from your function tho'. first tried to make a bitmap but it didn't work…

From: senrath

I'm confused. Why set xs and ys to 1 shl 20? Wouldn't it be faster just to set them to 1048576?

i don't understand what you mean, i'm not that leet with colors
edit: ah you meant wizzups function ^^

Tniffoc

2009-05-13 07:31:19

From: senrath
I'm confused. Why set xs and ys to 1 shl 20? Wouldn't it be faster just to set them to 1048576?

Wizzup likes to confuse people.

ZephyrsFury

2009-05-13 14:52:58

BTW yes FindDTMsRotated requires the angle to be in radians. Maybe thats why your function is slow.

Markus

2009-05-13 15:03:23

Tolerance 30 CTS 1 anyone? Always works, or at least used to work (haven't tested lately).

Home

2009-05-13 15:55:21

So i made this little function that will pick a Wall Color from Minimap, doesn't matter what angle or anything you are..
I think Old School Scriptin Rules (:

[PHP]function GetWallColor: Integer;
var TimeMark, DTM, x, y: integer;
acc: extended;
begin
MarkTime(TimeMark);
DTM := DTMFromString('78DA634C676260086240016F9F7C641001D28' +
'C40FC1F0818416AFC71AB0101B09A7022D44413A1C60BBF1A009F' +
'1015DF');
if FindDtmRotated(DTM, x, y, MMX1, MMY1, MMX2, MMY2, radians(-40), radians(40), 0.01, acc) then
begin
Result := GetColor(x, y);
Writeln('Time: ' + inttostr(TimeFromMark(TimeMark)) + ' Ms');
Writeln(Inttostr(Result));
end;
FreeDtm(DTM);
end;
[/PHP]


Your Friend,
~Home

Nadeem

2009-05-13 16:07:47

From: senrath
I'm confused. Why set xs and ys to 1 shl 20? Wouldn't it be faster just to set them to 1048576?


lol senrath :P Actually I remember Wizzup? or Sky Scripter… Saying that instead of declaring the actualy value, using shl/shr on a number is faster and uses lesser clock cycle..? Or wait… maybe that was for xor'ing a value by itself :P



~NS

NiCbaZ

2009-05-13 16:26:03

Nice function, could be done faster though.


Nadeem, so you think its ok to steel my avatar? :D?

marpis

2009-05-13 16:38:31

Okay i did some testing and noticed that tol30, cts1 can find the color very well.
i used this in my function and now it's quite perfect :)

nielsie95

2009-05-13 16:49:35

I think you can also do it with some Luminance checks (it should be pretty high for walls)?


for i:= 0 to high(tpa) do
if not InCircle(TPA[i].x, TPA[i].y, MMCX, MMCy, 72) then
begin
swap(TPA[i], TPA[high(tpa)]);
setarraylength(TPA, High(TPA));
end;

You can use FilterPointsPie for that :)

marpis

2009-05-13 18:53:45

From: nielsie95
I think you can also do it with some Luminance checks (it should be pretty high for walls)?


well yes i could, would it be faster? could it be done by keeping saturation and hue constant and checking just for luminance? cause that would be faster than RGB (i believe so)

Nadeem

2009-05-13 19:13:45

lol NiCbaZ, your a lurker, i'm a lurker, we're both lurker squared :P so i think its OK :P

Yes luminance checks will actually make it alot better :P But you can always do it so, that if it is unable to find it properly with luminance, it can revert to the RGB as a fail :)

nielsie95

2009-05-13 20:56:51

From: marpis
well yes i could, would it be faster? could it be done by keeping saturation and hue constant and checking just for luminance? cause that would be faster than RGB (i believe so)


Here's something I quickly put together:


program New;
{.include SRL\SRL.scar}

function GetWallColors: TIntegerArray;
var
cts, i, B: Integer;
H, S, L: Extended;
p: TPointArray;
c, cBlackList: TIntegerArray;
begin
SetLength(Result, 0);
cts := GetColorToleranceSpeed;

try
ColorToleranceSpeed(1);

FindColorsTolerance(p, 15724270, MMX1, MMY1, MMX2, MMY2, 20);
FilterPointsPie(p, 0, 360, 5, 75, MMCX, MMCY);
if (Length(p) = 0) then
Exit;

cBlackList := [16777215, 16711422, 15527148, 13816530, 15527148, 14869218, 12961221];

c := GetColors(p);
ClearSameIntegers(c);

for i := High(c) downto 0 do
begin
if InIntArray(cBlackList, c[i]) then
Continue;
B := (c[i] shr 16 and $ff);
if (not InRange(B - 240, -12, 12)) then
Continue;
ColorToHSL(c[i], H, S, L);

if (L >= 88.0) then
begin
SetLength(Result, Length(Result) + 1);
Result[High(Result)] := c[i];
end;
end;
finally
ColorToleranceSpeed(cts);
end;
end;

var
c: TIntegerArray;
i, t: Integer;
begin
t := GetSystemTime;
c := GetWallColors;
WriteLn('Found ' + IntToStr(Length(c)) + ' WallColors in ' + IntToStr(GetSystemTime - t) + ' ms.');
for i := 0 to High(c) do
WriteLn(c[i]);
end.

marpis

2009-05-13 21:45:06

From: nielsie95
Here's something I quickly put together:


that's not funny dude :( i spent a lot of time on my function and now you just "quickly put together" an insanely accurate one that gets the colors in 0ms :D

i tried it, it's perfect. thanks!
add it to SRL asap! ^^

edit: well, it doesn't work with 0 tolerance but with 15 it got all walls but no other white points
edit: oh my mistake! it does work with 0 tolerance :D that's amazing dude

Naum

2009-05-13 23:10:24

Well, what can I say - Niels is a machine

nielsie95

2009-05-14 00:29:44

I could make it that fast, because I remember a function by Wizzup who thought of using luminance for walls. It was just after I got developer :)

Camaro'

2009-05-14 06:09:18

How come my scar 3.20 D doesnt show debug the function for me. Like the debugatpa function really isnt working for me. It hasnt worked for me in forever.