Check-in [897b5005ac]
Not logged in
Overview
SHA1 Hash:897b5005ac3a207c9b9075572081d29b835d54bf
Date: 2012-07-14 20:25:05
User: kinaba
Comment:Remove experimental code.
Timelines: family | ancestors | descendants | both | trunk
Diffs: redesign
Downloads: Tarball | ZIP archive
Other Links: files | file ages | manifest
Tags And Properties
Changes

Deleted 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 } <