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