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