commit ddc3808

ohmu  ·  2026-09-07 04:18:39 +0300 MSK
parent 9c4bcfd
added sokoban
19 files changed,  +4329, -0
+23, -0
 1@@ -0,0 +1,23 @@
 2+If you click with mouse button 1
 3+on a (destination) square then the following may happen.
 4+
 5+If
 6+ - the destination square is on the same row or column as glenda, and
 7+ - there is a ball next to glenda
 8+   (in the direction of the destination square), and
 9+ - all squares between the ball and the destination square
10+   (where glenda will move) are empty, and
11+ - the square next to the destination square where glenda will
12+   push the ball is empty too, 
13+then glenda will move to the destination square, pushing the
14+ball while moving.
15+
16+Otherwise, if glenda can go to the destination square
17+without touching anything, it will do so.
18+
19+Otherwise, nothing will happen.
20+
21+The breadth-first search algorithm should find a fast route.
22+it can be seen in action by toggling the 'animate'
23+entry in the button 3 menu.
24+
+60, -0
 1@@ -0,0 +1,60 @@
 2+#include <u.h>
 3+#include <libc.h>
 4+#include <draw.h>
 5+
 6+#include "sokoban.h"
 7+
 8+void
 9+initanimation(Animation *a)
10+{
11+	if (a == nil)
12+		return;
13+
14+	memset(a, 0, sizeof(Animation));
15+}
16+
17+void
18+setupanimation(Animation *a, Route *r)
19+{
20+	if (a == nil || r == nil || r->step == nil)
21+		return;
22+
23+	a->route = r;
24+	a->step = r->step;
25+	if (a->step < a->route->step + a->route->nstep)
26+		a->count = a->step->count;
27+	else
28+		stopanimation(a);
29+}
30+
31+int
32+onestep(Animation *a)
33+{
34+	if (a == nil)
35+		return 0;
36+
37+	if (a->count > 0 && a->step != nil && a->route != nil) {
38+		move(a->step->dir);
39+		a->count--;
40+		if (a->count == 0) {
41+			a->step++;
42+			if (a->step < a->route->step + a->route->nstep)
43+				a->count = a->step->count;
44+			else
45+				stopanimation(a);
46+		}
47+	} else if (a->count > 0 && (a->step == nil || a->route == nil))
48+		stopanimation(a);
49+	return (a->count > 0);
50+}
51+
52+void
53+stopanimation(Animation *a)
54+{
55+	if (a == nil)
56+		return;
57+
58+	if (a->route != nil)
59+		freeroute(a->route);
60+	memset(a, 0, sizeof(Animation));
61+}
+125, -0
  1@@ -0,0 +1,125 @@
  2+#include <u.h>
  3+#include <libc.h>
  4+#include <draw.h>
  5+#include <event.h>
  6+
  7+#include "sokoban.h"
  8+
  9+void
 10+drawscreen(void)
 11+{
 12+	draw(screen, screen->r, img, nil, ZP);
 13+	flushimage(display, 1);
 14+}
 15+
 16+void
 17+drawglenda(void)
 18+{
 19+	Rectangle r;
 20+	Point p;
 21+
 22+	p = level.glenda;
 23+	p.x *= BoardX;
 24+	p.y *= BoardY;
 25+	/* leave some room from the edge of the window */
 26+	p = addpt(p, Pt(1, 1));
 27+
 28+	r = Rpt(p, Pt(p.x + BoardX, p.y+BoardY));
 29+	draw(img, r, glenda, nil, ZP);
 30+}
 31+
 32+void
 33+drawwin(void)
 34+{
 35+	Rectangle r;
 36+	Point p;
 37+
 38+	p = level.glenda;
 39+	p.x *= BoardX;
 40+	p.y *= BoardY;
 41+	p = addpt(p, Pt(6, 6));
 42+	p = addpt(p, Pt(1, 1));
 43+
 44+	r = Rpt(p, Pt(p.x + BoardX, p.y+BoardY));
 45+	draw(img, r, text, win, ZP);
 46+}
 47+
 48+void
 49+drawboard(Point p)
 50+{
 51+	Rectangle r;
 52+	uint square = level.board[p.x][p.y];
 53+
 54+	p.x *= BoardX;
 55+	p.y *= BoardY;
 56+
 57+	/* leave some room from the edge of the window */
 58+	p = addpt(p, Pt(1, 1));
 59+
 60+	r = Rpt(p, Pt(p.x + BoardX, p.y+BoardY));
 61+
 62+	switch(square) {
 63+	case Background:
 64+		draw(img, r, bg, nil, ZP);
 65+		break;
 66+	case Empty:
 67+		draw(img, r, empty, nil, ZP);
 68+		break;
 69+	case Wall:
 70+		draw(img, r, wall, nil, ZP);
 71+		break;
 72+	case Cargo:
 73+		draw(img, r, cargo, nil, ZP);
 74+		break;
 75+	case Goal:
 76+		draw(img, r, goal, nil, ZP);
 77+		break;
 78+	case GoalCargo:
 79+		draw(img, r, goalcargo, nil, ZP);
 80+		break;
 81+	}
 82+}
 83+
 84+void
 85+resize(Point p)
 86+{
 87+	/* resize to the size of the current level */
 88+
 89+	int fd;
 90+
 91+	fd = open("/dev/wctl", OWRITE);
 92+	if(fd >= 0){
 93+		fprint(fd, "resize -dx %d -dy %d", p.x*BoardX+10, p.y*BoardY+10);
 94+		close(fd);
 95+	}
 96+
 97+}
 98+
 99+Point
100+boardsize(Point p)
101+{
102+	return Pt(p.x*BoardX+2, p.y*BoardY+2);
103+}
104+
105+void
106+drawlevel(void)
107+{
108+	int x, y;
109+
110+	resize(level.max);
111+
112+	if(img)
113+		freeimage(img);
114+	img = eallocimage(Rpt(Pt(0, 0), boardsize(level.max)), 0, 0);	
115+
116+	draw(img, insetrect(img->r, 1), empty, nil, ZP);
117+
118+	for(x = 0; x < MazeX; x++) {
119+		for(y = 0; y < MazeY; y++) {
120+			drawboard(Pt(x, y));
121+		}
122+	}
123+
124+	drawglenda();
125+}
126+
+0, -0
+0, -0
+0, -0
+0, -0
+0, -0
+0, -0
+0, -0
+0, -0
+102, -0
  1@@ -0,0 +1,102 @@
  2+#include <u.h>
  3+#include <libc.h>
  4+#include <bio.h>
  5+#include <draw.h>
  6+
  7+#include "sokoban.h"
  8+
  9+void
 10+consumeline(Biobuf *b)
 11+{
 12+	while(Bgetc(b) != '\n')
 13+		;
 14+}
 15+
 16+/* parse a level file */
 17+int
 18+loadlevels(char *path)
 19+{
 20+	Biobuf *b;
 21+	int x = 0, y = 0, lnum = 0;
 22+	char c;
 23+		
 24+	if(path == nil)
 25+		return 0;
 26+
 27+	b = Bopen(path, OREAD);
 28+	if(b == nil) {
 29+		fprint(2, "could not open file %s: %r\n", path);
 30+		return 0;
 31+	}
 32+
 33+	memset(levels, 0, Maxlevels*sizeof(Level));
 34+	
 35+	while((c = Bgetc(b)) > 0) {
 36+		switch(c)  {
 37+		case ';':
 38+			consumeline(b); 	/* no ';'-comments in the middle of a level */
 39+			break;
 40+		case '\n':
 41+			levels[lnum].index = lnum;
 42+			levels[lnum].done = 0;
 43+			x = 0;
 44+			levels[lnum].max.y = ++y;
 45+
 46+			c = Bgetc(b);
 47+			if(c == '\n' || c == Beof) {
 48+				/* end of level */
 49+				if(++lnum == Maxlevels)
 50+					goto Done;
 51+
 52+				x = 0;
 53+				y = 0;
 54+			} else
 55+				Bungetc(b);
 56+			break;
 57+		case '#':
 58+			levels[lnum].board[x][y] = Wall;
 59+			x++;
 60+			break;
 61+		case ' ':
 62+			levels[lnum].board[x][y] = Empty;
 63+			x++;
 64+			break;
 65+		case '$':
 66+			levels[lnum].board[x][y] = Cargo;
 67+			x++;
 68+			break;
 69+		case '*':
 70+			levels[lnum].board[x][y] = GoalCargo;
 71+			x++;
 72+			break;
 73+		case '.':
 74+			levels[lnum].board[x][y] = Goal;
 75+			x++;
 76+			break;
 77+		case '@':
 78+			levels[lnum].board[x][y] = Empty;
 79+			levels[lnum].glenda = Pt(x, y);
 80+			x++;
 81+			break;
 82+		case '+':
 83+			levels[lnum].board[x][y] = Goal;
 84+			levels[lnum].glenda = Pt(x, y);
 85+			x++;
 86+			break;
 87+		default:
 88+			fprint(2, "impossible character for level %d: %c\n", lnum+1, c);
 89+			return 0;
 90+		}
 91+		if(x > levels[lnum].max.x)
 92+			levels[lnum].max.x = x;
 93+		levels[lnum].max.y = y;
 94+	}
 95+Done:
 96+	Bterm(b);
 97+
 98+	level = levels[0];
 99+	numlevels = lnum;
100+
101+	return 1;
102+}
103+
+1549, -0
   1@@ -0,0 +1,1549 @@
   2+; #1
   3+ #####
   4+ #   ####
   5+ #   #  #
   6+ ##    .#
   7+### ###.#
   8+# $ # #.#
   9+# $$# ###
  10+#@  #
  11+#####
  12+
  13+; #2
  14+  #######
  15+  #     #
  16+  # $ @ #
  17+##### # #
  18+# $     #
  19+#  #$## ##
  20+#..$  #  #
  21+#..      #
  22+##########
  23+
  24+; #3
  25+######
  26+#..*.#
  27+#.$  #
  28+## $ #
  29+##$ ##
  30+#@$ #
  31+##  #
  32+ ####
  33+
  34+; #4
  35+########
  36+#.   $ #
  37+#.$  # #
  38+#.# #  #
  39+### # ##
  40+ # $  #
  41+ #@ ###
  42+ #####
  43+
  44+; #5
  45+ ########
  46+##..#   #
  47+# ..# $ ##
  48+# @ $  $ #
  49+##$###   #
  50+ #     ###
  51+ #######
  52+
  53+; #6
  54+ #######
  55+ #     ####
  56+ # ###.   #
  57+##    # # #
  58+# .#$ $ # #
  59+# #  *  # #
  60+# # $ $#. #
  61+# # #    ##
  62+#   .### ##
  63+####      #
  64+   #####  #
  65+       #@ #
  66+       ####
  67+
  68+; #7
  69+#########
  70+#.....  #
  71+### $ # ##
  72+  # $##  #
  73+  #$ $ $ #
  74+  #   #  #
  75+  ##  # @#
  76+   #######
  77+
  78+; #8
  79+    #####
  80+#####   #
  81+#.. $ $ ##
  82+#..$ $  @#
  83+##. $## ##
  84+ ###    #
  85+   ######
  86+
  87+; #9
  88+###########
  89+#     # @ #
  90+# $  $  $ #
  91+## #...# ##
  92+ # #...# #
  93+ #$ ### $#
  94+ #   $   #
  95+ #  ##   #
  96+ #########
  97+
  98+; #10
  99+   ####
 100+####  #
 101+# $...##
 102+#@ $.. #
 103+###$$$ #
 104+  #    #
 105+  ######
 106+
 107+; #11
 108+ ##########
 109+##    # @ ##
 110+#  $.... $ #
 111+# $ ####$  #
 112+##  #  #   #
 113+ ####  #####
 114+
 115+; #12
 116+    ########
 117+    #      #########
 118+##### #### #@##  ..#
 119+# $  $           ..#
 120+#   # ### #####  ..#
 121+### # ### #   ######
 122+  #  $  $ #
 123+  ###  $###
 124+    #$  #
 125+    #   #
 126+    #####
 127+
 128+; #13
 129+  #####
 130+  #   ##
 131+### *$ #
 132+#  .$. #
 133+#  $. ##
 134+###  @#
 135+  #####
 136+
 137+; #14
 138+  ########
 139+  #      #   ######
 140+  #$ $ $ #   #  ..#
 141+###  $  $#####  ..##
 142+#  $$$   $      ...#
 143+# #  $ ####@##  ..##
 144+# #  $ #  ####  ..#
 145+#    ###     ######
 146+######
 147+
 148+; #15
 149+########
 150+#  @   #
 151+#  #$$ #
 152+## $  ##
 153+ #  $.#
 154+ ## .##
 155+  #..#
 156+  ####
 157+
 158+; #16
 159+#########
 160+#   #   ##
 161+# $$#$$ @#
 162+#    $  ##
 163+#   # ##############
 164+####  $ #     #....#
 165+   # $$ #$ $ $#....#
 166+   #  $     $ #....#
 167+   # $$$#$  $ #  ..#
 168+   #    #  $ $   ..#
 169+   ############  ..#
 170+              #  ..#
 171+              ######
 172+
 173+; #17
 174+   #######
 175+   #  @  #
 176+#### # $ #
 177+#...$#$ ##
 178+#... $   #
 179+### $ ## #
 180+  # $    #
 181+  #    ###
 182+  ######
 183+
 184+; #18
 185+      ####
 186+#######@ #
 187+#   #    #
 188+#   $  $ #
 189+## ##$# ##
 190+ #  $ #*.#
 191+ ##  $...#
 192+  #   #. #
 193+  ########
 194+
 195+; #19
 196+ ########
 197+ # @    #
 198+##  ..$ #
 199+#  #..###
 200+# $$$##
 201+#    #
 202+######
 203+
 204+; #20
 205+########
 206+#  #   #
 207+# $..$ #
 208+#@$.* ##
 209+# $..$ #
 210+#  #   #
 211+########
 212+
 213+; #21
 214+   #####
 215+#### @ ###
 216+#    #   #
 217+# $$  #$ #
 218+#  $#$ $ #
 219+###...$###
 220+ #.... #
 221+ #######
 222+
 223+; #22
 224+ ###  ####
 225+##.####  ##
 226+#...  #  @###
 227+##..     $  #
 228+#...  # $ $ #
 229+##.###### ######
 230+ ###    # $ $  #
 231+       ## $ $# #
 232+       #   $   #
 233+       #  $ $# #
 234+       # # # # #
 235+       #       #
 236+       #########
 237+
 238+; #23
 239+#######
 240+#  #@ #
 241+# $$$ #
 242+#  $  #
 243+# $$$ #
 244+#..#..#
 245+#..$..#
 246+#######
 247+
 248+; #24
 249+########
 250+#  ##  #
 251+#  ##$ #
 252+#  $   ##
 253+## #    ##
 254+ # ## #  #
 255+ # $ $## #  ####
 256+## ##    ####..#
 257+# $ #$ #$##  ..#
 258+#      $     ..#
 259+########@##  ..#
 260+       #########
 261+
 262+; #25
 263+  ######
 264+  #  @ #
 265+  # $  #
 266+#### $ #
 267+# .#$ ##
 268+#..# $#
 269+#..$  ##
 270+#.. $  #
 271+####$  #
 272+   #   #
 273+   #####
 274+
 275+; #26
 276+       #####
 277+      ##   #
 278+      #  $ #####
 279+      # $ $    #
 280+      ### #### ##
 281+ ######## $    @#
 282+##...  ## $$## ##
 283+#....       ## #
 284+##...  #### ## #
 285+ ######## $ $  #
 286+        #  $ $ #
 287+        #      #
 288+        ########
 289+
 290+; #27
 291+ ########
 292+ #  #  @#
 293+ #$  $  #
 294+ # ## $ #
 295+##...$ ##
 296+# ...# #
 297+# #$$  #
 298+#      #
 299+########
 300+
 301+; #28
 302+  ######
 303+  #....#
 304+  #  ..#
 305+###$$#####
 306+# $   $ @#
 307+#   $ $  #
 308+###   ####
 309+  #####
 310+
 311+; #29
 312+ #######
 313+ #     ##
 314+ # $  $ #
 315+ ## # #@#
 316+  #.# $ #
 317+###..$ ##
 318+#  ..# #
 319+# #.*# ###
 320+#  #.$$$ #
 321+##   # # #
 322+ ###     #
 323+   #######
 324+
 325+; #30
 326+  ####
 327+  #  ####   ####
 328+  #     #####  #
 329+  #  $$$       #
 330+  ## #  #  # # #
 331+   #$ $ ####$# #
 332+   # $####     #
 333+####  #  #  ## ####
 334+# @$$    ## # ....#
 335+# #  $$ ### # ....#
 336+# $ $  $    # ....#
 337+# ## $  ##  # ....#
 338+#    $  ###########
 339+######  #
 340+     ####
 341+
 342+; #31
 343+  ############
 344+  #    #     #
 345+  # $  $ $ $ #
 346+###### ##$ $ #
 347+#..  # #  $ ##
 348+#..    @ ##  #
 349+#..  #$####  #
 350+#..  # $  $  #
 351+#..  #     ###
 352+############
 353+
 354+; #32
 355+      #######
 356+     ##@#   #
 357+    ##  # $ #
 358+ ####  # $  #
 359+ #    # $ # ##
 360+ #   # $  #  #
 361+ #  # $  #   #
 362+ # # $  #    #
 363+##  $  ### # #
 364+#  $  ##...# #
 365+#   ##.....  #
 366+########  ####
 367+       ####
 368+
 369+; #33
 370+########
 371+#....  ##########
 372+##...    $  $   #
 373+#....  ## $  $  #
 374+######### $ # ###
 375+        ##$ $ #
 376+        # $  $#
 377+        # $#$ ##
 378+        #     @#
 379+        ########
 380+
 381+; #34
 382+############
 383+#...#  @#  ##
 384+#...#$$  $  #
 385+#...   ##  $#
 386+#   # ##    ###
 387+#####  $ #$$  #
 388+  # $ $       #
 389+  #   #########
 390+  #####
 391+
 392+; #35
 393+   #########
 394+   #  ##   #
 395+   # $  $  #
 396+   #  $# $ #
 397+#### $ #$  #
 398+#..### # $ #
 399+#..  # # $ #
 400+#..     $$ #
 401+#..  ###   #
 402+#..  # ##@##
 403+######  ###
 404+
 405+; #36
 406+          #########
 407+######## ##   #   #
 408+#...#  ###  $  $  #
 409+#...#    @ # ### ##
 410+#...    # ##  #   #
 411+#  ### $#$  $  $  #
 412+##      # #  ## ###
 413+ #### #$$ ## ##  #
 414+    #   #   $    #
 415+    #####  #  ####
 416+        #######
 417+
 418+; #37
 419+           #####
 420+ ###########   #
 421+ #     $    ...#
 422+ #$$#  #####...#
 423+##  #$ #   #...#
 424+#  $   #   #...#
 425+#@#$$ ##   #...#
 426+# $    #   #...#
 427+##  $$ ######.##
 428+ # $ $ #   #   #
 429+ #$ $ $ $ $    #
 430+ #  ## #  $$# ##
 431+ #     ###    #
 432+ ####### ######
 433+
 434+; #38
 435+############
 436+###..##    #
 437+##....#  $ #
 438+#.....# $# #
 439+####.. $ #@#
 440+#   ..# ####
 441+# $# $#    #
 442+#  #  #  $ #
 443+#   # # $ ##
 444+# $$$ # ####
 445+#   $ #    #
 446+#### ## $$ #
 447+##   $   $ #
 448+##     ##  #
 449+############
 450+
 451+; #39
 452+        ####
 453+        #  #
 454+        #  #
 455+        #  #
 456+     #### ###
 457+     # $    #
 458+###### $$ $ #####
 459+#@ $  $    $  $ #
 460+##   #$ $   #   #
 461+ #####  $ $ #####
 462+     # $$$ ##
 463+     ### ########
 464+      ## ##  ...#
 465+      #  ##  ...#
 466+      #      ...#
 467+      #####  ...#
 468+          #  ...#
 469+          #######
 470+
 471+; #40
 472+####      ####
 473+#..########..#
 474+#.*.*.....*.*#
 475+#$ $ $ $ $ $ #
 476+# $ $ $ $ $ $#
 477+#$ $ $@$ $ $ #
 478+# $ $ $ $ $ $#
 479+#*.*.....*.*.#
 480+#..########..#
 481+####      ####
 482+
 483+; #41
 484+   ####
 485+   #  #####
 486+ ###$ $   ###
 487+ #  $ #  $  #
 488+ #    ## ## ##
 489+ #  ###  ##  #
 490+ # #  $ $ ## #
 491+ #$  $ $ $#  #
 492+## ###  $    #
 493+#     #$ ##$ #
 494+# ....#  #  ##
 495+##....# # @##
 496+ #.#.#  $ ##
 497+ #....   ##
 498+ #########
 499+
 500+; #42
 501+    ######
 502+    #....####
 503+    #....#  #
 504+    #...  $ #
 505+#####   #   #
 506+#   #####$####
 507+#   #      # #
 508+## $  $#     #
 509+ #$ ## # $ $ #
 510+ #  $   ####$##
 511+ # # #  ####  #
 512+## $       $  #
 513+#@  ########  #
 514+#####      ####
 515+
 516+; #43
 517+######
 518+#    ######  ####
 519+# $  $ #  ####  ##
 520+#  $   # $$      #
 521+##   $$#  ### #  #
 522+ # $#  ## ##  #  #
 523+ #$ $  $@$ # ##  ##
 524+ #  #  #   # #....#
 525+ # $ $ ##$## #....#
 526+ ##   # #  # #....#
 527+  ##### #  $ #....#
 528+        #  # ######
 529+        ######
 530+
 531+; #44
 532+      ####
 533+      #  #
 534+      #$ ###
 535+      #   ###
 536+ ######$ $  #
 537+ #... # $   #
 538+ #....  $$ ##
 539+ #....#   $#
 540+ #....#$ $ #
 541+#### ##   $#
 542+#@$ $ # $  #
 543+## $  ## ###
 544+ ##     $#
 545+  #####  #
 546+      ####
 547+
 548+; #45
 549+    #########
 550+    #.......#
 551+    #.......#
 552+    #.......#
 553+    #### $###
 554+     #  $  ##
 555+     # $ $  #
 556+ ###### # # ###
 557+ #  ## $ $ $  #
 558+## $$         #
 559+#   #####$##$##
 560+#   $     $ $ ###
 561+######## $#     #
 562+     #  $ #  #  #
 563+     #   @#$  $ #
 564+     ## $ $   $ #
 565+      ########  #
 566+             ####
 567+
 568+; #46
 569+######
 570+#....#
 571+#....#
 572+##   ############
 573+ #   #  #   #   #
 574+ ## ## $ $ $$   #
 575+  #    @# # #####
 576+  #  ##$# $  #
 577+  ####   $   #
 578+  #  $   #####
 579+  #      #
 580+  ########
 581+
 582+; #47
 583+       #######
 584+########.....#
 585+# $   $ .....####
 586+#  $ $ #.....   #
 587+##  ## #.....#  #
 588+ #  $  ###$### ##
 589+ # $  $  $   $ #
 590+ #$####  $   $ #
 591+ #   #  $# #####
 592+ ###   $$ $ $  #
 593+   #### $  $   #
 594+     #@  #######
 595+     #####
 596+
 597+; #48
 598+   #####
 599+   #...#
 600+   #...##
 601+   #....####
 602+ ####......####
 603+ #  #....     #
 604+##  ###  ###$ #
 605+# $ $ #$#  #  #
 606+# $    $  $## ####
 607+#  #  # #   $$$  #
 608+##  $## #$ $     #
 609+ #$  $  # $ $#  ##
 610+ #  $# $ $   ####
 611+ ##  ## @#   #
 612+  #  #########
 613+  ####
 614+
 615+; #49
 616+   #####
 617+   #   ##
 618+   # #  #
 619+ ### $  #
 620+##   # ##
 621+# .#.#  #
 622+# ..*$$ #
 623+# *#.#  #
 624+##  ##$##
 625+ #$ @  #
 626+ #  ####
 627+ ####
 628+
 629+; #50
 630+      ########
 631+      #      ##
 632+ ######  ##$$@#
 633+##  #  $$ #   #
 634+##$       $ $ #
 635+#   # $########
 636+#  $#  #... .#
 637+# $ #$$ ...  #
 638+#  $#  #...  #
 639+##  #  #...###
 640+ #  #  #####
 641+ #######
 642+
 643+; #51
 644+            #####
 645+     ########   #
 646+######@#   ## # #
 647+#   ##   $      #
 648+#...   ## ### ###
 649+#..## ##    # #
 650+#..#  ##$#### ##
 651+#..# $$     #  #
 652+#..#  ## $  $  #
 653+#####  #  $ #  #
 654+    #$$ $$# ####
 655+    #       #
 656+    #########
 657+
 658+; #52
 659+########
 660+#      ######
 661+# ####      #
 662+# #  ### ## #
 663+#     $   # #
 664+# #  #    # #
 665+# #$ ### #  # ######
 666+# # #### # #### ...#
 667+# #   # $$ #  #  ..#
 668+# #   #   ##$    ..#
 669+#  $$ #     $ #  ..#
 670+###   #   ##$ ######
 671+  ##########@ #
 672+           ####
 673+
 674+; #53
 675+#####
 676+#@  #######
 677+# #$#  #  #
 678+# $    $$ #
 679+### ##$#  #
 680+ #  # .# ##
 681+ #  $..   #
 682+ #  #..## #
 683+ #####.   #
 684+     ######
 685+
 686+; #54
 687+      #####
 688+     ##   #####
 689+ ##### $  #...#
 690+ #   # # ##...#
 691+ # #   # #.. .#
 692+ #   ##   ....#
 693+####  $$$ $#  #
 694+#  # ##  $ ####
 695+#  # ## $  #
 696+# $$$ $  $$#
 697+## #@##    #
 698+## #### #  #
 699+#       ####
 700+#       #
 701+#########
 702+
 703+; #55
 704+            ########
 705+        #####   #  #
 706+      ###   #$ $ $ #
 707+     ## #     $ $  #
 708+ #####    # #$ # $ #
 709+ #  #  # ## #   #  #
 710+ #    ##### ### #$ #
 711+ # $## ...# ##  $  #
 712+ ## ## ...#  #    ##
 713+ #  ###...   ######
 714+ #  $ ....####
 715+ #  #######
 716+### $ #
 717+#@$   #
 718+##  ###
 719+ ####
 720+
 721+; #56
 722+   ######
 723+ ###    ###
 724+ #        ####
 725+ # #$$$## #  #
 726+ # #    # #  #######
 727+ # #    # # $   ...#
 728+ # #$#$## #$    ...#
 729+##         $$###...#
 730+#  #$$$## #$   #...#
 731+# #     # #    #...#
 732+# #  $  # # ## #...#
 733+#  #$#$##  #   #...#
 734+##       $   $ #...#
 735+ # #$$$# ####$##.###
 736+ # # @ #  #  $   #
 737+ #  ###   # $$ ###
 738+ ##     ###    #
 739+  ####### ######
 740+
 741+; #57
 742+####
 743+# @#
 744+# $#####
 745+#  $   ##    #####
 746+#   $#  #    #   #
 747+##   $  #    # $ #
 748+ ##$# $ #######  #
 749+  #   #$    #  ..#
 750+  # # # $## # #..#
 751+  #      $     ..#
 752+  ###########  ..#
 753+      #     #$#..#
 754+      # $      ..#
 755+      #     #   ##
 756+      ###########
 757+
 758+; #58
 759+      #####
 760+  #####   #######
 761+  #@$    $   $  #
 762+ #### #$#  ##$  #
 763+ #  #  $  $ #   #
 764+ #  ### ##  # ####
 765+ #  $ # $  #  $  #
 766+ #        ### $  #
 767+#######$ ##  $ ###
 768+#.....#  #  $  #
 769+#.....## $ #$  #
 770+#....     $   ##
 771+#...   ########
 772+########
 773+
 774+; #59
 775+#######
 776+#     #
 777+# ### ###
 778+# #  $  #
 779+# # $ $ ##
 780+# #@ #$  #######
 781+# # $# $$#  ...#
 782+# #$ #   #  ...#
 783+# #  #$     ...#
 784+# #$ #  $#  ...#
 785+#   $ $  #  ...#
 786+###  $  $#######
 787+  ### ## #
 788+    #    #
 789+    ######
 790+
 791+; #60
 792+    ###########
 793+ ####.........#
 794+ #   .*******.#
 795+ # ###.......##
 796+## # #.$$$$$.#
 797+#@ ####     ##
 798+# $  ## $$$ #
 799+# $ $  #   ##
 800+# $ $ $    #
 801+# $ $ $  ###
 802+# $ $  ###
 803+# $  ###
 804+#  ###
 805+####
 806+
 807+; #61
 808+ ###
 809+##@#########
 810+# $#   ##  #
 811+#      $   #
 812+# $##$###  ##
 813+#  ## ### ###
 814+#####.###   #
 815+    #....#  #
 816+    #....#  #
 817+    #....## ##
 818+   ### ####  #
 819+   #         #
 820+   #   #### ####
 821+   #####  $ $  #
 822+       # $ $   #
 823+       # $$$$$ #
 824+       #       #
 825+       #########
 826+
 827+; #62
 828+####  ####
 829+#  ####  #
 830+#   @    #
 831+# $$$$$$ #
 832+##      ##
 833+# $$$$$$ #
 834+#        #
 835+#  $$$$  #
 836+###    ###
 837+ # $$$$ #
 838+ #      #
 839+ #  $$  #
 840+ ###..###
 841+ #..**..#
 842+ #......#
 843+ #..##..#
 844+ #......#
 845+ ########
 846+
 847+; #63
 848+  ###########
 849+  #....   ..#
 850+  # .......##
 851+### .#....#####
 852+#  #$##..##   #
 853+#     #### $  #
 854+# $$  #  #  $ #
 855+##  $$#   $$ ##
 856+ #$  $   #$  #
 857+ # $$ #  #  $#
 858+ # $ $#### $ #
 859+ #       #  ##
 860+ #### $  # ##
 861+    ### ## #
 862+     # $   #
 863+     #@ #  #
 864+     #######
 865+
 866+; #64
 867+   ######
 868+   #    #
 869+#### ## #######
 870+# @$  $   #   ##
 871+# # $  $  # $  #
 872+#  $  ##### #  #
 873+#### ##  #### ##
 874+  #  #  ##  #  #
 875+  #            #
 876+  #######  #  ##
 877+   #..  #  ####
 878+   #..      #
 879+   #..  #   #
 880+   ##########
 881+
 882+; #65
 883+#######
 884+#.....#
 885+#...#.#
 886+#.. ..# ####
 887+#.    ###  ########
 888+#### ## $         #
 889+####    #  $$ #   #
 890+ #   $ #  # $ #####
 891+ # # $ $$ # ###
 892+ #  #$##     #
 893+ ##  $ $$## ##
 894+  ##   @  $  #
 895+   ###  ###$ #
 896+     #### #  #
 897+          ####
 898+
 899+; #66
 900+       #########
 901+       #  ##   #
 902+     ### $     #
 903+  #### @$  ##$##
 904+###  #### ### #
 905+#  $ # #.*..# #
 906+# #   $ ....# #
 907+#    # #....$ #
 908+###  # #####  #
 909+  ####    $   #
 910+     ###$  $ ##
 911+       # $$ ##
 912+       #   ##
 913+       #  ##
 914+       ####
 915+
 916+; #67
 917+##################
 918+#   ##       $...#
 919+# $ $ $#$ ####  .#
 920+# $$#$       @...#
 921+# $   #$##$$ #...#
 922+# $ $$#    $ #...#
 923+#         ## #...#
 924+##################
 925+
 926+; #68
 927+ #######
 928+ #     #
 929+ # $ $ #
 930+ # $ ####
 931+## $##  #########
 932+#   #  $  ......#
 933+# *##  #$ #  $  #
 934+#.....*.  ## $  #
 935+#.###   ##  ##$ #
 936+### ######      #
 937+      #@$  $ $$ #
 938+      ###   #   #
 939+        #########
 940+
 941+; #69
 942+              ####
 943+             ##  ###
 944+##############  $  #
 945+#........... #   $ #
 946+#.# #######. #$ $###
 947+#.# ####### ##   ##
 948+#..           $$$@#
 949+#  ######## ##    #
 950+####   #   $$ #####
 951+       # $    $ #
 952+       ## $$  $ #
 953+        ##  $$  #
 954+         ##     #
 955+          ##   ##
 956+           #####
 957+
 958+; #70
 959+      #######
 960+  #####     #
 961+###   # ##$ ##
 962+# $   #      #
 963+# $# ##$# #$ #
 964+#@ # # $  #  #
 965+# $# # $###$ #
 966+# $  $    # ##
 967+## # $# #    #
 968+# $#  ..##. .#
 969+#  ### ..#.# #
 970+#   ## ......#
 971+##############
 972+
 973+; #71
 974+        #######
 975+        #     #
 976+    #####     ###
 977+#####   ## ##...#
 978+#     # ## ##...#
 979+# ###$$$ $ ##...#
 980+# #   $ $  ##...#
 981+# # #$ $ $###...#
 982+# #   $@$   ## ##
 983+# #  $ $ $ $#  #
 984+# # ######     #
 985+#              #
 986+################
 987+
 988+; #72
 989+             ####
 990+      ########  #
 991+      #     #   #
 992+    ### ###   # #
 993+#####     $   # #
 994+#   $ $ ###$$ # #
 995+#  $ $$$  # $## #
 996+#  #$   #  $  # #
 997+##   #### ### #$##
 998+ # ###......     #
 999+ #   $......## # #
1000+ # ###......##   #
1001+ #$$ #   #########
1002+ #     # $@$ #
1003+ #######     #
1004+       #######
1005+
1006+; #73
1007+    ####     ####
1008+  ###  #######  ##
1009+  #  ........... #
1010+  # $ ##### ### $##
1011+ ####  $ $ #   $  #
1012+ #  #  # # #$# @# ##
1013+ #         #   $ $ #
1014+ #   ##   # $$$#   #
1015+##  #     #      ###
1016+#    # ##  #  ####
1017+#         #   #
1018+########  #####
1019+       ####
1020+
1021+; #74
1022+  #####
1023+  #   #
1024+###$# ###
1025+# $...  ###
1026+# #.#*#   #
1027+# $.#.$   #
1028+#  ## ## ##
1029+## @ $ $ #
1030+ ###   ###
1031+   #####
1032+
1033+; #75
1034+          #### ####
1035+          #  ###  #
1036+          #  $    #
1037+          # # $ $ #
1038+      ##### # #  ##
1039+      #.....# $$$#
1040+      #....* $   #
1041+      #*..*.# #$##
1042+#######....*# $  #
1043+#     $*.*..#    #
1044+#  $$ # ##$###$$ #
1045+#    $   #      ##
1046+#####$ $ ####  ##
1047+ #@# $        ##
1048+ #    ######  #
1049+ ######    ####
1050+
1051+; #76
1052+      #####
1053+     ##   ##
1054+    ##  *  ##
1055+   ##  * *  ##
1056+  ##  * * *  ##
1057+ ##  * * * *  ####
1058+##  * * * * *  # ##
1059+#  * * * * * *    #
1060+# * * * . * * *@$ #
1061+#  * * * * * *    #
1062+##  * * * * *  # ##
1063+ ##  * * * *  ####
1064+  ##  * * *  ##
1065+   ##  * *  ##
1066+    ##  *  ##
1067+     ##   ##
1068+      #####
1069+
1070+; #77
1071+  ########
1072+ ##..    #
1073+ #...$ $ #
1074+###.## ###
1075+#   ##$ #
1076+#  $@$  #
1077+##$ ##  #
1078+ #  #####
1079+ ####
1080+
1081+; #78
1082+  ####
1083+  #  #
1084+  #  #########
1085+  # $$ #.....#
1086+  #    #.*...#
1087+ ###   $..##.#
1088+ #  #$##$  #.#
1089+ # $  ## ## .#
1090+ #  ##  $ $ ##
1091+###@ #$    ##
1092+#  $$ $   $#
1093+# $  ####  #
1094+#    #  ####
1095+#   ##
1096+#####
1097+
1098+; #79
1099+###
1100+# ##    ####
1101+#  ######  ###
1102+#   # $ $$ $ ###
1103+#  $ @ $    $  #
1104+# $ # #$  $    #
1105+#  ## # ### ####
1106+# ##    #  $  #
1107+###... ## $ $ #
1108+##....##   $  #
1109+#....## $  $###
1110+#...###  $  #
1111+#...# #  ####
1112+##### ####
1113+
1114+; #80
1115+           ####
1116+      ######  #
1117+      #   $   #
1118+      # $$ $  #
1119+      ## # $  #
1120+ ######   $ # #
1121+ #      $ $ $ ##
1122+ # ## #######  #
1123+ # $  ##...##$ #
1124+##   ##...#.#  #
1125+# $ $ #.....$$ #
1126+#    $$.....#  #
1127+##$   #..#..#$##
1128+ # $#$####### #
1129+ #    #       #
1130+ #### # # #####
1131+    #   #@#
1132+    #######
1133+
1134+; #81
1135+    ######
1136+    #    #
1137+ #### ##$###
1138+ #         #
1139+ # #....#  #
1140+## #....#$$#
1141+#   ....#  #
1142+# ##....   ##
1143+# ##....#$$ #
1144+#  $....#   #
1145+# $#### #   #
1146+#  $  $$$$$##
1147+##$    $   #
1148+ # $$# #   #
1149+ #  $ $ $$$#
1150+ # $   $   #
1151+ #@##   ####
1152+ ########
1153+
1154+; #82
1155+ ####
1156+ #  #######
1157+ #$  $    #
1158+ #   # #$ #
1159+ # #. .# ##
1160+ # $...  #
1161+##$#...# #
1162+#   $## $#
1163+#     $  #
1164+####### @#
1165+      ####
1166+
1167+; #83
1168+ #####
1169+ #   #    ##########
1170+ #$  ######    ##  #
1171+## $$  $   $  $... #
1172+# $ ##   #  #$#.#. #
1173+#    ##  ##$ $ ... #
1174+# $#    $ # # #.#. #
1175+#  ## #$  #    ... #
1176+# #  $#@$## # #.#. #
1177+#  $$ #$ #  #  ... #
1178+###      #  #   ####
1179+  ###   ##  #####
1180+    #########
1181+
1182+; #84
1183+   #####
1184+   #   #
1185+   # #$#
1186+####   #
1187+#  #.# ##
1188+#  *.* @#
1189+#  #.#  #
1190+## # #$##
1191+#  # #  #
1192+#    $  #
1193+#  ###  #
1194+#### ####
1195+
1196+; #85
1197+     #####
1198+######   #
1199+#  #     #
1200+# $$  #  #
1201+#   ### #######
1202+##  #.....#   #
1203+ #  $...*. $# ###
1204+ # $#.....# #   #
1205+ ## ####$##     #
1206+ #  #      $ ####
1207+ #  # @ $ # $#
1208+ #  $  ##$   #
1209+ ### #$   ####
1210+   #  $ $ #
1211+   ##  #  #
1212+    ####  #
1213+       ####
1214+
1215+; #86
1216+   ####
1217+   #  #####
1218+ ###$     #
1219+ #     .# #
1220+ # ## #.  #
1221+ # $  #*####
1222+## ####.   #
1223+#  #  @.#  #
1224+# $  #$.#$##
1225+###    . $ #
1226+  ######   #
1227+       #####
1228+
1229+; #87
1230+          #########
1231+          #       #
1232+          # ### # #
1233+     #### # #...# #
1234+######  ###  ...  #
1235+#         # #...# #
1236+#  $#  $  # ## ## #
1237+##  #### ##$      #
1238+ # ##### #  #$ ####
1239+ # #### $    $ #
1240+ # $ ##$ ###   #
1241+ #      $@######
1242+ # # ######
1243+ #   #
1244+ #####
1245+
1246+; #88
1247+####
1248+# @#   ####
1249+#  #####..###
1250+#  # $  $...#
1251+##   #  ... #
1252+ #$$  ###$# #
1253+##  # ### $ #
1254+# $   $   # #
1255+#    ####   #
1256+######  #####
1257+
1258+; #89
1259+    ########
1260+ ####  ....#
1261+ # #  $....######
1262+ # $  #....## ..####
1263+ #  $$## #### ....##
1264+####    $ @## .....#
1265+#    $ $$ #### #####
1266+# #$$$$# $$ $  #
1267+#       # $ ## #
1268+###  ## $  $  $#
1269+  # $   $      #
1270+  ####  $ ### $#
1271+     ###  # #  #
1272+       #### ####
1273+
1274+; #90
1275+     #####
1276+######   #
1277+#   ## # #
1278+#        #
1279+##$###*###
1280+## #.@.##
1281+#  *.#  #
1282+# # $ $ #
1283+#   ##  #
1284+#########
1285+
1286+; #91
1287+     #####
1288+  ####   #
1289+  #    #@#
1290+  # ###  #
1291+  # #  $ ###
1292+  # # # $$ #
1293+  # # $$   #
1294+### #   #$ #
1295+#   # $$ $ #
1296+# $ $      #
1297+##$#########
1298+# ....#
1299+# ....#
1300+# ....#
1301+#######
1302+
1303+; #92
1304+#########     #####
1305+#       #######   #
1306+# # # # #         #
1307+#   $ $ # ###### ##
1308+#####$#$# #  ..  ###
1309+  #  @$  $   ..# $ #
1310+  # #$#$# ###... $ #
1311+  #       ##...#   #
1312+  ##################
1313+
1314+; #93
1315+ ####
1316+ #  #
1317+ #  ###
1318+ # $  ###
1319+## ##.  #
1320+# $$..# #
1321+#  #*.$ #
1322+## #. ###
1323+ #   @#
1324+ #$ ###
1325+ #  #
1326+ ####
1327+
1328+; #94
1329+       #####
1330+####  ##   #######
1331+#  #  #  $   $   #
1332+#  #### $ $ $ #  #
1333+#... $ $  #$#$## #
1334+#...# $ $        #
1335+#..# $ $ $########
1336+#...$ $ $@##
1337+###### $ $ ###
1338+     # ##  ..#
1339+     # #  ...#
1340+     #    ...#
1341+     #########
1342+
1343+; #95
1344+    #####
1345+    #   #
1346+##### # #
1347+#   $   #
1348+#   #$#####
1349+##$## $ $ #
1350+ # ...#   #
1351+ # #..*   #
1352+ # @ ######
1353+ #####
1354+
1355+; #96
1356+    #######
1357+   ##     ##
1358+   #  ###  #
1359+ ###$##. # ###
1360+##    #..$   #
1361+#  $$ #..#   #
1362+# $$@ #.*# ###
1363+#  $#$#*.# #
1364+##     ..# #
1365+ ###$##  # #
1366+   #   ##  #
1367+   ###    ##
1368+     ######
1369+
1370+; #97
1371+ ###### ######
1372+ #    # #    #
1373+## ## ### $  #
1374+# $$     $$  #
1375+#  $ ## ## # #
1376+# # $ $    # #
1377+# $  $  # ## #######
1378+#  # #$   ## ##    #
1379+#### #  #### ## ## #
1380+ #  $ $##  #       #
1381+ # $ $     # ## ####
1382+## ## ###  #   ....#
1383+#   # ###   ## ....#
1384+#   $$#       .....#
1385+#   #    #@####....#
1386+############  ######
1387+
1388+; #98
1389+  #########
1390+  #.......#
1391+  #.......###
1392+  #         #
1393+  ##  ##### #
1394+   # ##   # #
1395+   # #   $  #
1396+   #  $ $ ###
1397+  ##$#   $ @#
1398+  #  ## # $##
1399+###$  $$#  ###
1400+#       #$   #
1401+# # $ $ $  $ #
1402+# ###### #  ##
1403+#        ####
1404+##########
1405+
1406+; #99
1407+#########
1408+#....   #
1409+#....   #
1410+#.#... ##
1411+#....#  ########
1412+######$$   #   #
1413+   #    ## $$# #
1414+   #  #  ##  $ #
1415+   ## $ $   ## #
1416+   #   # $   # #
1417+   #   $ #$  # #
1418+   ## ## # $ # ##
1419+    #$ #$#  ## @#
1420+    #  # #$$ $  #
1421+    #          ##
1422+    ############
1423+
1424+; #100
1425+  ####
1426+  #  #######
1427+###$       #######
1428+# $  $$  $ ##....#
1429+#  $# ###$$   ...#
1430+# #    @  #   ...#
1431+# #$$ $ $$#$##...#
1432+#   ## ##   ##...#
1433+##  $      $ #####
1434+ #########  ##
1435+         ####
1436+
1437+; #101
1438+#############
1439+#@$ $ $ *...#
1440+#  $ $ $.*..#
1441+# $ $ $ *...#
1442+#  $ $ $.*..#
1443+# $ $ $ *...#
1444+#  $ $ $.*..#
1445+# $ $ $ *...#
1446+#  $ $ $.*..#
1447+# $ $ $ *...#
1448+#  $ $ $.*..#
1449+#############
1450+
1451+; #102
1452+     #####    #####
1453+######   ######...##
1454+#   ## $ #  ##.... #
1455+# $$   $ #   #.. . #
1456+#   ### ## $ #....##
1457+### #     $  #....#
1458+ ## #   ### #####$#
1459+ ## ###   # ##    #
1460+ # $  @$$ # ##$$$ #
1461+ # $ ##   # ## $  #
1462+ #   ##### $## # ##
1463+ #####  #     $ $ #
1464+        #   #     #
1465+        ###########
1466+
1467+; #103
1468+  ####      ######
1469+  #  #      #    ##
1470+  #  ###   ##     #
1471+  #$   #   #   #  #
1472+  # $# #####      #
1473+  #   $   # # #####
1474+###$$   # # # # #
1475+# $   $   # #   #
1476+# @$ $ ###  # # ##
1477+#  ## #          #
1478+####...#  #    # #
1479+   #..*.# # # $  #
1480+   ##..*.# # #$ ##
1481+    ##..* $    $ #
1482+     ##..    #   #
1483+      ############
1484+
1485+; #104
1486+###################
1487+#  #   #   #   #  #
1488+#  $   $  $    $  #
1489+# $########## ##$ #
1490+## ## *.*..*.* # ##
1491+#  ## ..*..... # ##
1492+#  ### ######### ##
1493+#  #      $ #   $ #
1494+## #   $#$#@  #   #
1495+## # #       ######
1496+# $  #########
1497+#   ##
1498+#####
1499+
1500+; #105
1501+      ####
1502+#######  #
1503+#  #     #
1504+# $$ $#  #
1505+#  ##.# ####
1506+## ##.#  $ #
1507+## # . $ # #
1508+#   *..#   #
1509+#  # . # ###
1510+## ##.##$#
1511+ #     $@#
1512+ #  ######
1513+ ####
1514+
1515+; #106
1516+ ##########
1517+##  ..... #
1518+#  #..... #
1519+# $ #### ##
1520+# $  @   #
1521+## $ $ $ #
1522+ # $$$$$ #
1523+ #   #   #
1524+ #########
1525+
1526+; #107
1527+##############
1528+#     #      #
1529+# $$$    $$$ #
1530+##   $$$$   ##
1531+ #$ $    $ $#
1532+ #   $$$$   #
1533+ #$$$    $$$#
1534+ # $ $$$$ $ #
1535+ #          #
1536+######..######
1537+#..*.****.*..#
1538+#..*......*..#
1539+##.********.##
1540+ #..........#
1541+ ######@#####
1542+      ###
1543+
1544+; #108
1545+     #####
1546+######   #
1547+# $ .. $ #
1548+#@$$.. $##
1549+# $ ..  #
1550+#########
+1521, -0
   1@@ -0,0 +1,1521 @@
   2+; #1
   3+#####
   4+#   #####
   5+# $ #   #
   6+#   #$# #
   7+###$    #
   8+ #   ####
   9+ # @...#
  10+ #######
  11+
  12+; #2
  13+  ####
  14+  #  #
  15+### $####
  16+#@$.. $ #
  17+#  .*   #
  18+###  ####
  19+  #  #
  20+  ####
  21+
  22+; #3
  23+#######
  24+#  . ##
  25+# $ $ #
  26+#. * .#
  27+# $ $ #
  28+## . @#
  29+#######
  30+
  31+; #4
  32+#########
  33+#      @#
  34+# $.$.$ #
  35+# .$.$. #
  36+# $.*.$ #
  37+# .$.$. #
  38+# $.$.$ #
  39+#       #
  40+#########
  41+
  42+; #5
  43+#########
  44+#   @   #
  45+#$$$$$$$#
  46+#...#...#
  47+#.......#
  48+#$$$ $$$#
  49+#       #
  50+#########
  51+
  52+; #6
  53+##########
  54+#    $  .#
  55+#  $##$# #
  56+#   $    #
  57+### ## ###
  58+#  $#  ##
  59+#.*.  $@#
  60+#...##  #
  61+#########
  62+
  63+; #7
  64+#######
  65+#  .  #
  66+# $*$.#
  67+#  .. #
  68+#$$*$$#
  69+# ..  #
  70+#.$*$ #
  71+#  . @#
  72+#######
  73+
  74+; #8
  75+###########
  76+#  $  *.* #
  77+#  $  *.* #
  78+#  $  *.*@#
  79+#  $  *.* #
  80+## $  *.* #
  81+ ##########
  82+
  83+; #9
  84+   ###########
  85+  ##     #  .#
  86+  #  $#$ #...#
  87+###  $  $#  .#
  88+#  $$$   $ @.#
  89+# #  $ ###  .#
  90+#  $ $ # #...#
  91+#    ### #  .#
  92+######   #####
  93+
  94+; #10
  95+#### #####
  96+#  ### @ ###
  97+#..     $  #
  98+#..# # $ $ #
  99+#..#  ## ######
 100+#..   ## $ $  #
 101+#..#  ## $ $# #
 102+#######   $   #
 103+      #  $ $# #
 104+      # # # # #
 105+      #       #
 106+      #########
 107+
 108+; #11
 109+#########
 110+#  .#   #
 111+#  $ $*.#
 112+# $## # #
 113+#   #   #
 114+# * #  ##
 115+##  .@##
 116+ ######
 117+
 118+; #12
 119+  ####
 120+  #. # ###
 121+###$ ###.#
 122+#  .$.   #
 123+#   ##$$ #
 124+# $$.#@  #
 125+#  $.#####
 126+###   .#
 127+  ######
 128+
 129+; #13
 130+ ########
 131+ #......#
 132+ #......#
 133+ #......#
 134+ #      #
 135+ #      #
 136+ #### ##########
 137+##  $    $ $ $ #
 138+#    $ #$#   # #
 139+#@#$ $ $  ##   #
 140+### $# #  #### #
 141+  #  $ $  #    #
 142+  # $# $ #  $  #
 143+  #    $   $ $ #
 144+  #  ###########
 145+  ####
 146+
 147+; #14
 148+    #######
 149+    #     ##
 150+    #  $$  #####
 151+   ### #  $#...#
 152+ ### $ #  $ ...#
 153+ #     ## $#...#
 154+ # $ #$    #...#
 155+ # #  $ # $ ...#
 156+ #  $ $##$  #  #
 157+## ##$ #@ ######
 158+# $    ####
 159+#   #  #
 160+########
 161+
 162+; #15
 163+   ###########
 164+   #   #     #
 165+####   # $ $ #
 166+#  $  $   #$ #
 167+#   $  # $$  #
 168+# #  $$##  # #
 169+# $$    ##   #
 170+#@$  $ $   ###
 171+## ####$##$#
 172+#  #...... ##
 173+#   .....#  #
 174+####......  #
 175+   ##########
 176+
 177+; #16
 178+#####
 179+#...##########
 180+#....$ $     #
 181+#..*. $   #  #
 182+#.*..### ## ####
 183+#....# $  #    #
 184+###### #$ #$#$ #
 185+  #@$  $  # $  #
 186+  ##      #    #
 187+   ########$ # #
 188+   #     $   $ #
 189+   # # # # $## #
 190+   #   $   $ $ #
 191+   ########    #
 192+          ######
 193+
 194+; #17
 195+    ######
 196+  ###    ####
 197+  # $ $ $   ##
 198+###    $ ##  #
 199+# $ # ##$  $ #
 200+#   #$   $   #
 201+#  $   $  $$ #
 202+# $@## ### ###
 203+#   #  #. ...#
 204+#####   .....#
 205+    ####.....#
 206+       #######
 207+
 208+; #18
 209+       #####
 210+########   #
 211+#.....# $# #
 212+#.....   # #
 213+#...  # $# ###
 214+##### #  #   #
 215+    #   $#$# #
 216+    ###$ $ # ##
 217+      #   $@$ #
 218+      #   # $ #
 219+      #$ $$$  #
 220+      #       #
 221+      #########
 222+
 223+; #19
 224+ ##########
 225+##  #     #
 226+#     $...#
 227+# # @ #...#
 228+#    #....#
 229+# $#$$...####
 230+#    ###$   #
 231+##  #    $$$###
 232+ #$ $ ##   $  #
 233+ #  #$#  #    #
 234+ ###  $  ######
 235+   #   # #
 236+   ###   #
 237+     #####
 238+
 239+; #20
 240+      ######
 241+    ### ...##
 242+   ##   ....##
 243+   # $##$#...#
 244+   # $  @ ...#
 245+ ###  # # # $#
 246+## $ #  #$## #
 247+#    $ $   # ##
 248+# $ # ##   $  #
 249+#  #   ## # # #
 250+# # $$   $    #
 251+#     #  ##  ##
 252+#####   ######
 253+    #####
 254+
 255+; #21
 256+    ############
 257+   #......#####
 258+  #@..$ **.###
 259+  #  $ $      #
 260+  ####### #$#  #
 261+ # #  # $ $  $ #
 262+#  #  # #  # # #
 263+      #  #   $ #
 264+       #  $##  #
 265+        #     #
 266+         #####
 267+
 268+; #22
 269+     ######
 270+######    #####
 271+#   #  #  #   ##
 272+# $$  $#$#  $  #
 273+#  #.#...  $ $ #
 274+#   .....@# $  #
 275+# $#.##*#  $$$ #
 276+##  ....#$ #   #
 277+ ###.#...  #####
 278+  # $ $#$# #
 279+  # $#   $ #
 280+  #    #   #
 281+  ##########
 282+
 283+; #23
 284+########
 285+#  #.#.##
 286+# $.$. .#
 287+#   .#$##
 288+####   #
 289+   #$$$#
 290+   # @ #
 291+   #####
 292+
 293+; #24
 294+  ##########
 295+  #        #
 296+ ## $ ##   #
 297+ #@ $$$  # #
 298+ ##  $ $$  #
 299+######  $$ #
 300+#... #$ $  #
 301+#..  # $## #
 302+#..     #  #
 303+#..  # ##  #
 304+#... #     #
 305+############
 306+
 307+; #25
 308+   ######
 309+   # @  #
 310+####  $ #
 311+# *..*$ #
 312+# $*..* #
 313+# $  ####
 314+#    #
 315+######
 316+
 317+; #26
 318+  #######
 319+  #. .  #
 320+####$#$ #
 321+# $. .  #
 322+#@$# #$ #
 323+# $.$.  #
 324+####.  ##
 325+   #####
 326+
 327+; #27
 328+##########
 329+# @###...#
 330+# $$  .$.#
 331+#   #$#$ #
 332+##       #
 333+##########
 334+
 335+; #28
 336+######
 337+#    ##
 338+# $ * #
 339+##.$$.#
 340+#. @ .#
 341+#.$$.##
 342+# * $ #
 343+##    #
 344+ ######
 345+
 346+; #29
 347+#########
 348+#   @...#
 349+# #$#.*.#
 350+# $  $$ #
 351+## #$   #
 352+ #   ####
 353+ #####
 354+
 355+; #30
 356+     ######
 357+######    #
 358+# $ .*. $ #
 359+#@$.* *.$ #
 360+# $ .*. $ #
 361+#     #####
 362+#######
 363+
 364+; #31
 365+######
 366+# # .#
 367+# $ .#
 368+#@ $.#
 369+# $$.#
 370+#  ###
 371+####
 372+
 373+; #32
 374+####
 375+#  ###  #####
 376+# $$ #  #...#
 377+#    ####...#
 378+# $ $ $  ...#
 379+# $  #### ..#
 380+### ##  ##$###
 381+### ######   #
 382+#  $  #    $ #
 383+#    $  # $  #
 384+##@#  ###   ##
 385+ ###### #####
 386+
 387+; #33
 388+    ####
 389+#####  #
 390+#  $ $ # #######
 391+#   $  # #*.*.*#
 392+## $ $ ###.*.*.#
 393+ #$ $  #  *.*.*#
 394+ #@$ $    .*.*##
 395+ #$ $  #  *.*.*#
 396+## $ $ ###.*.*.#
 397+#   $  # #*.*.*#
 398+#  $ $ # #######
 399+#####  #
 400+    ####
 401+
 402+; #34
 403+     ####
 404+     #  #####
 405+ #####      #
 406+ #  ## ##   #
 407+##   $   #$$ #
 408+#  ####  # $ #
 409+#  ..##$#    #
 410+###... $ # # #
 411+  #.*.#$ #$  #
 412+  #...#  # $##
 413+  #####$    #
 414+     #@  ####
 415+     #####
 416+
 417+; #35
 418+ ####
 419+ #  ######
 420+ #@$  $  ####
 421+ #  #   $#  #
 422+ ## #$ $  ..####
 423+### # ####.....#
 424+#    $ # $.....#
 425+# $    $  #  ###
 426+#### #$#  ####
 427+   # $ $ ##
 428+   #    ##
 429+   ######
 430+
 431+; #36
 432+##############
 433+#....#       #
 434+#*...# $ $ $ #
 435+#..####  $   #
 436+#..#  #   $$ #
 437+#..$  ## #   #
 438+# $#  $  #####
 439+#  #  #      #
 440+## #### ## # #
 441+# $    $ #   #
 442+# #$#$#@ #####
 443+#       ##
 444+#########
 445+
 446+; #37
 447+  ###########
 448+  #.........#
 449+  #.........##
 450+##########$$ #
 451+#     $  $ $ #
 452+# @##$ $  $  #
 453+# $#  ## ### ##
 454+#    $$ $   $ #
 455+####$  $  #$$ #
 456+   #  $#      #
 457+   #     ######
 458+   #######
 459+
 460+; #38
 461+#########
 462+#....   #
 463+#....$# #
 464+#.#..  $##
 465+#..@ #$  #
 466+###### #$#####
 467+  ##   $   $ #
 468+  # $$ #$    #
 469+  #   $   $$ #
 470+  #   #$   ###
 471+  ###    ###
 472+    ######
 473+
 474+; #39
 475+###############
 476+#             #
 477+# # $..... ## #
 478+# ##.$###$. # #
 479+#    . # .  $ #
 480+# $#@$...# #  #
 481+# $  . # .$ # #
 482+# # # ... #   #
 483+#   ##$#$##$$ #
 484+# #  $ #      #
 485+# $ #$ # $##$ #
 486+#      #      #
 487+###############
 488+
 489+; #40
 490+####
 491+#  #####
 492+# $$ $ #######
 493+#        ##  ###
 494+### ####$# $ $ #
 495+#....        $ #
 496+#....####$ #   #
 497+#....###  ## $ #
 498+##.#### $ $@$# #
 499+ #    $   #    #
 500+ #  #    #######
 501+ #########
 502+
 503+; #41
 504+          ####
 505+###########  #
 506+#      $   $ #
 507+#  ##### ### #
 508+## # $...$ # ##
 509+ # # $...     #
 510+ # #@#...###$ #
 511+## ## ...    ##
 512+#  $ $$$ #####
 513+# $$   ###
 514+#      #
 515+########
 516+
 517+; #42
 518+       ####
 519+      ##  #
 520+ ###### $ #
 521+##    # $ #
 522+# $ $   # ####
 523+#  ##$#....#@##
 524+# #   #....   #
 525+# # $$ ....## #
 526+#     #....#  #
 527+### # ### # $ #
 528+ # $  $ #$ $  #
 529+ #   $  # $  ##
 530+ # $# # ##  ##
 531+ # $  # #  ##
 532+ #  ###   ##
 533+ #### #####
 534+
 535+; #43
 536+          #####
 537+        ###   #
 538+    #####   $ #
 539+#####   # $#$##
 540+#....$ $#     #
 541+#....$#   $ $ #
 542+#....@#  ###$##
 543+#....#   $    #
 544+## #$ $ $ #   #
 545+# $$ #$########
 546+#      #
 547+###   ##
 548+  #####
 549+
 550+; #44
 551+        ####
 552+     ####  ##
 553+ ##### $    #
 554+ #   #   #$ ##
 555+ # $$ #$#....#
 556+##  $    ....#
 557+#  ## $ #.##.#
 558+# #  ## #....#
 559+#  $ @ $  $ ##
 560+## $ $ #$ #$#
 561+ #   ###    #
 562+ ##### ######
 563+
 564+; #45
 565+  #####
 566+ ##   #
 567+ # $# ####
 568+##  .....##
 569+# $ #.....#
 570+# #$ # ...##
 571+#   $# ##  ##
 572+#    $$###$ ##
 573+# ##$#  @  $ #
 574+#    #$$ #   #
 575+### # $  $ ###
 576+  #   #  ###
 577+  ########
 578+
 579+; #46
 580+     ####
 581+ #####  ##
 582+##    $  ####
 583+#  $  #$  $ ##
 584+# $ #   #    #
 585+#  ### $@ #$ #
 586+######...##  #
 587+   ####..#####
 588+ ###  ... #
 589+## $$#... #
 590+#  # $ ## #
 591+# #    $  #
 592+#     #####
 593+##   ##
 594+ #####
 595+
 596+; #47
 597+  #########
 598+  #      @#
 599+  #$ $ $  #
 600+  # ##$# ##
 601+ ##.. .. #
 602+ # .. ..##
 603+## #$## #
 604+#  $ $ $#
 605+#       #
 606+#########
 607+
 608+; #48
 609+######
 610+#    ######
 611+# $$$#    #
 612+# @$ # ## #
 613+# $$....# #####
 614+#  #.#.*# #   #
 615+#  #.#*.$     #
 616+#  #.*.. ###$##
 617+#######$#  #  #
 618+      # $$    #
 619+      #    #  #
 620+      #  ######
 621+      ####
 622+
 623+; #49
 624+        #######
 625+        #     #
 626+        #$$ $ #
 627+   ######  $  #
 628+   #   ## $ $ #
 629+   # ....*  $ #
 630+   # .###.#####
 631+   ##.# #.#
 632+#####.###.#
 633+# $  *....#
 634+# $ $ #####
 635+#@ $  #
 636+# $ $$#
 637+#     #
 638+#######
 639+
 640+; #50
 641+ ########
 642+ #  @   #
 643+##$ $ $ #
 644+# $ # $ #
 645+#  $ # ##
 646+#......#
 647+########
 648+
 649+; #51
 650+   ####
 651+   #  ###
 652+####  $ ####
 653+#    $# #  #
 654+# $#  #   @##
 655+#    #  #  ####
 656+# #$ $ #..... #
 657+# $ # $ ..##. #
 658+##$  # #...*.##
 659+ #  $#  #..#. #
 660+ # $  #$$  $$ #
 661+ #  # $    #  #
 662+ ####    ######
 663+    ######
 664+
 665+; #52
 666+    ########
 667+    #  ....#
 668+ #### #....#
 669+##  # $...##
 670+#  $ #$.*. ###
 671+#    $ $# $$ #
 672+# $#  @ #    #
 673+##  #  #  $ ##
 674+ #  $ # $ ###
 675+ #  #  $ $#
 676+ #####    #
 677+     ######
 678+
 679+; #53
 680+#######
 681+#. . .#
 682+# $$$ #
 683+#.$@$.#
 684+# $$$ #
 685+#. . .#
 686+#######
 687+
 688+; #54
 689+##############
 690+#   ###      #
 691+# $$$     $$ #
 692+# $ ### $ $  #
 693+# $ #  ### ###
 694+#   #.*...$@##
 695+#   #.....#$ #
 696+## # ...#.#  #
 697+## # .....#  #
 698+##$#####  # ##
 699+#     $ ###  #
 700+# $$ $    $$ #
 701+#       ###  #
 702+##############
 703+
 704+; #55
 705+   #####
 706+####   #
 707+#  $.# ##
 708+#   $   #
 709+#.##.##.#
 710+#  $$$  #
 711+####.  @#
 712+   ######
 713+
 714+; #56
 715+ ##########
 716+ #    .   #
 717+## $##$## #
 718+# @$. . .$##
 719+#   ##$##  #
 720+###   .    #
 721+  ##########
 722+
 723+; #57
 724+########
 725+#   @  #
 726+# #$## #
 727+# $  $ #
 728+###  $##
 729+ #. $.#
 730+ #. ..#
 731+ ######
 732+
 733+; #58
 734+#######
 735+#  .  ####
 736+# $.$ $ @#
 737+#  .####.##
 738+#  $ $ $. #
 739+####    . #
 740+   ########
 741+
 742+; #59
 743+#####
 744+#   #######
 745+# $ * .$  #
 746+# #.#.#.# #
 747+# $ $@$ $ #
 748+# #.#.#.# #
 749+#  $. * $ #
 750+###   #   #
 751+  #########
 752+
 753+; #60
 754+ #####
 755+ #   ######
 756+ # $.##   #
 757+ ##$...$  #
 758+### .$. ###
 759+#@$ $$###
 760+# $ ..###
 761+# $  .  #
 762+#####   #
 763+   ######
 764+
 765+; #61
 766+  #########
 767+ ##.......##
 768+## .$$$$$. ##
 769+#   #   #   #
 770+#  #*#@#*#  #
 771+##  #   #  ##
 772+ #. $$$$$  #
 773+  #.$     #
 774+   ##   ##
 775+     ###
 776+      #
 777+      #
 778+
 779+; #62
 780+  ####
 781+###  ######
 782+#    ##   #
 783+# #     $ #
 784+# $$ #$#$##
 785+### $    ###
 786+  ##  ##.*.##
 787+   ##$ $... ##
 788+  ##  ##...  #
 789+  #   $ #. @ #
 790+  # #   $.# ##
 791+  #    ##   #
 792+  #######  ##
 793+        ####
 794+
 795+; #63
 796+ #######
 797+##  *  ##
 798+# . .@. #
 799+#   * $ #
 800+#*$$*$$*#
 801+# $ *   #
 802+# . . . #
 803+##  *  ##
 804+ #######
 805+
 806+; #64
 807+#######
 808+#     #
 809+# $.$ #
 810+# .$. #
 811+#*$.$*#
 812+# .$. #
 813+#  .$ #
 814+# @   #
 815+#######
 816+
 817+; #65
 818+ ######
 819+ # @  ##
 820+ #$##  #
 821+## ..  #
 822+# $**$ #
 823+#  .. ##
 824+#  ##$#
 825+##    #
 826+ ######
 827+
 828+; #66
 829+###############
 830+#             #
 831+# $.$.$.$.$.# #
 832+# .$.$.$.$.$  #
 833+# $.$.$.$.$.#@#
 834+# .$.$.$.$.$  #
 835+# $.$.$.$.$.# #
 836+#             #
 837+###############
 838+
 839+; #67
 840+#######
 841+# $.  #
 842+#. .$.#
 843+#$.*. #
 844+# $*$ #
 845+#  .  #
 846+# $*$ #
 847+#  * @#
 848+#######
 849+
 850+; #68
 851+   #######
 852+   # ... #
 853+####$##$ ##
 854+#    $    #
 855+# #$@.* # #
 856+#   $*. # #
 857+## # .* # #
 858+ #$ ####  #
 859+ #       ##
 860+ #########
 861+
 862+; #69
 863+#######
 864+#  .  #
 865+# $.$ #
 866+# $*$ #
 867+#..*..#
 868+#$$*$ #
 869+#  .  #
 870+# $. @#
 871+#######
 872+
 873+; #70
 874+##########
 875+#.     $.#
 876+# #### #.#
 877+#. $ #$  #
 878+#  $ # $ #
 879+#   $@ $##
 880+######...#
 881+     #####
 882+
 883+; #71
 884+    ##########
 885+   ##   #    ##
 886+####    #  #  #
 887+#  $.******.$ #
 888+#   #   @  #  #
 889+#####    ######
 890+    ######
 891+
 892+; #72
 893+       #
 894+      ###
 895+     ##  #
 896+    #  $ ##
 897+   #  $.$  #
 898+  ## $.*.$  #
 899+ #  $.*.*.$ ##
 900+## $.*.*.*.$ ##
 901+ ## $.*.*.$  #
 902+  #  $.*.$ ##
 903+   #  $.$  #
 904+    ## $  #
 905+     # @##
 906+      ###
 907+       #
 908+
 909+; #73
 910+#######
 911+#  *  #
 912+#  *  #
 913+# $*$ #
 914+#*...*#
 915+# $.$ #
 916+# $.$ #
 917+#  . @#
 918+#######
 919+
 920+; #74
 921+#########
 922+##  @  ##
 923+# $ $.# #
 924+#  $.#. #
 925+# $.#.$ #
 926+# .*.$  #
 927+# #.$ $ #
 928+##     ##
 929+#########
 930+
 931+; #75
 932+#######
 933+#  .  #
 934+# $*$ #
 935+# $.$ #
 936+# ... #
 937+#.$.$.#
 938+#$$*$ #
 939+#  . @#
 940+#######
 941+
 942+; #76
 943+###############
 944+#  .........  #
 945+# $.$$$$$$$$$ #
 946+# $.$.......$ #
 947+# $.$.$$$$$.$ #
 948+# $.$.$...$.$ #
 949+# $.$.$*$.$.$@#
 950+# $.$...$.$.$ #
 951+# $.$$$$$.$.$ #
 952+# $.......$.$ #
 953+# $$$$$$$$$.$ #
 954+#  .........  #
 955+###############
 956+
 957+; #77
 958+ ########
 959+##  @#  #
 960+#  ###$ ##
 961+#  * *   #
 962+# * * *  #
 963+#  * * . #
 964+###   ####
 965+  #####
 966+
 967+; #78
 968+#######
 969+#  .  #
 970+# $.$ #
 971+# $.* #
 972+#.$*$.#
 973+# *.$ #
 974+# $.$ #
 975+#  . @#
 976+#######
 977+
 978+; #79
 979+##########
 980+#        #
 981+# $#$#$#$##
 982+#. .$...$.#
 983+#. .$...$.#
 984+# $#$#$#$@#
 985+#        ##
 986+##########
 987+
 988+; #80
 989+#########
 990+#   #   ###
 991+#   $ $   #
 992+## ##.#   #
 993+#@$##.##$##
 994+# $.....  #
 995+##$##.##$ #
 996+#  ##.#   #
 997+#  $ $#  ##
 998+#     #  #
 999+##########
1000+
1001+; #81
1002+            ####
1003+ ############  #
1004+ #      $      #
1005+ #$$#  ## ###  #
1006+##  ## #....# ##
1007+#  $   #....$  #
1008+#@#$$ ##....#  #
1009+# $    #....#  #
1010+##  $$ ###$### #
1011+ # $ $ #       #
1012+ #$ $ $  #   # #
1013+ #  ## #####   #
1014+ #     #   #####
1015+ #######
1016+
1017+; #82
1018+ ####   ####
1019+##  #####  #
1020+# $ $   $$ #
1021+#    ## #  ###
1022+##$#.....$   #
1023+ # #.....#  $##
1024+ # #.....# $$ #
1025+ # ### ###    #
1026+ #    @    #$ #
1027+ #  #  $ ###  #
1028+ #### $ $ $ $ #
1029+    #####     #
1030+        #######
1031+
1032+; #83
1033+ ############
1034+ # @# ......#
1035+ #$ #...* $ #
1036+ #   $ ##  ##
1037+ # $ $  ## #
1038+## ### $#  #
1039+# $# $    $#
1040+#     ##   #
1041+####  ######
1042+   ####
1043+
1044+; #84
1045+   #########
1046+   #@      #
1047+ ### ##  # ##
1048+ # $$ # $#  ##
1049+ #    # $ #$ #
1050+ #  # # #    #
1051+ ## # $  $ $ #
1052+  # #   ###  ##
1053+  # ##...##$  #
1054+###$$ ..### # #
1055+#  $  ...##   #
1056+#   ##....#####
1057+###########
1058+
1059+; #85
1060+ ####
1061+ #  ########
1062+ #   $     ###
1063+ # ##$ ###   #
1064+ #    #...$  ##
1065+ #$ @ #...# $ ##
1066+##  #  ...#$   #
1067+# $$  $#..  #  #
1068+# #  $ #..$ $  #
1069+#  $  ##..#  ###
1070+### #$  $ ####
1071+  #    #  #
1072+  #########
1073+
1074+; #86
1075+#########
1076+#   ## @#
1077+# $  $  #
1078+## *.#$ ##
1079+ # #.*   #
1080+ # .. $# #
1081+ #####   #
1082+     #####
1083+
1084+; #87
1085+  ####
1086+  #  ########
1087+ ##    $    #
1088+ # $# #.# # #
1089+ #  ...*. $ #
1090+## #$##.##  #
1091+# $     $ @ #
1092+#   ###  #  #
1093+##### #######
1094+
1095+; #88
1096+#####
1097+#   ########
1098+#   # .    ##
1099+#  ## *$$#  #
1100+# @ # .   $ #
1101+#   # .#$#  #
1102+##  ##.# $ ##
1103+ #  ##.#   #
1104+ #   #. # ###
1105+ #   $* # $ #
1106+ #    . #   #
1107+ ############
1108+
1109+; #89
1110+   ###### #####
1111+   #    ###   #
1112+   # #$     $ #
1113+ ### $ ##### ##
1114+ #   #.##     #
1115+ # $##.##  #$ #
1116+ #  ..... $#  #
1117+##$ ##.##  ####
1118+#  $ #.#####
1119+#   $ @ #
1120+#####   #
1121+    #####
1122+
1123+; #90
1124+#########
1125+#  #    ###
1126+#  #  #   ###
1127+# .   # $ $ ###
1128+#..#  # $ $   #
1129+#..   # @$ $  #
1130+#..#  ##$# $  #
1131+#..  ##   $ ###
1132+#..#    $$# #
1133+#    ##     #
1134+#  ##########
1135+#  #
1136+####
1137+
1138+; #91
1139+############
1140+#    ... $ #
1141+# $$$*** $@#
1142+#    ... $ #
1143+############
1144+
1145+; #92
1146+     #####
1147+######   ######
1148+#   #  $ ##   #
1149+# $ $ $ #   $ ##
1150+#  $# @ $ $$#  #
1151+## $  #     $$ #
1152+#..#$#### #$#  #
1153+#....  #  #   ##
1154+#....   $$#####
1155+#...###   #
1156+#...# #####
1157+#####
1158+
1159+; #93
1160+  #####
1161+  #   #
1162+### . #
1163+#   . #####
1164+# ##$## @ #
1165+#   . $   #
1166+###$.$#####
1167+  #   #
1168+  #####
1169+
1170+; #94
1171+     #######
1172+     #@ #  #
1173+###### $   #
1174+#...### #  ##
1175+#.  #  $ #  #
1176+#.    $ $ $ #
1177+#.  #  $ #  #
1178+#...### #  ##
1179+###### $#  #
1180+     #  $$ #
1181+     #  #  #
1182+     #######
1183+
1184+; #95
1185+     #####
1186+   ###   ####
1187+ ### $ $ #  #
1188+##   .#     #
1189+# $# ..# $  #
1190+#@$  ...#  ##
1191+# $# #...#$ #
1192+##   $ $    #
1193+ #### # #####
1194+    #   #
1195+    #####
1196+
1197+; #96
1198+    ####
1199+  ### @####
1200+ #  #   #  #
1201+ #$ $ $$$ $#
1202+ #  #.#.#  #
1203+ # #.....# #
1204+ # #.....# #
1205+#   #...#   #
1206+# $  # #  $ #
1207+ #  $ $ $  #
1208+  #$ $ $ $#
1209+  #       #
1210+  #########
1211+
1212+; #97
1213+             #
1214+            ##
1215+           ###
1216+          #   #
1217+   ######## # #
1218+  # $ $ $ $   #
1219+ ## # # # #$##
1220+###.......   ##
1221+ ## #.#.#.#@$#
1222+  # $ $ $ $   #
1223+   ######## # #
1224+          #   #
1225+           ###
1226+            ##
1227+             #
1228+
1229+; #98
1230+    ##   ##
1231+   ######  #
1232+####  $ $  ####
1233+ ### *.*.* ###
1234+  ## .$ $. ##
1235+   # *.*.* #
1236+   #  $ $  #
1237+   ### @ ###
1238+     #####
1239+       #
1240+
1241+; #99
1242+#####       ####
1243+#   #########  #
1244+#              #
1245+## ##########  #
1246+ # # * . * ## ##
1247+ # #  * *  ## #
1248+ # # * * * ## #
1249+ # #  * *  ## #
1250+ # # * * * ## #
1251+ # #  * *  ## ##
1252+ # # * * *     #
1253+ #$#  * *  #   #
1254+ #@  * * * #  ##
1255+ ##############
1256+
1257+; #100
1258+###########
1259+#  #   #  #
1260+#  $  $   #
1261+#  ##.##  #
1262+## ...##$##
1263+##$#...   #
1264+#  #.##$# #
1265+# $$  $   #
1266+# @#  #####
1267+#######
1268+
1269+; #101
1270+##### ####
1271+#   ###  ######
1272+# $  $ @$.... #
1273+##$ $  #$.##. #
1274+ #  # $# ....##
1275+ #  $  #$.##. #
1276+ # $  #  .... #
1277+ #$$$ # $$  $##
1278+ #    #  ##  #
1279+ #############
1280+
1281+; #102
1282+   #####
1283+   #...######
1284+   #...#    #
1285+   #...$ $$ #
1286+#####.. @# ##
1287+#    $ ### ###
1288+#   #$####   #
1289+## $     ### #
1290+ #   # $  $  #
1291+ ######  # $ #
1292+     #  $#$# #
1293+     #       #
1294+     #########
1295+
1296+; #103
1297+    #####
1298+    #   #
1299+ ####$# ###
1300+ # $  @$  ###
1301+ #   #    $ #
1302+###$## $$   #
1303+#....#$#  $ ##
1304+#..... ###$  #
1305+##.#.  #   $ #
1306+ #... $#$ #  #
1307+ #  #   $ ####
1308+ ####  ####
1309+    ####
1310+
1311+; #104
1312+###########
1313+#   ##..  #
1314+# $ ....# ##
1315+#  #.... @ ###
1316+#  #.#.. #   #
1317+####.###  $# #
1318+ ##  ##  $ # ##
1319+##   #  #$    #
1320+#  $ #$$#   # #
1321+# # $  $ ##   #
1322+# ###$ $  $  ##
1323+# $    ##    #
1324+# $   ####   #
1325+#  ####  #####
1326+####
1327+
1328+; #105
1329+ #######
1330+ #...  #####
1331+ #...#$#   ###
1332+ #... $@ $   ###
1333+ ##$$# ##$#$   #
1334+ #   #     $$# #
1335+ # $###$## # $ #
1336+ # $.#.$       #
1337+##  ...#$$ #####
1338+#  $#..  ###
1339+#   ##.   #
1340+#######   #
1341+      #####
1342+
1343+; #106
1344+ ####   #####
1345+ #  #####   #
1346+##*   * #$# #
1347+#   #   #   #
1348+# * . *  ** #
1349+######   #@##
1350+# .   ###   #
1351+# $ *    *# #
1352+##*   * **  #
1353+ #  ####    #
1354+ ####  ######
1355+
1356+; #107
1357+      ####
1358+      #  #
1359+    ###  ####
1360+#####       ###
1361+#   $ #$###   #
1362+#  $@$....#$$ #
1363+######..*.  $ #
1364+   #####..#####
1365+   # $ $ ##
1366+   #     #
1367+   #######
1368+
1369+; #108
1370+         #####
1371+         #   #
1372+########## * ###
1373+#          .   #
1374+# $$$$****$...@#
1375+#          .   #
1376+########## * ###
1377+         #   #
1378+         #####
1379+
1380+; #109
1381+########
1382+#  .$  #
1383+# .$.$ ##
1384+#*$.$.@ #
1385+# .$.$  #
1386+#  .$ ###
1387+#######
1388+
1389+; #110
1390+###########
1391+#    .    #
1392+#  $.$.$  #
1393+###.$.$.###
1394+  ##.$.##
1395+   #$.$#
1396+   # $ #
1397+   # @ #
1398+   #####
1399+
1400+; #111
1401+       #####
1402+########   #
1403+#......... #
1404+#  $ #$#   #
1405+# $#    # ###
1406+#  #  # $   #
1407+#$### $ # # #
1408+#@$    $  $ #
1409+######  #####
1410+     ####
1411+
1412+; #112
1413+          #####
1414+          #   #
1415+########### # #
1416+#             #
1417+# # $#######$$#
1418+# #  *.....#  #
1419+# #$ #.***.*  #
1420+# #  #.....#  #
1421+# #  ####*###$##
1422+# #         $  #
1423+# $ $ $ $ $ $ @#
1424+##  ############
1425+ ####
1426+
1427+; #113
1428+###########
1429+#  .$ $.  #
1430+#  .$  #  #
1431+#.#*#..*..#
1432+#$ .$$$#$$#
1433+#  .$@$.  #
1434+#$$#$$$. $#
1435+#..*..#*#.#
1436+#  #  $.  #
1437+# $. $ .  #
1438+###########
1439+
1440+; #114
1441+   #####
1442+   # @ #
1443+   #$$$#
1444+#### . ####
1445+#   *.* $ #
1446+# $.....$ #
1447+# $ *.*   #
1448+#### . ####
1449+   # $$#
1450+   #   #
1451+   #####
1452+
1453+; #115
1454+#######
1455+# $. @#
1456+#  .$ #
1457+# **$ #
1458+#* .$*#
1459+# $*. #
1460+#  .$ #
1461+#  .  #
1462+#######
1463+
1464+; #116
1465+#######
1466+#  *  #
1467+# $.$ #
1468+#  .$ #
1469+#.*.*.#
1470+#$ *  #
1471+# $. $#
1472+#@ *  #
1473+#######
1474+
1475+; #117
1476+   ######
1477+####    ####
1478+#@ $.#*$   #
1479+# $ ...# $ #
1480+###$#.     #
1481+  #   ######
1482+  #####
1483+
1484+; #118
1485+   #####
1486+   #.  #
1487+   #...#
1488+   #.  #
1489+   #.  #
1490+##### #####
1491+#         #
1492+# $@$$$$$ #
1493+#    #    #
1494+###########
1495+
1496+; #119
1497+  #####
1498+  # . #
1499+  # * #
1500+  # . #
1501+###$*$###
1502+#   *   #
1503+# ***** #
1504+#   *   #
1505+### . ###
1506+  # $ #
1507+  # @ #
1508+  #####
1509+
1510+; #120
1511+#############
1512+#.          #
1513+#.#$#$#$#$#$#
1514+#.          #
1515+#.#########.#
1516+#.#.  $ ..$$#
1517+#.# $ $ *.$@#
1518+#.#.* $ ..$*##
1519+#.#########  #
1520+#.$ $ $ $ $  #
1521+#.           #
1522+##############
+15, -0
 1@@ -0,0 +1,15 @@
 2+<$PLAN9/src/mkhdr
 3+
 4+TARG=sokoban
 5+OFILES=\
 6+	animation.$O\
 7+	graphics.$O\
 8+	level.$O\
 9+	move.$O\
10+	sokoban.$O\
11+	route.$O\
12+
13+HFILES=sokoban.h\
14+
15+<$PLAN9/src/mkone
16+
+137, -0
  1@@ -0,0 +1,137 @@
  2+#include <u.h>
  3+#include <libc.h>
  4+#include <draw.h>
  5+
  6+#include "sokoban.h"
  7+
  8+/* pretty ghastly, if you ask me */
  9+void
 10+move(int key)
 11+{
 12+	Point g = level.glenda;
 13+	int moved = 0;
 14+
 15+	/* this is messy; no time for math */
 16+	switch(key) {
 17+	case Up:
 18+		switch(level.board[g.x][g.y-1]) {
 19+		case Empty:
 20+		case Goal:
 21+			moved = 1;
 22+			level.glenda = Pt(g.x, g.y-1);
 23+			break;
 24+		case Cargo:
 25+		case GoalCargo:
 26+			switch(level.board[g.x][g.y-2]) {
 27+			case Empty:
 28+				moved = 1;
 29+				level.board[g.x][g.y-2] = Cargo;
 30+				drawboard(Pt(g.x, g.y-2));
 31+				break;
 32+			case Goal:
 33+				moved = 1;
 34+				level.board[g.x][g.y-2] = GoalCargo;
 35+				drawboard(Pt(g.x, g.y-2));
 36+				break;
 37+			}
 38+			if(moved) {
 39+				level.board[g.x][g.y-1] = (level.board[g.x][g.y-1] == Cargo) ? Empty : Goal;
 40+				level.glenda = Pt(g.x, g.y-1);
 41+			}
 42+			break;
 43+		}
 44+		break;
 45+	case Down:
 46+		switch(level.board[g.x][g.y+1]) {
 47+		case Empty:
 48+		case Goal:
 49+			moved = 1;
 50+			level.glenda = Pt(g.x, g.y+1);
 51+			break;
 52+		case Cargo:
 53+		case GoalCargo:
 54+			switch(level.board[g.x][g.y+2]) {
 55+			case Empty:
 56+				moved = 1;
 57+				level.board[g.x][g.y+2] = Cargo;
 58+				drawboard(Pt(g.x, g.y+2));
 59+				break;
 60+			case Goal:
 61+				moved = 1;
 62+				level.board[g.x][g.y+2] = GoalCargo;
 63+				drawboard(Pt(g.x, g.y+2));
 64+				break;
 65+			}
 66+			if(moved) {
 67+				level.board[g.x][g.y+1] = (level.board[g.x][g.y+1] == Cargo) ? Empty : Goal;
 68+				level.glenda = Pt(g.x, g.y+1);
 69+			}
 70+			break;
 71+		}
 72+		break;
 73+	case Left:
 74+		glenda = gleft;
 75+		switch(level.board[g.x-1][g.y]) {
 76+		case Empty:
 77+		case Goal:
 78+			moved = 1;
 79+			level.glenda = Pt(g.x-1, g.y);
 80+			break;
 81+		case Cargo:
 82+		case GoalCargo:
 83+			switch(level.board[g.x-2][g.y]) {
 84+			case Empty:
 85+				moved = 1;
 86+				level.board[g.x-2][g.y] = Cargo;
 87+				drawboard(Pt(g.x-2, g.y));
 88+				break;
 89+			case Goal:
 90+				moved = 1;
 91+				level.board[g.x-2][g.y] = GoalCargo;
 92+				drawboard(Pt(g.x-2, g.y));
 93+				break;
 94+			}
 95+			if(moved) {
 96+				level.board[g.x-1][g.y] = (level.board[g.x-1][g.y] == Cargo) ? Empty : Goal;
 97+				level.glenda = Pt(g.x-1, g.y);
 98+			}
 99+			break;
100+		}
101+		break;
102+	case Right:
103+		glenda = gright;
104+		switch(level.board[g.x+1][g.y]) {
105+		case Empty:
106+		case Goal:
107+			moved = 1;
108+			level.glenda = Pt(g.x+1, g.y);
109+			break;
110+		case Cargo:
111+		case GoalCargo:
112+			switch(level.board[g.x+2][g.y]) {
113+			case Empty:
114+				moved = 1;
115+				level.board[g.x+2][g.y] = Cargo;
116+				drawboard(Pt(g.x+2, g.y));
117+				break;
118+			case Goal:
119+				moved = 1;
120+				level.board[g.x+2][g.y] = GoalCargo;
121+				drawboard(Pt(g.x+2, g.y));
122+				break;
123+			}
124+			if(moved) {
125+				level.board[g.x+1][g.y] = (level.board[g.x+1][g.y] == Cargo) ? Empty : Goal;
126+				level.glenda = Pt(g.x+1, g.y);
127+			}
128+			break;
129+		}
130+		break;
131+	}
132+	if(moved)
133+		drawboard(Pt(g.x, g.y));
134+
135+	drawglenda();
136+}
137+
138+
+281, -0
  1@@ -0,0 +1,281 @@
  2+#include <u.h>
  3+#include <libc.h>
  4+#include <draw.h>
  5+
  6+#include "sokoban.h"
  7+
  8+static int dirlist[] = { Up, Down, Left, Right, Up, Down, Left, Right, };
  9+static int ndir = 4;
 10+
 11+static Point
 12+dir2point(int dir)
 13+{
 14+	switch(dir) {
 15+	case Up:
 16+		return Pt(0, -1);
 17+	case Down:
 18+		return Pt(0, 1);
 19+	case Left:
 20+		return Pt(-1, 0);
 21+	case Right:
 22+		return Pt(1, 0);
 23+	}
 24+	return Pt(0,0);
 25+}
 26+
 27+int
 28+validpush(Point g, Step *s, Point *t)
 29+{
 30+	int i;
 31+	Point m;
 32+
 33+	if (s == nil)
 34+		return 0;
 35+
 36+	m = dir2point(s->dir);
 37+
 38+	// first test for  Cargo next to us (in direction dir)
 39+	if (s->count > 0) {
 40+		g = addpt(g, m);
 41+		if (!ptinrect(g, Rpt(Pt(0,0), level.max)))
 42+			return 0;
 43+		switch (level.board[g.x][g.y]) {
 44+		case Wall:
 45+		case Empty:
 46+		case Goal:
 47+			return 0;
 48+		}
 49+	}
 50+	// then test for  enough free space for us _and_ Cargo
 51+	for (i=0; i < s->count; i++) {
 52+		g = addpt(g, m);
 53+		if (!ptinrect(g, Rpt(Pt(0,0), level.max)))
 54+			return 0;
 55+		switch (level.board[g.x][g.y]) {
 56+		case Wall:
 57+		case Cargo:
 58+		case GoalCargo:
 59+			return 0;
 60+		}
 61+	}
 62+	if (t != nil)
 63+		*t = g;
 64+	return 1;
 65+}
 66+
 67+int
 68+isvalid(Point s, Route* r, int (*isallowed)(Point, Step*, Point*))
 69+{
 70+	Point m;
 71+	Step *p;
 72+
 73+	if (r == nil)
 74+		return 0;
 75+
 76+	m = s;
 77+	for (p = r->step; p < r->step + r->nstep; p++)
 78+		if (!isallowed(m, p, &m))
 79+			return 0;
 80+	return 1;
 81+}
 82+
 83+static Walk*
 84+newwalk(void)
 85+{
 86+	Walk *w;
 87+
 88+	w = mallocz(sizeof *w, 1);
 89+	if (w == nil)
 90+		sysfatal("cannot allocate walk");
 91+	return w;
 92+}
 93+
 94+static void
 95+resetwalk(Walk *w)
 96+{
 97+	Route **p;
 98+
 99+	if (w == nil || w->route == nil)
100+		return;
101+
102+	for (p=w->route; p < w->route + w->nroute; p++)
103+		freeroute(*p);
104+	w->nroute = 0;
105+}
106+
107+static void
108+freewalk(Walk *w)
109+{
110+	if (w == nil)
111+		return;
112+
113+	resetwalk(w);
114+	if(w->route)
115+		free(w->route);
116+	free(w);
117+}
118+
119+static void
120+addroute(Walk *w, Route *r)
121+{
122+	if (w == nil || r == nil)
123+		return;
124+
125+	if (w->beyond < w->nroute+1) {
126+		w->beyond = w->nroute+1;
127+		w->route = realloc(w->route, sizeof(Route*)*w->beyond);
128+	}
129+	if (w->route == nil)
130+		sysfatal("cannot allocate route in addroute");
131+	w->route[w->nroute] = r;
132+	w->nroute++;
133+}
134+
135+void
136+freeroute(Route *r)
137+{
138+	if (r == nil)
139+		return;
140+	free(r->step);
141+	free(r);
142+}
143+
144+Route*
145+extend(Route *rr, int dir, int count, Point dest)
146+{
147+	Route *r;
148+
149+	r = mallocz(sizeof *r, 1);
150+	if (r == nil)
151+		sysfatal("cannot allocate route in extend");
152+	r->dest = dest;
153+
154+	if (count > 0) {
155+		r->nstep = 1;
156+		if (rr != nil)
157+			r->nstep += rr->nstep;
158+
159+		r->step = malloc(sizeof(Step)*r->nstep);
160+		if (r->step == nil)
161+			sysfatal("cannot allocate step in extend");
162+
163+		if (rr != nil)
164+			memmove(r->step, rr->step, sizeof(Step)*rr->nstep);
165+
166+		r->step[r->nstep-1].dir = dir;
167+		r->step[r->nstep-1].count = count;
168+	}
169+	return r;
170+}
171+
172+static Step*
173+laststep(Route*r)
174+{
175+	if (r != nil && r->nstep > 0)
176+		return &r->step[r->nstep-1];
177+	return nil;
178+}
179+
180+static int*
181+startwithdirfromroute(Route *r, int* dl, int n)
182+{
183+	Step *s;
184+	int *p;
185+	
186+	if (r == nil || dl == nil)
187+		return dl;
188+
189+	s =  laststep(r);
190+	if (s == nil || s->count == 0)
191+		return dl;
192+
193+	for (p=dl; p < dl + n; p++)
194+		if (*p == s->dir)
195+			break;
196+	return p;
197+}
198+
199+static Route*
200+bfstrydir(Route *r, int dir, Visited *v)
201+{
202+	Point m, p, n;
203+
204+	if (r == nil)
205+		return nil;
206+
207+	m = r->dest;
208+	p = dir2point(dir);
209+	n = addpt(m, p);
210+
211+	if (ptinrect(n, Rpt(Pt(0,0), level.max)) && v->board[n.x][n.y] == 0) {
212+		v->board[n.x][n.y] = 1;
213+		switch (level.board[n.x][n.y]) {
214+		case Empty:
215+		case Goal:
216+			return extend(r, dir, 1, n);
217+		}
218+	}
219+	return nil;
220+}
221+
222+static Route*
223+bfs(Point src, Point dst, Visited *v)
224+{
225+	Walk *cur, *new, *tmp;
226+	Route *r, **p;
227+	int progress, *dirs, *dirp;
228+	Point n;
229+
230+	if (v == nil)
231+		return nil;
232+
233+	cur = newwalk();
234+	new = newwalk();
235+	v->board[src.x][src.y] = 1;
236+	r = extend(nil, 0, 0, src);
237+	if (eqpt(src, dst)) {
238+		freewalk(cur);
239+		freewalk(new);
240+		return r;
241+	}
242+	addroute(cur, r);
243+	progress = 1;
244+	while (progress) {
245+		progress = 0;
246+		for (p=cur->route; p < cur->route + cur->nroute; p++) {
247+			dirs = startwithdirfromroute(*p, dirlist, ndir);
248+			for (dirp=dirs; dirp < dirs + ndir; dirp++) {
249+				r = bfstrydir(*p, *dirp, v);
250+				if (r != nil) {
251+					progress = 1;
252+					n = r->dest;
253+					if (eqpt(n, dst)) {
254+						freewalk(cur);
255+						freewalk(new);
256+						return(r);
257+					}
258+					addroute(new, r);
259+				}
260+			}
261+		}
262+		resetwalk(cur);
263+		tmp = cur;
264+		cur = new;
265+		new = tmp;
266+	}
267+	freewalk(cur);
268+	freewalk(new);
269+	return nil;
270+}
271+
272+Route*
273+findroute(Point src, Point dst)
274+{
275+	Visited v;
276+	Route* r;
277+
278+	memset(&v, 0, sizeof(Visited));
279+	r = bfs(src, dst, &v);
280+	return r;
281+}
282+
+396, -0
  1@@ -0,0 +1,396 @@
  2+#include <u.h>
  3+#include <libc.h>
  4+#include <draw.h>
  5+#include <event.h>
  6+
  7+#include "sokoban.h"
  8+
  9+Level level;
 10+Level levels[Maxlevels];
 11+int numlevels;
 12+
 13+Image *img;
 14+Image *text;
 15+Image *win;
 16+Image *goal;
 17+Image *cargo;
 18+Image *goalcargo;
 19+Image *wall;
 20+Image *empty;
 21+Image *gleft;
 22+Image *gright;
 23+Image *glenda;
 24+Image *bg;
 25+
 26+#define SOKOTREE ""
 27+
 28+char *LEasy = SOKOTREE "levels/easy.slc";
 29+char *LHard = SOKOTREE "levels/hard.slc";
 30+char *levelfile;
 31+
 32+#define SOKOIMG SOKOTREE "images/"
 33+
 34+char	*GRImage =	SOKOIMG "right.bit";
 35+char	*GLImage =	SOKOIMG "left.bit";
 36+char	*WallImage =	SOKOIMG "wall.bit";
 37+char	*EmptyImage =	SOKOIMG "empty.bit";
 38+char	*CargoImage =	SOKOIMG "cargo.bit";
 39+char	*GoalCargoImage= SOKOIMG "goalcargo.bit";
 40+char	*GoalImage =	SOKOIMG "goal.bit";
 41+char	*WinImage =	SOKOIMG "win.bit";
 42+
 43+char *buttons[] = 
 44+{
 45+	"restart",
 46+	"easy",
 47+	"hard",
 48+	"noanimate", /* this menu string initialized in main */
 49+	"exit",
 50+	0
 51+};
 52+
 53+char **levelnames;
 54+
 55+Menu menu = 
 56+{
 57+	buttons,
 58+};
 59+
 60+Menu lmenu;
 61+
 62+void
 63+buildmenu(void)
 64+{
 65+	int i;
 66+
 67+	if (levelnames != nil) {
 68+		for(i=0; levelnames[i] != 0; i++)
 69+			free(levelnames[i]);
 70+	}
 71+	levelnames = realloc(levelnames, sizeof(char*)*(numlevels+1));
 72+	if (levelnames == nil)
 73+		sysfatal("cannot allocate levelnames");
 74+	for(i=0; i < numlevels; i++)
 75+		levelnames[i] = genlevels(i);
 76+	levelnames[numlevels] = 0;
 77+	lmenu.item = levelnames;
 78+}
 79+
 80+Image *
 81+eallocimage(Rectangle r, int repl, uint color)
 82+{
 83+	Image *tmp;
 84+
 85+	tmp = allocimage(display, r, screen->chan, repl, color);
 86+	if(tmp == nil)
 87+		sysfatal("cannot allocate buffer image: %r");
 88+
 89+	return tmp;
 90+}
 91+
 92+Image *
 93+eloadfile(char *path)
 94+{
 95+	Image *img;
 96+	int fd;
 97+
 98+	fd = open(path, OREAD);
 99+	if(fd < 0) {
100+		fprint(2, "cannot open image file %s: %r\n", path);
101+		exits("image");
102+	}
103+	img = readimage(display, fd, 0);
104+	if(img == nil)
105+		sysfatal("cannot load image: %r");
106+	close(fd);
107+	
108+	return img;
109+}
110+
111+
112+void
113+allocimages(void)
114+{
115+	Rectangle one = Rect(0, 0, 1, 1);
116+	
117+	bg		= eallocimage(one, 1, DDarkyellow);
118+	text 		= eallocimage(one, 1, DBluegreen);
119+
120+	gright = eloadfile(GRImage);
121+	gleft = eloadfile(GLImage);
122+	wall = eloadfile(WallImage);
123+	empty = eloadfile(EmptyImage);
124+	empty->repl = 1;
125+	goalcargo = eloadfile(GoalCargoImage);
126+	cargo = eloadfile(CargoImage);
127+	goal = eloadfile(GoalImage);
128+	win = eloadfile(WinImage);
129+}
130+
131+int
132+key2move(int key)
133+{
134+	int k = 0;
135+
136+	switch(key) {
137+	case 61454:
138+		k = Up;
139+		break;
140+	case 63488:
141+		k = Down;
142+		break;
143+	case 61457:
144+		k = Left;
145+		break;
146+	case 61458:
147+		k = Right;
148+		break;
149+	}
150+
151+	return k;
152+}
153+
154+static Route*
155+mouse2route(Mouse m)
156+{
157+	Point p, q;
158+	Route *r;
159+
160+	p = subpt(m.xy, screen->r.min);
161+	p.x /= BoardX;
162+	p.y /= BoardY;
163+
164+	q = subpt(p, level.glenda);
165+	// fprint(2, "x=%d y=%d\n", q.x, q.y);
166+
167+	if (q.x == 0 && q.y ==  0)
168+		return nil;
169+
170+	if (q.x == 0 || q.y ==  0) {
171+		if (q.x < 0)
172+			r = extend(nil, Left, -q.x, Pt(level.glenda.x, p.y));
173+		else if (q.x > 0)
174+			r = extend(nil, Right, q.x, Pt(level.glenda.x, p.y));
175+		else if (q.y < 0)
176+			r = extend(nil, Up, -q.y, level.glenda);
177+		else if (q.y > 0)
178+			r = extend(nil, Down, q.y, level.glenda);
179+		else
180+			r = nil;
181+
182+		if (r != nil && isvalid(level.glenda, r, validpush))
183+			return r;
184+		freeroute(r);
185+	}
186+
187+	return findroute(level.glenda, p);
188+}
189+
190+char *
191+genlevels(int i)
192+{
193+	
194+	if(i >= numlevels)
195+		return 0;
196+
197+	return smprint("level %d", i+1);
198+}
199+
200+
201+int
202+finished(void)
203+{
204+	int x, y;
205+	for(x = 0; x < MazeX; x++)
206+		for(y = 0; y < MazeY; y++)
207+			if(level.board[x][y] == Goal)
208+				return 0;
209+
210+	return 1;
211+}
212+
213+void
214+eresized(int new)
215+{
216+	Point p;
217+
218+	if(new && getwindow(display, Refnone) < 0)
219+		sysfatal("can't reattach to window");
220+	
221+	p = Pt(Dx(screen->r), Dy(screen->r));
222+
223+	if(!new || !eqpt(p, boardsize(level.max))) {
224+		drawlevel();
225+	}
226+	drawscreen();
227+}
228+
229+void 
230+main(int argc, char **argv)
231+{
232+	Mouse m;
233+	Event ev;
234+	int e;
235+	Route *r;
236+	int timer;
237+	Animation a;
238+	int animate;
239+
240+
241+	if(argc == 2) 
242+		levelfile = argv[1];
243+	else
244+		levelfile = LEasy;
245+		
246+	if(! loadlevels(levelfile)) {
247+		fprint(2, "usage: %s [levelfile]\n", argv[0]);
248+		exits("usage");
249+	}
250+	buildmenu();
251+
252+	animate = 0;
253+	buttons[3] = animate ? "noanimate" : "animate";
254+
255+	if(initdraw(nil, nil, "sokoban") < 0)
256+		sysfatal("initdraw failed: %r");
257+	einit(Emouse|Ekeyboard);
258+
259+	timer = etimer(0, 200);
260+	initanimation(&a);
261+
262+	allocimages();
263+	glenda = gright;
264+	eresized(0);
265+
266+	for(;;) {
267+		e = event(&ev);
268+		switch(e) {
269+		case Emouse:
270+			m = ev.mouse;
271+			if(m.buttons&1) {
272+				stopanimation(&a);
273+				r = mouse2route(m);
274+				if (r)
275+					setupanimation(&a, r);
276+				if (! animate) {
277+					while(onestep(&a))
278+						;
279+					drawscreen();
280+				}
281+			}
282+			if(m.buttons&2) {
283+				int l;
284+				/* levels start from 1 */
285+				lmenu.lasthit = level.index;
286+				l=emenuhit(2, &m, &lmenu);
287+				if(l>=0){
288+					stopanimation(&a);
289+					level = levels[l];
290+					drawlevel();
291+					drawscreen();
292+				}
293+			}
294+			if(m.buttons&4)
295+				switch(emenuhit(3, &m, &menu)) {
296+				case 0:
297+					stopanimation(&a);
298+					level = levels[level.index];
299+					drawlevel();
300+					drawscreen();
301+					break;
302+				case 1:
303+					stopanimation(&a);
304+					loadlevels(LEasy);
305+					buildmenu();
306+					drawlevel();
307+					drawscreen();
308+					break;
309+				case 2:
310+					stopanimation(&a);
311+					loadlevels(LHard);
312+					buildmenu();
313+					drawlevel();
314+					drawscreen();
315+					break;
316+				case 3:
317+					animate = !animate;
318+					buttons[3] = animate ? "noanimate" : "animate";
319+					break;
320+				case 4:
321+					exits(nil);
322+				}
323+			break;
324+
325+		case Ekeyboard:
326+			if(level.done)
327+				break;
328+
329+			stopanimation(&a);
330+
331+			switch(ev.kbdc) {
332+			case 127:
333+			case 'q':
334+			case 'Q':
335+				exits(nil);
336+			case 'n':
337+			case 'N':
338+				if(level.index < numlevels - 1) {
339+					level = levels[++level.index];
340+					drawlevel();
341+					drawscreen();
342+				}
343+				break;
344+			case 'p':
345+			case 'P':
346+				if(level.index > 0) {
347+					level = levels[--level.index];
348+					drawlevel();
349+					drawscreen();
350+				}
351+				break;
352+			case 'r':
353+			case 'R':
354+				level = levels[level.index];
355+				drawlevel();
356+				drawscreen();
357+				break;
358+			case 61454:
359+			case 63488:
360+			case 61457:
361+			case 61458:
362+			case ' ':
363+				move(key2move(ev.kbdc));
364+				drawscreen();
365+				break;
366+			default:
367+				// fprint(2, "key: %d]\n", e.kbdc);
368+				break;
369+			}
370+			break;
371+
372+		default:
373+			if (e == timer) {
374+				if (animate)
375+					onestep(&a);
376+				else
377+					while(onestep(&a))
378+						;
379+				drawscreen();
380+			}
381+			break;
382+		}
383+
384+		if(finished()) {
385+			level.done = 1;
386+			drawwin();
387+			drawscreen();
388+			sleep(3000);
389+			if(level.index < numlevels - 1) {
390+				level = levels[++level.index];
391+				drawlevel();
392+				drawscreen();
393+			}
394+		}
395+	}
396+}
397+
+120, -0
  1@@ -0,0 +1,120 @@
  2+enum {
  3+	/* levels */
  4+	Empty		= 0,
  5+	Background,
  6+	Wall, 
  7+	Cargo,
  8+	Goal,
  9+	GoalCargo,
 10+	Glenda,
 11+
 12+	/* movements */
 13+	Up,
 14+	Down,
 15+	Left,
 16+	Right,
 17+};
 18+
 19+enum {
 20+	/* glenda faces the horizontal direction she's moving in */
 21+	GLeft	= 0,
 22+	GRight 	= 1,
 23+};
 24+
 25+enum {
 26+	MazeX = 20,
 27+	MazeY = 18,
 28+	BoardX = 49,
 29+	BoardY = 49,
 30+	SizeX = MazeX*BoardX+10,	
 31+	SizeY = MazeY*BoardY+10,
 32+
 33+	Maxlevels = 200,
 34+};
 35+
 36+typedef struct Step {
 37+	uint dir;		/* direction */
 38+	uint count;	/* number of single-step moves */
 39+} Step;
 40+
 41+typedef struct Route {
 42+	uint nstep;	/* number of valid Step */
 43+	Step *step;
 44+	Point dest;	/* result of step */
 45+} Route;
 46+
 47+typedef struct Walk {
 48+	uint nroute;	/* number of valid Route* */
 49+	Route **route;
 50+	uint beyond;	/* number of allocated Route* */
 51+} Walk;
 52+
 53+typedef struct Visited {
 54+	uint 	board[MazeX][MazeY];
 55+} Visited;
 56+
 57+typedef struct Animation {
 58+	Route* route;
 59+	Step *step;
 60+	int count;
 61+} Animation;
 62+
 63+typedef struct {
 64+	Point 	glenda;
 65+	Point 	max;		/* that's how much the board spans */
 66+	uint 	index;
 67+	uint	done;
 68+	uint 	board[MazeX][MazeY];
 69+} Level;
 70+
 71+extern Level level;		/* the current level */
 72+extern Level levels[Maxlevels];	/* all levels from this file */
 73+extern int numlevels;		/* how many levels do we have */
 74+
 75+extern Image *img;		/* buffer */
 76+extern Image *text;		/* for text messages */
 77+extern Image *win;
 78+
 79+extern Image *goal;
 80+extern Image *cargo;
 81+extern Image *goalcargo;
 82+extern Image *wall;
 83+extern Image *empty;
 84+extern Image *gleft;
 85+extern Image *gright;
 86+extern Image *glenda;
 87+extern Image *bg;
 88+
 89+/* graphics.c */
 90+void drawscreen(void);
 91+void drawlevel(void);
 92+void drawwin(void);
 93+void drawglenda(void);
 94+void drawboard(Point);
 95+void resize(Point);
 96+Point boardsize(Point);
 97+
 98+/* level.c */
 99+int loadlevels(char *);
100+
101+/* move.c */
102+void move(int);
103+
104+/* route.c */
105+int validpush(Point, Step*, Point*);
106+int isvalid(Point, Route*, int (*)(Point, Step*, Point*));
107+void freeroute(Route*);
108+Route* extend(Route*, int, int, Point);
109+Route* findroute(Point, Point);
110+
111+/* animation.c */
112+void initanimation(Animation*);
113+void setupanimation(Animation*, Route*);
114+int onestep(Animation*);
115+void stopanimation(Animation*);
116+
117+
118+/* sokoban.c */
119+char *genlevels(int);
120+Image *eallocimage(Rectangle, int, uint);
121+