xref: /csrg-svn/games/robots/move.c (revision 60840)
121468Smckusick /*
2*60840Sbostic  * Copyright (c) 1980, 1993
3*60840Sbostic  *	The Regents of the University of California.  All rights reserved.
433690Sbostic  *
542589Sbostic  * %sccs.include.redist.c%
621468Smckusick  */
721468Smckusick 
821468Smckusick #ifndef lint
9*60840Sbostic static char sccsid[] = "@(#)move.c	8.1 (Berkeley) 05/31/93";
1033690Sbostic #endif /* not lint */
1121468Smckusick 
1256100Selan #include <sys/ttydefaults.h>
1356100Selan #include <ctype.h>
1456100Selan #include "robots.h"
1521468Smckusick 
1621468Smckusick # define	ESC	'\033'
1721468Smckusick 
1821468Smckusick /*
1921468Smckusick  * get_move:
2021468Smckusick  *	Get and execute a move from the player
2121468Smckusick  */
get_move()2221468Smckusick get_move()
2321468Smckusick {
2421468Smckusick 	register int	c;
2521468Smckusick 	register int	y, x, lastmove;
2621468Smckusick 	static COORD	newpos;
2721468Smckusick 
2821468Smckusick 	if (Waiting)
2921468Smckusick 		return;
3021468Smckusick 
3121468Smckusick #ifdef	FANCY
3221468Smckusick 	if (Pattern_roll) {
3321468Smckusick 		if (Next_move >= Move_list)
3421468Smckusick 			lastmove = *Next_move;
3521468Smckusick 		else
3621468Smckusick 			lastmove = -1;	/* flag for "first time in" */
3721468Smckusick 	}
3821468Smckusick #endif
3921468Smckusick 	for (;;) {
4021468Smckusick 		if (Teleport && must_telep())
4121468Smckusick 			goto teleport;
4221468Smckusick 		if (Running)
4321468Smckusick 			c = Run_ch;
4421468Smckusick 		else if (Count != 0)
4521468Smckusick 			c = Cnt_move;
4621468Smckusick #ifdef	FANCY
4721468Smckusick 		else if (Num_robots > 1 && Stand_still)
4821468Smckusick 			c = '>';
4921468Smckusick 		else if (Num_robots > 1 && Pattern_roll) {
5021468Smckusick 			if (*++Next_move == '\0') {
5121468Smckusick 				if (lastmove < 0)
5221468Smckusick 					goto over;
5321468Smckusick 				Next_move = Move_list;
5421468Smckusick 			}
5521468Smckusick 			c = *Next_move;
5621468Smckusick 			mvaddch(0, 0, c);
5721468Smckusick 			if (c == lastmove)
5821468Smckusick 				goto over;
5921468Smckusick 		}
6021468Smckusick #endif
6121468Smckusick 		else {
6221468Smckusick over:
6321468Smckusick 			c = getchar();
6421468Smckusick 			if (isdigit(c)) {
6521468Smckusick 				Count = (c - '0');
6621468Smckusick 				while (isdigit(c = getchar()))
6721468Smckusick 					Count = Count * 10 + (c - '0');
6821468Smckusick 				if (c == ESC)
6921468Smckusick 					goto over;
7021468Smckusick 				Cnt_move = c;
7121468Smckusick 				if (Count)
7221468Smckusick 					leaveok(stdscr, TRUE);
7321468Smckusick 			}
7421468Smckusick 		}
7521468Smckusick 
7621468Smckusick 		switch (c) {
7721468Smckusick 		  case ' ':
7821468Smckusick 		  case '.':
7921468Smckusick 			if (do_move(0, 0))
8021468Smckusick 				goto ret;
8121468Smckusick 			break;
8221468Smckusick 		  case 'y':
8321468Smckusick 			if (do_move(-1, -1))
8421468Smckusick 				goto ret;
8521468Smckusick 			break;
8621468Smckusick 		  case 'k':
8721468Smckusick 			if (do_move(-1, 0))
8821468Smckusick 				goto ret;
8921468Smckusick 			break;
9021468Smckusick 		  case 'u':
9121468Smckusick 			if (do_move(-1, 1))
9221468Smckusick 				goto ret;
9321468Smckusick 			break;
9421468Smckusick 		  case 'h':
9521468Smckusick 			if (do_move(0, -1))
9621468Smckusick 				goto ret;
9721468Smckusick 			break;
9821468Smckusick 		  case 'l':
9921468Smckusick 			if (do_move(0, 1))
10021468Smckusick 				goto ret;
10121468Smckusick 			break;
10221468Smckusick 		  case 'b':
10321468Smckusick 			if (do_move(1, -1))
10421468Smckusick 				goto ret;
10521468Smckusick 			break;
10621468Smckusick 		  case 'j':
10721468Smckusick 			if (do_move(1, 0))
10821468Smckusick 				goto ret;
10921468Smckusick 			break;
11021468Smckusick 		  case 'n':
11121468Smckusick 			if (do_move(1, 1))
11221468Smckusick 				goto ret;
11321468Smckusick 			break;
11421468Smckusick 		  case 'Y': case 'U': case 'H': case 'J':
11521468Smckusick 		  case 'K': case 'L': case 'B': case 'N':
11621468Smckusick 		  case '>':
11721468Smckusick 			Running = TRUE;
11821468Smckusick 			if (c == '>')
11921468Smckusick 				Run_ch = ' ';
12021468Smckusick 			else
12121468Smckusick 				Run_ch = tolower(c);
12221468Smckusick 			leaveok(stdscr, TRUE);
12321468Smckusick 			break;
12421468Smckusick 		  case 'q':
12521468Smckusick 		  case 'Q':
12621468Smckusick 			if (query("Really quit?"))
12721468Smckusick 				quit();
12821468Smckusick 			refresh();
12921468Smckusick 			break;
13021468Smckusick 		  case 'w':
13121468Smckusick 		  case 'W':
13221468Smckusick 			Waiting = TRUE;
13321468Smckusick 			leaveok(stdscr, TRUE);
13421468Smckusick 			flushok(stdscr, FALSE);
13521468Smckusick 			goto ret;
13621468Smckusick 		  case 't':
13721468Smckusick 		  case 'T':
13821468Smckusick teleport:
13921468Smckusick 			Running = FALSE;
14021468Smckusick 			mvaddch(My_pos.y, My_pos.x, ' ');
14121468Smckusick 			My_pos = *rnd_pos();
14221468Smckusick 			mvaddch(My_pos.y, My_pos.x, PLAYER);
14321468Smckusick 			leaveok(stdscr, FALSE);
14421468Smckusick 			refresh();
14521468Smckusick 			flush_in();
14621468Smckusick 			goto ret;
14756100Selan 		  case CTRL('L'):
14821468Smckusick 			wrefresh(curscr);
14921468Smckusick 			break;
15021468Smckusick 		  case EOF:
15121468Smckusick 			break;
15221468Smckusick 		  default:
15356100Selan 			putchar(CTRL('G'));
15421468Smckusick 			reset_count();
15521468Smckusick 			fflush(stdout);
15621468Smckusick 			break;
15721468Smckusick 		}
15821468Smckusick 	}
15921468Smckusick ret:
16021468Smckusick 	if (Count > 0)
16121468Smckusick 		if (--Count == 0)
16221468Smckusick 			leaveok(stdscr, FALSE);
16321468Smckusick }
16421468Smckusick 
16521468Smckusick /*
16621468Smckusick  * must_telep:
16721468Smckusick  *	Must I teleport; i.e., is there anywhere I can move without
16821468Smckusick  * being eaten?
16921468Smckusick  */
must_telep()17021468Smckusick must_telep()
17121468Smckusick {
17221468Smckusick 	register int	x, y;
17321468Smckusick 	static COORD	newpos;
17421468Smckusick 
17521468Smckusick #ifdef	FANCY
17621468Smckusick 	if (Stand_still && Num_robots > 1 && eaten(&My_pos))
17721468Smckusick 		return TRUE;
17821468Smckusick #endif
17921468Smckusick 
18021468Smckusick 	for (y = -1; y <= 1; y++) {
18121468Smckusick 		newpos.y = My_pos.y + y;
18221468Smckusick 		if (newpos.y <= 0 || newpos.y >= Y_FIELDSIZE)
18321468Smckusick 			continue;
18421468Smckusick 		for (x = -1; x <= 1; x++) {
18521468Smckusick 			newpos.x = My_pos.x + x;
18621468Smckusick 			if (newpos.x <= 0 || newpos.x >= X_FIELDSIZE)
18721468Smckusick 				continue;
18821468Smckusick 			if (Field[newpos.y][newpos.x] > 0)
18921468Smckusick 				continue;
19021468Smckusick 			if (!eaten(&newpos))
19121468Smckusick 				return FALSE;
19221468Smckusick 		}
19321468Smckusick 	}
19421468Smckusick 	return TRUE;
19521468Smckusick }
19621468Smckusick 
19721468Smckusick /*
19821468Smckusick  * do_move:
19921468Smckusick  *	Execute a move
20021468Smckusick  */
do_move(dy,dx)20121468Smckusick do_move(dy, dx)
20221468Smckusick int	dy, dx;
20321468Smckusick {
20421468Smckusick 	static COORD	newpos;
20521468Smckusick 
20621468Smckusick 	newpos.y = My_pos.y + dy;
20721468Smckusick 	newpos.x = My_pos.x + dx;
20821468Smckusick 	if (newpos.y <= 0 || newpos.y >= Y_FIELDSIZE ||
20921468Smckusick 	    newpos.x <= 0 || newpos.x >= X_FIELDSIZE ||
21021468Smckusick 	    Field[newpos.y][newpos.x] > 0 || eaten(&newpos)) {
21121468Smckusick 		if (Running) {
21221468Smckusick 			Running = FALSE;
21321468Smckusick 			leaveok(stdscr, FALSE);
21421468Smckusick 			move(My_pos.y, My_pos.x);
21521468Smckusick 			refresh();
21621468Smckusick 		}
21721468Smckusick 		else {
21856100Selan 			putchar(CTRL('G'));
21921468Smckusick 			reset_count();
22021468Smckusick 		}
22121468Smckusick 		return FALSE;
22221468Smckusick 	}
22321468Smckusick 	else if (dy == 0 && dx == 0)
22421468Smckusick 		return TRUE;
22521468Smckusick 	mvaddch(My_pos.y, My_pos.x, ' ');
22621468Smckusick 	My_pos = newpos;
22721468Smckusick 	mvaddch(My_pos.y, My_pos.x, PLAYER);
22821468Smckusick 	if (!jumping())
22921468Smckusick 		refresh();
23021468Smckusick 	return TRUE;
23121468Smckusick }
23221468Smckusick 
23321468Smckusick /*
23421468Smckusick  * eaten:
23521468Smckusick  *	Player would get eaten at this place
23621468Smckusick  */
eaten(pos)23721468Smckusick eaten(pos)
23821468Smckusick register COORD	*pos;
23921468Smckusick {
24021468Smckusick 	register int	x, y;
24121468Smckusick 
24221468Smckusick 	for (y = pos->y - 1; y <= pos->y + 1; y++) {
24321468Smckusick 		if (y <= 0 || y >= Y_FIELDSIZE)
24421468Smckusick 			continue;
24521468Smckusick 		for (x = pos->x - 1; x <= pos->x + 1; x++) {
24621468Smckusick 			if (x <= 0 || x >= X_FIELDSIZE)
24721468Smckusick 				continue;
24821468Smckusick 			if (Field[y][x] == 1)
24921468Smckusick 				return TRUE;
25021468Smckusick 		}
25121468Smckusick 	}
25221468Smckusick 	return FALSE;
25321468Smckusick }
25421468Smckusick 
25521468Smckusick /*
25621468Smckusick  * reset_count:
25721468Smckusick  *	Reset the count variables
25821468Smckusick  */
reset_count()25921468Smckusick reset_count()
26021468Smckusick {
26121468Smckusick 	Count = 0;
26221468Smckusick 	Running = FALSE;
26321468Smckusick 	leaveok(stdscr, FALSE);
26421468Smckusick 	refresh();
26521468Smckusick }
26621468Smckusick 
26721468Smckusick /*
26821468Smckusick  * jumping:
26921468Smckusick  *	See if we are jumping, i.e., we should not refresh.
27021468Smckusick  */
jumping()27121468Smckusick jumping()
27221468Smckusick {
27321468Smckusick 	return (Jump && (Count || Running || Waiting));
27421468Smckusick }
275