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