[comp.sources.games] v03i085: knight - knights tour, a chess oriented brain game

games-request@tekred.TEK.COM (02/19/88)

Submitted by: bobc@killer.UUCP (Bob Calbridge)
Comp.sources.games: Volume 3, Issue 85
Archive-name: knight

	[I had to add a little bit (#ifdef'd) to get this to compile
	 on my Sun, then had to add a few refresh() calls to see
	 the instructions. It compiles and runs OK now. (I assume it
	 worked OK on SYSV before.)   -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 shell archive."
# Contents:  README Makefile knight.c
# Wrapped by billr@saab on Thu Feb 18 17:47:54 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(838 characters\)
sed "s/^X//" >README <<'END_OF_README'
X     The following program is derived from a game that was on a
Xsystem where I used to work.  I don't know what the origins  or
Xthe history game are. Instructions are included in the game  so
Xthere is no need to explain  it here except  to mention that it 
Xis a board game for one player.  It is actually more of a brain
Xpuzzle.
X     The only thing I can think of that would enhance the game is
Xto make the program make the moves if there is only one move
Xavailable from the current position.  I've run the game several
Xtimes but so far I haven't been able to get all 64 squares so I
Xdon't know for sure if the graphic representation for a winner 
Xcomes out properly.  Logic says it does.  If anyone finds fault
Xwith this program please send gripes or groans to bobc@killer.
XAll suggestions appreciated.
XBatteries not included.
XBest,
XBob
END_OF_README
if test 838 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(201 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
X# simple makefile for knight
XCFLAGS = -O -DBSD	# Remove -DBSD if on SYSV or derivative
XLIBS = -lcurses -ltermcap # don't need termcap for SYSV
Xknight: knight.c
X	cc -o knight $(CFLAGS) knight.c $(LIBS)
END_OF_Makefile
if test 201 -ne `wc -c <Makefile`; then
    echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f knight.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"knight.c\"
else
echo shar: Extracting \"knight.c\" \(7138 characters\)
sed "s/^X//" >knight.c <<'END_OF_knight.c'
X/* Knights Tour - a brain game */
X
X#include <stdio.h>
X#ifdef BSD
X#include <ctype.h>
X#endif
X#include <curses.h>
X#include <signal.h>
X
Xshort   board [64];     /* the squares */
Xchar    row, column;    /* input characters */
Xint     rw,col;         /* numeric equivalent of row and column */
Xint     curow,curcol;   /* current row and column integers */
Xint     rdif, cdif;     /* difference between input and current */
Xint     j;              /* index into board */
X
Xchar	script[]={"'_)//,/(-)/__/__(_<_(__),|/|/_///_/_<//_/_)__o__o'______///_(--_(_)___,(_/,_/__(_\0"};
X
Xint	ypos[] ={1,0,1,2,3,0,1,2,2,3,3,2,2,3,2,2,3,3,3,3,3,2,3,3,2,4,5,5,
X	4,3,3,2,1,2,3,3,3,2,1,3,3,2,3,3,3,2,1,1,0,1,4,4,4,4,4,4,5,6,7,7,
X	7,6,6,6,7,7,7,6,6,6,6,7,7,7,6,7,7,6,6,7,7};
X
Xint	xpos[]={0,1,2,1,0,5,4,3,2,4,6,7,8,8,9,10,10,11,12,13,14,15,15,16,
X	16,16,15,14,15,17,18,19,20,20,20,21,22,23,24,23,25,26,27,26,28,
X	13,23,25,27,27,2,3,4,5,6,7,4,3,2,1,0,1,2,5,4,5,6,6,7,8,9,8,9,10,
X	11,11,12,13,14,14,15};
X
Xstatic char *instructions[] = 
X{
X"     Knight's Tour is a board game for one player.   It is played on",
X"an eight by eight board and is based on the allowable moves that a knight",
X"can make in the game of chess.  For those who are unfamiliar with the",
X"game, a knight may move either on a row or a column but not diagonally.",
X"He may move one square in any direction and two squares in a perpendicular",
X"direction >or< two squares in any direction and one square in a",
X"perpendicular direction.  He may not, of course, move off the board.",
X"",
X"     At the beginning of a game you will be asked to either choose a",
X"starting square or allow the computer to select a random location.",
X"Squares are designated by a letter-number combination where the row is",
X"specified by a letter A-H and the numbers 1-8 define a column.  Invalid",
X"entries are ignored and illegal moves produce a beep at the terminal.",
X"",
X"     The objective is to visit every square on the board.  When you claim",
X"a square a marker is placed on it to show where you've been.  You may",
X"not revisit a square that you've landed on before.",
X"",
X"     After each move the program checks to see if you have any legal",
X"moves left.  If not, the game ends and your squares are counted.  If",
X"you've made all the squares you win the game.  Otherwise, you are told",
X"the number of squares you did make.",
X"END"
X};
X
X
Xmain ()
X{
X	init ();
X	for (;;)  if (!play ()) {
X			endwin ();
X			exit (0);
X	}
X}
X
Xinit ()
X{
X	char c;
X
X	srand48 (getpid());
X	initscr ();
X	signal (SIGINT,SIG_IGN); 
X	cbreak ();              /* immediate char return */
X	noecho ();              /* no immediate echo */
X	title (1,23);
X	mvaddstr (23, 25, "Would you like instructions? ");
X	refresh();
X	if ((c=toupper (getch())) == 'Y') instruct();
X	clear ();
X}
X
Xplay ()
X{
X	drawboard ();           /* clear screen and drawboard */
X	for (j = 0; j < 64; j++) board[j]=0;
X	getfirst ();            /* get the starting square */
X	for (;;) {
X		getrc();
X		if (evalmove()) {
X			putstars ();
X			if (!chkmoves()) return (endgame ());
X		}
X#ifdef BSD
X		else putchar('\007');
X#else
X		else beep();
X#endif
X	}
X}
X
Xdrawboard ()
X{
X	erase ();
X	dosquares ();
X	refresh ();
X	mvaddstr (0, 7, "1   2   3   4   5   6   7   8");
X	for (j = 0; j < 8; j++) mvaddch (2*j+2, 3, j + 'A');
X	refresh ();
X	mvaddstr (20,  5, "ROW:");
X	mvaddstr (20, 27, "COLUMN:");
X	mvaddstr (14, 49, "CURRENT ROW");
X	mvaddstr (16, 49, "CURRENT COL");
X	mvaddstr (22,  5, "A - H or Q to quit");
X	mvaddstr (22, 27, "1 - 8 or ESC to cancel row");
X	refresh ();
X	title (1,40);
X}
X
Xdosquares ()
X{
X	mvaddstr (1, 6, "-------------------------------");
X	for (j = 1; j < 9; j++){
X		mvaddstr (2*j, 5,  "|   |   |   |   |   |   |   |   |");
X		mvaddstr (2*j+1, 6, "-------------------------------");
X	}
X}
X
Xgetfirst ()                             /* get first square */
X{
X	mvaddstr (23, 25, "(S)elect or (R)andom "); refresh ();
X	do {
X		row = toupper(getch());
X	} while ((row != 'S') && (row != 'R'));
X	if (row == 'R') {
X		rw = lrand48() % 8;
X		col = lrand48() % 8;
X		row = rw + 'A';
X		column = col + '1';
X	}
X	else {
X		mvaddstr (23, 25, "Enter starting row and column");
X		refresh ();
X		getrc();                        /* get row and column */
X	}
X	putstars ();
X	move (23, 0);
X	clrtobot();
X}       
X
Xgetrc ()                                /* get row and column */
X{
X	noecho ();
X	do {
X		mvaddstr (20, 35, "  ");
X		refresh ();
X		do {
X			mvaddch (20, 11, ' ');
X			move (20, 11);
X			refresh ();
X			row=toupper(getch());
X			if (row == 'Q') {
X				endwin ();
X				exit (1);
X			}
X		} while ((row < 'A') || (row > 'H'));
X		addch (row);
X		move (20, 35);
X		refresh ();
X		do {
X			column=getch();
X			if (column == '\033') break;
X		} while ((column < '1') || (column > '8'));
X		if (column != '\033') addch (column);
X	} while (column == '\033');
X	refresh();
X	rw = row - 'A';
X	col= column - '1';
X	j = 8 * rw + col;
X}
X
Xputstars ()                     /* place the stars, update board & currents */
X{
X	mvaddch (2*curow+2, 38, ' ');
X	mvaddch (2*rw+2, 38, '<');
X	mvaddch (18, curcol*4+7, ' ');
X	mvaddch (18, col*4+7, '^');
X	curow = rw;
X	curcol= col;
X	mvaddstr (2 * rw + 2, 4*col+6, "***");
X	mvaddch (14, 61, row);
X	mvaddch (16, 61, column);
X	refresh ();
X	board[j] = 1;
X}
X
Xevalmove()                      /* convert row and column to integers */
X		                /* and evaluate move */
X{
X	rdif = rw - curow;
X	cdif = col - curcol;
X	rdif = abs(rw  - curow);
X	cdif = abs(col - curcol);
X	refresh ();
X	if ((rdif == 1) && (cdif == 2)) if (board [j] == 0) return (1);
X	if ((rdif == 2) && (cdif == 1)) if (board [j] == 0) return (1);
X	return (0);
X}
X
Xchkmoves ()                     /* check to see if valid moves are available */
X{
X	if (chksqr(2,1))   return (1);
X	if (chksqr(2,-1))  return (1);
X	if (chksqr(-2,1))  return (1);
X	if (chksqr(-2,-1)) return (1);
X	if (chksqr(1,2))   return (1);
X	if (chksqr(1,-2))  return (1);
X	if (chksqr(-1,2))  return (1);
X	if (chksqr(-1,-2)) return (1);
X	return (0);
X}
X
Xendgame ()                      /* check for filled board or not */
X{
X	rw = 0;
X	for (j = 0; j < 64; j++) if (board[j] != 0) rw+=1;
X	if (rw == 64) mvaddstr (20, 20, "Congratulations !! You got 'em all");
X		else mvprintw (20, 20, "You have ended up with %2d squares",rw);
X	mvaddstr (21, 25, "Play again ? (y/n) ");
X	refresh ();
X	if ((row=tolower(getch())) == 'y') return (1);
X		else return (0);
X}
X
Xabs(num)
Xint	num;
X{
X	if (num < 0) return (-num);
X		else return (num);
X}
X
Xchksqr (n1, n2)
Xint	n1,n2;
X
X{
X	int	r1, c1;
X
X	r1 = rw + n1;
X	c1 = col + n2;
X	if ((r1<0) || (r1>7)) return (0);
X	if ((c1<0) || (c1>7)) return (0);
X	if (board[r1*8+c1] == 0) return (1);
X		else return (0);
X}
X
Xinstruct()
X{
X	int i;
X	char	c;
X
X	clear ();
X	for (i=0;;i++) {
X		if ((strcmp(instructions[i],"END"))) mvaddstr (i, 0, instructions[i]);
X			else {
X				mvaddstr (23, 25, "Ready to play ? (y/n) ");
X				refresh();
X				if ((c=toupper(getch())) == 'Y') {
X					clear ();
X					return (1);
X				}
X					else {
X						clear ();
X						refresh ();
X						endwin ();
X						exit ();
X					}
X			}
X	}
X}
X
Xtitle (y,x)
Xint	y,x;
X{
X	char c;
X	j = 0;
X	do {
X		c = script[j];
X		if (c == 0) break ;
X		mvaddch (ypos[j]+y, xpos[j]+x, c);
X		refresh ();
X		j++;
X	} while (c != 0);
X}
END_OF_knight.c
if test 7138 -ne `wc -c <knight.c`; then
    echo shar: \"knight.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0