xref: /plan9/sys/src/games/sokoban/move.c (revision a7b224503558a0aa961cd3f8978597a7421dac99)
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 
5 #include "sokoban.h"
6 
7 /* pretty ghastly, if you ask me */
8 void
move(int key)9 move(int key)
10 {
11 	Point g = level.glenda;
12 	int moved = 0;
13 
14 	/* this is messy; no time for math */
15 	switch(key) {
16 	case Up:
17 		switch(level.board[g.x][g.y-1]) {
18 		case Empty:
19 		case Goal:
20 			moved = 1;
21 			level.glenda = Pt(g.x, g.y-1);
22 			break;
23 		case Cargo:
24 		case GoalCargo:
25 			switch(level.board[g.x][g.y-2]) {
26 			case Empty:
27 				moved = 1;
28 				level.board[g.x][g.y-2] = Cargo;
29 				drawboard(Pt(g.x, g.y-2));
30 				break;
31 			case Goal:
32 				moved = 1;
33 				level.board[g.x][g.y-2] = GoalCargo;
34 				drawboard(Pt(g.x, g.y-2));
35 				break;
36 			}
37 			if(moved) {
38 				level.board[g.x][g.y-1] = (level.board[g.x][g.y-1] == Cargo) ? Empty : Goal;
39 				level.glenda = Pt(g.x, g.y-1);
40 			}
41 			break;
42 		}
43 		break;
44 	case Down:
45 		switch(level.board[g.x][g.y+1]) {
46 		case Empty:
47 		case Goal:
48 			moved = 1;
49 			level.glenda = Pt(g.x, g.y+1);
50 			break;
51 		case Cargo:
52 		case GoalCargo:
53 			switch(level.board[g.x][g.y+2]) {
54 			case Empty:
55 				moved = 1;
56 				level.board[g.x][g.y+2] = Cargo;
57 				drawboard(Pt(g.x, g.y+2));
58 				break;
59 			case Goal:
60 				moved = 1;
61 				level.board[g.x][g.y+2] = GoalCargo;
62 				drawboard(Pt(g.x, g.y+2));
63 				break;
64 			}
65 			if(moved) {
66 				level.board[g.x][g.y+1] = (level.board[g.x][g.y+1] == Cargo) ? Empty : Goal;
67 				level.glenda = Pt(g.x, g.y+1);
68 			}
69 			break;
70 		}
71 		break;
72 	case Left:
73 		glenda = gleft;
74 		switch(level.board[g.x-1][g.y]) {
75 		case Empty:
76 		case Goal:
77 			moved = 1;
78 			level.glenda = Pt(g.x-1, g.y);
79 			break;
80 		case Cargo:
81 		case GoalCargo:
82 			switch(level.board[g.x-2][g.y]) {
83 			case Empty:
84 				moved = 1;
85 				level.board[g.x-2][g.y] = Cargo;
86 				drawboard(Pt(g.x-2, g.y));
87 				break;
88 			case Goal:
89 				moved = 1;
90 				level.board[g.x-2][g.y] = GoalCargo;
91 				drawboard(Pt(g.x-2, g.y));
92 				break;
93 			}
94 			if(moved) {
95 				level.board[g.x-1][g.y] = (level.board[g.x-1][g.y] == Cargo) ? Empty : Goal;
96 				level.glenda = Pt(g.x-1, g.y);
97 			}
98 			break;
99 		}
100 		break;
101 	case Right:
102 		glenda = gright;
103 		switch(level.board[g.x+1][g.y]) {
104 		case Empty:
105 		case Goal:
106 			moved = 1;
107 			level.glenda = Pt(g.x+1, g.y);
108 			break;
109 		case Cargo:
110 		case GoalCargo:
111 			switch(level.board[g.x+2][g.y]) {
112 			case Empty:
113 				moved = 1;
114 				level.board[g.x+2][g.y] = Cargo;
115 				drawboard(Pt(g.x+2, g.y));
116 				break;
117 			case Goal:
118 				moved = 1;
119 				level.board[g.x+2][g.y] = GoalCargo;
120 				drawboard(Pt(g.x+2, g.y));
121 				break;
122 			}
123 			if(moved) {
124 				level.board[g.x+1][g.y] = (level.board[g.x+1][g.y] == Cargo) ? Empty : Goal;
125 				level.glenda = Pt(g.x+1, g.y);
126 			}
127 			break;
128 		}
129 		break;
130 	}
131 	if(moved)
132 		drawboard(Pt(g.x, g.y));
133 
134 	drawglenda();
135 }
136 
137