Check-in Differences
Not logged in

Difference From:

[62a5c6c47f] Correctly implemented below-rock avoider. (user: kinaba, tags: trunk, date: 2012-07-14 13:45:03)

To:

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

Added 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 ################################################################################

Added 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

Added 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

Added 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

Added 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

Added 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 ####################

Added maps/fun1.map version [2f7f87a4d02c6448]

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

Added 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

Added 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

Added 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

Added 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

Added 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 [a0394f9b9692c1eb] to [b38d60ea39d11e6e].

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) { < 10 solver = new Solver(g); | 9 this(in Game g) { solver = new Solver(g); } 11 } < 12 Solver solver; 10 Solver solver; 13 bool fin; 11 bool fin; 14 override void on_game_changed(char c, const(Game) g, bool finished) | 12 override void on_game_changed(char c, in Game g, bool finished) 15 { 13 { 16 fin = finished; 14 fin = finished; 17 } 15 } 18 } 16 } 19 17 20 void main(string[] args) 18 void main(string[] args) 21 { 19 { 22 Driver d = new Driver(stdin); 20 Driver d = new Driver(stdin); 23 d.addObserver!(GuardedOutput)(); 21 d.addObserver!(GuardedOutput)(); 24 auto c = d.addObserver!(CUI!Solver_1)(); | 22 auto c = d.addObserver!(CUI!MainSolver)(); 25 while(!c.fin) 23 while(!c.fin) 26 d.command(c.solver.single_step()); 24 d.command(c.solver.single_step()); 27 } 25 }

Added 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 [17dbdc662950a670] to [fc05481901940844].

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 new Pos(y, x); } | 11 Pos clone() const { return cast(Pos) this; } 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 new Water(base, pace); } | 48 Water clone() const { return cast(Water)this; } 49 49 50 static load(string[string] params) 50 static load(string[string] params) 51 { 51 { 52 return new Water( < 53 params.get("Water", "0").to!int(), | 52 return new Water(params.get("Water", "0").to!int(), 54 params.get("Flooding", "0").to!int() | 53 params.get("Flooding", "0").to!int()); 55 ); < 56 } 54 } 57 55 58 int level(int number_of_update) const 56 int level(int number_of_update) const 59 { 57 { 60 return pace ? base+(number_of_update/pace) : base; 58 return pace ? base+(number_of_update/pace) : base; 61 } 59 } 62 60 ................................................................................................................................................................................ 84 assert( 1 == w.level(3) ); 82 assert( 1 == w.level(3) ); 85 assert( 1 == w.level(4) ); 83 assert( 1 == w.level(4) ); 86 assert( 1 == w.level(5) ); 84 assert( 1 == w.level(5) ); 87 } 85 } 88 86 89 //////////////////////////////////////////////////////////////////////////////// 87 //////////////////////////////////////////////////////////////////////////////// 90 88 > 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 91 class Map 115 class Map 92 { 116 { 93 mixin DeriveShow; 117 mixin DeriveShow; 94 118 95 static Map load(string[] raw_data, string[string] params) | 119 static Map load(string[] raw_data, string[string] params, char[char] tra 96 { 120 { 97 // TODO: choose optimal representation. 121 // TODO: choose optimal representation. 98 return new Map(raw_data, params); | 122 return new Map(raw_data, params, trampo); 99 } 123 } 100 124 101 char[][] data; 125 char[][] data; 102 Pos robot; 126 Pos robot; 103 Pos lift; 127 Pos lift; 104 int waterproof; 128 int waterproof; > 129 Pos[char] tr_target; > 130 Pos[][char] tr_source; > 131 const(Hige) hige; > 132 int razor; 105 133 106 Map clone() const { return new Map(this); } 134 Map clone() const { return new Map(this); } 107 this(const(Map) m) { | 135 this(in Map m) { 108 foreach(s; m.data) 136 foreach(s; m.data) 109 this.data ~= s.dup; 137 this.data ~= s.dup; 110 this.robot = m.robot.clone(); 138 this.robot = m.robot.clone(); 111 this.lift = m.lift.clone(); 139 this.lift = m.lift.clone(); 112 this.waterproof = m.waterproof; 140 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; 113 } 145 } 114 146 115 this(string[] raw_data, string[string] params) | 147 this(string[] raw_data, string[string] params, char[char] trampo) 116 { 148 { 117 int width = 0; 149 int width = 0; 118 foreach(r; raw_data) 150 foreach(r; raw_data) 119 width = max(width, r.length); 151 width = max(width, r.length); 120 foreach(r; raw_data) { 152 foreach(r; raw_data) { 121 this.data ~= r.dup; 153 this.data ~= r.dup; 122 this.data[$-1].length = width; 154 this.data[$-1].length = width; ................................................................................................................................................................................ 126 for(int y=1; y<=H; ++y) 158 for(int y=1; y<=H; ++y) 127 for(int x=1; x<=W; ++x) { 159 for(int x=1; x<=W; ++x) { 128 if(this[y,x] == 'R') 160 if(this[y,x] == 'R') 129 this.robot = new Pos(y,x); 161 this.robot = new Pos(y,x); 130 if(this[y,x] == 'L' || this[y,x] == 'O') 162 if(this[y,x] == 'L' || this[y,x] == 'O') 131 this.lift = new Pos(y,x); 163 this.lift = new Pos(y,x); 132 } 164 } > 165 > 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 } 133 173 134 this.waterproof = params.get("Waterproof", "5").to!int(); 174 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(); 135 } 183 } 136 184 137 const @property { 185 const @property { 138 int H() { return data.length; } 186 int H() { return data.length; } 139 int W() { return data[0].length; } 187 int W() { return data[0].length; } 140 } 188 } 141 189 ................................................................................................................................................................................ 165 } 213 } 166 214 167 void opIndexAssign(char c, in Pos p) 215 void opIndexAssign(char c, in Pos p) 168 { 216 { 169 this[p.y, p.x] = c; 217 this[p.y, p.x] = c; 170 } 218 } 171 219 172 Pos[] lambdas() const { | 220 Pos[] objects(char c) const { 173 Pos[] ans; 221 Pos[] ans; 174 for(int y=1; y<=H; ++y) 222 for(int y=1; y<=H; ++y) 175 for(int x=1; x<=W; ++x) 223 for(int x=1; x<=W; ++x) 176 if(this[y,x] == '\\') | 224 if(this[y,x] == c) 177 ans ~= new Pos(y,x); 225 ans ~= new Pos(y,x); 178 return ans; 226 return ans; 179 } 227 } 180 228 > 229 Pos[] razors() const { return objects('!'); } > 230 Pos[] lambdas() const { return objects('\\'); } > 231 181 bool cleared() const 232 bool cleared() const 182 { 233 { 183 for(int y=1; y<=H; ++y) 234 for(int y=1; y<=H; ++y) 184 for(int x=1; x<=W; ++x) 235 for(int x=1; x<=W; ++x) 185 if(this[y,x] == 'L' || this[y,x] == 'O') 236 if(this[y,x] == 'L' || this[y,x] == 'O') 186 return false; 237 return false; 187 return true; 238 return true; 188 } 239 } 189 240 190 Tuple!(int,bool) command(char c) | 241 Tuple!(int,bool) command(char c, int turn) 191 { 242 { > 243 assert( this[robot] == 'R' ); 192 if(c=='R') return move( 0, +1); | 244 if(c=='R') return move( 0, +1, turn); 193 if(c=='L') return move( 0, -1); | 245 if(c=='L') return move( 0, -1, turn); 194 if(c=='U') return move(+1, 0); | 246 if(c=='U') return move(+1, 0, turn); 195 if(c=='D') return move(-1, 0); | 247 if(c=='D') return move(-1, 0, turn); 196 if(c=='W') return move( 0, 0); | 248 if(c=='W') return move( 0, 0, turn); > 249 if(c=='S') return use_razor(turn); 197 assert(false); 250 assert(false); 198 } 251 } 199 252 > 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 200 Tuple!(int, bool) move(int dy, int dx) | 267 Tuple!(int, bool) move(int dy, int dx, int turn) 201 { 268 { 202 int y = robot.y; 269 int y = robot.y; 203 int x = robot.x; 270 int x = robot.x; 204 assert( this[robot] == 'R' ); < 205 int lambda = 0; 271 int lambda = 0; 206 bool dead = false; < 207 if( '\\' == this[y+dy,x+dx] ) 272 if( '\\' == this[y+dy,x+dx] ) 208 lambda++; 273 lambda++; > 274 if( '!' == this[y+dy,x+dx] ) > 275 razor++; 209 if( " \\.O".count(this[y+dy,x+dx])==1 ) { | 276 if( " \\!.O".count(this[y+dy,x+dx])==1 ) { 210 this[y,x]=' '; 277 this[y,x]=' '; 211 this[y+dy,x+dx]='R'; 278 this[y+dy,x+dx]='R'; 212 robot = new Pos(y+dy,x+dx); 279 robot = new Pos(y+dy,x+dx); 213 } else if(dy==0 && '*'==this[y+dy,x+dx] && ' '==this[y+dy*2,x+dx 280 } else if(dy==0 && '*'==this[y+dy,x+dx] && ' '==this[y+dy*2,x+dx 214 this[y,x]=' '; 281 this[y,x]=' '; 215 this[y+dy,x+dx]='R'; 282 this[y+dy,x+dx]='R'; 216 this[y+dy*2,x+dx*2]='*'; 283 this[y+dy*2,x+dx*2]='*'; 217 robot = new Pos(y+dy,x+dx); 284 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; 218 } 292 } 219 if( update() ) | 293 bool dead = update(turn); 220 dead = true; < 221 return tuple(lambda,dead); 294 return tuple(lambda,dead); 222 } 295 } 223 296 224 bool update() | 297 bool update(int turn) 225 { 298 { 226 bool dead = false; 299 bool dead = false; 227 300 228 char[][] next; 301 char[][] next; 229 foreach(y,s; data) 302 foreach(y,s; data) 230 next ~= s.dup; 303 next ~= s.dup; 231 304 ................................................................................................................................................................................ 259 dead=true; 332 dead=true; 260 } 333 } 261 } 334 } 262 else if(this[p]=='L') { 335 else if(this[p]=='L') { 263 if(!lambda) 336 if(!lambda) 264 access(p) = 'O'; 337 access(p) = 'O'; 265 } 338 } > 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 } 266 } 346 } 267 data = next; 347 data = next; 268 return dead; 348 return dead; 269 } 349 } 270 } 350 } 271 351 272 //////////////////////////////////////////////////////////////////////////////// 352 //////////////////////////////////////////////////////////////////////////////// 273 353 274 class Game 354 class Game 275 { 355 { 276 mixin DeriveShow; | 356 public: 277 < 278 static Game load(File input) | 357 this(File input) 279 { 358 { 280 string[] raw_data; | 359 // Read map data 281 string[string] params; | 360 string[] map_data_lines; 282 < 283 // Raw map data; read until empty line. < 284 for(string line; !(line=input.readln().chomp()).empty; ) 361 for(string line; !(line=input.readln().chomp()).empty; ) 285 raw_data ~= line; | 362 map_data_lines ~= line; 286 | 363 287 // Additional commands; read until EOF. | 364 // H*W 288 for(string line; !(line=input.readln()).empty; ) { < 289 string[] ss = line.split(); < 290 if( ss.length == 2 ) | 365 H_ = map_data_lines.length; > 366 W_ = 0; > 367 foreach(mdl; map_data_lines) 291 params[ss[0]] = ss[1]; | 368 W_ = max(W_, mdl.length); 292 } | 369 293 < > 370 // Copy to modifiable buffer and adjust coordinates. 294 return load(raw_data, params); | 371 raw_data_ = new char[][H_+1]; 295 } < 296 < > 372 foreach(i,mdl; map_data_lines) { > 373 char[] buf = new char[mdl.length+1]; 297 static Game load(string[] raw_data, string[string] params) | 374 buf[0] = '#'; 298 { < > 375 buf[1..$] = mdl[]; 299 return new Game(raw_data, params); | 376 raw_data_[H_-i] = buf; 300 } | 377 } 301 | 378 302 this(string[] raw_data, string[string] params) | 379 // Detect objects > 380 for(int y=1; y<=H_; ++y) > 381 for(int x=1; x<raw_data_[y].length; ++x) 303 { | 382 { 304 this.map = Map.load(raw_data, params); < 305 this.water = Water.load(params); < 306 } < > 383 char c = raw_data_[y][x]; > 384 switch(c) 307 | 385 { 308 Game clone() const { return new Game(this); } < 309 this(const(Game) g) { | 386 case '#': 310 map = g.map.clone(); | 387 case '.': 311 water = g.water.clone(); | 388 case ' ': 312 turn = g.turn; | 389 break; 313 dead = g.dead; | 390 case 'L': 314 lambda = g.lambda; | 391 case 'O': 315 exit_bonus = g.exit_bonus; | 392 lift_pos_ = new Pos(y,x); 316 under_water = g.under_water; | 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; 317 } | 404 > 405 // Moving objects are erased from raw_data_ > 406 case 'R': > 407 robot_pos_ = new Pos(y,x); > 408 raw_data_[y][x] = ' '; > 409 break; > 410 case '*': > 411 case 'W': > 412 dynamic_objects_[new Pos(y,x)] = c; > 413 raw_data_[y][x] = ' '; > 414 if(c=='*') > 415 may_update_[new Pos(y,x)] = true; > 416 break; > 417 default: > 418 assert(false); 318 | 419 } 319 void command(char c) < 320 { < 321 if(dead || cleared) < 322 return; < 323 | 420 } 324 if(c == 'A') < > 421 > 422 // Read other parameters > 423 for(string line; !(line=input.readln()).empty; ) 325 { 424 { 326 exit_bonus = 1; | 425 string[] ss = line.split(); 327 return; | 426 if( ss.length == 2 ) 328 } < > 427 switch(ss[0]) 329 | 428 { 330 // TODO: clarify the event order | 429 case "Water": water_base_ = ss[1].to!int(); 331 Tuple!(int,bool) ld = map.command(c); | 430 case "Flooding": water_pace_ = ss[1].to!int(); 332 if( map.cleared() ) { | 431 case "Waterproof": max_air_ = ss[1].to!int(); 333 exit_bonus = 2; | 432 case "Growth": hige_pace_ = ss[1].to!int(); > 433 case "Razors": num_razor_ = ss[1].to!int(); > 434 default: assert(false); 334 } | 435 } 335 else { < 336 lambda += ld[0]; < 337 if( ld[1] ) { | 436 if( ss.length == 4 && ss[0]=="Trampoline" && ss[2]=="tar 338 dead = true; < > 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; 339 } 442 } 340 } 443 } 341 if( map.robot.y <= water_level ) < > 444 342 ++under_water; | 445 air_left_ = max_air_; 343 else < 344 under_water = 0; < 345 if( under_water > map.waterproof ) < 346 dead = true; < 347 turn += 1; < 348 } 446 } 349 447 350 Map map; < 351 Water water; < 352 int turn = 0; < 353 bool dead = false; < 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. < 359 < 360 @property const { 448 @property const { 361 long score() { return lambda*25L*(1+exit_bonus) - turn; } | 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 } 362 int water_level() { return water.level(turn); } | 460 int water_level() { > 461 return water_pace_ ? water_base_ + turn_/water_pace_ : w > 462 } 363 int water_until_rise() { return water.until_rise(turn); } | 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_; } 364 bool cleared() { return exit_bonus>0; } | 474 bool cleared() { return cleared_; } 365 int hp() { return map.waterproof - under_water; } < 366 long score_if_abort_now() { return lambda*25*(1+max(1,exit_bonus < > 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) > 506 { > 507 if(dead || cleared) > 508 return; > 509 > 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') {} > 516 > 517 if(!cleared) > 518 { > 519 map_update(); > 520 water_update(); > 521 } > 522 turn_ ++; > 523 } > 524 > 525 void command_move(int dy, int dx) > 526 { > 527 int y = robot_pos_.y, x = robot_pos_.x; > 528 char c = this[y+dy, x+dx]; > 529 Pos p = new Pos(y+dy, x+dx); > 530 > 531 switch(c){ > 532 case 'O': > 533 cleared_ = true; > 534 move_robot_to(p); > 535 break; > 536 case '\\': > 537 take_lambda_at(p); > 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 } > 561 > 562 void use_razor() > 563 { > 564 if(num_razor_ == 0) > 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; 367 } 759 } 368 } | 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; 369 779 370 unittest | 780 int turn_ = 0; 371 { < > 781 int air_left_ = 0; 372 Game.load(["###","...","#RL"], ["xxx":"yyy"]); | 782 bool cleared_ = false; > 783 bool dead_ = false; > 784 bool[Pos] may_update_; 373 } 785 }

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

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

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

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!Solver_1)(); | 12 auto g = d.addObserver!(GUI!MainSolver)(); 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 [7fa423ba9f8ebe92] to [e2d0d7db868c3a44].

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

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

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 */ < 12 3 13 class Solver_0 4 class Solver_0 14 { 5 { 15 this(const(Game) g) {} | 6 this(in Game g) {} 16 char single_step() { return 'W'; } 7 char single_step() { return 'W'; } > 8 void force(char c) {} 17 } 9 } 18 10 19 class Solver_1 11 class Solver_1 20 { 12 { 21 int g_wc = 0; | 13 int wait_count = 0; > 14 int choke_count = 0; 22 15 23 Game g; 16 Game g; 24 this(const(Game) g) | 17 this(in Game g) 25 { 18 { 26 this.g = g.clone(); 19 this.g = g.clone(); > 20 forbidden_cell = new bool[][](g.H+2, g.W+2); 27 } 21 } 28 22 29 char single_step() 23 char single_step() 30 { 24 { > 25 Tuple!(string,int) de = death_move(g); 31 char c = act(g, death_move(g)); | 26 char c = act(g, de[0], de[1]); 32 g.command(c); | 27 force(c); 33 return c; 28 return c; 34 } 29 } 35 30 > 31 void force(char c) > 32 { > 33 if(c != 'A') > 34 g.command(c); > 35 } > 36 36 string death_move(const(Game) g) | 37 Tuple!(string,int) death_move(const(Game) g) 37 { 38 { 38 string death; 39 string death; > 40 int choice = 0; 39 foreach(char c; "UDLRW") { 41 foreach(char c; "UDLRW") { 40 Game gg = g.clone(); 42 Game gg = g.clone(); 41 gg.command(c); 43 gg.command(c); 42 if( !gg.cleared && gg.dead ) 44 if( !gg.cleared && gg.dead ) 43 death ~= c; 45 death ~= c; > 46 else if( gg.robot != g.robot ) > 47 choice++; > 48 else if( c != 'W' ) // meaningless move > 49 death ~= c; 44 } 50 } 45 return death; | 51 return tuple(death, choice); 46 } 52 } 47 53 > 54 Tuple!(Pos, int)[] log; > 55 bool[][] forbidden_cell; > 56 48 char act(const(Game) g, string death) | 57 char act(const(Game) g, string death, int breath) 49 { 58 { 50 const Pos ro = g.map.robot; | 59 const Pos ro = g.robot; 51 const Pos[] la = g.map.lambdas(); | 60 const Pos li = g.lift; 52 const Pos li = g.map.lift; | 61 Pos[] la = g.lambdas(); > 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(); 53 69 54 Tuple!(char,int)[] cand; 70 Tuple!(char,int)[] cand; 55 char c = 'W'; 71 char c = 'W'; 56 if( la.empty ) { 72 if( la.empty ) { 57 cand = search(g, ro, li, death); | 73 cand = search(g, ro, [li], death); 58 } else { 74 } else { 59 foreach(lam; la) | 75 cand ~= search(g, ro, la~ra, death); > 76 } > 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 > 86 if(his>=2 || his==hi.length) > 87 cand = [tuple('S',int.max)]; > 88 if(cand.empty) { > 89 const(Pos)[] tgt; > 90 for(int y=1; y<=g.H; ++y) > 91 for(int x=1; x<=g.W; ++x) > 92 if(g[y,x]=='.'||g[y,x]==' ') { > 93 his = 0; > 94 for(int dy=-1; dy<=+1; ++dy) > 95 for(int dx=-1; dx<=+1; ++dx) > 96 if(g[y+dy,x+dx] == 'W') > 97 his++; > 98 if(his>=2) > 99 tgt ~= new Pos(y,x); > 100 } 60 cand ~= search(g, ro, lam, death); | 101 cand ~= search(g, ro, tgt, death, true); > 102 } > 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); > 115 } > 116 > 117 if(cand.empty) { > 118 choke_count++; > 119 cand ~= tuple('W',int.max); 61 } 120 } 62 sort!((Tuple!(char,int) c1, Tuple!(char,int) c2){ 121 sort!((Tuple!(char,int) c1, Tuple!(char,int) c2){ 63 if(c1[1] != c2[1]) 122 if(c1[1] != c2[1]) 64 return c1[1] < c2[1]; 123 return c1[1] < c2[1]; 65 return c1[0] < c2[0]; 124 return c1[0] < c2[0]; 66 })(cand); 125 })(cand); 67 c = cand[0][0]; 126 c = cand[0][0]; 68 127 69 if(c=='W') { | 128 if(death.count(c) || wait_count>=2) { 70 g_wc++; | 129 foreach(char live; "UDLRW") 71 if(g_wc > 10) | 130 if(death.count(live)==0) { 72 c = 'A'; | 131 c=live; > 132 break; > 133 } 73 } 134 } > 135 > 136 if(c == 'W') > 137 wait_count++; 74 else 138 else > 139 wait_count = 0; > 140 if(choke_count >= g.H) 75 g_wc = 0; | 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 76 return c; 157 return c; 77 } 158 } 78 159 79 Tuple!(char,int)[] search(in Game g, in Pos s, in Pos o, string death) | 160 Tuple!(char,int)[] search(in Game g, in Pos s, in Pos[] gs, string death 80 { 161 { 81 bool danger(int y, int x) 162 bool danger(int y, int x) 82 { 163 { > 164 if(g[y,x] == ' ' || g[y,x] == 'R') > 165 return false; 83 if(g.map[y+1,x] == '*') | 166 if(g[y+1,x] == '*') > 167 return true; > 168 if(g[y+1,x-1]=='*' && (g[y,x-1]=='\\'||g[y,x-1]=='*') && 84 return true; 169 return true; 85 if(g.map[y+1,x-1]=='*' && (g.map[y,x-1]=='\\'||g.map[y,x | 170 if(g[y+1,x+1]=='*' && (g[y,x+1]=='*') && (g[y+1,x]==' '| 86 return true; 171 return true; 87 if(g.map[y+1,x+1]=='*' && (g.map[y,x+1]=='*') && (g.map[ | 172 if(g[y,x-1]=='*' && (g[y-1,x-1]=='\\'||g[y-1,x-1]=='*') 88 return true; 173 return true; 89 if(g.map[y,x-1]=='*' && (g.map[y-1,x-1]=='\\'||g.map[y-1 | 174 if(g[y,x+1]=='*' && (g[y-1,x+1]=='*') && (g[y-1,x]==' '| 90 return true; < 91 if(g.map[y,x+1]=='*' && (g.map[y-1,x+1]=='*') && (g.map[ < 92 return true; 175 return true; 93 return false; 176 return false; 94 } 177 } 95 178 96 // avoid directly below '*' 179 // avoid directly below '*' 97 Tuple!(char,int)[] tryA() { 180 Tuple!(char,int)[] tryA() { 98 const(Pos)[] q = [o]; | 181 const(Pos)[] q; > 182 foreach(p; gs) > 183 if(!danger(p.y,p.x)) > 184 q ~= p; 99 bool[][] v = new bool[][](g.map.H+2, g.map.W+2); | 185 bool[][] v = new bool[][](g.H+2, g.W+2); 100 if( !danger(o.y,o.x) ) { < 101 v[o.y][o.x]=true; | 186 foreach(p; q) v[p.y][p.x]=true; 102 for(int step=1; q.length; ++step) { | 187 for(int step=1; q.length; ++step) { 103 Pos[] q2; | 188 Pos[] q2; 104 foreach(p; q) { | 189 foreach(p; q) { 105 int[] dy=[-1,+1,0,0]; < 106 int[] dx=[0,0,-1,+1]; < > 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]; 107 for(int i=0; i<4; ++i) { | 192 for(int i=0; i<yyy.length; ++i) { 108 int y = p.y+dy[i]; | 193 int y = yyy[i]; 109 int x = p.x+dx[i]; | 194 int x = xxx[i]; 110 if(v[y][x]) continue; < 111 if(y==s.y && x==s.x) { < 112 char c = "UDRL"[ | 195 if('1'<=g[y,x]&&g[y,x]<='9') { 113 if( death.count( | 196 foreach(ppp; g.trampolin 114 return [ | 197 yyy ~= ppp.y; 115 } else if(g.map[y,x]==' | 198 xxx ~= ppp.x; 116 if(danger(y,x)) < 117 continue < 118 q2 ~= new Pos(y, < 119 v[y][x]=true; < 120 } 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; 121 } 213 } 122 } 214 } 123 q = q2; < 124 } 215 } > 216 q = q2; 125 } 217 } 126 return []; 218 return []; 127 } 219 } 128 220 129 // any empty space is my ground 221 // any empty space is my ground 130 Tuple!(char,int)[] tryB() { 222 Tuple!(char,int)[] tryB() { 131 const(Pos)[] q = [o]; | 223 const(Pos)[] q; > 224 foreach(p; gs) q ~= p; 132 bool[][] v = new bool[][](g.map.H+2, g.map.W+2); | 225 bool[][] v = new bool[][](g.H+2, g.W+2); 133 v[o.y][o.x]=true; | 226 foreach(p; q) v[p.y][p.x]=true; 134 for(int step=15; q.length; ++step) { | 227 for(int step=10; q.length; ++step) { 135 Pos[] q2; 228 Pos[] q2; 136 foreach(p; q) { 229 foreach(p; q) { 137 int[] dy=[-1,+1,0,0]; | 230 int[] yyy=[p.y-1,p.y+1,p.y,p.y]; 138 int[] dx=[0,0,-1,+1]; | 231 int[] xxx=[p.x,p.x,p.x-1,p.x+1]; 139 for(int i=0; i<4; ++i) { | 232 for(int i=0; i<yyy.length; ++i) { 140 int y = p.y+dy[i]; | 233 int y = yyy[i]; 141 int x = p.x+dx[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 } 142 if(v[y][x]) continue; 242 if(v[y][x]) continue; 143 if(y==s.y && x==s.x) { | 243 if(y==s.y && x==s.x && i<4) { 144 char c = "UDRL"[i]; 244 char c = "UDRL"[i]; 145 if( death.count(c) == 0 245 if( death.count(c) == 0 146 return [tuple(c, 246 return [tuple(c, 147 } else if(g.map[y,x]==' '||g.map | 247 } else if(forbidden_cell[y][x]){ > 248 } else if(g[y,x]==' '||g[y,x]==' 148 q2 ~= new Pos(y,x); 249 q2 ~= new Pos(y,x); 149 v[y][x]=true; 250 v[y][x]=true; 150 } 251 } 151 } 252 } 152 } 253 } 153 q = q2; 254 q = q2; 154 } 255 } 155 return []; 256 return []; 156 } 257 } 157 258 158 // push rocks! 259 // push rocks! 159 Tuple!(char,int)[] tryC() { 260 Tuple!(char,int)[] tryC() { 160 const(Pos)[] q = [o]; | 261 const(Pos)[] q; > 262 foreach(p; gs) q ~= p; 161 bool[][] v = new bool[][](g.map.H+2, g.map.W+2); | 263 bool[][] v = new bool[][](g.H+2, g.W+2); 162 v[o.y][o.x]=true; | 264 foreach(p; q) v[p.y][p.x]=true; 163 for(int step=30; q.length; ++step) { | 265 for(int step=20; q.length; ++step) { 164 Pos[] q2; 266 Pos[] q2; 165 foreach(p; q) { 267 foreach(p; q) { 166 int[] dy=[-1,+1,0,0]; | 268 int[] yyy=[p.y-1,p.y+1,p.y,p.y]; 167 int[] dx=[0,0,-1,+1]; | 269 int[] xxx=[p.x,p.x,p.x-1,p.x+1]; 168 for(int i=0; i<4; ++i) { | 270 for(int i=0; i<yyy.length; ++i) { 169 int y = p.y+dy[i]; | 271 int y = yyy[i]; 170 int x = p.x+dx[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 } 171 if(v[y][x]) continue; 285 if(v[y][x]) continue; 172 if(y==s.y && x==s.x) { | 286 if(y==s.y && x==s.x && i<4) { 173 char c = "UDRL"[i]; 287 char c = "UDRL"[i]; 174 if( death.count(c) == 0 288 if( death.count(c) == 0 175 return [tuple(c, 289 return [tuple(c, 176 } else if(g.map[y,x]==' '||g.map | 290 } else if(forbidden_cell[y][x]){ 177 q2 ~= new Pos(y,x); | 291 } else if(g[y,x]==' '||g[y,x]==' 178 v[y][x]=true; < 179 } else if(dy[i]==0 && g.map[p]== < 180 q2 ~= new Pos(y,x); 292 q2 ~= new Pos(y,x); 181 v[y][x]=true; 293 v[y][x]=true; 182 } 294 } 183 } 295 } 184 } 296 } 185 q = q2; 297 q = q2; 186 } 298 } 187 return []; 299 return []; 188 } 300 } 189 return tryA() ~ tryB() ~ tryC() ~ tuple('W', int.max); | 301 return (danger_ok ? [] : tryA()) ~ tryB() ~ tryC(); > 302 } > 303 } > 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..$]; 190 } 387 } 191 } 388 } > 389 > 390 alias Solver_2!(Solver_1) MainSolver; > 391 //alias Solver_1 MainSolver;

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

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; 8 import std.c.stdlib; 9 import std.c.stdlib; > 10 > 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 } 9 32 10 void application_exit() 33 void application_exit() 11 { 34 { 12 std.c.stdlib.exit(0); 35 std.c.stdlib.exit(0); 13 } 36 } 14 37 15 template DeriveCreate() 38 template DeriveCreate() ................................................................................................................................................................................ 19 this.tupleof = params; 42 this.tupleof = params; 20 } 43 } 21 } 44 } 22 45 23 template DeriveCompare() 46 template DeriveCompare() 24 { 47 { 25 override: 48 override: 26 bool opEquals(Object rhs) | 49 bool opEquals(Object rhs) const 27 { 50 { 28 return tuple(this.tupleof) == tuple((cast(typeof(this))rhs).tupl 51 return tuple(this.tupleof) == tuple((cast(typeof(this))rhs).tupl 29 } 52 } 30 53 31 int opCmp(Object rhs) | 54 int opCmp(Object rhs) const 32 { 55 { 33 return tuple(this.tupleof).opCmp(tuple((cast(typeof(this))rhs).t 56 return tuple(this.tupleof).opCmp(tuple((cast(typeof(this))rhs).t 34 } 57 } 35 58 36 hash_t toHash() | 59 hash_t toHash() const 37 { 60 { 38 hash_t v = 0; 61 hash_t v = 0; 39 foreach(mem; this.tupleof) { 62 foreach(mem; this.tupleof) { 40 v *= 11; 63 v *= 11; 41 static if(__traits(compiles, v^=mem)) 64 static if(__traits(compiles, v^=mem)) 42 v ^= mem; 65 v ^= mem; 43 else 66 else ................................................................................................................................................................................ 46 return v; 69 return v; 47 } 70 } 48 } 71 } 49 72 50 template DeriveShow() 73 template DeriveShow() 51 { 74 { 52 override: 75 override: 53 string toString() | 76 string toString() const 54 { 77 { 55 string str = text(typeof(this).stringof, "("); 78 string str = text(typeof(this).stringof, "("); 56 foreach(i,mem; this.tupleof) { 79 foreach(i,mem; this.tupleof) { 57 if(i) str ~= ", "; 80 if(i) str ~= ", "; 58 str = text(str, this.tupleof[i].stringof[5..$], ":", me 81 str = text(str, this.tupleof[i].stringof[5..$], ":", me 59 } 82 } 60 return str ~ ")"; 83 return str ~ ")"; 61 } 84 } 62 } 85 }

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

> 1 Team: 1 Team "Dark Integers". | 2 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 <