[comp.sources.games] v06i077: greed - a logic grid game using curses

games@tekred.CNA.TEK.COM (06/16/89)

Submitted-by: "Matthew T. Day" <ohs!mday@uunet.uu.net>
Posting-number: Volume 6, Issue 77
Archive-name: greed

	[From the author....  -br]

[[Here's a pretty good game I just wrote.  It's portable to all Unix systems
(I think) through the Makefile.  It's not very complicated, but I think it's
a very addictive game.  It's like the game "robots", a screen-oriented game
that combines luck, skill, and logic.  Please direct any comments to me at
mday@ohs.uucp, I would love to hear them.]]

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README Makefile greed.c
# Wrapped by billr@saab on Thu Jun 15 15:05:51 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1351 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XThis is a small game called Greed.  It's a very simple, yet fun game to play.
XThere should be no major problems with it.  To install it, simply edit the
XMakefile to configure your system type, and run "make install".  It should
Xcompile the program and install it correctly.  It does run set-uid, but there
Xis no danger of security problems.
X
XI also do not take credit for inventing the game, I once saw it on an IBM,
Xand wrote it for Unix in C.
X
XFor competition, here's the scores that the students here at Orem High School
Xobtained after about three weeks of game playing:
X
XRank  Score  Name     Percentage
X1     1542   stay     87.61%
X2     1504   ndes     85.45%
X3     1501   stay     85.28%
X4     1497   stay     85.06%
X5     1490   skel     84.66%
X6     1464   dvar     83.18%
X7     1463   stay     83.13%
X8     1463   stay     83.13%
X9     1460   stay     82.95%
X10    1454   skel     82.61%
X
XI would be interested in hearing about scores higher than these.
X
XIf anyone has a comment or problem, please to mail to mday@ohs.uucp.
X
X+----------------------------------------------------------+-----------------+
X| Matthew T. Day, Orem High School, Orem, Utah             | "He who laughs, |
X| Internet: mday@ohs.uucp  UUCP: ..!uunet!iconsys!ohs!mday |  lasts."        |
X+----------------------------------------------------------+-----------------+
END_OF_FILE
if test 1351 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(449 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# Makefile for Greed v1.1a, by Matthew T. Day (mday@ohs.uucp)
X
X# Choose BSD for Berkeley 4.[23] Unix, NOTBSD for all others
XSYSDEF=BSD -lcurses -ltermcap
X#SYSDEF=NOTBSD -lcurses
X
X# Location of high score file
XSCOREFILE=/usr/games/lib/greed.hs
X# Location of game executable
XBIN=/usr/games
X
XCFLAGS=-O -s -DSCOREFILE=\"$(SCOREFILE)\" -D$(SYSDEF) 
X
Xgreed: greed.c
X	cc -o greed greed.c $(CFLAGS)
X
Xinstall: greed
X	mv greed $(BIN)
X	chmod 4711 $(BIN)/greed
END_OF_FILE
if test 449 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'greed.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'greed.c'\"
else
echo shar: Extracting \"'greed.c'\" \(6666 characters\)
sed "s/^X//" >'greed.c' <<'END_OF_FILE'
X/* greed.c v1.1a - Written by Matthew T. Day (mday@ohs.uucp), 06/12/89 */
X
X#include <curses.h>
X#include <signal.h>
X#include <pwd.h>
X#ifdef NOTBSD
X#include <fcntl.h>
X#else
X#include <sys/file.h>
X#endif
X
X#ifdef NOTBSD
X#define crmode cbreak
X#define random lrand48
X#define srandom srand48
X#endif
X
X#define MAXSCORE 10
X#define FILESIZE (MAXSCORE * sizeof(struct score))
X#define rnd(x) (int) ((random() % (x))+1)
X
Xstruct score {
X	char user[9];
X	int score;
X};
Xint score = 1, grid[22][80], y, x;
XWINDOW *gridwin, *botwin = NULL;
Xextern long random();
X
Xout() {
X	if (botwin) {
X		(void) wmove(botwin, 0, 40);
X		wclrtoeol(botwin);
X		wrefresh(botwin);
X		endwin();
X	}
X	exit(0);
X}
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X	register val = 1;
X	extern long time();
X
X	if (argc > 1)
X		if (argc == 2 && !strcmp(argv[1], "-s")) {
X			topscores(0);
X			exit(0);
X		} else {
X			fprintf(stderr, "Usage: %s [-s]\n", argv[0]);
X			exit(1);
X		}
X
X	(void) signal(SIGINT, out);
X	(void) signal(SIGQUIT, out);
X	(void) signal(SIGTERM, out);
X
X	initscr();
X	botwin = newwin(1, 80, 23, 0);
X	gridwin = newwin(22, 80, 0, 0);
X
X	crmode();
X	noecho();
X	refresh();
X
X	srandom(time(0) ^ getpid() << 16);
X
X	for (y=0; y < 22; y++)
X		for (x=0; x < 80; x++)
X			(void) waddch(gridwin, (grid[y][x] = rnd(9)) + '0');
X	wstandout(gridwin);
X	y = rnd(22)-1; x = rnd(80)-1;
X	mvwaddch(gridwin, y, x, ' ');
X	grid[y][x] = 0;
X
X	(void) wmove(gridwin, y, x);
X	waddstr(botwin, "Score: ");
X	mvwaddstr(botwin, 0, 40, "Greed v1.1a - Hit '?' for help.");
X	showscore();
X
X	while ((val = tunnel(wgetch(gridwin))) > 0);
X
X	if (!val) {
X		mvwaddstr(botwin, 0, 20, "Hit <Enter>");
X		wrefresh(botwin);
X		while (wgetch(botwin) != '\n');
X	}
X	(void) wclear(botwin);
X	wrefresh(botwin);
X	endwin();
X	topscores(score);
X}
X
Xshowscore() {
X	mvwprintw(botwin, 0, 7, "%d  %.2f%%", score, (float) score / 17.6);
X	wrefresh(botwin);
X	wrefresh(gridwin);
X}
X
Xtunnel(cmd)
Xregister cmd;
X{
X	register dy, dx, distance;
X
X	switch (cmd) {
X	case 'h': case '4':
X		dy = 0; dx = -1;
X		break;
X	case 'j': case '2':
X		dy = 1; dx = 0;
X		break;
X	case 'k': case '8':
X		dy = -1; dx = 0;
X		break;
X	case 'l': case '6':
X		dy = 0; dx = 1;
X		break;
X	case 'b': case '1':
X		dy = 1; dx = -1;
X		break;
X	case 'n': case '3':
X		dy = dx = 1;
X		break;
X	case 'y': case '7':
X		dy = dx = -1;
X		break;
X	case 'u': case '9':
X		dy = -1; dx = 1;
X		break;
X	case 'q':
X		botmsg("Really quit? ");
X		if (wgetch(botwin) == 'y') return(-1);
X		wrefresh(gridwin);
X		return(1);
X	case '?':
X		help();
X		return(1);
X	case '\14':
X		redraw();
X	default:
X		return(1);
X	}
X	distance = grid[y+dy][x+dx];
X
X	{
X		register j = y, i = x, d = distance;
X
X		do {
X			j += dy;
X			i += dx;
X			if (j >= 0 && i >= 0 && j < 22 && i < 80 && grid[j][i])
X				continue;
X			else if (!othermove(dy, dx)) {
X				j -= dy;
X				i -= dx;
X				while (y != j || x != i) {
X					y += dy;
X					x += dx;
X					score++;
X					mvwaddch(gridwin, y, x, ' ');
X				}
X				mvwaddch(gridwin, y, x, '*');
X				showscore();
X				return(0);
X			} else {
X				botmsg("Bad move.");
X				wrefresh(gridwin);
X				return(1);
X			}
X		} while (--d);
X	}
X
X	do {
X		y += dy;
X		x += dx;
X		score++;
X		grid[y][x] = 0;
X		mvwaddch(gridwin, y, x, ' ');
X	} while (--distance);
X	(void) wmove(gridwin, y, x);
X	showscore();
X	return(1);
X}
X
Xbotmsg(msg)
Xregister char *msg;
X{
X	(void) wmove(botwin, 0, 40);
X	wclrtoeol(botwin);
X	waddstr(botwin, msg);
X	wrefresh(botwin);
X}
X
Xothermove(bady, badx)
Xregister bady, badx;
X{
X	register dy = -1, dx;
X
X	for (; dy <= 1; dy++)
X		for (dx = -1; dx <= 1; dx++)
X			if ((!dy && !dx) || (dy == bady && dx == badx))
X				continue;
X			else {
X				register j=y, i=x, d=grid[y+dy][x+dx];
X
X				if (!d) continue;
X				do {
X					j += dy;
X					i += dx;
X					if (j < 0 || i < 0 || j >= 22
X					    || i >= 80 || !grid[j][i]) break;
X				} while (--d);
X				if (!d) return(1);
X			}
X	return(0);
X}
X
Xredraw() {
X	clearok(curscr, TRUE);
X	wrefresh(curscr);
X}
X
Xtopscores(newscore)
Xregister int newscore;
X{
X	register fd, count = 1;
X	struct score *toplist = (struct score *) malloc(FILESIZE);
X	register struct score *ptrtmp, *eof = &toplist[MAXSCORE], *new;
X	extern int _putchar();
X
X	(void) signal(SIGINT, SIG_IGN);
X	(void) signal(SIGQUIT, SIG_IGN);
X	(void) signal(SIGTERM, SIG_IGN);
X	(void) signal(SIGHUP, SIG_IGN);
X
X	if ((fd = open(SCOREFILE, O_RDWR | O_CREAT, 0600)) == -1) {
X		fprintf(stderr, "greed: %s: Cannot open.\n", SCOREFILE);
X		exit(1);
X	}
X
X	flock(fd, LOCK_EX);
X	for (ptrtmp=toplist; ptrtmp < eof; ptrtmp++) ptrtmp->score = 0;
X	read(fd, toplist, FILESIZE);
X	if (newscore) {
X		for (ptrtmp=toplist; ptrtmp < eof; ptrtmp++)
X			if (newscore >= ptrtmp->score) break;
X		if (ptrtmp < eof) {
X			new = ptrtmp;
X			ptrtmp = eof-1;
X			if (ptrtmp < new)
X				while (ptrtmp < new) {
X					*ptrtmp = *(ptrtmp+1);
X					ptrtmp++;
X				}
X			else while (ptrtmp > new) {
X					*ptrtmp = *(ptrtmp-1);
X					ptrtmp--;
X				}
X
X			new->score = newscore;
X			strncpy(new->user, getpwuid(getuid())->pw_name, 8);
X			(void) lseek(fd, 0, 0);
X			write(fd, toplist, FILESIZE);
X		}
X	}
X	close(fd);
X	flock(fd, LOCK_UN);
X
X	if (toplist->score) puts("Rank  Score  Name     Percentage");
X	else puts("No high scores.");
X	for (ptrtmp=toplist; ptrtmp < eof && ptrtmp->score; ptrtmp++, count++) {
X		if (ptrtmp == new && SO) tputs(SO, 0, _putchar);
X		printf("%-5d %-6d %-8s %.2f%%\n", count, ptrtmp->score,
X			ptrtmp->user, (float) ptrtmp->score / 17.6);
X		if (ptrtmp == new && SE) tputs(SE, 0, _putchar);
X	}
X}
X
X#define msg(row, msg) mvwaddstr(helpwin, row, 2, msg);
X
Xhelp() {
X	WINDOW *helpwin = newwin(16, 65, 1, 7);
X
X	overlay(helpwin, gridwin);
X	(void) wclear(helpwin);
X	box(helpwin, '|', '-');
X	(void) waddch(helpwin, '+'); mvwaddch(helpwin, 0, 64, '+');
X	mvwaddch(helpwin, 15, 0, '+'); mvwaddch(helpwin, 15, 64, '+');
X
X	msg(1, "Welcome to Greed v1.1a, by Matthew T. Day (mday@ohs.uucp).");
X	msg(3, "The object of Greed is to erase as much of the screen as");
X	msg(4, "possible by moving around in a grid of numbers.  To move your");
X	msg(5, "cursor, simply use the standard hjklyubn keys or the number");
X	msg(6, "keypad.  Use the number keypad with your Num Lock on.");
X	msg(7, "When you move in a direction, you erase N number of grid");
X	msg(8, "squares in that direction, N being the first number in that");
X	msg(9, "direction.  Your score reflects the total number of squares");
X	msg(10, "eaten.  Greed will not let you make a move that would have");
X	msg(11, "placed you off the grid or over a previously eaten square");
X	msg(12, "unless no valid moves exist, in which case your game ends.");
X	msg(13, "Other Greed commands are 'Ctrl-L' to redraw the screen and");
X	msg(14, "'q' to quit.");
X	(void) wmove(helpwin, 15, 64);
X	wrefresh(helpwin);
X	(void) wgetch(helpwin);
X	delwin(helpwin);
X	touchwin(gridwin);
X	wrefresh(gridwin);
X}
END_OF_FILE
if test 6666 -ne `wc -c <'greed.c'`; then
    echo shar: \"'greed.c'\" unpacked with wrong size!
fi
# end of 'greed.c'
fi
echo shar: End of shell archive.
exit 0