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 * @(#)move.c 8.1 (Berkeley) 5/31/93 34 * $FreeBSD: src/games/robots/move.c,v 1.6 1999/11/30 03:49:18 billf Exp $ 35 * $DragonFly: src/games/robots/move.c,v 1.2 2003/06/17 04:25:24 dillon Exp $ 36 */ 37 38 #include <sys/ttydefaults.h> 39 #include <ctype.h> 40 #include "robots.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 int c; 51 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 } else 64 lastmove = 0; /* Shut up gcc */ 65 #endif 66 for (;;) { 67 if (Teleport && must_telep()) 68 goto teleport; 69 if (Running) 70 c = Run_ch; 71 else if (Count != 0) 72 c = Cnt_move; 73 #ifdef FANCY 74 else if (Num_robots > 1 && Stand_still) 75 c = '>'; 76 else if (Num_robots > 1 && Pattern_roll) { 77 if (*++Next_move == '\0') { 78 if (lastmove < 0) 79 goto over; 80 Next_move = Move_list; 81 } 82 c = *Next_move; 83 mvaddch(0, 0, c); 84 if (c == lastmove) 85 goto over; 86 } 87 #endif 88 else { 89 over: 90 c = getchar(); 91 if (isdigit(c)) { 92 Count = (c - '0'); 93 while (isdigit(c = getchar())) 94 Count = Count * 10 + (c - '0'); 95 if (c == ESC) 96 goto over; 97 Cnt_move = c; 98 if (Count) 99 leaveok(stdscr, TRUE); 100 } 101 } 102 103 switch (c) { 104 case ' ': 105 case '.': 106 if (do_move(0, 0)) 107 goto ret; 108 break; 109 case 'y': 110 if (do_move(-1, -1)) 111 goto ret; 112 break; 113 case 'k': 114 if (do_move(-1, 0)) 115 goto ret; 116 break; 117 case 'u': 118 if (do_move(-1, 1)) 119 goto ret; 120 break; 121 case 'h': 122 if (do_move(0, -1)) 123 goto ret; 124 break; 125 case 'l': 126 if (do_move(0, 1)) 127 goto ret; 128 break; 129 case 'b': 130 if (do_move(1, -1)) 131 goto ret; 132 break; 133 case 'j': 134 if (do_move(1, 0)) 135 goto ret; 136 break; 137 case 'n': 138 if (do_move(1, 1)) 139 goto ret; 140 break; 141 case 'Y': case 'U': case 'H': case 'J': 142 case 'K': case 'L': case 'B': case 'N': 143 case '>': 144 Running = TRUE; 145 if (c == '>') 146 Run_ch = ' '; 147 else 148 Run_ch = tolower(c); 149 leaveok(stdscr, TRUE); 150 break; 151 case 'q': 152 case 'Q': 153 if (query("Really quit?")) 154 quit(); 155 refresh(); 156 break; 157 case 'w': 158 case 'W': 159 Waiting = TRUE; 160 leaveok(stdscr, TRUE); 161 /* flushok(stdscr, FALSE); */ 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; 184 } 185 } 186 ret: 187 if (Count > 0) 188 if (--Count == 0) 189 leaveok(stdscr, FALSE); 190 } 191 192 /* 193 * must_telep: 194 * Must I teleport; i.e., is there anywhere I can move without 195 * being eaten? 196 */ 197 must_telep() 198 { 199 int x, y; 200 static COORD newpos; 201 202 #ifdef FANCY 203 if (Stand_still && Num_robots > 1 && eaten(&My_pos)) 204 return TRUE; 205 #endif 206 207 for (y = -1; y <= 1; y++) { 208 newpos.y = My_pos.y + y; 209 if (newpos.y <= 0 || newpos.y >= Y_FIELDSIZE) 210 continue; 211 for (x = -1; x <= 1; x++) { 212 newpos.x = My_pos.x + x; 213 if (newpos.x <= 0 || newpos.x >= X_FIELDSIZE) 214 continue; 215 if (Field[newpos.y][newpos.x] > 0) 216 continue; 217 if (!eaten(&newpos)) 218 return FALSE; 219 } 220 } 221 return TRUE; 222 } 223 224 /* 225 * do_move: 226 * Execute a move 227 */ 228 do_move(dy, dx) 229 int dy, dx; 230 { 231 static COORD newpos; 232 233 newpos.y = My_pos.y + dy; 234 newpos.x = My_pos.x + dx; 235 if (newpos.y <= 0 || newpos.y >= Y_FIELDSIZE || 236 newpos.x <= 0 || newpos.x >= X_FIELDSIZE || 237 Field[newpos.y][newpos.x] > 0 || eaten(&newpos)) { 238 if (Running) { 239 Running = FALSE; 240 leaveok(stdscr, FALSE); 241 move(My_pos.y, My_pos.x); 242 refresh(); 243 } 244 else { 245 putchar(CTRL('G')); 246 reset_count(); 247 } 248 return FALSE; 249 } 250 else if (dy == 0 && dx == 0) 251 return TRUE; 252 mvaddch(My_pos.y, My_pos.x, ' '); 253 My_pos = newpos; 254 mvaddch(My_pos.y, My_pos.x, PLAYER); 255 if (!jumping()) 256 refresh(); 257 return TRUE; 258 } 259 260 /* 261 * eaten: 262 * Player would get eaten at this place 263 */ 264 eaten(pos) 265 COORD *pos; 266 { 267 int x, y; 268 269 for (y = pos->y - 1; y <= pos->y + 1; y++) { 270 if (y <= 0 || y >= Y_FIELDSIZE) 271 continue; 272 for (x = pos->x - 1; x <= pos->x + 1; x++) { 273 if (x <= 0 || x >= X_FIELDSIZE) 274 continue; 275 if (Field[y][x] == 1) 276 return TRUE; 277 } 278 } 279 return FALSE; 280 } 281 282 /* 283 * reset_count: 284 * Reset the count variables 285 */ 286 reset_count() 287 { 288 Count = 0; 289 Running = FALSE; 290 leaveok(stdscr, FALSE); 291 refresh(); 292 } 293 294 /* 295 * jumping: 296 * See if we are jumping, i.e., we should not refresh. 297 */ 298 jumping() 299 { 300 return (Jump && (Count || Running || Waiting)); 301 } 302