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