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