Check-in Differences
Not logged in

Difference From:

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

To:

[dbff34ac59] Lightning submission. (user: kinaba, tags: trunk, lightning, date: 2012-07-14 09:30:06)

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 <

Deleted src/cui_auto_main.d version [b38d60ea39d11e6e]

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

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 [7c15481493257083].

1 import util; 1 import util; > 2 import output; 2 3 3 //////////////////////////////////////////////////////////////////////////////// 4 //////////////////////////////////////////////////////////////////////////////// 4 5 5 class Pos 6 class Pos 6 { 7 { 7 public immutable int y, x; 8 public immutable int y, x; 8 mixin DeriveCreate; 9 mixin DeriveCreate; 9 mixin DeriveCompare; 10 mixin DeriveCompare; 10 mixin DeriveShow; 11 mixin DeriveShow; 11 Pos clone() const { return cast(Pos) this; } | 12 Pos clone() { return this; } 12 13 13 @property: 14 @property: 14 Pos wait() { return this.clone(); } | 15 Pos wait() { return this; } 15 Pos up() { return new Pos(y+1, x); } 16 Pos up() { return new Pos(y+1, x); } 16 Pos down() { return new Pos(y-1, x); } 17 Pos down() { return new Pos(y-1, x); } 17 Pos left() { return new Pos(y, x-1); } 18 Pos left() { return new Pos(y, x-1); } 18 Pos right() { return new Pos(y, x+1); } 19 Pos right() { return new Pos(y, x+1); } 19 alias wait W,w; 20 alias wait W,w; 20 alias up U,u; 21 alias up U,u; 21 alias down D,d; 22 alias down D,d; ................................................................................................................................................................................ 41 42 42 class Water 43 class Water 43 { 44 { 44 public immutable int base, pace; 45 public immutable int base, pace; 45 mixin DeriveCreate; 46 mixin DeriveCreate; 46 mixin DeriveCompare; 47 mixin DeriveCompare; 47 mixin DeriveShow; 48 mixin DeriveShow; 48 Water clone() const { return cast(Water)this; } | 49 Water clone() { return this; } 49 50 50 static load(string[string] params) 51 static load(string[string] params) 51 { 52 { > 53 return new Water( 52 return new Water(params.get("Water", "0").to!int(), | 54 params.get("Water", "0").to!int(), 53 params.get("Flooding", "0").to!int()); | 55 params.get("Flooding", "0").to!int() > 56 ); 54 } 57 } 55 58 56 int level(int number_of_update) const | 59 int level(int number_of_update) 57 { 60 { 58 return pace ? base+(number_of_update/pace) : base; 61 return pace ? base+(number_of_update/pace) : base; 59 } 62 } 60 63 61 int until_rise(int number_of_update) const | 64 int until_rise(int number_of_update) 62 { 65 { 63 return pace ? pace-number_of_update%pace : int.max; 66 return pace ? pace-number_of_update%pace : int.max; 64 } 67 } 65 } 68 } 66 69 67 unittest 70 unittest 68 { 71 { ................................................................................................................................................................................ 82 assert( 1 == w.level(3) ); 85 assert( 1 == w.level(3) ); 83 assert( 1 == w.level(4) ); 86 assert( 1 == w.level(4) ); 84 assert( 1 == w.level(5) ); 87 assert( 1 == w.level(5) ); 85 } 88 } 86 89 87 //////////////////////////////////////////////////////////////////////////////// 90 //////////////////////////////////////////////////////////////////////////////// 88 91 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 92 class Map 116 { 93 { 117 mixin DeriveShow; 94 mixin DeriveShow; 118 95 119 static Map load(string[] raw_data, string[string] params, char[char] tra | 96 static Map load(string[] raw_data, string[string] params) 120 { 97 { 121 // TODO: choose optimal representation. 98 // TODO: choose optimal representation. 122 return new Map(raw_data, params, trampo); | 99 return new Map(raw_data, params); 123 } 100 } 124 101 125 char[][] data; 102 char[][] data; 126 Pos robot; 103 Pos robot; 127 Pos lift; 104 Pos lift; 128 int waterproof; 105 int waterproof; 129 Pos[char] tr_target; < 130 Pos[][char] tr_source; < 131 const(Hige) hige; < 132 int razor; < 133 106 134 Map clone() const { return new Map(this); } | 107 Map clone() { return new Map(this); } 135 this(in Map m) { | 108 this(Map m) { 136 foreach(s; m.data) 109 foreach(s; m.data) 137 this.data ~= s.dup; 110 this.data ~= s.dup; 138 this.robot = m.robot.clone(); 111 this.robot = m.robot.clone(); 139 this.lift = m.lift.clone(); 112 this.lift = m.lift.clone(); 140 this.waterproof = m.waterproof; 113 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 } 114 } 146 115 147 this(string[] raw_data, string[string] params, char[char] trampo) | 116 this(string[] raw_data, string[string] params) 148 { 117 { 149 int width = 0; 118 int width = 0; 150 foreach(r; raw_data) 119 foreach(r; raw_data) 151 width = max(width, r.length); 120 width = max(width, r.length); 152 foreach(r; raw_data) { 121 foreach(r; raw_data) { 153 this.data ~= r.dup; 122 this.data ~= r.dup; 154 this.data[$-1].length = width; 123 this.data[$-1].length = width; ................................................................................................................................................................................ 159 for(int x=1; x<=W; ++x) { 128 for(int x=1; x<=W; ++x) { 160 if(this[y,x] == 'R') 129 if(this[y,x] == 'R') 161 this.robot = new Pos(y,x); 130 this.robot = new Pos(y,x); 162 if(this[y,x] == 'L' || this[y,x] == 'O') 131 if(this[y,x] == 'L' || this[y,x] == 'O') 163 this.lift = new Pos(y,x); 132 this.lift = new Pos(y,x); 164 } 133 } 165 134 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(); 135 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 } 136 } 184 137 185 const @property { 138 const @property { 186 int H() { return data.length; } 139 int H() { return data.length; } 187 int W() { return data[0].length; } 140 int W() { return data[0].length; } 188 } 141 } 189 142 190 const { < 191 char opIndex(int y, int x) | 143 char opIndex(int y, int x) 192 { | 144 { 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 } < 204 } 155 } 205 156 206 void opIndexAssign(char c, int y, int x) 157 void opIndexAssign(char c, int y, int x) 207 { 158 { 208 // Adjust coordinate to the spec. bottom-left is (1,1). 159 // Adjust coordinate to the spec. bottom-left is (1,1). 209 --y, --x; 160 --y, --x; 210 if(y<0||H<=y||x<0||W<=x) 161 if(y<0||H<=y||x<0||W<=x) 211 return; 162 return; 212 data[H-1-y][x] = c; 163 data[H-1-y][x] = c; 213 } 164 } 214 165 215 void opIndexAssign(char c, in Pos p) | 166 void opIndexAssign(char c, Pos p) 216 { 167 { 217 this[p.y, p.x] = c; 168 this[p.y, p.x] = c; 218 } 169 } 219 170 220 Pos[] objects(char c) const { | 171 Pos[] lambdas() { 221 Pos[] ans; 172 Pos[] ans; 222 for(int y=1; y<=H; ++y) 173 for(int y=1; y<=H; ++y) 223 for(int x=1; x<=W; ++x) 174 for(int x=1; x<=W; ++x) 224 if(this[y,x] == c) | 175 if(this[y,x] == '\\') 225 ans ~= new Pos(y,x); 176 ans ~= new Pos(y,x); 226 return ans; 177 return ans; 227 } 178 } 228 179 229 Pos[] razors() const { return objects('!'); } < 230 Pos[] lambdas() const { return objects('\\'); } < 231 < 232 bool cleared() const | 180 bool cleared() 233 { 181 { 234 for(int y=1; y<=H; ++y) 182 for(int y=1; y<=H; ++y) 235 for(int x=1; x<=W; ++x) 183 for(int x=1; x<=W; ++x) 236 if(this[y,x] == 'L' || this[y,x] == 'O') 184 if(this[y,x] == 'L' || this[y,x] == 'O') 237 return false; 185 return false; 238 return true; 186 return true; 239 } 187 } 240 188 241 Tuple!(int,bool) command(char c, int turn) | 189 Tuple!(int,bool) command(char c) 242 { 190 { 243 assert( this[robot] == 'R' ); < 244 if(c=='R') return move( 0, +1, turn); | 191 if(c=='R') return move( 0, +1); 245 if(c=='L') return move( 0, -1, turn); | 192 if(c=='L') return move( 0, -1); 246 if(c=='U') return move(+1, 0, turn); | 193 if(c=='U') return move(+1, 0); 247 if(c=='D') return move(-1, 0, turn); | 194 if(c=='D') return move(-1, 0); 248 if(c=='W') return move( 0, 0, turn); | 195 if(c=='W') return move( 0, 0); 249 if(c=='S') return use_razor(turn); < 250 assert(false); 196 assert(false); 251 } 197 } 252 198 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) | 199 Tuple!(int, bool) move(int dy, int dx) 268 { 200 { 269 int y = robot.y; 201 int y = robot.y; 270 int x = robot.x; 202 int x = robot.x; > 203 assert( this[robot] == 'R' ); 271 int lambda = 0; 204 int lambda = 0; > 205 bool dead = false; 272 if( '\\' == this[y+dy,x+dx] ) 206 if( '\\' == this[y+dy,x+dx] ) 273 lambda++; 207 lambda++; 274 if( '!' == this[y+dy,x+dx] ) < 275 razor++; < 276 if( " \\!.O".count(this[y+dy,x+dx])==1 ) { | 208 if( " \\.O".count(this[y+dy,x+dx])==1 ) { 277 this[y,x]=' '; 209 this[y,x]=' '; 278 this[y+dy,x+dx]='R'; 210 this[y+dy,x+dx]='R'; 279 robot = new Pos(y+dy,x+dx); 211 robot = new Pos(y+dy,x+dx); 280 } else if(dy==0 && '*'==this[y+dy,x+dx] && ' '==this[y+dy*2,x+dx 212 } else if(dy==0 && '*'==this[y+dy,x+dx] && ' '==this[y+dy*2,x+dx 281 this[y,x]=' '; 213 this[y,x]=' '; 282 this[y+dy,x+dx]='R'; 214 this[y+dy,x+dx]='R'; 283 this[y+dy*2,x+dx*2]='*'; 215 this[y+dy*2,x+dx*2]='*'; 284 robot = new Pos(y+dy,x+dx); 216 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 } 217 } 293 bool dead = update(turn); | 218 if( update() ) > 219 dead = true; 294 return tuple(lambda,dead); 220 return tuple(lambda,dead); 295 } 221 } 296 222 297 bool update(int turn) | 223 bool update() 298 { 224 { 299 bool dead = false; 225 bool dead = false; 300 226 301 char[][] next; 227 char[][] next; 302 foreach(y,s; data) 228 foreach(y,s; data) 303 next ~= s.dup; 229 next ~= s.dup; 304 230 ................................................................................................................................................................................ 332 dead=true; 258 dead=true; 333 } 259 } 334 } 260 } 335 else if(this[p]=='L') { 261 else if(this[p]=='L') { 336 if(!lambda) 262 if(!lambda) 337 access(p) = 'O'; 263 access(p) = 'O'; 338 } 264 } 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 } 265 } 347 data = next; 266 data = next; 348 return dead; 267 return dead; 349 } 268 } 350 } 269 } 351 270 352 //////////////////////////////////////////////////////////////////////////////// 271 //////////////////////////////////////////////////////////////////////////////// 353 272 354 class Game 273 class Game 355 { 274 { 356 public: | 275 mixin DeriveShow; > 276 357 this(File input) | 277 static Game load(File input) 358 { 278 { 359 // Read map data | 279 string[] raw_data; 360 string[] map_data_lines; | 280 string[string] params; > 281 > 282 // Raw map data; read until empty line. 361 for(string line; !(line=input.readln().chomp()).empty; ) 283 for(string line; !(line=input.readln().chomp()).empty; ) 362 map_data_lines ~= line; | 284 raw_data ~= line; 363 285 364 // H*W | 286 // Additional commands; read until EOF. > 287 for(string line; !(line=input.readln()).empty; ) { > 288 string[] ss = line.split(); 365 H_ = map_data_lines.length; | 289 if( ss.length == 2 ) 366 W_ = 0; < 367 foreach(mdl; map_data_lines) < 368 W_ = max(W_, mdl.length); | 290 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 } 291 } 378 292 379 // Detect objects | 293 return load(raw_data, params); 380 for(int y=1; y<=H_; ++y) < 381 for(int x=1; x<raw_data_[y].length; ++x) < > 294 } 382 { | 295 383 char c = raw_data_[y][x]; < > 296 static Game load(string[] raw_data, string[string] params) > 297 { 384 switch(c) | 298 return new Game(raw_data, params); > 299 } 385 { | 300 386 case '#': < 387 case '.': | 301 this(string[] raw_data, string[string] params) 388 case ' ': < > 302 { 389 break; | 303 this.map = Map.load(raw_data, params); 390 case 'L': | 304 this.water = Water.load(params); 391 case 'O': | 305 this.output = new NilOutput; 392 lift_pos_ = new Pos(y,x); < 393 break; < > 306 } > 307 394 case 'A': .. case 'I': | 308 Game clone() { return new Game(this); } 395 case '1': .. case '9': | 309 this(Game g) { 396 trampoline_pos_[c] = new Pos(y,x); | 310 map = g.map.clone(); 397 break; | 311 water = g.water.clone(); 398 case '!': | 312 output = new NilOutput; 399 razor_pos_ ~= new Pos(y,x); | 313 turn = g.turn; 400 break; | 314 dead = g.dead; 401 case '\\': | 315 lambda = g.lambda; 402 lambda_pos_ ~= new Pos(y,x); | 316 exit_bonus = g.exit_bonus; 403 break; | 317 under_water = g.under_water; > 318 } 404 319 405 // Moving objects are erased from raw_data_ | 320 void set_output(Output o) { this.output = (o is null ? new NilOutput : o 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); < 419 } < 420 } < 421 321 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 } < 447 < 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) 322 void command(char c) 506 { 323 { 507 if(dead || cleared) 324 if(dead || cleared) 508 return; 325 return; > 326 scope(exit) { > 327 if(dead || cleared) > 328 output.flush(); 509 | 329 } 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); | 330 this.output.command(c); 514 if(c == 'S') use_razor(); < 515 if(c == 'W') {} < 516 331 517 if(!cleared) | 332 if(c == 'A') 518 { 333 { 519 map_update(); | 334 exit_bonus = 1; 520 water_update(); | 335 return; > 336 } > 337 > 338 // TODO: clarify the event order > 339 Tuple!(int,bool) ld = map.command(c); > 340 if( map.cleared() ) { > 341 exit_bonus = 2; > 342 } > 343 else { > 344 lambda += ld[0]; > 345 if( ld[1] ) { > 346 dead = true; > 347 } 521 } 348 } > 349 if( map.robot.y <= water_level ) > 350 ++under_water; > 351 else > 352 under_water = 0; > 353 if( under_water > map.waterproof ) > 354 dead = true; 522 turn_ ++; | 355 turn += 1; 523 } 356 } 524 357 525 void command_move(int dy, int dx) | 358 Map map; 526 { < > 359 Water water; 527 int y = robot_pos_.y, x = robot_pos_.x; | 360 Output output; 528 char c = this[y+dy, x+dx]; | 361 int turn = 0; 529 Pos p = new Pos(y+dy, x+dx); | 362 bool dead = false; > 363 int lambda = 0; > 364 int exit_bonus = 0; > 365 int under_water = 0; > 366 // TODO: when adding members, take care of clone(). > 367 // TODO: fix this poor design. 530 368 531 switch(c){ | 369 @property { 532 case 'O': | 370 long score() { return lambda*25L*(1+exit_bonus) - turn; } 533 cleared_ = true; | 371 int water_level() { return water.level(turn); } 534 move_robot_to(p); | 372 int water_until_rise() { return water.until_rise(turn); } 535 break; | 373 bool cleared() { return exit_bonus>0; } 536 case '\\': | 374 int hp() { return map.waterproof - under_water; } 537 take_lambda_at(p); | 375 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 } 376 } > 377 } 561 378 562 void use_razor() | 379 unittest 563 { | 380 { 564 if(num_razor_ == 0) | 381 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 } 382 }

Modified src/gui.d from [e84cacd6262f93a7] to [8bca70d55515c665].

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

Deleted src/gui_main.d version [05082d0f328d756c]

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

Modified src/output.d from [e2d0d7db868c3a44] to [1b458d7cd25e92dc].

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

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

1 import util; 1 import util; 2 import game; 2 import game; > 3 import output; 3 4 4 class Solver_0 | 5 int g_wc = 0; 5 { < 6 this(in Game g) {} < 7 char single_step() { return 'W'; } < 8 void force(char c) {} < 9 } < 10 6 11 class Solver_1 | 7 void act(Game g) 12 { 8 { 13 int wait_count = 0; | 9 Pos ro = g.map.robot; 14 int choke_count = 0; | 10 Pos[] la = g.map.lambdas(); > 11 Pos li = g.map.lift; 15 12 16 Game g; | 13 char c = 'W'; 17 this(in Game g) | 14 if( la.empty ) { 18 { < > 15 auto r = search(g, ro, li); 19 this.g = g.clone(); | 16 c = r[0]; 20 forbidden_cell = new bool[][](g.H+2, g.W+2); | 17 } else { 21 } < 22 < 23 char single_step() < 24 { < 25 Tuple!(string,int) de = death_move(g); < 26 char c = act(g, de[0], de[1]); < 27 force(c); < 28 return c; < 29 } < 30 < 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) < 38 { < 39 string death; < 40 int choice = 0; < 41 foreach(char c; "UDLRW") { < 42 Game gg = g.clone(); < 43 gg.command(c); < 44 if( !gg.cleared && gg.dead ) < 45 death ~= c; < 46 else if( gg.robot != g.robot ) < 47 choice++; < 48 else if( c != 'W' ) // meaningless move < 49 death ~= c; < 50 } < 51 return tuple(death, choice); < 52 } < 53 < 54 Tuple!(Pos, int)[] log; < 55 bool[][] forbidden_cell; < 56 < 57 char act(const(Game) g, string death, int breath) < 58 { < 59 const Pos ro = g.robot; < 60 const Pos li = g.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(); < 69 < 70 Tuple!(char,int)[] cand; 18 Tuple!(char,int)[] cand; 71 char c = 'W'; | 19 foreach(lam; la) 72 if( la.empty ) { < 73 cand = search(g, ro, [li], death); < 74 } else { < 75 cand ~= search(g, ro, la~ra, death); | 20 cand ~= search(g, ro, lam); 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 } < 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); < 120 } < 121 sort!((Tuple!(char,int) c1, Tuple!(char,int) c2){ 21 sort!((Tuple!(char,int) c1, Tuple!(char,int) c2){ 122 if(c1[1] != c2[1]) 22 if(c1[1] != c2[1]) 123 return c1[1] < c2[1]; 23 return c1[1] < c2[1]; 124 return c1[0] < c2[0]; 24 return c1[0] < c2[0]; 125 })(cand); 25 })(cand); 126 c = cand[0][0]; 26 c = cand[0][0]; 127 | 27 } 128 if(death.count(c) || wait_count>=2) { | 28 if(c=='W') { 129 foreach(char live; "UDLRW") | 29 g_wc++; 130 if(death.count(live)==0) { | 30 if(g_wc > 10) 131 c=live; < 132 break; < 133 } < 134 } < 135 < 136 if(c == 'W') < 137 wait_count++; < 138 else < 139 wait_count = 0; < 140 if(choke_count >= g.H) < 141 c = 'A'; 31 c = 'A'; > 32 } > 33 else > 34 g_wc = 0; > 35 g.command(c); > 36 } 142 37 143 bool[char] choice; | 38 Tuple!(char,int) search(Game g, Pos s, Pos o) 144 foreach(t; cand) < > 39 { 145 choice[t[0]] = true; | 40 Pos[] q = [o]; 146 log ~= tuple(ro.clone(), cast(int)choice.length); | 41 bool[][] v = new bool[][](g.map.H+2, g.map.W+2); 147 if(log.length > 5) | 42 for(int step=1; q.length; ++step) { 148 log = log[$-5..$]; | 43 Pos[] q2; 149 int cnt = 0; < 150 foreach(l; log) | 44 foreach(p; q) { > 45 int[] dy=[-1,+1,0,0]; 151 if(l[0] == log[$-1][0]) | 46 int[] dx=[0,0,-1,+1]; 152 ++cnt; | 47 for(int i=0; i<4; ++i) { 153 if( cnt >= 3 && breath==1 ) { | 48 int y = p.y+dy[i]; 154 forbidden_cell[ro.y][ro.x] = true; | 49 int x = p.x+dx[i]; > 50 if(v[y][x]) continue; > 51 if(y==s.y && x==s.x) { > 52 if(i==0) return tuple('U',step); > 53 if(i==1) return tuple('D',step); > 54 if(i==2) return tuple('R',step); > 55 if(i==3) return tuple('L',step); > 56 } else if(g.map[y,x]==' '||g.map[y,x]=='\\') { > 57 q2 ~= new Pos(y,x); > 58 v[y][x]=true; > 59 } else if(g.map[y,x]=='.' && g.map[y-1,x]!='*') > 60 q2 ~= new Pos(y,x); > 61 v[y][x]=true; > 62 } > 63 } 155 } 64 } 156 < 157 return c; < > 65 q = q2; 158 } 66 } 159 < > 67 q = [o]; 160 Tuple!(char,int)[] search(in Game g, in Pos s, in Pos[] gs, string death | 68 v = new bool[][](g.map.H+2, g.map.W+2); 161 { < > 69 for(int step=1000; q.length; ++step) { 162 bool danger(int y, int x) | 70 Pos[] q2; 163 { < > 71 foreach(p; q) { 164 if(g[y,x] == ' ' || g[y,x] == 'R') | 72 int[] dy=[-1,+1,0,0]; 165 return false; | 73 int[] dx=[0,0,-1,+1]; 166 if(g[y+1,x] == '*') | 74 for(int i=0; i<4; ++i) { > 75 int y = p.y+dy[i]; > 76 int x = p.x+dx[i]; > 77 if(v[y][x]) continue; > 78 if(y==s.y && x==s.x) { 167 return true; | 79 if(i==0) return tuple('U',step); 168 if(g[y+1,x-1]=='*' && (g[y,x-1]=='\\'||g[y,x-1]=='*') && < 169 return true; | 80 if(i==1) return tuple('D',step); 170 if(g[y+1,x+1]=='*' && (g[y,x+1]=='*') && (g[y+1,x]==' '| < 171 return true; | 81 if(i==2) return tuple('R',step); 172 if(g[y,x-1]=='*' && (g[y-1,x-1]=='\\'||g[y-1,x-1]=='*') < > 82 if(i==3) return tuple('L',step); > 83 } else if(g.map[y,x]==' '||g.map[y,x]=='\\') { > 84 q2 ~= new Pos(y,x); 173 return true; | 85 v[y][x]=true; 174 if(g[y,x+1]=='*' && (g[y-1,x+1]=='*') && (g[y-1,x]==' '| < > 86 } else if(g.map[y,x]=='.'/* && g[y-1,x]!='*'*/) > 87 q2 ~= new Pos(y,x); 175 return true; | 88 v[y][x]=true; 176 return false; < > 89 } > 90 } 177 } 91 } 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; | 92 q = q2; 217 } | 93 } 218 return []; | 94 return tuple('W', int.max); 219 } | 95 } 220 96 221 // any empty space is my ground | 97 void main(string[] args) 222 Tuple!(char,int)[] tryB() { < > 98 { 223 const(Pos)[] q; | 99 auto g = Game.load(stdin); 224 foreach(p; gs) q ~= p; | 100 g.set_output(new GuardedOutput(g)); 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 101 259 // push rocks! | 102 while(!g.dead && !g.cleared) 260 Tuple!(char,int)[] tryC() { | 103 act(g); 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 } 104 } 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; <

Added src/test.d version [d9955daaabe58d54]

> 1 import std.algorithm; > 2 import std.array; > 3 import std.conv; > 4 import std.stdio; > 5 import std.string; > 6 import std.typecons; > 7 import core.stdc.signal; > 8 import core.stdc.stdlib; > 9 import dfl.all; > 10 > 11 class Map > 12 { > 13 private char[][] data; > 14 bool dead = false; > 15 bool cleared = false; > 16 int water = 0; > 17 int flooding = 0; > 18 int water_proof = 10; > 19 int underwater = 0; > 20 int flooding_counter = 0; > 21 > 22 this(File input) > 23 { > 24 string line; > 25 while( (line=input.readln().chomp()).length ) > 26 data ~= line.dup; > 27 > 28 int width = 0; > 29 foreach(s; data) > 30 width = max(width, s.length); > 31 > 32 // space padding and sentinels > 33 foreach(ref s; data) { > 34 int p = s.length; > 35 s.length = width; > 36 s[p..$] = ' '; > 37 s = '#' ~ s ~ '#'; > 38 } > 39 > 40 // vertical sentinel > 41 char[] sen = new char[width+2]; > 42 sen[] = '#'; > 43 data = sen.dup ~ data ~ sen; > 44 > 45 // flooding > 46 water = H-1; > 47 while( (line=input.readln()).length ) { > 48 string[] ss = line.split(); > 49 if(ss.length==2 && ss[0]=="Water") > 50 water = H-1 - ss[1].to!int(); > 51 else if(ss.length==2 && ss[0]=="Flooding") > 52 flooding = ss[1].to!int(); > 53 else if(ss.length==2 && ss[0]=="Waterproof") > 54 water_proof = ss[1].to!int(); > 55 } > 56 } > 57 > 58 @property const > 59 { > 60 int W() { return data[0].length; } > 61 int H() { return data.length; } > 62 string toString() { > 63 string result; > 64 foreach(i,s; data) { > 65 if(i) result ~= '\n'; > 66 result ~= s.idup; > 67 } > 68 return result; > 69 } > 70 } > 71 > 72 int command_R() { if(dead)return 0; write("R"); return move(0, +1); } > 73 int command_L() { if(dead)return 0; write("L"); return move(0, -1); } > 74 int command_U() { if(dead)return 0; write("U"); return move(-1, 0); } > 75 int command_D() { if(dead)return 0; write("D"); return move(+1, 0); } > 76 int wait() { if(dead)return 0; update(); write("W"); return -1; } > 77 int abort() { if(dead)return 0; cleared=true; write("A"); return gained* > 78 > 79 int move(int dy, int dx) { > 80 foreach(y,s; data) > 81 foreach(x,c; s) > 82 if(c == 'R') > 83 return move(dy, dx, y, x); > 84 assert(false); > 85 } > 86 > 87 int gained = 0; // TODO: atode naosu > 88 int move(int dy, int dx, int y, int x) { > 89 if(dead) > 90 return 0; > 91 int score = 0; > 92 if(data[y+dy][x+dx]=='\\') { > 93 score += 25; > 94 ++gained; > 95 } > 96 if(data[y+dy][x+dx]=='O') { > 97 score += gained*50; > 98 cleared = true; > 99 } > 100 > 101 if(data[y+dy][x+dx]==' ' || data[y+dy][x+dx]=='.' > 102 || data[y+dy][x+dx]=='\\' || data[y+dy][x+dx]=='O') { > 103 data[y][x]=' '; > 104 data[y+dy][x+dx]='R'; > 105 } else if(dy==0 && data[y+dy][x+dx]=='*' && data[y+2*dy][x+2*dx] > 106 data[y][x]=' '; > 107 data[y+dy][x+dx]='R'; > 108 data[y+2*dy][x+2*dx]='*'; > 109 } > 110 update(); > 111 return score-1; > 112 } > 113 > 114 void update() { > 115 char[][] next; > 116 foreach(y,s; data) > 117 next ~= s.dup; > 118 > 119 bool lambda = false; > 120 for(int y=1; y+1<H; ++y) > 121 for(int x=1; x+1<W; ++x) > 122 lambda |= (data[y][x] == '\\'); > 123 > 124 for(int y=H-2; y>=1; --y) > 125 for(int x=1; x+1<W; ++x) { > 126 if(data[y][x]=='*') { > 127 if(data[y+1][x]==' ') { > 128 next[y][x]=' '; > 129 next[y+1][x]='*'; > 130 if(next[y+2][x]=='R') > 131 dead=true; > 132 } > 133 else if(data[y+1][x]=='*' && data[y][x+1]==' ' & > 134 next[y][x]=' '; > 135 next[y+1][x+1]='*'; > 136 if(next[y+2][x+1]=='R') > 137 dead=true; > 138 } > 139 else if(data[y+1][x]=='*' && data[y][x-1]==' ' & > 140 next[y][x]=' '; > 141 next[y+1][x-1]='*'; > 142 if(next[y+2][x-1]=='R') > 143 dead=true; > 144 } > 145 else if(data[y+1][x]=='\\' && data[y][x+1]==' ' > 146 next[y][x]=' '; > 147 next[y+1][x+1]='*'; > 148 if(next[y+2][x+1]=='R') > 149 dead=true; > 150 } > 151 } > 152 else if(data[y][x]=='L') { > 153 if(!lambda) > 154 next[y][x] = 'O'; > 155 } > 156 } > 157 data = next; > 158 > 159 if(flooding) { > 160 bool wa = false; > 161 for(int y=water; y+1<H; ++y) > 162 for(int x=1; x+1<W; ++x) > 163 if(data[y][x]=='R') { > 164 wa = true; > 165 underwater++; > 166 if(underwater > water_proof) > 167 dead = true; > 168 } > 169 flooding_counter ++; > 170 if(flooding_counter == flooding) { > 171 flooding_counter = 0; > 172 water --; > 173 } > 174 } > 175 } > 176 > 177 int clever() > 178 { > 179 if(dead) > 180 return 0; > 181 int sy,sx; > 182 int[] ly,lx; > 183 int oy,ox; > 184 for(int y=0; y<H; ++y) > 185 for(int x=0; x<W; ++x) > 186 if(data[y][x]=='R') > 187 sy=y, sx=x; > 188 else if(data[y][x]=='\\') > 189 ly~=y, lx~=x; > 190 else if(data[y][x]=='O') > 191 oy=y, ox=x; > 192 if(ly.length==0) { > 193 auto r = search(sy,sx,oy,ox); > 194 switch(r[0]) { > 195 case 'D': return command_D(); > 196 case 'U': return command_U(); > 197 case 'L': return command_L(); > 198 case 'R': return command_R(); > 199 case 'A': return abort(); > 200 default: return wait(); > 201 } > 202 } else { > 203 Tuple!(char,int)[] cand; > 204 for(int i=0; i<ly.length; ++i) { > 205 auto r = search(sy,sx,ly[i],lx[i]); > 206 cand ~= r; > 207 } > 208 sort!((Tuple!(char,int) c1, Tuple!(char,int) c2){ > 209 if(c1[1] != c2[1]) > 210 return c1[1] < c2[1]; > 211 return c1[0] < c2[0]; > 212 })(cand); > 213 switch(cand[0][0]) { > 214 case 'D': return command_D(); > 215 case 'U': return command_U(); > 216 case 'L': return command_L(); > 217 case 'R': return command_R(); > 218 case 'A': return abort(); > 219 default: return wait(); > 220 } > 221 } > 222 return wait(); > 223 } > 224 Tuple!(char,int) search(int sy, int sx, int oy, int ox) > 225 { > 226 alias Tuple!(int,"y",int,"x") Pt; > 227 Pt[] q = [Pt(oy,ox)]; > 228 bool[][] v = new bool[][](H,W); > 229 for(int step=1; q.length; ++step) { > 230 Pt[] q2; > 231 foreach(p; q) { > 232 int[] dy=[-1,+1,0,0]; > 233 int[] dx=[0,0,-1,+1]; > 234 for(int i=0; i<4; ++i) { > 235 int y = p.y+dy[i]; > 236 int x = p.x+dx[i]; > 237 if(v[y][x]) continue; > 238 if(y==sy && x==sx) { > 239 if(i==0) return tuple('D',step); > 240 if(i==1) return tuple('U',step); > 241 if(i==2) return tuple('R',step); > 242 if(i==3) return tuple('L',step); > 243 } else if(data[y][x]==' '||data[y][x]==' > 244 q2 ~= Pt(y,x); > 245 v[y][x]=true; > 246 } else if(data[y][x]=='.' && data[y-1][x > 247 q2 ~= Pt(y,x); > 248 v[y][x]=true; > 249 } > 250 } > 251 } > 252 q = q2; > 253 } > 254 q = [Pt(oy,ox)]; > 255 v = new bool[][](H,W); > 256 for(int step=1<<10; q.length; ++step) { > 257 Pt[] q2; > 258 foreach(p; q) { > 259 > 260 int[] dy=[-1,+1,0,0]; > 261 int[] dx=[0,0,-1,+1]; > 262 for(int i=0; i<4; ++i) { > 263 int y = p.y+dy[i]; > 264 int x = p.x+dx[i]; > 265 if(v[y][x]) continue; > 266 if(y==sy && x==sx) { > 267 if(i==0) return tuple('D',step); > 268 if(i==1) return tuple('U',step); > 269 if(i==2) return tuple('R',step); > 270 if(i==3) return tuple('L',step); > 271 } else if(data[y][x]==' '||data[y][x]==' > 272 q2 ~= Pt(y,x); > 273 v[y][x]=true; > 274 } else if(data[y][x]=='.'/* && data[y-1] > 275 q2 ~= Pt(y,x); > 276 v[y][x]=true; > 277 } > 278 } > 279 } > 280 q = q2; > 281 } > 282 return tuple('A',int.max); > 283 } > 284 } > 285 > 286 class MyForm : Form > 287 { > 288 Map m; > 289 int score; > 290 > 291 this(Map m) > 292 { > 293 noMessageFilter(); > 294 this.m = m; > 295 this.text = .text("Score: ", score, " air[",m.water_proof-m.und > 296 this.keyDown ~= &myKey; > 297 this.score = 0; > 298 } > 299 override void onResize(EventArgs ev) { > 300 invalidate(); > 301 } > 302 override void onPaint(PaintEventArgs ev) > 303 { > 304 int Z = min(this.clientSize.width/(m.W-2), this.clientSize.heigh > 305 Font font = new Font("MS Gothic", Z-4); > 306 Graphics g = ev.graphics; > 307 g.fillRectangle(Color(0,233,255), Rect(0,Z*(m.water-1),this.clie > 308 for(int y=1; y+1<m.H; ++y) > 309 for(int x=1; x+1<m.W; ++x) { > 310 if(m.data[y][x]=='*') { > 311 g.drawText("岩", font, Color(0,0,0), Rect((x-1)*Z > 312 } > 313 if(m.data[y][x]=='\\') { > 314 g.drawText("λ", font, Color(0,255,0), Rect((x-1) > 315 } > 316 if(m.data[y][x]=='R') { > 317 if(m.dead) > 318 g.drawText("Я", font, Color(255,0,0), Re > 319 else > 320 g.drawText("R", font, Color(128,128,0), > 321 } > 322 if(m.data[y][x]=='L') { > 323 g.drawText("扉", font, Color(255,255,0), Rect((x- > 324 } > 325 if(m.data[y][x]=='O') { > 326 g.drawText("外", font, Color(255,255,0), Rect((x- > 327 } > 328 if(m.data[y][x]=='#') { > 329 g.drawText("#", font, Color(0,0,0), Rect((x-1)*Z > 330 } > 331 if(m.data[y][x]=='.') { > 332 g.drawText("・", font, Color(128,40,0), Rect((x-1 > 333 } > 334 } > 335 } > 336 void myKey(Control c, KeyEventArgs ev) > 337 { > 338 switch(ev.keyCode) > 339 { > 340 case Keys.DOWN: > 341 score += m.command_D(); > 342 stdout.flush(); > 343 break; > 344 case Keys.UP: > 345 score += m.command_U(); > 346 stdout.flush(); > 347 break; > 348 case Keys.LEFT: > 349 score += m.command_L(); > 350 stdout.flush(); > 351 break; > 352 case Keys.RIGHT: > 353 score += m.command_R(); > 354 stdout.flush(); > 355 break; > 356 case Keys.W: > 357 score += m.wait(); > 358 stdout.flush(); > 359 break; > 360 case Keys.A: > 361 score += m.abort(); > 362 stdout.flush(); > 363 break; > 364 case Keys.G: > 365 score += m.clever(); > 366 stdout.flush(); > 367 break; > 368 default: > 369 break; > 370 } > 371 if(m.cleared) { > 372 writeln(); > 373 writeln("Score: ", score); > 374 Application.exit(); > 375 } > 376 this.text = .text("Score: ", score, " air[",m.water_proof-m.und > 377 invalidate(); > 378 } > 379 } > 380 > 381 extern(C) { > 382 void sigint(int) { > 383 write("A"); > 384 stdout.flush(); > 385 exit(0); > 386 } > 387 } > 388 > 389 void main(string[] args) > 390 { > 391 signal(SIGINT, &sigint); > 392 > 393 Form myForm = new MyForm(new Map(File(args[1]))); > 394 Application.run(myForm); > 395 }

Modified src/util.d from [b76be1f6ad977d56] to [8d98b81c5616ea88].

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

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