mandoc(1): Update to 1.9.15.
[dragonfly.git] / games / robots / move.c
blob4103f0fc8269c2ad60831941f39e6fa1389a2c30
1 /*-
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
29 * @(#)move.c 8.1 (Berkeley) 5/31/93
30 * $FreeBSD: src/games/robots/move.c,v 1.6 1999/11/30 03:49:18 billf Exp $
31 * $DragonFly: src/games/robots/move.c,v 1.3 2006/08/27 21:45:07 pavalos Exp $
34 #include <sys/ttydefaults.h>
35 #include <ctype.h>
36 #include "robots.h"
38 #define ESC '\033'
40 static bool must_telep(void);
41 static bool do_move(int, int);
42 static bool eaten(COORD *);
45 * get_move:
46 * Get and execute a move from the player
48 void
49 get_move(void)
51 int c;
52 #ifdef FANCY
53 int lastmove;
54 #endif
55 if (Waiting)
56 return;
58 #ifdef FANCY
59 if (Pattern_roll) {
60 if (Next_move >= Move_list)
61 lastmove = *Next_move;
62 else
63 lastmove = -1; /* flag for "first time in" */
64 } else
65 lastmove = 0; /* Shut up gcc */
66 #endif
67 for (;;) {
68 if (Teleport && must_telep())
69 goto teleport;
70 if (Running)
71 c = Run_ch;
72 else if (Count != 0)
73 c = Cnt_move;
74 #ifdef FANCY
75 else if (Num_robots > 1 && Stand_still)
76 c = '>';
77 else if (Num_robots > 1 && Pattern_roll) {
78 if (*++Next_move == '\0') {
79 if (lastmove < 0)
80 goto over;
81 Next_move = Move_list;
83 c = *Next_move;
84 mvaddch(0, 0, c);
85 if (c == lastmove)
86 goto over;
88 #endif
89 else {
90 over:
91 c = getchar();
92 if (isdigit(c)) {
93 Count = (c - '0');
94 while (isdigit(c = getchar()))
95 Count = Count * 10 + (c - '0');
96 if (c == ESC)
97 goto over;
98 Cnt_move = c;
99 if (Count)
100 leaveok(stdscr, true);
104 switch (c) {
105 case ' ':
106 case '.':
107 if (do_move(0, 0))
108 goto ret;
109 break;
110 case 'y':
111 if (do_move(-1, -1))
112 goto ret;
113 break;
114 case 'k':
115 if (do_move(-1, 0))
116 goto ret;
117 break;
118 case 'u':
119 if (do_move(-1, 1))
120 goto ret;
121 break;
122 case 'h':
123 if (do_move(0, -1))
124 goto ret;
125 break;
126 case 'l':
127 if (do_move(0, 1))
128 goto ret;
129 break;
130 case 'b':
131 if (do_move(1, -1))
132 goto ret;
133 break;
134 case 'j':
135 if (do_move(1, 0))
136 goto ret;
137 break;
138 case 'n':
139 if (do_move(1, 1))
140 goto ret;
141 break;
142 case 'Y': case 'U': case 'H': case 'J':
143 case 'K': case 'L': case 'B': case 'N':
144 case '>':
145 Running = true;
146 if (c == '>')
147 Run_ch = ' ';
148 else
149 Run_ch = tolower(c);
150 leaveok(stdscr, true);
151 break;
152 case 'q':
153 case 'Q':
154 if (query("Really quit?"))
155 quit();
156 refresh();
157 break;
158 case 'w':
159 case 'W':
160 Waiting = true;
161 leaveok(stdscr, true);
162 goto ret;
163 case 't':
164 case 'T':
165 teleport:
166 Running = false;
167 mvaddch(My_pos.y, My_pos.x, ' ');
168 My_pos = *rnd_pos();
169 mvaddch(My_pos.y, My_pos.x, PLAYER);
170 leaveok(stdscr, false);
171 refresh();
172 flush_in();
173 goto ret;
174 case CTRL('L'):
175 wrefresh(curscr);
176 break;
177 case EOF:
178 break;
179 default:
180 putchar(CTRL('G'));
181 reset_count();
182 fflush(stdout);
183 break;
186 ret:
187 if (Count > 0)
188 if (--Count == 0)
189 leaveok(stdscr, false);
193 * must_telep:
194 * Must I teleport; i.e., is there anywhere I can move without
195 * being eaten?
197 static bool
198 must_telep(void)
200 int x, y;
201 static COORD newpos;
203 #ifdef FANCY
204 if (Stand_still && Num_robots > 1 && eaten(&My_pos))
205 return true;
206 #endif
208 for (y = -1; y <= 1; y++) {
209 newpos.y = My_pos.y + y;
210 if (newpos.y <= 0 || newpos.y >= Y_FIELDSIZE)
211 continue;
212 for (x = -1; x <= 1; x++) {
213 newpos.x = My_pos.x + x;
214 if (newpos.x <= 0 || newpos.x >= X_FIELDSIZE)
215 continue;
216 if (Field[newpos.y][newpos.x] > 0)
217 continue;
218 if (!eaten(&newpos))
219 return false;
222 return true;
226 * do_move:
227 * Execute a move
229 static bool
230 do_move(int dy, int dx)
232 static COORD newpos;
234 newpos.y = My_pos.y + dy;
235 newpos.x = My_pos.x + dx;
236 if (newpos.y <= 0 || newpos.y >= Y_FIELDSIZE ||
237 newpos.x <= 0 || newpos.x >= X_FIELDSIZE ||
238 Field[newpos.y][newpos.x] > 0 || eaten(&newpos)) {
239 if (Running) {
240 Running = false;
241 leaveok(stdscr, false);
242 move(My_pos.y, My_pos.x);
243 refresh();
245 else {
246 putchar(CTRL('G'));
247 reset_count();
249 return false;
251 else if (dy == 0 && dx == 0)
252 return true;
253 mvaddch(My_pos.y, My_pos.x, ' ');
254 My_pos = newpos;
255 mvaddch(My_pos.y, My_pos.x, PLAYER);
256 if (!jumping())
257 refresh();
258 return true;
262 * eaten:
263 * Player would get eaten at this place
265 static bool
266 eaten(COORD *pos)
268 int x, y;
270 for (y = pos->y - 1; y <= pos->y + 1; y++) {
271 if (y <= 0 || y >= Y_FIELDSIZE)
272 continue;
273 for (x = pos->x - 1; x <= pos->x + 1; x++) {
274 if (x <= 0 || x >= X_FIELDSIZE)
275 continue;
276 if (Field[y][x] == 1)
277 return true;
280 return false;
284 * reset_count:
285 * Reset the count variables
287 void
288 reset_count(void)
290 Count = 0;
291 Running = false;
292 leaveok(stdscr, false);
293 refresh();
297 * jumping:
298 * See if we are jumping, i.e., we should not refresh.
300 bool
301 jumping(void)
303 return (Jump && (Count || Running || Waiting));