[comp.sources.games] v09i036: tttt2 - tic-tac-toc-toe with wraparound edges

billr@saab.CNA.TEK.COM (Bill Randle) (04/12/90)

Submitted-by: Eric Lechner <lechner@ucscb.ucsc.edu>
Posting-number: Volume 9, Issue 36
Archive-name: tttt2/Part01
Supersedes: tttt: Volume 9, Issue 33-34

	[This is an improved version of the tttt game. The
	 diffs were larger than the source, so I'm posting
	 it anew.  -br]

#! /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 archive 1 (of 1)."
# Contents:  README Makefile tttt.6 tttt.c
# Wrapped by billr@saab on Wed Apr 11 17:43:18 1990
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'\" \(698 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XThis is version 2 of my 4 by 4 version of tic-tac-toe with
X"wraparound edges" (so you can have off-center diagonal wins).
X
XIt has an ever-so-slightly improved computer player, and a vastly
Ximproved user interface, including online help,  being able to
Xchange who moves first, and change the number of players (0, 1, or 2).
X
XI've compiled it under 4.3 BSD Unix, but it should compile
Xok just about everywhere that has a curses package.
X
XEdit the Makefile as necessary, then make.
X
XIf you improve the code, please let me know.  I'd be interested
Xin seeing any changes to it.
X
XThis program is public domain.
X
X-Eric Lechner,  25 March 1990
Xlechner@ucscb.ucsc.edu         ...!ucbvax!ucscc!ucscb!lechner
END_OF_FILE
if test 698 -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'\" \(657 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# makefile for tic-tac-toc-toe
X#
X# edit as necessary, then make
X
X# where the executable will go
XBINDIR = /usr/games
X
X# where the formatted manpage will go
XMANDIR = /usr/games/Doc
X
X# options for the c compiler (-g, -O, etc.)
XCFLAGS = -O
X
X# compiler libraries (-ltermcap, etc.)
XLIBS = -lcurses -ltermcap
X
Xtttt: tttt.c
X	cc $(CFLAGS) -o tttt tttt.c $(LIBS)
X
Xinstall: tttt tttt.man
X	cp tttt $(BINDIR)/tttt
X	strip $(BINDIR)/tttt
X	chmod 711 $(BINDIR)/tttt
X	cp tttt.man $(MANDIR)/tttt.doc
X	chmod 644 $(MANDIR)/tttt.doc
X
Xtttt.man: tttt.6
X	nroff -man tttt.6 > tttt.man
X
Xclean:
X	rm -f tttt *.o tttt.man tttt.shar
X
Xshar:
X	shar README Makefile tttt.6 tttt.c > tttt.shar
END_OF_FILE
if test 657 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'tttt.6' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tttt.6'\"
else
echo shar: Extracting \"'tttt.6'\" \(1875 characters\)
sed "s/^X//" >'tttt.6' <<'END_OF_FILE'
X.TH TTTT 6 "25 March 1990"
X.SH NAME
Xtttt
X\- tic-tac-toc-toe with wraparound edges
X.SH SYNOPSIS
X.B /usr/games/tttt [ options ]
X.SH DESCRIPTION
XTic-Tac-Toc-Toe is a 4 by 4 version of Tic-Tac-Toe
Xwith wraparound edges.  The goal of the game is to
Xconnect 4 of your pieces in a row, either horizontally,
Xvertically, or diagonally.  Note that diagonal wins can
Xbe off-center, due to the wraparound edges (and hence, there
Xare no corners in the board).
X.PP
XTo play, simply press the letter and number corresponding
Xto select the appropriate square, and the computer will then
Xtake its turn.
X.PP
XThe first player to connect four squares in a row wins.
X.PP
XIf the board becomes filled without a winner, it is a tie game.
X.PP
XIf there are no possible wins on the board before the board
Xis entirely filled, the game ends as a tie game.
X.SH COMMANDS
X.RS
X.IP "a-d, 0-4"
XSelect the row and column for your move.
X.IP ?
XDisplay the help screen.
X.IP h
XScroll the board left.
X.IP l
XScroll the board right.
X.IP k
XScroll the board up.
X.IP j
XScroll the board down.
X.IP ctrl-L
XRedraw the screen.
X.IP q
XQuit the game.
X.RE
X.SH OPTIONS
X.RS
X.IP -o
XHave player `O' move first.
X.IP -2
XPlay with two human players, instead of against the computer.
X.IP -0
XHave the computer play against itself.
X.IP -h
XPrint the list of command line flags.
X.IP -r
XDisable all randomness in the computer player.
X.RE
X.SH HISTORY
XThis program was originally written for an Advanced Logic
XDesign class, as a high level version of the program to
Xlater be implemented in hardware.
X.PP
XIt was converted to run with curses in an attempt to procrastinate
Xworking on the hardware implementation.
X.PP
XAs people requested them, additional features were added, even
Xsome that people didn't want (like a slightly better computer player).
X.SH BUGS
XYou can still beat the computer player.
X.SH AUTHOR
XEric Lechner, lechner@ucscb.ucsc.edu
END_OF_FILE
if test 1875 -ne `wc -c <'tttt.6'`; then
    echo shar: \"'tttt.6'\" unpacked with wrong size!
fi
# end of 'tttt.6'
fi
if test -f 'tttt.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tttt.c'\"
else
echo shar: Extracting \"'tttt.c'\" \(16091 characters\)
sed "s/^X//" >'tttt.c' <<'END_OF_FILE'
X/*
X	Eric Lechner		Tic-Tac-Toc-Toe, Version 2
X	March 25, 1990		CE 126 Final Project Development
X
X	a 4x4 version of tic-tac-toe with "wraparound edges"
X
X	Originally written Feb. 27, 1990
X
X	revised for curses output: march 6, 1990
X
X	user interface enhanced, help features added: march 22-25, 1990
X
X	Everything should be reasonably self documenting...
X*/
X
X#include <stdio.h>
X#include <curses.h>
X#include <signal.h>
X
X#define EMPTY	0
X#define X	1
X#define O	2
X
X#define MORE	0
X#define TIE	-1		/* for ending when there are no more moves */
X#define QUIT	-3
X
X#define UP	1		/* definitions for board scrolling routine */
X#define DOWN	2
X#define LEFT	3
X#define RIGHT	4
X#define WIN	100		/* for position rank scoring */
X
X#define ACROSS		1	/* types of wins for win hiliting... */
X#define VERTICAL	2
X#define DIAG1		3
X#define DIAG2		4
X
X#ifndef TRUE
X#define TRUE	1		/* cause they aren't included elsewhere */
X#define FALSE	0
X#endif
X
Xchar board [4][4];		/* this is the playing board */
Xint pieces;
Xint randomness;			/* whether the computer uses randomness */
X
X/* this is the help screen part for the command list */
Xchar *commands[] = {	" ---------------------- ",
X			"|     Command Help     |",
X			" ---------------------- ",
X			"| Adding pieces :      |",
X			"|  Type the letter and |",
X			"|  number of your move |",
X			"|----------------------|",
X			"| Scroll the Board :   |",
X			"|      h : left        |",
X			"|      j : down        |",
X			"|      k : up          |",
X			"|      l : right       |",
X			"|----------------------|",
X			"|     ^L : redraw      |",
X			"|      q : quit        |",
X			" ---------------------- ",
X			0 };
X
X/* and this is the "objective of the game" help stuff */
Xchar *objective[] = {	" --------------------- ",
X			"|      Objective      |",
X			" --------------------- ",
X			"| Try to connect four |",
X			"|  of your pieces in  |",
X			"|  a row before your  |",
X			"|   opponent does!    |",
X			"|---------------------|",
X			"|  Wins can be :      |",
X			"|        vertical,    |",
X			"|        horizontal,  |",
X			"|    and diagonal.    |",
X			"|---------------------|",
X			"| The board edges are |",
X			"| `wraparound' edges. |",
X			" --------------------- ",
X			0 };
X
Xvoid	displayhelp(),		/* display on-screen help */
X	getrank(),		/* move ranking */
X	hilite_win(),		/* for hiliting wins */
X	initboard(),		/* initialize the board */
X	print_help(),		/* print the command flag help list */
X	printboard(),		/* print the board */
X	shift(),		/* board shifter */
X	updaterank();		/* update rank status */
X
Xint	wins(),			/* see if any wins are still possible */
X	check_win(),		/* check for a win */
X	human_move(),		/* "our" move */
X	computer_move(),	/* the computer player's move */
X	quit();			/* control-c signal exit */
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X	int	done,
X		i,
X		win,
X		players = 1,
X		startx = TRUE,
X		xmove;
X
X	randomness = TRUE;	/* default player uses some randomness */
X
X	for (i=1;i<argc;i++) {
X		if ((*argv[i] == '-') || (*argv[i] == '+')) {
X			while (*++argv[i]) {
X				switch (*argv[i]) {
X					case 'o' :
X					case 'O' :
X						startx = FALSE;
X						break;
X					case '2' :
X						players = 2;
X						break;
X					case '0' :
X						players = 0;
X						break;
X					case 'r' :
X					case 'R' :
X						randomness = FALSE;
X						break;
X					case 'h' :
X					case 'H' :
X					case '?' :
X						print_help();
X						exit();
X					default	:
X						break;
X				}
X			}
X		}
X	}
X
X	initscr();
X	savetty();
X	cbreak();
X	noecho();
X
X	signal(SIGINT,quit);
X	srandom(getpid() * (1 + getuid()));
X
X	clear();
X
XStartGame:
X	done = FALSE;
X	xmove = startx;		/* reset who moves first */
X	initboard();		/* reset the board to all empty */
X
X	printboard(1);
X	while (!done) {
X		if (xmove) {
X			if (players > 0) {
X				done = human_move(X);
X			} else {
X				done = computer_move(X);
X			}
X		} else {
X			if (players < 2) {
X				done = computer_move(O);
X			} else {
X				done = human_move(O);
X			}
X		}
X		if ((++pieces == 16) && !done) done = TIE;
X		if (!done) done = wins();
X
X		xmove = !xmove;
X	}
X
X	move(15,0);
X	clrtoeol();
X
X	win = done;			/* save type of win */
X
XDisplayEnd:
X	switch (win) {
X		case TIE :
X			move(17,28);
X			printw("Tie game! Nobody can win.\n");
X			break;
X		case QUIT :
X			goto EndGame;
X			break;
X		default :
X			move(17,33);
X			printw("Player `%c' Wins!\n",(win == X) ? 'X' : 'O');
X	}
X
X	move(19,31);
X	printw("Play again (y/n) ? ");
X	refresh();
X
X	done = FALSE;
X	while (!done) {
X		i = getch();
X		switch (i) {
X			case 'y' :
X			case 'Y' :
X				move(19,0);
X				clrtoeol();
X				move(17,0);
X				clrtoeol();
X				goto StartGame;
X				break;
X			case 'q' :
X			case 'Q' :
X			case 'x' :
X			case 'X' :
X			case 'n' :
X			case 'N' :
X				done = TRUE;
X				break;
X			case 0x12 :
X			case 0x0c :
X				clear();
X				printboard(0);
X				if ((win == X) || (win == O))
X					hilite_win(-1,-1,-1,-1);
X				goto DisplayEnd;
X		}
X	}
X
XEndGame:
X	move(19,31);
X	printw("Thanks for playing!");
X	refresh();
X	move(21,0);
X	refresh();
X	resetty();
X	endwin();
X}
X
X/*
X	initialize the board to all empty
X*/
Xvoid initboard()
X{
X	int i,j;
X
X	for (i=0; i<4; i++)
X		for (j=0; j<4; j++)
X			board [i][j] = EMPTY;
X
X	pieces = 0;
X}
X
X/*
X	print the current board
X*/
Xvoid printboard(do_refresh)
Xint do_refresh;
X{
X	int i;
X
X	move(2,24);
X	printw("Tic-Tac-Toc-Toe - by Eric Lechner");
X
X	move(5,30);
X	printw("    A   B   C   D \n");
X	move(6,30);
X	printw("   --- --- --- ---\n");
X	for (i=0; i<4; i++) {
X		move(7 + (i * 2), 30);
X		printw("%d | %c | %c | %c | %c |\n", i,
X			(!board[i][0]) ? ' ' : (board[i][0] == X) ? 'X' : 'O',
X			(!board[i][1]) ? ' ' : (board[i][1] == X) ? 'X' : 'O',
X			(!board[i][2]) ? ' ' : (board[i][2] == X) ? 'X' : 'O',
X			(!board[i][3]) ? ' ' : (board[i][3] == X) ? 'X' : 'O');
X		move(8 + (i * 2), 30);
X		printw("   --- --- --- ---\n");
X	}
X
X	if (do_refresh) refresh();
X}
X
X/*
X	the human player's move
X*/
Xint human_move(type)
Xint type;
X{
X	int row, col, tmp, mess = 0;
XMove:	row = col = -1;
X
X	move(15,32);
X	printw("Player `%c' : ",(type == X) ? 'X' : 'O');
X	clrtoeol();
X	refresh();
X	while ((row == -1) || (col == -1)) {
X		tmp = getch();
X		switch (tmp) {
X			case 'A' :
X			case 'a' :
X			case 'B' :
X			case 'b' :
X			case 'C' :
X			case 'c' :
X			case 'D' :
X			case 'd' :
X				move(15,45);
X				printw("%c ",tmp);
X				if ((tmp >= 'a') && (tmp <= 'd'))
X					col = tmp - 'a';
X				else
X					col = tmp - 'A';
X				break;
X			case '0' :
X			case '1' :
X			case '2' :
X			case '3' :
X				move(15,47);
X				printw("%c",tmp);
X				row = tmp - '0';
X				break;
X			case 'q' :
X			case 'Q' :
X				return(QUIT);
X				break;
X			case 'j' :
X			case 'J' :
X				shift(DOWN);
X				printboard(1);
X				goto Move;
X			case 'k' :
X			case 'K' :
X				shift(UP);
X				printboard(1);
X				goto Move;
X			case 'l' :
X			case 'L' :
X				shift(RIGHT);
X				printboard(1);
X				goto Move;
X			case 'h' :
X			case 'H' :
X				shift(LEFT);
X				printboard(1);
X				goto Move;
X			case 0x12 :
X			case 0x0c :
X				clear();
X				printboard(0);
X				goto Move;
X			case '?' :
X				displayhelp();
X				move(15,45);
X				goto Move;
X			default:
X				move(17,34);
X				printw("`?' for help");
X				move(15,45);
X				mess = 1;
X				break;
X		}
X		refresh();
X	}
X	if (board[row][col] == EMPTY) board[row][col] = type;
X	else {
X		move(17,34);
X		printw("Illegal move!\n");
X		mess = 1;	/* whether an error message has been printed */
X		goto Move;
X	}
X	
X	if (mess) {		/* if there was an error message, clear it */
X		move(17,1);
X		clrtoeol();
X	}
X
X	move(7 + (row * 2), 34 + (col * 4));	/* print the move */
X	printw("%c",(type == X) ? 'X' : 'O');
X
X	refresh();
X
X	return (check_win (type,row,col));
X}
X
X/*
X	the computer player
X*/
Xint computer_move(type)
Xint type;
X{
X	int bestrow = 0, bestcol = 0, i, j;
X	int bestrank = 0, numbest = 0, rank, numrank;
X		/* rank == the rank score */
X		/* num == the number of times the score happened */
X
X	for (i=0; i<4; i++) {
X		for (j=0; j<4; j++) {
X			getrank(type,i,j,&rank,&numrank);
X			if (rank > bestrank) {
X				bestrow = i;
X				bestcol = j;
X				bestrank = rank;
X				numbest = numrank;
X			} else if (rank == bestrank) {
X				if (numrank > numbest) {
X					bestrow = i;
X					bestcol = j;
X					bestrank = rank;
X					numbest = numrank;
X				} else if (numrank == numbest) {
X					if ((random() % 2) && randomness) {
X						bestrow = i;
X						bestcol = j;
X						bestrank = rank;
X						numbest = numrank;
X					}
X				}
X			}
X		}
X	}
X
X	board [bestrow][bestcol] = type;
X
X	move(7 + (bestrow * 2), 34 + (bestcol * 4));
X	printw("%c",(type == O) ? 'O' : 'X');
X	refresh();
X
X	return (check_win (type,bestrow,bestcol));
X}
X
X/*
X	this ranks a move location in order of "preference".
X
X	the strategy is to not let the opponent get lots in a row.
X	ever.
X
X
X	rows, columns, and diagonals get treated independently, and
X	the "best" rank of them all is considered.
X*/
Xvoid getrank(type,row,col,rank,numrank)
Xint type, row, col, *rank, *numrank;
X{
X	int i, j, countx = 0, counto = 0;
X	
X	*rank = 0;
X	*numrank = 0;
X
X	/* if already taken, this isn't a good spot */
X	if (board[row][col]) return;
X
X	/* check across */
X	countx = counto = 0;
X	for (i=0; i<4; i++) {
X		if (board[row][i] == X) countx++;
X		else if (board[row][i] == O) counto++;
X	}
X
X	updaterank(type,countx,counto,rank,numrank);
X
X	/* check vertically */
X	countx = counto = 0;
X	for (i=0; i<4; i++) {
X		if (board[i][col] == X) countx++;
X		else if (board[i][col] == O) counto++;
X	}
X
X	updaterank(type,countx,counto,rank,numrank);
X
X	/* check \ diagonal */
X	countx = counto = 0;
X	for (i=0; i<4; i++) {
X		if (board[(row + i) % 4][(col + i) % 4] == X) countx++;
X		else if (board[(row + i) % 4][(col + i) % 4] == O) counto++;
X	}
X
X	updaterank(type,countx,counto,rank,numrank);
X
X	/* check / diagonal */
X	countx = counto = 0;
X	for (i=0; i<4; i++) {
X		if (board[(row + 4 - i) % 4][(col + i) % 4] == X) countx++;
X		else if (board[(row + 4 - i) % 4][(col + i) % 4] == O) counto++;
X	}
X
X	updaterank(type,countx,counto,rank,numrank);
X
X	/* add one, so that even no blocks still shows as a valid move	*/
X	/* and return the rank for this move				*/
X	*rank++;
X}
X
X/*
X	checks for a win at a specific location, and returns the
X	type of win, or 0, if there wasn't a win.
X*/
Xint check_win(type,row,col)
Xint type, row, col;
X{
X	int r[4],c[4], i;	/* temp row, col, and counter vars */
X
X	/* check across */
X	if ((board [row][0] == type) && (board [row][1] == type) &&
X		(board [row][2] == type) && (board [row][3] == type)) {
X		hilite_win(row,col,ACROSS,type);
X		return (type);
X	}
X
X	/* check vertically */
X	if ((board [0][col] == type) && (board [1][col] == type) &&
X		(board [2][col] == type) && (board [3][col] == type)) {
X		hilite_win(row,col,VERTICAL,type);
X		return (type);
X	}
X
X	/* check \ diagonal */
X	for (i=0; i<4; i++) {
X		r[i] = (row + i) % 4;
X		c[i] = (col + i) % 4;
X	}
X	if ((board [r[0]][c[0]] == type) && (board [r[1]][c[1]] == type) &&
X		(board [r[2]][c[2]] == type) && (board [r[3]][c[3]] == type)) {
X		hilite_win(row,col,DIAG1,type);
X		return (type);
X	}
X
X	/* check / diagonal */
X	for (i=0; i<4; i++) {
X		r[i] = (row + i) % 4;
X		c[i] = (col + (4 - i)) % 4;
X	}
X	if ((board [r[0]][c[0]] == type) && (board [r[1]][c[1]] == type) &&
X		(board [r[2]][c[2]] == type) && (board [r[3]][c[3]] == type)) {
X		hilite_win(row,col,DIAG2,type);
X		return (type);
X	}
X
X	/* if it got here, there aren't any wins at that spot */
X	return (0);
X}
X
X/*
X	this is the board shifter.  it's so you can move the
X	board around to look at wraparound edges better...
X*/
Xvoid shift(type)
Xint type;
X{
X	int i, j, tmp;
X
X	for (i=0; i<4; i++) {
X		switch (type) {
X			case UP:
X				tmp = board[0][i];
X				for (j=0; j<3; j++)
X					board[j][i] = board[j+1][i];
X				board[3][i] = tmp;
X				break;
X			case DOWN:
X				tmp = board[3][i];
X				for (j=3; j>0; j--)
X					board[j][i] = board[j-1][i];
X				board[0][i] = tmp;
X				break;
X			case LEFT:
X				tmp = board[i][0];
X				for (j=0; j<3; j++)
X					board[i][j] = board[i][j+1];
X				board[i][3] = tmp;
X				break;
X			case RIGHT:
X				tmp = board[i][3];
X				for (j=3; j>0; j--)
X					board[i][j] = board[i][j-1];
X				board[i][0] = tmp;
X				break;
X		}
X	}
X}
X
X/*
X	the nice control-C handler
X*/
Xint quit()
X{
X	move(21,0);
X	refresh();
X	resetty();
X	endwin();
X
X	exit(0);
X}
X
X/*
X	this checks the board to see if any wins are still possible
X	and returns TIE if no more wins, or MORE if there are.
X*/
Xint wins()
X{
X	int i, j, rank = 0, countx = 0, counto = 0;
X
X	/* check across */
X	for (j=0; j<4; j++) {
X		countx = counto = 0;
X		for (i=0; i<4; i++) {
X			if (board[j][i] == X) countx++;
X			else if (board[j][i] == O) counto++;
X		}
X		if ((countx == 0) || (counto == 0)) return (MORE);
X	}
X
X	/* check vertically */
X	for (j=0; j<4; j++) {
X		countx = counto = 0;
X		for (i=0; i<4; i++) {
X			if (board[i][j] == X) countx++;
X			else if (board[i][j] == O) counto++;
X		}
X		if ((countx == 0) || (counto == 0)) return (MORE);
X	}
X
X	/* check \ diagonal */
X	for (j=0; j<4; j++) {
X		countx = counto = 0;
X		for (i=0; i<4; i++) {
X			if (board[(j + i) % 4][i] == X) countx++;
X			else if (board[(j + i) % 4][i] == O) counto++;
X		}
X		if ((countx == 0) || (counto == 0)) return (MORE);
X	}
X
X	/* check / diagonal */
X	for (j=0; j<4; j++) {
X		countx = counto = 0;
X		for (i=0; i<4; i++) {
X			if (board[(j + 4 - i) % 4][i] == X) countx++;
X			else if (board[(j + 4 - i) % 4][i] == O) counto++;
X		}
X		if ((countx == 0) || (counto == 0)) return (MORE);
X	}
X
X	/* if there are more moves, then we've already returned */
X	return (TIE);
X}
X
X/*
X	print the command line help stuff
X*/
Xvoid print_help()
X{
X	fprintf(stderr,"Tic Tac Toc Toe - By Eric Lechner\n\n");
X	fprintf(stderr,"Command line options:\n");
X	fprintf(stderr,"\t-h - print this help screen\n");
X	fprintf(stderr,"\t-o - Have player `O' move first\n");
X	fprintf(stderr,"\t-r - disallow randomness for the computer player\n");
X	fprintf(stderr,"\t-0 - Have the computer play against itself\n");
X	fprintf(stderr,"\t-2 - Play with two human players\n");
X	fflush(stderr);
X}
X
Xvoid hilite_win(row,col,wintype,playertype)
Xint row, col, wintype, playertype;
X{
X	int i, row_step, col_step, tmprow, tmpcol;
X	static int oldrow, oldcol, oldwintype, oldplayertype;
X
X	/* in order to redraw the hilited win, we need to save the values */
X	/* to redisplay the hilite, call hilite_win with row == -1 */
X
X	if (row != -1) {
X		oldrow = row;
X		oldcol = col;
X		oldwintype = wintype;
X		oldplayertype = playertype;
X	} else {
X		row =oldrow;
X		col = oldcol;
X		wintype = oldwintype;
X		playertype = oldplayertype;
X	}
X
X	switch (wintype) {
X		case ACROSS :
X			row_step = 0;
X			col_step = 1;
X			break;
X		case VERTICAL :
X			row_step = 1;
X			col_step = 0;
X			break;
X		case DIAG1 :
X			row_step = 1;
X			col_step = 1;
X			break;
X		case DIAG2 :
X			row_step = 3;
X			col_step = 1;
X			break;
X	}
X
X	for (i=0; i<4; i++) {
X		tmprow = (row + (row_step * i)) % 4;
X		tmpcol = (col + (col_step * i)) % 4;
X		move(7 + (tmprow * 2), 33 + (tmpcol * 4));
X
X		printw("*%c*", (board[tmprow][tmpcol] == X) ? 'X' : 'O');
X	}
X}
X
X/*
X	this is the on-screen help stuff
X	(^L will redraw the screen)
X*/
Xvoid displayhelp()
X{
X	int i = 0, j =0, tmp;
X
XDisplayHelp:
X	i = j = 0;
X
X	move(15,32);
X	printw("                ");
X
X	while (commands[i]) {
X		move(4 + i,3);
X		printw("%s",commands[i++]);
X	}
X
X	while (objective[j]) {
X		move(4 + j,52);
X		printw("%s",objective[j++]);
X	}
X
X	move(17,33);
X	printw("Hit any hey to");
X	move(18,33);
X	printw("  continue. ");
X	refresh();
X
X	
X	tmp = getch();
X	if ((tmp == 0x12) || (tmp == 0x0c)) {
X		clear();
X		printboard(0);
X		goto DisplayHelp;
X	}
X
X	move(17,33);
X	printw("              ");
X	move(18,33);
X	printw("            ");
X
X	while (j--) {
X		move(4 + j,52);
X		printw("                        ");
X	}
X
X	while (i--) {
X		move(4 + i,3);
X		printw("                        ");
X	}
X}
X
Xvoid updaterank(type,countx,counto,rank,numrank)
Xint type, countx, counto, *rank, *numrank;
X{
X	if (type == X) {
X		if (countx >= 3) {
X			if (*rank < countx) {
X				*rank = WIN;
X				*numrank = 1;
X			} else if (*rank == countx) *numrank++;
X		} else if (!countx && (counto > *rank)) {
X			if (*rank < counto) {
X				*rank = counto;
X				*numrank = 1;
X			} else if (*rank == counto) *numrank++;
X		}
X	} else {
X		if (counto >= 3) {
X			if (*rank < counto) {
X				*rank = WIN;
X				*numrank = 1;
X			} else if (*rank == counto) *numrank++;
X		} else if (!counto && (countx > *rank)) {
X			if (*rank < countx) {
X				*rank = countx;
X				*numrank = 1;
X			} else if (*rank == countx) *numrank++;
X		}
X	}
X}
END_OF_FILE
if test 16091 -ne `wc -c <'tttt.c'`; then
    echo shar: \"'tttt.c'\" unpacked with wrong size!
fi
# end of 'tttt.c'
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have the archive.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0