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