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