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