Check-in Differences
Not logged in

Difference From:

[fc9286dad1] uum (user: kinaba, tags: redesign, date: 2012-07-15 12:11:33)

To:

[b4aceba693] 1 step death move detector rev.1 (user: kinaba, tags: trunk, date: 2012-07-14 13:02:03)

Deleted maps/100x100.map version [5beaf6fad4143830]

1 ################################################################################ < 2 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 3 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 4 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 5 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 6 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\L\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 7 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 8 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 9 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 10 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 11 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 12 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 13 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 14 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 15 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 16 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 17 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 18 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 19 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 20 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 21 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 22 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 23 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 24 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 25 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 26 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 27 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 28 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 29 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 30 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 31 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 32 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 33 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 34 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 35 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 36 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 37 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 38 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 39 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 40 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 41 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 42 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 43 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 44 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 45 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 46 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 47 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 48 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 49 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 50 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 51 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 52 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 53 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 54 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 55 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 56 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 57 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 58 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 59 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 60 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 61 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 62 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\R\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 63 #************************\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 64 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.********************************\.\.\.\.\.\.\.\.\. < 65 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.************* < 66 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 67 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 68 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 69 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 70 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 71 #************************\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 72 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.********************************\.\.\.\.\.\.\.\.\. < 73 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.************* < 74 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 75 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 76 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 77 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 78 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 79 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 80 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 81 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 82 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 83 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 84 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 85 #************************\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 86 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.********************************\.\.\.\.\.\.\.\.\. < 87 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.************* < 88 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 89 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 90 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 91 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 92 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 93 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 94 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 95 #************************\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 96 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.********************************\.\.\.\.\.\.\.\.\. < 97 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.************* < 98 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. < 99 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\ < 100 ################################################################################ <

Deleted maps/40x40.map version [06dc362ef16f425d]

1 ######################################## < 2 #L\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\# < 3 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.# < 4 #.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*# < 5 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.# < 6 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\# < 7 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.# < 8 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\# < 9 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.# < 10 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\# < 11 #.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*# < 12 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\# < 13 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.# < 14 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\# < 15 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.# < 16 #.\.\.\.\.\.\.\.\.\W\.\.\.\.\.\.\.\.\.\# < 17 #.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*# < 18 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\# < 19 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.# < 20 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\# < 21 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.# < 22 #.\.\.\.\!\.\.\.\.\.\.\.\W\.\.\.\.\.\.\# < 23 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.# < 24 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\# < 25 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.# < 26 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\# < 27 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.# < 28 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\# < 29 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.# < 30 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\# < 31 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\!\.\.# < 32 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\# < 33 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.# < 34 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\# < 35 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\!\.\.# < 36 #.\.\.\.\.\.\.\.\W\.\.\.\.\.\.\.\.\.\.\# < 37 #\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.# < 38 #.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.R# < 39 ######################################## < 40 < 41 Flooding 80 <

Deleted maps/beard1.map version [bb6926793a51311a]

1 ########## < 2 #** \\\\# < 3 #.R.. # < 4 # \ ..*\# < 5 #! ..*!# < 6 #### # # < 7 #\\... # L < 8 #\\.W... # < 9 #\\. # < 10 ########## < 11 < 12 Growth 15 < 13 Razors 0 <

Deleted maps/beard2.map version [2e942009c89717d7]

1 ############################## < 2 #R...........................# < 3 #.........................W..# < 4 #..\\\\\\\\\\\\\\\\\\\\\\\\..# < 5 #............................# < 6 #..*****.*\...*...*...*****..# < 7 #..*\....*\....*\*..*.\\*\\..# < 8 #..*\....****..!*!......*....# < 9 #..*\....*\....*\*..*...*....# < 10 #..*\....*\...*...*.....*....# < 11 #............................# < 12 #..\\\\\\\\\\\\\\\\\\\\\\\\..# < 13 #................ ..... .....# < 14 #................ W....L# < 15 ############################## < 16 < 17 Growth 25 < 18 Razors 10 < 19 Flooding 20 <

Deleted maps/beard3.map version [1dcab340493857d0]

1 ################ < 2 #*****#!! 1 # < 3 #..\..# # < 4 #########\\\\ # .\\\. # < 5 #.............# * # < 6 #.. .\\\#..!..#\** # < 7 #.. LW\\#W ..##### #### < 8 #..R\\\\#.. ..*\*\*W...# < 9 #.......A.. ...\.\...\\# < 10 #.......... ** # < 11 ############....\.###### < 12 #.....!# < 13 ######## < 14 < 15 Growth 10 < 16 Trampoline A targets 1 <

Deleted maps/beard4.map version [b62967eb47a5f507]

1 #################### < 2 #W\\!#\\\**.\#W\\\W# < 3 ##*######..###..\\\# < 4 #.......\.R ###...\# < 5 #####.###.#.......## < 6 #.......#.#\####.### < 7 #\\##\###\#\\#...#.L < 8 #\##\.###.####.#.#.# < 9 #\W#####.....###.W.# < 10 ####\\...\\\...#.#.# < 11 #W*######.######.#.# < 12 #\\\\\\\\\.........# < 13 ############\###\### < 14 #\\.. *..........\\# < 15 #W... #.........##W# < 16 #################### <

Deleted maps/fun1.map version [2f7f87a4d02c6448]

1 \\\\\\\\\L < 2 ********** < 3 < 4 < 5 < 6 < 7 < 8 R <

Deleted maps/trampoline1.map version [5af697c0003d5516]

1 ############ < 2 #..*.R..*..# < 3 #..A....B..###### < 4 #....2.. ..#\\\C# < 5 #......* *.#\\\1# < 6 ########L######## < 7 < 8 Trampoline A targets 1 < 9 Trampoline B targets 1 < 10 Trampoline C targets 2 <

Deleted maps/trampoline2.map version [288f9d055c2777fa]

1 ###### < 2 #....# < 3 #.**.# < 4 #.**.# < 5 #.**.# < 6 ######.\\.###### < 7 #**....*.......# < 8 #\\....L\\\....# < 9 #A......*****..# < 10 ######R.....########### < 11 ###.....*.....\\\# < 12 #\\\\#..1...\\\# < 13 #\\\\#......\\\# < 14 ################ < 15 < 16 Trampoline A targets 1 <

Deleted maps/trampoline3.map version [7fcf90c1ca373c41]

1 ####################################### < 2 #****................#..1...\\\\\\\B..# < 3 #R.......############################## < 4 #.. ..................................# < 5 #.. ........ \ ......# < 6 #.. .*. ....**.*...#....... ..........# < 7 #.. ... ....\\\\...#.A..... ..........# < 8 #.. ... ....\ .....#....... * \\..# < 9 #.. ... ....\......#....... ..........# < 10 #.. ... ....\......#....... ..........# < 11 #.. ... ...........#................**# < 12 #..\\\\\...........#................\\# < 13 ########### ############## ############ < 14 #...*.................................# < 15 #....*.................. ......# < 16 #... .*....*.............. ..... .....# < 17 #....*2*........########.. ..... .....L < 18 #...*...*.......#\\\#..... ...*.......# < 19 #.....\\\.......#\\\#....**..***......# < 20 #.... .......#\\\#*................# < 21 #...............#\\\#*...**...*.......# < 22 #...............#.....................# < 23 ###### ############## ### ####### < 24 #\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\# < 25 ####################################### < 26 < 27 Trampoline A targets 1 < 28 Trampoline B targets 2 < 29 <

Deleted score_memo.txt version [95f0626c958d6d31]

1 contest1 212! < 2 contest2 280? < 3 contest3 275! < 4 contest4 561? < 5 contest5 1281? < 6 contest6 737 // deadend trap < 7 contest7 867? < 8 contest8 1245 // tricky < 9 contest9 3042? < 10 contest10 2076 // * on lambda, must move * first < 11 flood1 569 // too slow, because of 1-left danger lambda < 12 flood2 280? < 13 flood3 802 // too slow, drown < 14 flood4 970 // incorrect order of digging < 15 flood5 561? < 16 trampoline1 291 // * on trampoline. must move * first < 17 trampoline2 1728? < 18 trampoline3 698 // * on trampoline target. must move * first. < 19 beard1 856? < 20 beard2 2792 // hutsu-ni muzui < 21 beard3 811 // tricky. must hurry to cut hige. < 22 beard4 677 // deadend trap <

Deleted src/Makefile version [01a4f7a0531dae71]

1 # To build, the following packages are needed. < 2 # wget http://ftp.digitalmars.com/dmd_2.059-0_i386.deb < 3 # sudo apt-get install gcc gcc-multilib < 4 # sudo pkg -i dmd_2.059-0_i386.deb < 5 < 6 all: < 7 dmd -O -release -inline -oflifter cui_auto_main.d driver.d game.d output <

Modified src/cui_auto_main.d from [b38d60ea39d11e6e] to [a0394f9b9692c1eb].

2 import game; 2 import game; 3 import output; 3 import output; 4 import driver; 4 import driver; 5 import solver; 5 import solver; 6 6 7 class CUI(Solver) : GameObserver 7 class CUI(Solver) : GameObserver 8 { 8 { > 9 this(const(Game) g) { 9 this(in Game g) { solver = new Solver(g); } | 10 solver = new Solver(g); > 11 } 10 Solver solver; 12 Solver solver; 11 bool fin; 13 bool fin; 12 override void on_game_changed(char c, in Game g, bool finished) | 14 override void on_game_changed(char c, const(Game) g, bool finished) 13 { 15 { 14 fin = finished; 16 fin = finished; 15 } 17 } 16 } 18 } 17 19 18 void main(string[] args) 20 void main(string[] args) 19 { 21 { 20 Driver d = new Driver(stdin); 22 Driver d = new Driver(stdin); 21 d.addObserver!(GuardedOutput)(); 23 d.addObserver!(GuardedOutput)(); 22 auto c = d.addObserver!(CUI!MainSolver)(); | 24 auto c = d.addObserver!(CUI!Solver_1)(); 23 while(!c.fin) 25 while(!c.fin) 24 d.command(c.solver.single_step()); 26 d.command(c.solver.single_step()); 25 } 27 }

Deleted src/driver.d version [3d15ff20e76164b8]

1 import game; < 2 import util; < 3 < 4 interface GameObserver < 5 { < 6 // this(in Game g); < 7 void on_game_changed(char c, in Game g, bool finished); < 8 } < 9 < 10 class Driver < 11 { < 12 this(Game g) { this.game = g; } < 13 this(File game_data) { this(new Game(game_data)); } < 14 < 15 void command(char c) < 16 { < 17 if( finished ) < 18 return; < 19 if( c == 'A' ) < 20 aborted = true; < 21 else < 22 game.command(c); < 23 foreach(ob; observers) < 24 ob.on_game_changed(c, game, finished); < 25 } < 26 < 27 T addObserver(T)() < 28 { < 29 T t = new T(game); < 30 observers ~= t; < 31 return t; < 32 } < 33 < 34 @property bool finished() < 35 { < 36 return game.cleared || game.dead || aborted; < 37 } < 38 < 39 private: < 40 Game game; < 41 GameObserver[] observers; < 42 bool aborted = false; < 43 } < 44 < 45 unittest < 46 { < 47 static class MockGame : Game { < 48 this() { super(null,null,null); } < 49 string log; < 50 void command(char c) { log ~= c; } < 51 } < 52 static class MockObserver : GameObserver { < 53 string log; < 54 this(in Game g) {} < 55 void on_game_changed(char c, in Game g, bool fin) { log~=c; if(f < 56 } < 57 < 58 auto g = new MockGame; < 59 auto d = new Driver(g); < 60 auto o = d.addObserver!MockObserver(); < 61 foreach(char c; "UDLRSAUDLRSA") < 62 d.command(c); < 63 assert(g.log == "UDLRS"); < 64 assert(o.log == "UDLRSA$"); < 65 } <

Modified src/game.d from [fc05481901940844] to [545a22e98c8c86c7].

4 4 5 class Pos 5 class Pos 6 { 6 { 7 public immutable int y, x; 7 public immutable int y, x; 8 mixin DeriveCreate; 8 mixin DeriveCreate; 9 mixin DeriveCompare; 9 mixin DeriveCompare; 10 mixin DeriveShow; 10 mixin DeriveShow; 11 Pos clone() const { return cast(Pos) this; } | 11 Pos clone() const { return new Pos(y, x); } 12 12 13 @property: 13 @property: 14 Pos wait() { return this.clone(); } 14 Pos wait() { return this.clone(); } 15 Pos up() { return new Pos(y+1, x); } 15 Pos up() { return new Pos(y+1, x); } 16 Pos down() { return new Pos(y-1, x); } 16 Pos down() { return new Pos(y-1, x); } 17 Pos left() { return new Pos(y, x-1); } 17 Pos left() { return new Pos(y, x-1); } 18 Pos right() { return new Pos(y, x+1); } 18 Pos right() { return new Pos(y, x+1); } ................................................................................................................................................................................ 41 41 42 class Water 42 class Water 43 { 43 { 44 public immutable int base, pace; 44 public immutable int base, pace; 45 mixin DeriveCreate; 45 mixin DeriveCreate; 46 mixin DeriveCompare; 46 mixin DeriveCompare; 47 mixin DeriveShow; 47 mixin DeriveShow; 48 Water clone() const { return cast(Water)this; } | 48 Water clone() const { return new Water(base, pace); } 49 49 50 static load(string[string] params) 50 static load(string[string] params) 51 { 51 { > 52 return new Water( 52 return new Water(params.get("Water", "0").to!int(), | 53 params.get("Water", "0").to!int(), 53 params.get("Flooding", "0").to!int()); | 54 params.get("Flooding", "0").to!int() > 55 ); 54 } 56 } 55 57 56 int level(int number_of_update) const 58 int level(int number_of_update) const 57 { 59 { 58 return pace ? base+(number_of_update/pace) : base; 60 return pace ? base+(number_of_update/pace) : base; 59 } 61 } 60 62 ................................................................................................................................................................................ 82 assert( 1 == w.level(3) ); 84 assert( 1 == w.level(3) ); 83 assert( 1 == w.level(4) ); 85 assert( 1 == w.level(4) ); 84 assert( 1 == w.level(5) ); 86 assert( 1 == w.level(5) ); 85 } 87 } 86 88 87 //////////////////////////////////////////////////////////////////////////////// 89 //////////////////////////////////////////////////////////////////////////////// 88 90 89 class Hige < 90 { < 91 public immutable int pace; < 92 mixin DeriveCreate; < 93 mixin DeriveCompare; < 94 mixin DeriveShow; < 95 Hige clone() const { return cast(Hige)this; } < 96 < 97 static load(string[string] params) < 98 { < 99 return new Hige(params.get("Growth", "25").to!int()); < 100 } < 101 < 102 bool is_growing_turn(int turn) const < 103 { < 104 return pace ? turn%pace == pace-1 : false; < 105 } < 106 < 107 int until_rise(int turn) const < 108 { < 109 return pace ? pace-turn%pace : int.max; < 110 } < 111 } < 112 < 113 //////////////////////////////////////////////////////////////////////////////// < 114 < 115 class Map 91 class Map 116 { 92 { 117 mixin DeriveShow; 93 mixin DeriveShow; 118 94 119 static Map load(string[] raw_data, string[string] params, char[char] tra | 95 static Map load(string[] raw_data, string[string] params) 120 { 96 { 121 // TODO: choose optimal representation. 97 // TODO: choose optimal representation. 122 return new Map(raw_data, params, trampo); | 98 return new Map(raw_data, params); 123 } 99 } 124 100 125 char[][] data; 101 char[][] data; 126 Pos robot; 102 Pos robot; 127 Pos lift; 103 Pos lift; 128 int waterproof; 104 int waterproof; 129 Pos[char] tr_target; < 130 Pos[][char] tr_source; < 131 const(Hige) hige; < 132 int razor; < 133 105 134 Map clone() const { return new Map(this); } 106 Map clone() const { return new Map(this); } 135 this(in Map m) { | 107 this(const(Map) m) { 136 foreach(s; m.data) 108 foreach(s; m.data) 137 this.data ~= s.dup; 109 this.data ~= s.dup; 138 this.robot = m.robot.clone(); 110 this.robot = m.robot.clone(); 139 this.lift = m.lift.clone(); 111 this.lift = m.lift.clone(); 140 this.waterproof = m.waterproof; 112 this.waterproof = m.waterproof; 141 this.tr_target = cast(Pos[char])m.tr_target; < 142 this.tr_source = cast(Pos[][char])m.tr_source; < 143 this.hige = m.hige.clone(); < 144 this.razor = m.razor; < 145 } 113 } 146 114 147 this(string[] raw_data, string[string] params, char[char] trampo) | 115 this(string[] raw_data, string[string] params) 148 { 116 { 149 int width = 0; 117 int width = 0; 150 foreach(r; raw_data) 118 foreach(r; raw_data) 151 width = max(width, r.length); 119 width = max(width, r.length); 152 foreach(r; raw_data) { 120 foreach(r; raw_data) { 153 this.data ~= r.dup; 121 this.data ~= r.dup; 154 this.data[$-1].length = width; 122 this.data[$-1].length = width; ................................................................................................................................................................................ 159 for(int x=1; x<=W; ++x) { 127 for(int x=1; x<=W; ++x) { 160 if(this[y,x] == 'R') 128 if(this[y,x] == 'R') 161 this.robot = new Pos(y,x); 129 this.robot = new Pos(y,x); 162 if(this[y,x] == 'L' || this[y,x] == 'O') 130 if(this[y,x] == 'L' || this[y,x] == 'O') 163 this.lift = new Pos(y,x); 131 this.lift = new Pos(y,x); 164 } 132 } 165 133 166 Pos[char] tr_pos; < 167 for(int y=1; y<=H; ++y) < 168 for(int x=1; x<=W; ++x) { < 169 char c = this[y,x]; < 170 if('1'<=c && c<='9' || 'A'<=c&&c<='I') < 171 tr_pos[c] = new Pos(y,x); < 172 } < 173 < 174 this.waterproof = params.get("Waterproof", "5").to!int(); 134 this.waterproof = params.get("Waterproof", "5").to!int(); 175 foreach(fr,to; trampo) { < 176 tr_target[fr] = tr_pos[to]; < 177 if(to !in tr_source) tr_source[to] = []; < 178 tr_source[to] ~= tr_pos[fr]; < 179 } < 180 < 181 this.hige = Hige.load(params); < 182 this.razor = params.get("Razors", "0").to!int(); < 183 } 135 } 184 136 185 const @property { 137 const @property { 186 int H() { return data.length; } 138 int H() { return data.length; } 187 int W() { return data[0].length; } 139 int W() { return data[0].length; } 188 } 140 } 189 141 ................................................................................................................................................................................ 193 // Adjust coordinate to the spec. bottom-left is (1,1). 145 // Adjust coordinate to the spec. bottom-left is (1,1). 194 --y, --x; 146 --y, --x; 195 if(y<0||H<=y||x<0||W<=x) 147 if(y<0||H<=y||x<0||W<=x) 196 return '#'; 148 return '#'; 197 return data[H-1-y][x]; 149 return data[H-1-y][x]; 198 } 150 } 199 151 200 char opIndex(in Pos p) | 152 char opIndex(Pos p) 201 { 153 { 202 return this[p.y, p.x]; 154 return this[p.y, p.x]; 203 } 155 } 204 } 156 } 205 157 206 void opIndexAssign(char c, int y, int x) 158 void opIndexAssign(char c, int y, int x) 207 { 159 { ................................................................................................................................................................................ 208 // Adjust coordinate to the spec. bottom-left is (1,1). 160 // Adjust coordinate to the spec. bottom-left is (1,1). 209 --y, --x; 161 --y, --x; 210 if(y<0||H<=y||x<0||W<=x) 162 if(y<0||H<=y||x<0||W<=x) 211 return; 163 return; 212 data[H-1-y][x] = c; 164 data[H-1-y][x] = c; 213 } 165 } 214 166 215 void opIndexAssign(char c, in Pos p) | 167 void opIndexAssign(char c, Pos p) 216 { 168 { 217 this[p.y, p.x] = c; 169 this[p.y, p.x] = c; 218 } 170 } 219 171 220 Pos[] objects(char c) const { | 172 Pos[] lambdas() const { 221 Pos[] ans; 173 Pos[] ans; 222 for(int y=1; y<=H; ++y) 174 for(int y=1; y<=H; ++y) 223 for(int x=1; x<=W; ++x) 175 for(int x=1; x<=W; ++x) 224 if(this[y,x] == c) | 176 if(this[y,x] == '\\') 225 ans ~= new Pos(y,x); 177 ans ~= new Pos(y,x); 226 return ans; 178 return ans; 227 } 179 } 228 180 229 Pos[] razors() const { return objects('!'); } < 230 Pos[] lambdas() const { return objects('\\'); } < 231 < 232 bool cleared() const 181 bool cleared() const 233 { 182 { 234 for(int y=1; y<=H; ++y) 183 for(int y=1; y<=H; ++y) 235 for(int x=1; x<=W; ++x) 184 for(int x=1; x<=W; ++x) 236 if(this[y,x] == 'L' || this[y,x] == 'O') 185 if(this[y,x] == 'L' || this[y,x] == 'O') 237 return false; 186 return false; 238 return true; 187 return true; 239 } 188 } 240 189 241 Tuple!(int,bool) command(char c, int turn) | 190 Tuple!(int,bool) command(char c) 242 { 191 { 243 assert( this[robot] == 'R' ); < 244 if(c=='R') return move( 0, +1, turn); | 192 if(c=='R') return move( 0, +1); 245 if(c=='L') return move( 0, -1, turn); | 193 if(c=='L') return move( 0, -1); 246 if(c=='U') return move(+1, 0, turn); | 194 if(c=='U') return move(+1, 0); 247 if(c=='D') return move(-1, 0, turn); | 195 if(c=='D') return move(-1, 0); 248 if(c=='W') return move( 0, 0, turn); | 196 if(c=='W') return move( 0, 0); 249 if(c=='S') return use_razor(turn); < 250 assert(false); 197 assert(false); 251 } 198 } 252 199 253 Tuple!(int, bool) use_razor(int turn) < 254 { < 255 if(razor) { < 256 razor--; < 257 for(int dy=-1; dy<=+1; ++dy) < 258 for(int dx=-1; dx<=+1; ++dx) < 259 if(this[robot.y+dy,robot.x+dx] == 'W') < 260 this[robot.y+dy,robot.x+dx] = ' '; < 261 } < 262 < 263 bool dead = update(turn); < 264 return tuple(0,dead); < 265 } < 266 < 267 Tuple!(int, bool) move(int dy, int dx, int turn) | 200 Tuple!(int, bool) move(int dy, int dx) 268 { 201 { 269 int y = robot.y; 202 int y = robot.y; 270 int x = robot.x; 203 int x = robot.x; > 204 assert( this[robot] == 'R' ); 271 int lambda = 0; 205 int lambda = 0; > 206 bool dead = false; 272 if( '\\' == this[y+dy,x+dx] ) 207 if( '\\' == this[y+dy,x+dx] ) 273 lambda++; 208 lambda++; 274 if( '!' == this[y+dy,x+dx] ) < 275 razor++; < 276 if( " \\!.O".count(this[y+dy,x+dx])==1 ) { | 209 if( " \\.O".count(this[y+dy,x+dx])==1 ) { 277 this[y,x]=' '; 210 this[y,x]=' '; 278 this[y+dy,x+dx]='R'; 211 this[y+dy,x+dx]='R'; 279 robot = new Pos(y+dy,x+dx); 212 robot = new Pos(y+dy,x+dx); 280 } else if(dy==0 && '*'==this[y+dy,x+dx] && ' '==this[y+dy*2,x+dx 213 } else if(dy==0 && '*'==this[y+dy,x+dx] && ' '==this[y+dy*2,x+dx 281 this[y,x]=' '; 214 this[y,x]=' '; 282 this[y+dy,x+dx]='R'; 215 this[y+dy,x+dx]='R'; 283 this[y+dy*2,x+dx*2]='*'; 216 this[y+dy*2,x+dx*2]='*'; 284 robot = new Pos(y+dy,x+dx); 217 robot = new Pos(y+dy,x+dx); 285 } else if('A'<=this[y+dy,x+dx] && this[y+dy,x+dx]<='I') { < 286 this[y,x]=' '; < 287 Pos tp = tr_target[this[y+dy,x+dx]]; < 288 foreach(p; tr_source[this[tp]]) < 289 this[p] = ' '; < 290 this[tp] = 'R'; < 291 robot = tp; < 292 } 218 } 293 bool dead = update(turn); | 219 if( update() ) > 220 dead = true; 294 return tuple(lambda,dead); 221 return tuple(lambda,dead); 295 } 222 } 296 223 297 bool update(int turn) | 224 bool update() 298 { 225 { 299 bool dead = false; 226 bool dead = false; 300 227 301 char[][] next; 228 char[][] next; 302 foreach(y,s; data) 229 foreach(y,s; data) 303 next ~= s.dup; 230 next ~= s.dup; 304 231 ................................................................................................................................................................................ 332 dead=true; 259 dead=true; 333 } 260 } 334 } 261 } 335 else if(this[p]=='L') { 262 else if(this[p]=='L') { 336 if(!lambda) 263 if(!lambda) 337 access(p) = 'O'; 264 access(p) = 'O'; 338 } 265 } 339 else if(this[p]=='W') { < 340 if( hige.is_growing_turn(turn) ) < 341 for(int dy=-1; dy<=+1; ++dy) < 342 for(int dx=-1; dx<=+1; ++dx) < 343 if(this[p.y+dy,p.x+dx] == ' ') < 344 access(new Pos(p.y+dy,p. < 345 } < 346 } 266 } 347 data = next; 267 data = next; 348 return dead; 268 return dead; 349 } 269 } 350 } 270 } 351 271 352 //////////////////////////////////////////////////////////////////////////////// 272 //////////////////////////////////////////////////////////////////////////////// 353 273 354 class Game 274 class Game 355 { 275 { 356 public: | 276 mixin DeriveShow; > 277 357 this(File input) | 278 static Game load(File input) 358 { 279 { 359 // Read map data | 280 string[] raw_data; 360 string[] map_data_lines; | 281 string[string] params; > 282 > 283 // Raw map data; read until empty line. 361 for(string line; !(line=input.readln().chomp()).empty; ) 284 for(string line; !(line=input.readln().chomp()).empty; ) 362 map_data_lines ~= line; | 285 raw_data ~= line; 363 286 364 // H*W | 287 // Additional commands; read until EOF. > 288 for(string line; !(line=input.readln()).empty; ) { > 289 string[] ss = line.split(); 365 H_ = map_data_lines.length; | 290 if( ss.length == 2 ) 366 W_ = 0; < 367 foreach(mdl; map_data_lines) < 368 W_ = max(W_, mdl.length); | 291 params[ss[0]] = ss[1]; 369 < 370 // Copy to modifiable buffer and adjust coordinates. < 371 raw_data_ = new char[][H_+1]; < 372 foreach(i,mdl; map_data_lines) { < 373 char[] buf = new char[mdl.length+1]; < 374 buf[0] = '#'; < 375 buf[1..$] = mdl[]; < 376 raw_data_[H_-i] = buf; < 377 } 292 } 378 293 379 // Detect objects | 294 return load(raw_data, params); 380 for(int y=1; y<=H_; ++y) < 381 for(int x=1; x<raw_data_[y].length; ++x) < > 295 } 382 { | 296 383 char c = raw_data_[y][x]; < > 297 static Game load(string[] raw_data, string[string] params) > 298 { 384 switch(c) | 299 return new Game(raw_data, params); > 300 } 385 { | 301 386 case '#': < 387 case '.': | 302 this(string[] raw_data, string[string] params) 388 case ' ': < > 303 { 389 break; | 304 this.map = Map.load(raw_data, params); 390 case 'L': | 305 this.water = Water.load(params); 391 case 'O': < 392 lift_pos_ = new Pos(y,x); < 393 break; < 394 case 'A': .. case 'I': < 395 case '1': .. case '9': < 396 trampoline_pos_[c] = new Pos(y,x); < 397 break; < 398 case '!': < 399 razor_pos_ ~= new Pos(y,x); < 400 break; < 401 case '\\': < 402 lambda_pos_ ~= new Pos(y,x); < 403 break; < > 306 } 404 307 405 // Moving objects are erased from raw_data_ | 308 Game clone() const { return new Game(this); } 406 case 'R': | 309 this(const(Game) g) { 407 robot_pos_ = new Pos(y,x); | 310 map = g.map.clone(); 408 raw_data_[y][x] = ' '; | 311 water = g.water.clone(); 409 break; | 312 turn = g.turn; 410 case '*': | 313 dead = g.dead; 411 case 'W': | 314 lambda = g.lambda; 412 dynamic_objects_[new Pos(y,x)] = c; | 315 exit_bonus = g.exit_bonus; 413 raw_data_[y][x] = ' '; | 316 under_water = g.under_water; 414 if(c=='*') < 415 may_update_[new Pos(y,x)] = true; < 416 break; < 417 default: < 418 assert(false); < 419 } < 420 } < 421 < 422 // Read other parameters < 423 for(string line; !(line=input.readln()).empty; ) < 424 { < 425 string[] ss = line.split(); < 426 if( ss.length == 2 ) < 427 switch(ss[0]) < 428 { < 429 case "Water": water_base_ = ss[1].to!int(); < 430 case "Flooding": water_pace_ = ss[1].to!int(); < 431 case "Waterproof": max_air_ = ss[1].to!int(); < 432 case "Growth": hige_pace_ = ss[1].to!int(); < 433 case "Razors": num_razor_ = ss[1].to!int(); < 434 default: assert(false); < 435 } < 436 if( ss.length == 4 && ss[0]=="Trampoline" && ss[2]=="tar < 437 { < 438 char fr=ss[1][0], to=ss[3][0]; < 439 trampoline_[fr] = to; < 440 if(to !in trampoline_rev_) trampoline_rev_[to] = < 441 trampoline_rev_[to] ~= fr; < 442 } < 443 } < 444 < 445 air_left_ = max_air_; < 446 } 317 } 447 318 448 @property const { < 449 int H() { return H_; } < 450 int W() { return W_; } < 451 char trampoline(char c) { return (c in trampoline_ ? trampoline_ < 452 const(Pos)[] trampoline_rev(char c) { < 453 const(Pos)[] pp; < 454 if(c in trampoline_rev_) { < 455 foreach(ch; trampoline_rev_[c]) < 456 pp ~= trampoline_pos_[ch]; < 457 } < 458 return pp; < 459 } < 460 int water_level() { < 461 return water_pace_ ? water_base_ + turn_/water_pace_ : w < 462 } < 463 int water_until_rise() { < 464 return water_pace_ ? water_pace_ - turn_%water_pace_ : i < 465 } < 466 int hige_until_rise() { < 467 return hige_pace_ ? hige_pace_ - turn_%hige_pace_ : int. < 468 } < 469 bool is_hige_turn() { < 470 return hige_pace_ ? turn_%hige_pace_ == hige_pace_-1 : f < 471 } < 472 int hp() { return air_left_; } < 473 int num_razor() { return num_razor_; } < 474 bool cleared() { return cleared_; } < 475 bool dead() { return dead_; } < 476 long score() { return num_lambda_*(dead_ ? 25L : cleared_ ? 75L < 477 const(Pos) robot() { return robot_pos_; } < 478 const(Pos) lift() { return lift_pos_; } < 479 Pos[] lambdas() { < 480 Pos[] pp; < 481 foreach(p; lambda_pos_) < 482 pp ~= p.clone(); < 483 return pp; < 484 } < 485 Pos[] razors() { < 486 Pos[] pp; < 487 foreach(p; razor_pos_) < 488 pp ~= p.clone(); < 489 return pp; < 490 } < 491 const(Pos)[] higes() { < 492 const(Pos)[] pp; < 493 foreach(p,c; dynamic_objects_) < 494 if(c=='W') < 495 pp ~= p; < 496 return pp; < 497 } < 498 } < 499 const { < 500 char opIndex(in Pos p) { return opIndex(p.y, p.x); } < 501 char opIndex(int y, int x) { return map_get(y, x); } < 502 } < 503 < 504 public: < 505 void command(char c) 319 void command(char c) 506 { 320 { 507 if(dead || cleared) 321 if(dead || cleared) 508 return; 322 return; 509 323 510 if(c == 'U') command_move(+1, 0); < 511 if(c == 'D') command_move(-1, 0); < 512 if(c == 'L') command_move(0, -1); < 513 if(c == 'R') command_move(0, +1); < 514 if(c == 'S') use_razor(); < 515 if(c == 'W') {} | 324 if(c == 'A') > 325 { > 326 exit_bonus = 1; > 327 return; > 328 } 516 329 > 330 // TODO: clarify the event order > 331 Tuple!(int,bool) ld = map.command(c); 517 if(!cleared) | 332 if( map.cleared() ) { 518 { < 519 map_update(); < 520 water_update(); | 333 exit_bonus = 2; > 334 } > 335 else { > 336 lambda += ld[0]; > 337 if( ld[1] ) { > 338 dead = true; > 339 } 521 } 340 } > 341 if( map.robot.y <= water_level ) > 342 ++under_water; > 343 else > 344 under_water = 0; > 345 if( under_water > map.waterproof ) > 346 dead = true; 522 turn_ ++; | 347 turn += 1; 523 } 348 } 524 349 525 void command_move(int dy, int dx) | 350 Map map; 526 { < > 351 Water water; 527 int y = robot_pos_.y, x = robot_pos_.x; | 352 int turn = 0; 528 char c = this[y+dy, x+dx]; | 353 bool dead = false; 529 Pos p = new Pos(y+dy, x+dx); | 354 int lambda = 0; > 355 int exit_bonus = 0; > 356 int under_water = 0; > 357 // TODO: when adding members, take care of clone(). > 358 // TODO: fix this poor design. 530 359 531 switch(c){ | 360 @property const { 532 case 'O': | 361 long score() { return lambda*25L*(1+exit_bonus) - turn; } 533 cleared_ = true; | 362 int water_level() { return water.level(turn); } 534 move_robot_to(p); | 363 int water_until_rise() { return water.until_rise(turn); } 535 break; | 364 bool cleared() { return exit_bonus>0; } 536 case '\\': | 365 int hp() { return map.waterproof - under_water; } 537 take_lambda_at(p); | 366 long score_if_abort_now() { return lambda*25*(1+max(1,exit_bonus 538 move_robot_to(p); < 539 break; < 540 case '!': < 541 take_razor_at(p); < 542 move_robot_to(p); < 543 break; < 544 case 'A': .. case 'I': < 545 enter_trampoline_at(p, c); < 546 break; < 547 case ' ': < 548 case '.': < 549 move_robot_to(p); < 550 break; < 551 case '*': < 552 if(dy!=0 || this[y,x+dx*2]!=' ') < 553 break; < 554 move_robot_to(p); < 555 push_rock(p, new Pos(y,x+dx*2)); < 556 break; < 557 default: < 558 break; < 559 } < 560 } 367 } > 368 } 561 369 562 void use_razor() | 370 unittest 563 { | 371 { 564 if(num_razor_ == 0) | 372 Game.load(["###","...","#RL"], ["xxx":"yyy"]); 565 return; < 566 num_razor_ --; < 567 < 568 for(int dy=-1; dy<=+1; ++dy) < 569 for(int dx=-1; dx<=+1; ++dx) if(dy||dx) < 570 { < 571 Pos p = new Pos(robot_pos_.y+dy, robot_pos_.x+dx); < 572 if(auto it = p in dynamic_objects_) < 573 if(*it == 'W') { < 574 something_gone(p); < 575 dynamic_objects_.remove(p); < 576 } < 577 } < 578 } < 579 < 580 void take_lambda_at(Pos p) < 581 { < 582 map_set_empty(p); < 583 num_lambda_ ++; < 584 lambda_pos_ = lambda_pos_.erase(p); < 585 } < 586 < 587 void take_razor_at(Pos p) < 588 { < 589 map_set_empty(p); < 590 num_razor_ ++; < 591 razor_pos_ = razor_pos_.erase(p); < 592 } < 593 < 594 void enter_trampoline_at(Pos p, char c) < 595 { < 596 char d = trampoline(c); < 597 foreach(cc; trampoline_rev_[d]) { < 598 Pos pp = trampoline_pos_[cc]; < 599 something_gone(pp); < 600 map_set_empty(pp); < 601 } < 602 move_robot_to(trampoline_pos_[d]); < 603 } < 604 < 605 void move_robot_to(Pos p) < 606 { < 607 something_gone(robot_pos_); < 608 map_set_empty(p.y, p.x); < 609 robot_pos_ = p; < 610 } < 611 < 612 void push_rock(Pos fr, Pos to) < 613 { < 614 dynamic_objects_.remove(fr); < 615 dynamic_objects_[to] = '*'; < 616 may_update_[to] = true; < 617 } < 618 < 619 void something_gone(Pos p) < 620 { < 621 for(int dy=0; dy<=+1; ++dy) < 622 for(int dx=-1; dx<=+1; ++dx) if(dy||dx) < 623 may_update_[new Pos(p.y+dy,p.x+dx)] = true; < 624 } < 625 < 626 void map_update() < 627 { < 628 Pos[] may_update_list; < 629 foreach(p,_; may_update_) < 630 if(this[p] == '*') < 631 may_update_list ~= p; < 632 may_update_ = null; < 633 < 634 if( is_hige_turn() ) < 635 foreach(p,c; dynamic_objects_) < 636 if(c == 'W') < 637 may_update_list ~= p; < 638 < 639 sort(may_update_list); < 640 char[Pos] to_be_written; < 641 foreach(p; may_update_list) < 642 if(is_hige_turn() && this[p]=='W') < 643 { < 644 for(int dy=-1; dy<=+1; ++dy) < 645 for(int dx=-1; dx<=+1; ++dx) { < 646 Pos q = new Pos(p.y+dy,p.x+dx); < 647 if( this[q] == ' ' ) < 648 to_be_written[q] = 'W'; < 649 } < 650 } < 651 else < 652 { < 653 int y = p.y; < 654 int x = p.x; < 655 char below = this[y-1,x]; < 656 // * < 657 // _ < 658 if(below==' ') { < 659 Pos q = new Pos(y-1,x); < 660 to_be_written[p] = ' '; < 661 to_be_written[q] = '*'; < 662 may_update_[q] = true; < 663 } < 664 // *_ *_ < 665 // *_ or \_ < 666 else if((below=='*'||below=='\\')&&this[y-1,x+1] < 667 Pos q = new Pos(y-1,x+1); < 668 to_be_written[p] = ' '; < 669 to_be_written[q] = '*'; < 670 may_update_[q] = true; < 671 } < 672 // _* < 673 // _* < 674 else if(below=='*'&&this[y-1,x-1]==' '&&this[y,x < 675 Pos q = new Pos(y-1,x-1); < 676 to_be_written[p] = ' '; < 677 to_be_written[q] = '*'; < 678 may_update_[q] = true; < 679 } < 680 } < 681 < 682 foreach(p,c; to_be_written) { < 683 dynamic_objects_[p] = c; < 684 if(c=='*' && p.y==robot_pos_.y+1 && p.x==robot_pos_.x) < 685 dead_ = true; < 686 } < 687 < 688 if(lambda_pos_.empty) < 689 raw_data_[lift_pos_.y][lift_pos_.x] = 'O'; < 690 } < 691 < 692 void water_update() < 693 { < 694 if( robot_pos_.y <= water_level() ) < 695 air_left_ --; < 696 else < 697 air_left_ = max_air_; < 698 if( air_left_ < 0 ) < 699 dead_ = true; < 700 } < 701 < 702 private: < 703 char map_get(int y, int x) const < 704 { < 705 if( y<1 || H<y || x<1 || W<x ) return '#'; < 706 Pos p = new Pos(y,x); < 707 if(p == robot_pos_) < 708 return 'R'; < 709 if(auto it = (p in dynamic_objects_)) < 710 return *it; < 711 if( x<0 || raw_data_[y].length<=x ) return ' '; < 712 return raw_data_[y][x]; < 713 } < 714 < 715 void map_set_empty(in Pos p) < 716 { < 717 return map_set_empty(p.y, p.x); < 718 } < 719 < 720 void map_set_empty(int y, int x) < 721 { < 722 if( y<1 || H<y || x<1 || W<x ) return; < 723 if( x<0 || raw_data_[y].length<=x ) return; < 724 raw_data_[y][x] = ' '; < 725 } < 726 < 727 public: < 728 Game clone() const { return new Game(this); } < 729 this(in Game g) { < 730 H_ = g.H_; < 731 W_ = g.W_; < 732 raw_data_ = new char[][g.raw_data_.length]; < 733 foreach(i,d; g.raw_data_) raw_data_[i] = d.dup; < 734 trampoline_pos_ = cast(Pos[char]) g.trampoline_pos_; < 735 razor_pos_ = (cast(Game)g).razor_pos_.dup; < 736 lambda_pos_ = (cast(Game)g).lambda_pos_.dup; < 737 lift_pos_ = g.lift_pos_.clone(); < 738 robot_pos_ = g.robot_pos_.clone(); < 739 dynamic_objects_ = dup(g.dynamic_objects_); < 740 trampoline_ = (cast(Game)g).trampoline_; < 741 trampoline_rev_ = (cast(Game)g).trampoline_rev_; < 742 water_base_ = g.water_base_; < 743 water_pace_ = g.water_pace_; < 744 max_air_ = g.max_air_; < 745 hige_pace_ = g.hige_pace_; < 746 num_razor_ = g.num_razor_; < 747 num_lambda_ = g.num_lambda_; < 748 turn_ = g.turn_; < 749 air_left_ = g.air_left_; < 750 cleared_ = g.cleared_; < 751 dead_ = g.dead_; < 752 may_update_ = dup(g.may_update_); < 753 } < 754 < 755 V[K] dup(V,K)(in V[K] aa) { < 756 V[K] aa2; < 757 foreach(k,v; aa) aa2[k] = v; < 758 return aa2; < 759 } < 760 < 761 private: < 762 int H_; < 763 int W_; < 764 char[][] raw_data_; < 765 Pos[char] trampoline_pos_; < 766 Pos[] razor_pos_; < 767 Pos[] lambda_pos_; < 768 Pos lift_pos_; < 769 Pos robot_pos_; < 770 char[Pos] dynamic_objects_; < 771 char[char] trampoline_; < 772 char[][char] trampoline_rev_; < 773 int water_base_ = 0; < 774 int water_pace_ = 0; < 775 int max_air_ = 10; < 776 int hige_pace_ = 25; < 777 int num_razor_ = 0; < 778 int num_lambda_ = 0; < 779 < 780 int turn_ = 0; < 781 int air_left_ = 0; < 782 bool cleared_ = false; < 783 bool dead_ = false; < 784 bool[Pos] may_update_; < 785 } 373 }

Modified src/gui.d from [e84cacd6262f93a7] to [4cc6400795e7a727].

1 import dfl.all; 1 import dfl.all; 2 import util; 2 import util; 3 import game; 3 import game; 4 import driver; 4 import driver; 5 5 6 class GUI(Solver) : Form, GameObserver 6 class GUI(Solver) : Form, GameObserver 7 { 7 { 8 this(in Game g) | 8 this(const(Game) g) 9 { 9 { 10 this.solver = new Solver(g); 10 this.solver = new Solver(g); 11 setup_size(g.W, g.H); | 11 setup_size(g.map.W, g.map.H); 12 setup_resources(g); | 12 setup_resources(); > 13 setup_keyhandling(); 13 draw(g); 14 draw(g); 14 } 15 } 15 16 16 private void delegate(char c) fn; 17 private void delegate(char c) fn; 17 void set_fn(F)(F f) { this.fn = f; } 18 void set_fn(F)(F f) { this.fn = f; } 18 19 19 void run(bool automate = false) 20 void run(bool automate = false) 20 { 21 { 21 if(automate) { 22 if(automate) { 22 Timer t = new Timer; 23 Timer t = new Timer; 23 t.interval = 50; | 24 t.interval = 100; 24 t.tick ~= (Timer sender, EventArgs ea){ 25 t.tick ~= (Timer sender, EventArgs ea){ 25 fn(solver.single_step()); 26 fn(solver.single_step()); 26 }; 27 }; 27 t.start(); 28 t.start(); 28 this.closing ~= (Form f,CancelEventArgs c){t.stop();}; < 29 } else { < 30 setup_keyhandling(); < 31 } 29 } 32 Application.run(this); 30 Application.run(this); 33 } 31 } 34 32 35 override void on_game_changed(char c, in Game g, bool finished) | 33 override void on_game_changed(char c, const(Game) g, bool finished) 36 { 34 { 37 draw(g); 35 draw(g); 38 } 36 } 39 37 40 private: 38 private: 41 int cell; 39 int cell; 42 40 ................................................................................................................................................................................ 50 } 48 } 51 49 52 Font font; 50 Font font; 53 Color[char] colors; 51 Color[char] colors; 54 string[char] render; 52 string[char] render; 55 Graphics graphicContext; 53 Graphics graphicContext; 56 54 57 void setup_resources(in Game g) | 55 void setup_resources() 58 { 56 { 59 this.graphicContext = new MemoryGraphics(this.clientSize.width, 57 this.graphicContext = new MemoryGraphics(this.clientSize.width, 60 this.setStyle(ControlStyles.OPAQUE, true); 58 this.setStyle(ControlStyles.OPAQUE, true); 61 this.font = new Font("MS Gothic", cell-2, GraphicsUnit.PIXEL); 59 this.font = new Font("MS Gothic", cell-2, GraphicsUnit.PIXEL); 62 this.backColor = Color(255,255,255); 60 this.backColor = Color(255,255,255); 63 this.colors['#'] = 61 this.colors['#'] = 64 this.colors['.'] = Color(255,191,127); 62 this.colors['.'] = Color(255,191,127); 65 this.colors['*'] = Color(255,127,127); 63 this.colors['*'] = Color(255,127,127); 66 this.colors['R'] = Color(128,128,0); 64 this.colors['R'] = Color(128,128,0); 67 this.colors['d'] = Color(255,0,0); | 65 this.colors['D'] = Color(255,0,0); 68 this.colors['\\'] = 66 this.colors['\\'] = 69 this.colors['L'] = 67 this.colors['L'] = 70 this.colors['O'] = Color(127,255,127); 68 this.colors['O'] = Color(127,255,127); 71 this.colors['w'] = Color(204,229,255); < 72 this.colors['W'] = | 69 this.colors['W'] = Color(204,229,255); 73 this.colors['!'] = Color(159,159,159); < 74 foreach(char c; 'A'..'J') this.colors[c] = Color(142,142,255); < 75 foreach(char c; '1'..':') this.colors[c] = Color(255,142,255); < 76 this.render['#'] = "■"; 70 this.render['#'] = "■"; 77 this.render['*'] = "✹"; 71 this.render['*'] = "✹"; 78 this.render['.'] = "♒"; 72 this.render['.'] = "♒"; 79 this.render['\\'] = "λ"; 73 this.render['\\'] = "λ"; 80 this.render['R'] = "☃"; 74 this.render['R'] = "☃"; 81 this.render['d'] = "☠"; | 75 this.render['D'] = "☠"; 82 this.render['L'] = "☒"; 76 this.render['L'] = "☒"; 83 this.render['O'] = "☐"; 77 this.render['O'] = "☐"; 84 this.render['W'] = "ꔣ"; < 85 this.render['!'] = "✄"; < 86 foreach(char c; 'A'..'J') this.render[c] = [cast(dchar)('☢'+g.tr < 87 foreach(char c; '1'..':') this.render[c] = [cast(dchar)('☢'+c-'1 < 88 this.paint ~= (Control c, PaintEventArgs ev) { 78 this.paint ~= (Control c, PaintEventArgs ev) { 89 graphicContext.copyTo(ev.graphics, Rect(0,0,this.clientS 79 graphicContext.copyTo(ev.graphics, Rect(0,0,this.clientS 90 }; 80 }; 91 } 81 } 92 82 93 void draw(in Game g) | 83 void draw(const(Game) g) 94 { 84 { 95 int scrW = this.clientSize.width; 85 int scrW = this.clientSize.width; 96 int scrH = this.clientSize.height; 86 int scrH = this.clientSize.height; 97 87 98 // Fill bg. 88 // Fill bg. 99 graphicContext.fillRectangle(this.backColor, Rect(0,0,scrW,scrH) 89 graphicContext.fillRectangle(this.backColor, Rect(0,0,scrW,scrH) 100 90 101 // Fill water. 91 // Fill water. 102 int w = g.water_level(); 92 int w = g.water_level(); 103 graphicContext.fillRectangle(this.colors['w'], Rect(0, scrH-cell | 93 graphicContext.fillRectangle(this.colors['W'], Rect(0, scrH-cell 104 94 105 // Paint map. 95 // Paint map. 106 for(int y=1; y<=g.H; ++y) | 96 for(int y=1; y<=g.map.H; ++y) 107 for(int x=1; x<=g.W; ++x) { | 97 for(int x=1; x<=g.map.W; ++x) { 108 Rect r = Rect(cell*(x-1), scrH-cell*y, cell, cell); 98 Rect r = Rect(cell*(x-1), scrH-cell*y, cell, cell); 109 char c = g[y,x]; | 99 char c = g.map[y,x]; 110 if( c != ' ' ) { 100 if( c != ' ' ) { 111 if( c == 'R' && g.dead ) 101 if( c == 'R' && g.dead ) 112 c = 'd'; | 102 c = 'D'; 113 graphicContext.drawText(this.render[c], font, th 103 graphicContext.drawText(this.render[c], font, th 114 } 104 } 115 } 105 } 116 106 117 // Update textual info. 107 // Update textual info. 118 this.text = .text( < 119 "Score: ", g.score, < 120 " Air: ", g.hp, < 121 " Tide: ", g.water_until_rise, | 108 this.text = .text("Score: ", g.score, " Air: ", g.hp, " Tide: ", 122 " Wadler: ", g.hige_until_rise, < 123 " Razor: ", g.num_razor); < 124 invalidate(); 109 invalidate(); 125 } 110 } 126 111 127 private: 112 private: 128 void setup_keyhandling() 113 void setup_keyhandling() 129 { 114 { 130 noMessageFilter(); 115 noMessageFilter(); 131 this.keyDown ~= &my_keydown; 116 this.keyDown ~= &my_keydown; 132 } 117 } 133 118 134 void do_manual_command(char c) < 135 { < 136 solver.force(c); < 137 fn(c); < 138 } < 139 < 140 void my_keydown(Control c, KeyEventArgs ev) 119 void my_keydown(Control c, KeyEventArgs ev) 141 { 120 { 142 switch(ev.keyCode) 121 switch(ev.keyCode) 143 { 122 { 144 case Keys.DOWN: do_manual_command('D'); break; | 123 case Keys.DOWN: fn('D'); break; 145 case Keys.UP: do_manual_command('U'); break; | 124 case Keys.UP: fn('U'); break; 146 case Keys.LEFT: do_manual_command('L'); break; | 125 case Keys.LEFT: fn('L'); break; 147 case Keys.RIGHT: do_manual_command('R'); break; | 126 case Keys.RIGHT: fn('R'); break; 148 case Keys.W: do_manual_command('W'); break; | 127 case Keys.W: fn('W'); break; 149 case Keys.S: do_manual_command('S'); break; < 150 case Keys.A: do_manual_command('A'); break; | 128 case Keys.A: fn('A'); break; 151 case Keys.G: fn(solver.single_step()); break; 129 case Keys.G: fn(solver.single_step()); break; 152 default: break; 130 default: break; 153 } 131 } 154 } 132 } 155 133 156 Solver solver; 134 Solver solver; 157 } 135 }

Modified src/gui_main.d from [05082d0f328d756c] to [49f16753320613b8].

5 import std.stdio; 5 import std.stdio; 6 pragma(lib, "dfl.lib"); 6 pragma(lib, "dfl.lib"); 7 7 8 void main(string[] args) 8 void main(string[] args) 9 { 9 { 10 Driver d = new Driver(stdin); 10 Driver d = new Driver(stdin); 11 d.addObserver!(GuardedOutput)(); 11 d.addObserver!(GuardedOutput)(); 12 auto g = d.addObserver!(GUI!MainSolver)(); | 12 auto g = d.addObserver!(GUI!Solver_1)(); 13 g.set_fn(&d.command); 13 g.set_fn(&d.command); 14 g.run(); 14 g.run(); 15 } 15 }

Modified src/output.d from [e2d0d7db868c3a44] to [7fa423ba9f8ebe92].

1 import util; 1 import util; 2 import game; 2 import game; 3 import driver; 3 import driver; 4 import core.stdc.signal; 4 import core.stdc.signal; 5 5 6 class NilOutput : GameObserver 6 class NilOutput : GameObserver 7 { 7 { 8 this(in Game g) {} | 8 this(const(Game) g) {} 9 override void on_game_changed(char c, in Game g, bool finished) {} | 9 override void on_game_changed(char c, const(Game) g, bool finished) {} 10 } 10 } 11 11 12 class StdOutput : GameObserver 12 class StdOutput : GameObserver 13 { 13 { 14 this(in Game g) {} | 14 this(const(Game) g) {} 15 override void on_game_changed(char c, in Game g, bool finished) | 15 override void on_game_changed(char c, const(Game) g, bool finished) 16 { 16 { 17 stdout.write(c); 17 stdout.write(c); 18 stdout.flush(); 18 stdout.flush(); 19 } 19 } 20 } 20 } 21 21 22 class GuardedOutput : GameObserver 22 class GuardedOutput : GameObserver 23 { 23 { 24 this(in Game g) | 24 this(const(Game) g) 25 { 25 { 26 setup_sigint_handling(); 26 setup_sigint_handling(); 27 score_log ~= g.score; | 27 ideal_log ~= g.score_if_abort_now; 28 flushed = false; < 29 } 28 } 30 29 31 override void on_game_changed(char c, in Game g, bool finished) | 30 override void on_game_changed(char c, const(Game) g, bool finished) 32 { 31 { 33 if(flushed) < 34 return; < 35 < 36 log ~= c; 32 log ~= c; 37 score_log ~= g.score; 33 score_log ~= g.score; > 34 ideal_log ~= g.score_if_abort_now; 38 if(finished || log.length+1==g.W*g.H) | 35 if(finished) 39 flush(); 36 flush(); 40 } 37 } 41 38 42 private: 39 private: 43 string log; 40 string log; 44 long[] score_log; 41 long[] score_log; 45 bool flushed; | 42 long[] ideal_log; 46 43 47 void flush() 44 void flush() 48 { 45 { 49 if(flushed) < 50 return; < 51 < 52 Tuple!(long, int) cand; | 46 Tuple!(long, int, int) cand; 53 cand[0] = long.min; 47 cand[0] = long.min; 54 48 55 for(int i=0; i<score_log.length; ++i) 49 for(int i=0; i<score_log.length; ++i) 56 if(cand[0] < score_log[i]) 50 if(cand[0] < score_log[i]) 57 cand = tuple(score_log[i],i); | 51 cand = tuple(score_log[i],i,0); > 52 for(int i=0; i<ideal_log.length; ++i) > 53 if(cand[0] < ideal_log[i]) > 54 cand = tuple(ideal_log[i],i,1); 58 55 > 56 if(cand[2]==0) { > 57 string str = log[0..cand[1]+1]; > 58 std.c.stdio.printf("%.*s\n", str.length, str.ptr); > 59 } else { > 60 string str = log[0..cand[1]]; 59 std.c.stdio.printf("%.*sA\n", cand[1], log.ptr); | 61 std.c.stdio.printf("%.*sA\n", str.length, str.ptr); > 62 } 60 std.c.stdio.fflush(std.c.stdio.stdout); 63 std.c.stdio.fflush(std.c.stdio.stdout); 61 flushed = true; < 62 } 64 } 63 65 64 private: 66 private: 65 static __gshared GuardedOutput g_output; 67 static __gshared GuardedOutput g_output; 66 68 67 void setup_sigint_handling() 69 void setup_sigint_handling() 68 { 70 { 69 assert(g_output is null); 71 assert(g_output is null); 70 g_output = this; 72 g_output = this; 71 extern(C) static void catch_sigint(int) { g_output.flush(); appl 73 extern(C) static void catch_sigint(int) { g_output.flush(); appl 72 core.stdc.signal.signal(SIGINT, &catch_sigint); 74 core.stdc.signal.signal(SIGINT, &catch_sigint); 73 } 75 } 74 } 76 }

Modified src/solver.d from [22c356ff1975e92f] to [e22cb888fb6353ea].

1 import util; 1 import util; 2 import game; 2 import game; > 3 import driver; > 4 > 5 /* > 6 interface Solver > 7 { > 8 this(const(Game) g); > 9 char single_step(); > 10 } > 11 */ 3 12 4 class Solver_0 13 class Solver_0 5 { 14 { 6 this(in Game g) {} | 15 this(const(Game) g) {} 7 char single_step() { return 'W'; } 16 char single_step() { return 'W'; } 8 void force(char c) {} < 9 } 17 } 10 18 11 class Solver_1 19 class Solver_1 12 { 20 { 13 int wait_count = 0; | 21 int g_wc = 0; 14 int choke_count = 0; < 15 22 16 Game g; 23 Game g; 17 this(in Game g) | 24 this(const(Game) g) 18 { 25 { 19 this.g = g.clone(); 26 this.g = g.clone(); 20 forbidden_cell = new bool[][](g.H+2, g.W+2); < 21 } 27 } 22 28 23 char single_step() 29 char single_step() 24 { 30 { 25 Tuple!(string,int) de = death_move(g); < 26 char c = act(g, de[0], de[1]); | 31 char c = act(g, death_move(g)); 27 force(c); | 32 g.command(c); 28 return c; 33 return c; 29 } 34 } 30 35 31 void force(char c) < 32 { < 33 if(c != 'A') < 34 g.command(c); < 35 } < 36 < 37 Tuple!(string,int) death_move(const(Game) g) | 36 string death_move(const(Game) g) 38 { 37 { 39 string death; 38 string death; 40 int choice = 0; < 41 foreach(char c; "UDLRW") { 39 foreach(char c; "UDLRW") { 42 Game gg = g.clone(); 40 Game gg = g.clone(); 43 gg.command(c); 41 gg.command(c); 44 if( !gg.cleared && gg.dead ) 42 if( !gg.cleared && gg.dead ) 45 death ~= c; 43 death ~= c; 46 else if( gg.robot != g.robot ) < 47 choice++; < 48 else if( c != 'W' ) // meaningless move < 49 death ~= c; < 50 } 44 } 51 return tuple(death, choice); | 45 return death; 52 } 46 } 53 47 54 Tuple!(Pos, int)[] log; < 55 bool[][] forbidden_cell; < 56 < 57 char act(const(Game) g, string death, int breath) | 48 char act(const(Game) g, string death) 58 { 49 { 59 const Pos ro = g.robot; | 50 const Pos ro = g.map.robot; 60 const Pos li = g.lift; | 51 const Pos[] la = g.map.lambdas(); 61 Pos[] la = g.lambdas(); | 52 const Pos li = g.map.lift; 62 sort!((Pos a,Pos b){ < 63 int ad=abs(a.y-li.y)+abs(a.x-li.x); < 64 int bd=abs(b.y-li.y)+abs(b.x-li.x); < 65 return ad>bd;; < 66 })(la); < 67 Pos[] ra = g.razors(); < 68 const(Pos)[] hi = g.higes(); < 69 53 70 Tuple!(char,int)[] cand; < 71 char c = 'W'; 54 char c = 'W'; 72 if( la.empty ) { 55 if( la.empty ) { 73 cand = search(g, ro, [li], death); | 56 auto r = search(g, ro, li, death); > 57 c = r[0]; 74 } else { 58 } else { > 59 Tuple!(char,int)[] cand; > 60 foreach(lam; la) 75 cand ~= search(g, ro, la~ra, death); | 61 cand ~= search(g, ro, lam, death); > 62 sort!((Tuple!(char,int) c1, Tuple!(char,int) c2){ > 63 if(c1[1] != c2[1]) > 64 return c1[1] < c2[1]; > 65 return c1[0] < c2[0]; > 66 })(cand); > 67 c = cand[0][0]; > 68 } > 69 if(c=='W') { > 70 g_wc++; > 71 if(g_wc > 10) > 72 c = 'A'; 76 } 73 } > 74 else > 75 g_wc = 0; > 76 return c; 77 | 77 } 78 // 'higesori' mode < 79 if( !hi.empty && g.num_razor>0 ) { < 80 int his = 0; < 81 for(int dy=-1; dy<=+1; ++dy) < 82 for(int dx=-1; dx<=+1; ++dx) < 83 if(g[ro.y+dy,ro.x+dx] == 'W') < 84 his++; < 85 78 86 if(his>=2 || his==hi.length) | 79 Tuple!(char,int) search(in Game g, in Pos s, in Pos o, string death) 87 cand = [tuple('S',int.max)]; < 88 if(cand.empty) { < > 80 { 89 const(Pos)[] tgt; | 81 const(Pos)[] q = [o]; > 82 bool[][] v = new bool[][](g.map.H+2, g.map.W+2); 90 for(int y=1; y<=g.H; ++y) | 83 for(int step=1; q.length; ++step) { 91 for(int x=1; x<=g.W; ++x) | 84 Pos[] q2; 92 if(g[y,x]=='.'||g[y,x]==' ') { | 85 foreach(p; q) { 93 his = 0; | 86 int[] dy=[-1,+1,0,0]; 94 for(int dy=-1; dy<=+1; ++dy) | 87 int[] dx=[0,0,-1,+1]; 95 for(int dx=-1; dx<=+1; ++dx) | 88 for(int i=0; i<4; ++i) { 96 if(g[y+dy,x+dx] == 'W') | 89 int y = p.y+dy[i]; 97 his++; | 90 int x = p.x+dx[i]; 98 if(his>=2) | 91 if(v[y][x]) continue; > 92 if(y==s.y && x==s.x) { > 93 char c = "UDRL"[i]; > 94 if( death.count(c) == 0 ) > 95 return tuple(c,step); > 96 } else if(g.map[y,x]==' '||g.map[y,x]==' 99 tgt ~= new Pos(y,x); | 97 q2 ~= new Pos(y,x); > 98 v[y][x]=true; > 99 } else if(g.map[y,x]=='.' && g.map[y-1,x > 100 q2 ~= new Pos(y,x); > 101 v[y][x]=true; 100 } 102 } 101 cand ~= search(g, ro, tgt, death, true); < > 103 } 102 } 104 } 103 } < 104 < 105 // 'dig' mode < 106 if(cand.empty) { < 107 const(Pos)[] tgt; < 108 for(int y=1; y<=g.H; ++y) < 109 for(int x=1; x<=g.W; ++x) < 110 if(g[y,x]=='.') < 111 if(g[y+1,x]=='*'||g[y+1,x-1]=='*'||g[y+1 < 112 ||g[y,x+1]=='*'||g[y,x-1]=='*') < 113 tgt ~= new Pos(y,x); < 114 cand ~= search(g, ro, tgt, death, true); < > 105 q = q2; 115 } 106 } 116 < > 107 q = [o]; 117 if(cand.empty) { | 108 v = new bool[][](g.map.H+2, g.map.W+2); 118 choke_count++; | 109 for(int step=1000; q.length; ++step) { 119 cand ~= tuple('W',int.max); | 110 Pos[] q2; 120 } < > 111 foreach(p; q) { 121 sort!((Tuple!(char,int) c1, Tuple!(char,int) c2){ | 112 int[] dy=[-1,+1,0,0]; 122 if(c1[1] != c2[1]) | 113 int[] dx=[0,0,-1,+1]; 123 return c1[1] < c2[1]; | 114 for(int i=0; i<4; ++i) { 124 return c1[0] < c2[0]; | 115 int y = p.y+dy[i]; 125 })(cand); | 116 int x = p.x+dx[i]; 126 c = cand[0][0]; | 117 if(v[y][x]) continue; > 118 if(y==s.y && x==s.x) { > 119 char c = "UDRL"[i]; > 120 if( death.count(c) == 0 ) > 121 return tuple(c,step); > 122 } else if(g.map[y,x]==' '||g.map[y,x]==' > 123 q2 ~= new Pos(y,x); > 124 v[y][x]=true; > 125 } else if(g.map[y,x]=='.'/* && g[y-1,x]! > 126 q2 ~= new Pos(y,x); > 127 v[y][x]=true; 127 | 128 } 128 if(death.count(c) || wait_count>=2) { < 129 foreach(char live; "UDLRW") < 130 if(death.count(live)==0) { < 131 c=live; < 132 break; < 133 } 129 } > 130 } > 131 q = q2; 134 } 132 } 135 < 136 if(c == 'W') < 137 wait_count++; < 138 else < 139 wait_count = 0; < 140 if(choke_count >= g.H) < 141 c = 'A'; < 142 < 143 bool[char] choice; < 144 foreach(t; cand) < 145 choice[t[0]] = true; < 146 log ~= tuple(ro.clone(), cast(int)choice.length); < 147 if(log.length > 5) < 148 log = log[$-5..$]; < 149 int cnt = 0; < 150 foreach(l; log) < 151 if(l[0] == log[$-1][0]) < 152 ++cnt; < 153 if( cnt >= 3 && breath==1 ) { < 154 forbidden_cell[ro.y][ro.x] = true; < 155 } < 156 < 157 return c; | 133 return tuple('W', int.max); 158 } 134 } 159 < 160 Tuple!(char,int)[] search(in Game g, in Pos s, in Pos[] gs, string death < 161 { < 162 bool danger(int y, int x) < 163 { < 164 if(g[y,x] == ' ' || g[y,x] == 'R') < 165 return false; < 166 if(g[y+1,x] == '*') < 167 return true; < 168 if(g[y+1,x-1]=='*' && (g[y,x-1]=='\\'||g[y,x-1]=='*') && < 169 return true; < 170 if(g[y+1,x+1]=='*' && (g[y,x+1]=='*') && (g[y+1,x]==' '| < 171 return true; < 172 if(g[y,x-1]=='*' && (g[y-1,x-1]=='\\'||g[y-1,x-1]=='*') < 173 return true; < 174 if(g[y,x+1]=='*' && (g[y-1,x+1]=='*') && (g[y-1,x]==' '| < 175 return true; < 176 return false; < 177 } < 178 < 179 // avoid directly below '*' < 180 Tuple!(char,int)[] tryA() { < 181 const(Pos)[] q; < 182 foreach(p; gs) < 183 if(!danger(p.y,p.x)) < 184 q ~= p; < 185 bool[][] v = new bool[][](g.H+2, g.W+2); < 186 foreach(p; q) v[p.y][p.x]=true; < 187 for(int step=1; q.length; ++step) { < 188 Pos[] q2; < 189 foreach(p; q) { < 190 int[] yyy=[p.y-1,p.y+1,p.y,p.y]; < 191 int[] xxx=[p.x,p.x,p.x-1,p.x+1]; < 192 for(int i=0; i<yyy.length; ++i) { < 193 int y = yyy[i]; < 194 int x = xxx[i]; < 195 if('1'<=g[y,x]&&g[y,x]<='9') { < 196 foreach(ppp; g.trampolin < 197 yyy ~= ppp.y; < 198 xxx ~= ppp.x; < 199 } < 200 continue; < 201 } < 202 if(v[y][x]) continue; < 203 if(y==s.y && x==s.x && i<4) { < 204 char c = "UDRL"[i]; < 205 if( death.count(c) == 0 < 206 return [tuple(c, < 207 } else if(forbidden_cell[y][x]){ < 208 } else if(g[y,x]==' '||g[y,x]==' < 209 if(danger(y,x)) < 210 continue; < 211 q2 ~= new Pos(y,x); < 212 v[y][x]=true; < 213 } < 214 } < 215 } < 216 q = q2; < 217 } < 218 return []; < 219 } < 220 < 221 // any empty space is my ground < 222 Tuple!(char,int)[] tryB() { < 223 const(Pos)[] q; < 224 foreach(p; gs) q ~= p; < 225 bool[][] v = new bool[][](g.H+2, g.W+2); < 226 foreach(p; q) v[p.y][p.x]=true; < 227 for(int step=10; q.length; ++step) { < 228 Pos[] q2; < 229 foreach(p; q) { < 230 int[] yyy=[p.y-1,p.y+1,p.y,p.y]; < 231 int[] xxx=[p.x,p.x,p.x-1,p.x+1]; < 232 for(int i=0; i<yyy.length; ++i) { < 233 int y = yyy[i]; < 234 int x = xxx[i]; < 235 if('1'<=g[y,x]&&g[y,x]<='9') { < 236 foreach(ppp; g.trampolin < 237 yyy ~= ppp.y; < 238 xxx ~= ppp.x; < 239 } < 240 continue; < 241 } < 242 if(v[y][x]) continue; < 243 if(y==s.y && x==s.x && i<4) { < 244 char c = "UDRL"[i]; < 245 if( death.count(c) == 0 < 246 return [tuple(c, < 247 } else if(forbidden_cell[y][x]){ < 248 } else if(g[y,x]==' '||g[y,x]==' < 249 q2 ~= new Pos(y,x); < 250 v[y][x]=true; < 251 } < 252 } < 253 } < 254 q = q2; < 255 } < 256 return []; < 257 } < 258 < 259 // push rocks! < 260 Tuple!(char,int)[] tryC() { < 261 const(Pos)[] q; < 262 foreach(p; gs) q ~= p; < 263 bool[][] v = new bool[][](g.H+2, g.W+2); < 264 foreach(p; q) v[p.y][p.x]=true; < 265 for(int step=20; q.length; ++step) { < 266 Pos[] q2; < 267 foreach(p; q) { < 268 int[] yyy=[p.y-1,p.y+1,p.y,p.y]; < 269 int[] xxx=[p.x,p.x,p.x-1,p.x+1]; < 270 for(int i=0; i<yyy.length; ++i) { < 271 int y = yyy[i]; < 272 int x = xxx[i]; < 273 if(g[p] == '*') { < 274 if(i>=4)continue; < 275 if(y!=p.y)continue; < 276 if(g[y,p.x+(p.x-x)]!=' ' < 277 } < 278 if('1'<=g[y,x]&&g[y,x]<='9') { < 279 foreach(ppp; g.trampolin < 280 yyy ~= ppp.y; < 281 xxx ~= ppp.x; < 282 } < 283 continue; < 284 } < 285 if(v[y][x]) continue; < 286 if(y==s.y && x==s.x && i<4) { < 287 char c = "UDRL"[i]; < 288 if( death.count(c) == 0 < 289 return [tuple(c, < 290 } else if(forbidden_cell[y][x]){ < 291 } else if(g[y,x]==' '||g[y,x]==' < 292 q2 ~= new Pos(y,x); < 293 v[y][x]=true; < 294 } < 295 } < 296 } < 297 q = q2; < 298 } < 299 return []; < 300 } < 301 return (danger_ok ? [] : tryA()) ~ tryB() ~ tryC(); < 302 } < 303 } 135 } 304 < 305 class Solver_2(Solver) < 306 { < 307 string plan; < 308 bool plan_broken = true; < 309 < 310 Game g; < 311 this(in Game g) < 312 { < 313 this.g = g.clone(); < 314 make_plan(g); < 315 } < 316 < 317 Tuple!(Solver,string) run_sub_solver(in Game g) < 318 { < 319 string log; < 320 auto s = new Solver(g); < 321 while(!g.cleared && !g.dead && plan.length<=g.H*g.W) { < 322 char c = s.single_step(); < 323 if( c == 'A' ) < 324 break; < 325 log ~= c; < 326 } < 327 while(log.length>0 && log[$-1]=='W') < 328 log.length--; < 329 return tuple(s, log); < 330 } < 331 < 332 void make_plan(in Game g) { < 333 plan_broken = false; < 334 Tuple!(Solver,string) x = run_sub_solver(g); < 335 plan = x[1]; < 336 if(x[0].g.cleared) < 337 return; < 338 modify_plan(g, x[0].g.score); < 339 } < 340 < 341 void modify_plan(in Game ini, long unmod) < 342 { < 343 int bp = max(0, (cast(int)plan.length)-10); < 344 Game g = ini.clone(); < 345 for(int i=0; i<bp; ++i) g.command(plan[i]); < 346 < 347 Tuple!(string,long) cand = tuple(plan, unmod); < 348 for(int i=bp; i<plan.length; ++i) { < 349 foreach(string c; ["U","D","L","R","UD","DU","LR","RL"]) < 350 if(c[0] != plan[i]) { < 351 Tuple!(string,long) zz = try_plan(c, g); < 352 if(cand[1]<zz[1]) < 353 cand = tuple(plan[0..i]~c~zz[0], < 354 } < 355 g.command(plan[i]); < 356 } < 357 plan = cand[0]; < 358 } < 359 < 360 Tuple!(string,long) try_plan(string c, in Game g) < 361 { < 362 Game gg = g.clone(); < 363 foreach(cc;c)gg.command(cc); < 364 Tuple!(Solver, string) x = run_sub_solver(gg); < 365 return tuple(x[1], x[0].g.score); < 366 } < 367 < 368 char single_step() { < 369 if(plan_broken) < 370 make_plan(g); < 371 if(plan.empty) < 372 return 'A'; < 373 char c = plan[0]; < 374 plan = plan[1..$]; < 375 g.command(c); < 376 return c; < 377 } < 378 < 379 void force(char c) { < 380 g.command(c); < 381 if(plan.length==0 || plan[0]!=c) { < 382 plan = ""; < 383 plan_broken = true; < 384 } < 385 else < 386 plan = plan[1..$]; < 387 } < 388 } < 389 < 390 alias Solver_2!(Solver_1) MainSolver; < 391 //alias Solver_1 MainSolver; <

Modified src/util.d from [b76be1f6ad977d56] to [783554bf667412ed].

1 public import std.algorithm; 1 public import std.algorithm; 2 public import std.array; 2 public import std.array; 3 public import std.conv; 3 public import std.conv; 4 public import std.range; 4 public import std.range; 5 public import std.stdio; 5 public import std.stdio; 6 public import std.string; 6 public import std.string; 7 public import std.typecons; 7 public import std.typecons; 8 public import std.math; < 9 import std.c.stdlib; 8 import std.c.stdlib; 10 9 11 T[] erase(T,V)(T[] xs, V y) < 12 { < 13 foreach(i,x; xs) < 14 if(x == y) < 15 return xs[0..i]~xs[i+1..$]; < 16 return xs; < 17 } < 18 < 19 // To avoide the following ICE: < 20 // src\phobos\std\algorithm.d(4552): < 21 // Error: function std.algorithm.count!("a == b",string,char).count < 22 // compiler error, parameter 'value', bugzilla 2962? < 23 // Assertion failure: '0' on line 717 in file 'glue.c' < 24 int count(T,V)(T[] a, V v) < 25 { < 26 int cnt = 0; < 27 foreach(e; a) < 28 if(e == v) < 29 ++cnt; < 30 return cnt; < 31 } < 32 < 33 void application_exit() 10 void application_exit() 34 { 11 { 35 std.c.stdlib.exit(0); 12 std.c.stdlib.exit(0); 36 } 13 } 37 14 38 template DeriveCreate() 15 template DeriveCreate() 39 { 16 { ................................................................................................................................................................................ 42 this.tupleof = params; 19 this.tupleof = params; 43 } 20 } 44 } 21 } 45 22 46 template DeriveCompare() 23 template DeriveCompare() 47 { 24 { 48 override: 25 override: 49 bool opEquals(Object rhs) const | 26 bool opEquals(Object rhs) 50 { 27 { 51 return tuple(this.tupleof) == tuple((cast(typeof(this))rhs).tupl 28 return tuple(this.tupleof) == tuple((cast(typeof(this))rhs).tupl 52 } 29 } 53 30 54 int opCmp(Object rhs) const | 31 int opCmp(Object rhs) 55 { 32 { 56 return tuple(this.tupleof).opCmp(tuple((cast(typeof(this))rhs).t 33 return tuple(this.tupleof).opCmp(tuple((cast(typeof(this))rhs).t 57 } 34 } 58 35 59 hash_t toHash() const | 36 hash_t toHash() 60 { 37 { 61 hash_t v = 0; 38 hash_t v = 0; 62 foreach(mem; this.tupleof) { 39 foreach(mem; this.tupleof) { 63 v *= 11; 40 v *= 11; 64 static if(__traits(compiles, v^=mem)) 41 static if(__traits(compiles, v^=mem)) 65 v ^= mem; 42 v ^= mem; 66 else 43 else ................................................................................................................................................................................ 69 return v; 46 return v; 70 } 47 } 71 } 48 } 72 49 73 template DeriveShow() 50 template DeriveShow() 74 { 51 { 75 override: 52 override: 76 string toString() const | 53 string toString() 77 { 54 { 78 string str = text(typeof(this).stringof, "("); 55 string str = text(typeof(this).stringof, "("); 79 foreach(i,mem; this.tupleof) { 56 foreach(i,mem; this.tupleof) { 80 if(i) str ~= ", "; 57 if(i) str ~= ", "; 81 str = text(str, this.tupleof[i].stringof[5..$], ":", me 58 str = text(str, this.tupleof[i].stringof[5..$], ":", me 82 } 59 } 83 return str ~ ")"; 60 return str ~ ")"; 84 } 61 } 85 } 62 }

Modified submission/README from [9ce063855f41ff05] to [0cf14a3b96651332].

1 Team: < 2 Dark Integers | 1 Team "Dark Integers". > 2 3 Member: 3 Member: 4 Kazuhiro Inaba (www.kmonos.net / kiki@kmonos.net) 4 Kazuhiro Inaba (www.kmonos.net / kiki@kmonos.net) 5 Language: 5 Language: 6 D Programming Language (dlang.org) 6 D Programming Language (dlang.org) 7 7 8 This submission for lightning division is not particulary interseting. 8 This submission for lightning division is not particulary interseting. 9 9 ................................................................................................................................................................................ 18 trims the command history and inserts the 'A'bort at the optimal timing. 18 trims the command history and inserts the 'A'bort at the optimal timing. 19 This is also used for SIGINT handling. 19 This is also used for SIGINT handling. 20 20 21 - gui.d is a windows GUI for the game, using DFL (http://github.com/Rayerd/dfl) 21 - gui.d is a windows GUI for the game, using DFL (http://github.com/Rayerd/dfl) 22 it is not compiled into the submitted routine. This is just a helper. 22 it is not compiled into the submitted routine. This is just a helper. 23 23 24 Stay tuned for the full submission, judges! 24 Stay tuned for the full submission, judges! > 25