diff options
| author | cvs2svn <cvs2svn@FreeBSD.org> | 1996-10-06 07:58:04 +0000 | 
|---|---|---|
| committer | cvs2svn <cvs2svn@FreeBSD.org> | 1996-10-06 07:58:04 +0000 | 
| commit | 34181e06a7fb1dad00312dfc5e13b2f0d4d8f8ef (patch) | |
| tree | a05adbf3b725986cc9283700c0cadd7067e18d01 /games/tetris/tetris.c | |
| parent | 2cbfdf51d83d2fc0f0396562250a188cb6faba48 (diff) | |
Diffstat (limited to 'games/tetris/tetris.c')
| -rw-r--r-- | games/tetris/tetris.c | 312 | 
1 files changed, 312 insertions, 0 deletions
| diff --git a/games/tetris/tetris.c b/games/tetris/tetris.c new file mode 100644 index 000000000000..63265bc6b754 --- /dev/null +++ b/games/tetris/tetris.c @@ -0,0 +1,312 @@ +/*- + * Copyright (c) 1992, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek and Darren F. Provine. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + *	@(#)tetris.c	8.1 (Berkeley) 5/31/93 + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1992, 1993\n\ +	The Regents of the University of California.  All rights reserved.\n"; +#endif /* not lint */ + +/* + * Tetris (or however it is spelled). + */ + +#include <sys/time.h> + +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "input.h" +#include "scores.h" +#include "screen.h" +#include "tetris.h" + +void onintr __P((int)); +void usage __P((void)); + +/* + * Set up the initial board.  The bottom display row is completely set, + * along with another (hidden) row underneath that.  Also, the left and + * right edges are set. + */ +static void +setup_board() +{ +	register int i; +	register cell *p; + +	p = board; +	for (i = B_SIZE; i; i--) +#ifndef mips +		*p++ = i <= (2 * B_COLS) || (i % B_COLS) < 2; +#else /* work around compiler bug */ +		*p++ = i <= (2 * B_COLS) || (i % B_COLS) < 2 ? 1 : 0; +#endif +} + +/* + * Elide any full active rows. + */ +static void +elide() +{ +	register int i, j, base; +	register cell *p; + +	for (i = A_FIRST; i < A_LAST; i++) { +		base = i * B_COLS + 1; +		p = &board[base]; +		for (j = B_COLS - 2; *p++ != 0;) { +			if (--j <= 0) { +				/* this row is to be elided */ +				bzero(&board[base], B_COLS - 2); +				scr_update(); +				tsleep(); +				while (--base != 0) +					board[base + B_COLS] = board[base]; +				scr_update(); +				tsleep(); +				break; +			} +		} +	} +} + +int +main(argc, argv) +	int argc; +	char *argv[]; +{ +	register int pos, c; +	register struct shape *curshape; +	register char *keys; +	register int level = 2; +	char key_write[6][10]; +	int ch, i, j; + +	keys = "jkl pq"; + +	while ((ch = getopt(argc, argv, "k:l:s")) != EOF) +		switch(ch) { +		case 'k': +			if (strlen(keys = optarg) != 6) +				usage(); +			break; +		case 'l': +			level = atoi(optarg); +			if (level < MINLEVEL || level > MAXLEVEL) { +				(void)fprintf(stderr, +				    "tetris: level must be from %d to %d", +				    MINLEVEL, MAXLEVEL); +				exit(1); +			} +			break; +		case 's': +			showscores(0); +			exit(0); +		case '?': +		default: +			usage(); +		} + +	argc -= optind; +	argv += optind; + +	if (argc) +		usage(); + +	fallrate = 1000000 / level; + +	for (i = 0; i <= 5; i++) { +		for (j = i+1; j <= 5; j++) { +			if (keys[i] == keys[j]) { +				(void)fprintf(stderr, +				    "%s: Duplicate command keys specified.\n", +				    argv[0]); +				exit (1); +			} +		} +		if (keys[i] == ' ') +			strcpy(key_write[i], "<space>"); +		else { +			key_write[i][0] = keys[i]; +			key_write[i][1] = '\0'; +		} +	} + +	sprintf(key_msg, +"%s - left   %s - rotate   %s - right   %s - drop   %s - pause   %s - quit", +		key_write[0], key_write[1], key_write[2], key_write[3], +		key_write[4], key_write[5]); + +	(void)signal(SIGINT, onintr); +	scr_init(); +	setup_board(); + +	srandom(getpid()); +	scr_set(); + +	pos = A_FIRST*B_COLS + (B_COLS/2)-1; +	curshape = randshape(); + +	scr_msg(key_msg, 1); + +	for (;;) { +		place(curshape, pos, 1); +		scr_update(); +		place(curshape, pos, 0); +		c = tgetchar(); +		if (c < 0) { +			/* +			 * Timeout.  Move down if possible. +			 */ +			if (fits_in(curshape, pos + B_COLS)) { +				pos += B_COLS; +				continue; +			} + +			/* +			 * Put up the current shape `permanently', +			 * bump score, and elide any full rows. +			 */ +			place(curshape, pos, 1); +			score++; +			elide(); + +			/* +			 * Choose a new shape.  If it does not fit, +			 * the game is over. +			 */ +			curshape = randshape(); +			pos = A_FIRST*B_COLS + (B_COLS/2)-1; +			if (!fits_in(curshape, pos)) +				break; +			continue; +		} + +		/* +		 * Handle command keys. +		 */ +		if (c == keys[5]) { +			/* quit */ +			break; +		} +		if (c == keys[4]) { +			static char msg[] = +			    "paused - press RETURN to continue"; + +			place(curshape, pos, 1); +			do { +				scr_update(); +				scr_msg(key_msg, 0); +				scr_msg(msg, 1); +				(void) fflush(stdout); +			} while (rwait((struct timeval *)NULL) == -1); +			scr_msg(msg, 0); +			scr_msg(key_msg, 1); +			place(curshape, pos, 0); +			continue; +		} +		if (c == keys[0]) { +			/* move left */ +			if (fits_in(curshape, pos - 1)) +				pos--; +			continue; +		} +		if (c == keys[1]) { +			/* turn */ +			struct shape *new = &shapes[curshape->rot]; + +			if (fits_in(new, pos)) +				curshape = new; +			continue; +		} +		if (c == keys[2]) { +			/* move right */ +			if (fits_in(curshape, pos + 1)) +				pos++; +			continue; +		} +		if (c == keys[3]) { +			/* move to bottom */ +			while (fits_in(curshape, pos + B_COLS)) { +				pos += B_COLS; +				score++; +			} +			continue; +		} +		if (c == '\f') +			scr_clear(); +	} + +	scr_clear(); +	scr_end(); + +	(void)printf("Your score:  %d point%s  x  level %d  =  %d\n", +	    score, score == 1 ? "" : "s", level, score * level); +	savescore(level); + +	printf("\nHit RETURN to see high scores, ^C to skip.\n"); + +	while ((i = getchar()) != '\n') +		if (i == EOF) +			break; + +	showscores(level); + +	exit(0); +} + +void +onintr(signo) +	int signo; +{ +	scr_clear(); +	scr_end(); +	exit(0); +} + +void +usage() +{ +	(void)fprintf(stderr, "usage: tetris [-s] [-l level] [-keys]\n"); +	exit(1); +} | 
