The following Pascal script needs a bit of context for its purpose to be understood. For those who don't give about purpose, feel free to skip ahead.
Background
A game I'm terribly fond of has a couple of levels which have nothing to do with the rest of the game. One of those is a puzzle: Alpha Sector::virgilw::Brain
When you open the game, it looks like this:
Turns out you need to connect all the 8 red dots to the emitter like this:
All dots must be clicked in a specific sequence. If a dot is clicked and allowed to switch, it will light up if not already lit up. If it was already lit up it will darken again. The sequence to light up the 8th dot looks like this:
1 2 1 3 1 2 1 4
1 2 1 3 1 2 1 5
1 2 1 3 1 2 1 4
1 2 1 3 1 2 1 6
1 2 1 3 1 2 1 4
1 2 1 3 1 2 1 5
1 2 1 3 1 2 1 4
1 2 1 3 1 2 1 7
1 2 1 3 1 2 1 4
1 2 1 3 1 2 1 5
1 2 1 3 1 2 1 4
1 2 1 3 1 2 1 6
1 2 1 3 1 2 1 4
1 2 1 3 1 2 1 5
1 2 1 3 1 2 1 4
1 2 1 3 1 2 1 8
The mathematically inclined can probably tell us what such a sequence is called, but it should be obvious to the rest of us that the first 7 characters are always the same and only the 8th varies.
Now, there's an achievement for lighting up all 8 dots within 60 seconds. Since it's already 128 clicks for lighting up the 8th one alone, I decided to automate the process using SCAR Divi (manual), an environment running Pascal scripts which allows you to automate keyboard presses and mouse movements.
Code
The resulting code is ugly, but I was mainly looking for fast code. This means it may not be up to par with Pascal-style and I took a short-cut wherever I thought it would influence the execution speed.
I'm looking for improvements on readability wherever this does not hurt the performance in any way. I've written a fair bit of Pascal but I've always been a little fuzzy on what did and didn't impact performance. General tips about this are welcome.
The most used procedure is MnC(x, y)
, short for Move'n'Click. It moves the mouse to whatever coordinate you give it, clicks once with the left mouse-button and halts in between to give the rest of the computer time to catch up. Or whatever it does in that time, but it breaks terribly if it doesn't wait long enough.
All values are hardcoded. I'm aware I can put them at the front of the program as global variables, but I wasn't sure whether the additional look-up would penalize performance. Current script manages to win in 21.86 seconds :-)
virgilwBrain.scar
Procedure MnC(x,y : integer);
begin
MoveMouse(x,y);
Wait(30);
ClickMouse(x,y,false);
Wait(29);
end;
Procedure hit1();
begin
MnC(421,298);
end;
Procedure hit2();
begin
MnC(470,311);
end;
Procedure hit3();
begin
MnC(500,318);
end;
Procedure hit4();
begin
MnC(539,325);
end;
Procedure hit5();
begin
MnC(577,325);
end;
Procedure hit6();
begin
MnC(611,318);
end;
Procedure hit7();
begin
MnC(655,311);
end;
Procedure hit8();
begin
MnC(694,298);
end;
Procedure line();
begin
hit1;
hit2;
hit1;
hit3;
hit1;
hit2;
hit1;
end;
begin
line;
hit4;
line;
hit5;
line;
hit4;
line;
hit6;
line;
hit4;
line;
hit5;
line;
hit4;
line;
hit7;
line;
hit4;
line;
hit5;
line;
hit4;
line;
hit6;
line;
hit4;
line;
hit5;
line;
hit4;
line;
hit8;
line;
hit4;
line;
hit5;
line;
hit4;
line;
hit6;
line;
hit4;
hit1;
hit2;
end.