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*25; } 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]==' ' && data[y+1][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]==' ' && data[y+1][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]==' ' && data[y+1][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][x]!='*'*/) { 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.underwater,"]"); 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.height/(m.H-2)); 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.clientSize.width,this.clientSize.height-(Z*(m.water-1)))); 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, (y-1)*Z, Z, Z)); 312 - } 313 - if(m.data[y][x]=='\\') { 314 - g.drawText("λ", font, Color(0,255,0), Rect((x-1)*Z, (y-1)*Z, Z, Z)); 315 - } 316 - if(m.data[y][x]=='R') { 317 - if(m.dead) 318 - g.drawText("Я", font, Color(255,0,0), Rect((x-1)*Z, (y-1)*Z, Z, Z)); 319 - else 320 - g.drawText("R", font, Color(128,128,0), Rect((x-1)*Z, (y-1)*Z, Z, Z)); 321 - } 322 - if(m.data[y][x]=='L') { 323 - g.drawText("扉", font, Color(255,255,0), Rect((x-1)*Z, (y-1)*Z, Z, Z)); 324 - } 325 - if(m.data[y][x]=='O') { 326 - g.drawText("外", font, Color(255,255,0), Rect((x-1)*Z, (y-1)*Z, Z, Z)); 327 - } 328 - if(m.data[y][x]=='#') { 329 - g.drawText("#", font, Color(0,0,0), Rect((x-1)*Z, (y-1)*Z, Z, Z)); 330 - } 331 - if(m.data[y][x]=='.') { 332 - g.drawText("・", font, Color(128,40,0), Rect((x-1)*Z, (y-1)*Z, Z, Z)); 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.underwater,"]"); 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 -}