xref: /original-bsd/games/robots/move.c (revision 6fcea464)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
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.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)move.c	5.3 (Berkeley) 06/18/88";
20 #endif /* not lint */
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  */
31 get_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 {
71 over:
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':
147 teleport:
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 	}
168 ret:
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  */
179 must_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  */
210 do_move(dy, dx)
211 int	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  */
246 eaten(pos)
247 register 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  */
268 reset_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  */
280 jumping()
281 {
282 	return (Jump && (Count || Running || Waiting));
283 }
284