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