1 /*
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)move.c 8.1 (Berkeley) 05/31/93";
10 #endif /* not lint */
11
12 #include <sys/ttydefaults.h>
13 #include <ctype.h>
14 #include "robots.h"
15
16 # define ESC '\033'
17
18 /*
19 * get_move:
20 * Get and execute a move from the player
21 */
get_move()22 get_move()
23 {
24 register int c;
25 register int y, x, lastmove;
26 static COORD newpos;
27
28 if (Waiting)
29 return;
30
31 #ifdef FANCY
32 if (Pattern_roll) {
33 if (Next_move >= Move_list)
34 lastmove = *Next_move;
35 else
36 lastmove = -1; /* flag for "first time in" */
37 }
38 #endif
39 for (;;) {
40 if (Teleport && must_telep())
41 goto teleport;
42 if (Running)
43 c = Run_ch;
44 else if (Count != 0)
45 c = Cnt_move;
46 #ifdef FANCY
47 else if (Num_robots > 1 && Stand_still)
48 c = '>';
49 else if (Num_robots > 1 && Pattern_roll) {
50 if (*++Next_move == '\0') {
51 if (lastmove < 0)
52 goto over;
53 Next_move = Move_list;
54 }
55 c = *Next_move;
56 mvaddch(0, 0, c);
57 if (c == lastmove)
58 goto over;
59 }
60 #endif
61 else {
62 over:
63 c = getchar();
64 if (isdigit(c)) {
65 Count = (c - '0');
66 while (isdigit(c = getchar()))
67 Count = Count * 10 + (c - '0');
68 if (c == ESC)
69 goto over;
70 Cnt_move = c;
71 if (Count)
72 leaveok(stdscr, TRUE);
73 }
74 }
75
76 switch (c) {
77 case ' ':
78 case '.':
79 if (do_move(0, 0))
80 goto ret;
81 break;
82 case 'y':
83 if (do_move(-1, -1))
84 goto ret;
85 break;
86 case 'k':
87 if (do_move(-1, 0))
88 goto ret;
89 break;
90 case 'u':
91 if (do_move(-1, 1))
92 goto ret;
93 break;
94 case 'h':
95 if (do_move(0, -1))
96 goto ret;
97 break;
98 case 'l':
99 if (do_move(0, 1))
100 goto ret;
101 break;
102 case 'b':
103 if (do_move(1, -1))
104 goto ret;
105 break;
106 case 'j':
107 if (do_move(1, 0))
108 goto ret;
109 break;
110 case 'n':
111 if (do_move(1, 1))
112 goto ret;
113 break;
114 case 'Y': case 'U': case 'H': case 'J':
115 case 'K': case 'L': case 'B': case 'N':
116 case '>':
117 Running = TRUE;
118 if (c == '>')
119 Run_ch = ' ';
120 else
121 Run_ch = tolower(c);
122 leaveok(stdscr, TRUE);
123 break;
124 case 'q':
125 case 'Q':
126 if (query("Really quit?"))
127 quit();
128 refresh();
129 break;
130 case 'w':
131 case 'W':
132 Waiting = TRUE;
133 leaveok(stdscr, TRUE);
134 flushok(stdscr, FALSE);
135 goto ret;
136 case 't':
137 case 'T':
138 teleport:
139 Running = FALSE;
140 mvaddch(My_pos.y, My_pos.x, ' ');
141 My_pos = *rnd_pos();
142 mvaddch(My_pos.y, My_pos.x, PLAYER);
143 leaveok(stdscr, FALSE);
144 refresh();
145 flush_in();
146 goto ret;
147 case CTRL('L'):
148 wrefresh(curscr);
149 break;
150 case EOF:
151 break;
152 default:
153 putchar(CTRL('G'));
154 reset_count();
155 fflush(stdout);
156 break;
157 }
158 }
159 ret:
160 if (Count > 0)
161 if (--Count == 0)
162 leaveok(stdscr, FALSE);
163 }
164
165 /*
166 * must_telep:
167 * Must I teleport; i.e., is there anywhere I can move without
168 * being eaten?
169 */
must_telep()170 must_telep()
171 {
172 register int x, y;
173 static COORD newpos;
174
175 #ifdef FANCY
176 if (Stand_still && Num_robots > 1 && eaten(&My_pos))
177 return TRUE;
178 #endif
179
180 for (y = -1; y <= 1; y++) {
181 newpos.y = My_pos.y + y;
182 if (newpos.y <= 0 || newpos.y >= Y_FIELDSIZE)
183 continue;
184 for (x = -1; x <= 1; x++) {
185 newpos.x = My_pos.x + x;
186 if (newpos.x <= 0 || newpos.x >= X_FIELDSIZE)
187 continue;
188 if (Field[newpos.y][newpos.x] > 0)
189 continue;
190 if (!eaten(&newpos))
191 return FALSE;
192 }
193 }
194 return TRUE;
195 }
196
197 /*
198 * do_move:
199 * Execute a move
200 */
do_move(dy,dx)201 do_move(dy, dx)
202 int dy, dx;
203 {
204 static COORD newpos;
205
206 newpos.y = My_pos.y + dy;
207 newpos.x = My_pos.x + dx;
208 if (newpos.y <= 0 || newpos.y >= Y_FIELDSIZE ||
209 newpos.x <= 0 || newpos.x >= X_FIELDSIZE ||
210 Field[newpos.y][newpos.x] > 0 || eaten(&newpos)) {
211 if (Running) {
212 Running = FALSE;
213 leaveok(stdscr, FALSE);
214 move(My_pos.y, My_pos.x);
215 refresh();
216 }
217 else {
218 putchar(CTRL('G'));
219 reset_count();
220 }
221 return FALSE;
222 }
223 else if (dy == 0 && dx == 0)
224 return TRUE;
225 mvaddch(My_pos.y, My_pos.x, ' ');
226 My_pos = newpos;
227 mvaddch(My_pos.y, My_pos.x, PLAYER);
228 if (!jumping())
229 refresh();
230 return TRUE;
231 }
232
233 /*
234 * eaten:
235 * Player would get eaten at this place
236 */
eaten(pos)237 eaten(pos)
238 register COORD *pos;
239 {
240 register int x, y;
241
242 for (y = pos->y - 1; y <= pos->y + 1; y++) {
243 if (y <= 0 || y >= Y_FIELDSIZE)
244 continue;
245 for (x = pos->x - 1; x <= pos->x + 1; x++) {
246 if (x <= 0 || x >= X_FIELDSIZE)
247 continue;
248 if (Field[y][x] == 1)
249 return TRUE;
250 }
251 }
252 return FALSE;
253 }
254
255 /*
256 * reset_count:
257 * Reset the count variables
258 */
reset_count()259 reset_count()
260 {
261 Count = 0;
262 Running = FALSE;
263 leaveok(stdscr, FALSE);
264 refresh();
265 }
266
267 /*
268 * jumping:
269 * See if we are jumping, i.e., we should not refresh.
270 */
jumping()271 jumping()
272 {
273 return (Jump && (Count || Running || Waiting));
274 }
275