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, 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 /*static char sccsid[] = "from: @(#)move.c 5.4 (Berkeley) 6/1/90";*/ 36 static char rcsid[] = "$Id: move.c,v 1.3 1993/08/01 18:52:44 mycroft Exp $"; 37 #endif /* not lint */ 38 39 # include "robots.h" 40 # include <ctype.h> 41 42 # define ESC '\033' 43 44 /* 45 * get_move: 46 * Get and execute a move from the player 47 */ 48 get_move() 49 { 50 register int c; 51 register int y, x, lastmove; 52 static COORD newpos; 53 54 if (Waiting) 55 return; 56 57 #ifdef FANCY 58 if (Pattern_roll) { 59 if (Next_move >= Move_list) 60 lastmove = *Next_move; 61 else 62 lastmove = -1; /* flag for "first time in" */ 63 } 64 #endif 65 for (;;) { 66 if (Teleport && must_telep()) 67 goto teleport; 68 if (Running) 69 c = Run_ch; 70 else if (Count != 0) 71 c = Cnt_move; 72 #ifdef FANCY 73 else if (Num_robots > 1 && Stand_still) 74 c = '>'; 75 else if (Num_robots > 1 && Pattern_roll) { 76 if (*++Next_move == '\0') { 77 if (lastmove < 0) 78 goto over; 79 Next_move = Move_list; 80 } 81 c = *Next_move; 82 mvaddch(0, 0, c); 83 if (c == lastmove) 84 goto over; 85 } 86 #endif 87 else { 88 over: 89 c = getchar(); 90 if (isdigit(c)) { 91 Count = (c - '0'); 92 while (isdigit(c = getchar())) 93 Count = Count * 10 + (c - '0'); 94 if (c == ESC) 95 goto over; 96 Cnt_move = c; 97 if (Count) 98 leaveok(stdscr, TRUE); 99 } 100 } 101 102 switch (c) { 103 case ' ': 104 case '.': 105 if (do_move(0, 0)) 106 goto ret; 107 break; 108 case 'y': 109 if (do_move(-1, -1)) 110 goto ret; 111 break; 112 case 'k': 113 if (do_move(-1, 0)) 114 goto ret; 115 break; 116 case 'u': 117 if (do_move(-1, 1)) 118 goto ret; 119 break; 120 case 'h': 121 if (do_move(0, -1)) 122 goto ret; 123 break; 124 case 'l': 125 if (do_move(0, 1)) 126 goto ret; 127 break; 128 case 'b': 129 if (do_move(1, -1)) 130 goto ret; 131 break; 132 case 'j': 133 if (do_move(1, 0)) 134 goto ret; 135 break; 136 case 'n': 137 if (do_move(1, 1)) 138 goto ret; 139 break; 140 case 'Y': case 'U': case 'H': case 'J': 141 case 'K': case 'L': case 'B': case 'N': 142 case '>': 143 Running = TRUE; 144 if (c == '>') 145 Run_ch = ' '; 146 else 147 Run_ch = tolower(c); 148 leaveok(stdscr, TRUE); 149 break; 150 case 'q': 151 case 'Q': 152 if (query("Really quit?")) 153 quit(); 154 refresh(); 155 break; 156 case 'w': 157 case 'W': 158 Waiting = TRUE; 159 leaveok(stdscr, TRUE); 160 flushok(stdscr, FALSE); 161 goto ret; 162 case 't': 163 case 'T': 164 teleport: 165 Running = FALSE; 166 mvaddch(My_pos.y, My_pos.x, ' '); 167 My_pos = *rnd_pos(); 168 mvaddch(My_pos.y, My_pos.x, PLAYER); 169 leaveok(stdscr, FALSE); 170 refresh(); 171 flush_in(); 172 goto ret; 173 case CTRL('L'): 174 wrefresh(curscr); 175 break; 176 case EOF: 177 break; 178 default: 179 putchar(CTRL('G')); 180 reset_count(); 181 fflush(stdout); 182 break; 183 } 184 } 185 ret: 186 if (Count > 0) 187 if (--Count == 0) 188 leaveok(stdscr, FALSE); 189 } 190 191 /* 192 * must_telep: 193 * Must I teleport; i.e., is there anywhere I can move without 194 * being eaten? 195 */ 196 must_telep() 197 { 198 register int x, y; 199 static COORD newpos; 200 201 #ifdef FANCY 202 if (Stand_still && Num_robots > 1 && eaten(&My_pos)) 203 return TRUE; 204 #endif 205 206 for (y = -1; y <= 1; y++) { 207 newpos.y = My_pos.y + y; 208 if (newpos.y <= 0 || newpos.y >= Y_FIELDSIZE) 209 continue; 210 for (x = -1; x <= 1; x++) { 211 newpos.x = My_pos.x + x; 212 if (newpos.x <= 0 || newpos.x >= X_FIELDSIZE) 213 continue; 214 if (Field[newpos.y][newpos.x] > 0) 215 continue; 216 if (!eaten(&newpos)) 217 return FALSE; 218 } 219 } 220 return TRUE; 221 } 222 223 /* 224 * do_move: 225 * Execute a move 226 */ 227 do_move(dy, dx) 228 int dy, dx; 229 { 230 static COORD newpos; 231 232 newpos.y = My_pos.y + dy; 233 newpos.x = My_pos.x + dx; 234 if (newpos.y <= 0 || newpos.y >= Y_FIELDSIZE || 235 newpos.x <= 0 || newpos.x >= X_FIELDSIZE || 236 Field[newpos.y][newpos.x] > 0 || eaten(&newpos)) { 237 if (Running) { 238 Running = FALSE; 239 leaveok(stdscr, FALSE); 240 move(My_pos.y, My_pos.x); 241 refresh(); 242 } 243 else { 244 putchar(CTRL('G')); 245 reset_count(); 246 } 247 return FALSE; 248 } 249 else if (dy == 0 && dx == 0) 250 return TRUE; 251 mvaddch(My_pos.y, My_pos.x, ' '); 252 My_pos = newpos; 253 mvaddch(My_pos.y, My_pos.x, PLAYER); 254 if (!jumping()) 255 refresh(); 256 return TRUE; 257 } 258 259 /* 260 * eaten: 261 * Player would get eaten at this place 262 */ 263 eaten(pos) 264 register COORD *pos; 265 { 266 register int x, y; 267 268 for (y = pos->y - 1; y <= pos->y + 1; y++) { 269 if (y <= 0 || y >= Y_FIELDSIZE) 270 continue; 271 for (x = pos->x - 1; x <= pos->x + 1; x++) { 272 if (x <= 0 || x >= X_FIELDSIZE) 273 continue; 274 if (Field[y][x] == 1) 275 return TRUE; 276 } 277 } 278 return FALSE; 279 } 280 281 /* 282 * reset_count: 283 * Reset the count variables 284 */ 285 reset_count() 286 { 287 Count = 0; 288 Running = FALSE; 289 leaveok(stdscr, FALSE); 290 refresh(); 291 } 292 293 /* 294 * jumping: 295 * See if we are jumping, i.e., we should not refresh. 296 */ 297 jumping() 298 { 299 return (Jump && (Count || Running || Waiting)); 300 } 301