Path: uunet!husc6!mailrus!ames!ll-xn!mit-eddie!uw-beaver!tektronix!tekgen!tekred!games-request
From: games-request@tekred.TEK.COM
Newsgroups: comp.sources.games
Subject: v03i085: knight - knights tour, a chess oriented brain game
Message-ID: <2195@tekred.TEK.COM>
Date: 19 Feb 88 01:46:34 GMT
Sender: billr@tekred.TEK.COM
Lines: 367
Approved: billr@tekred.TEK.COM
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 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 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 knight.c <<'END_OF_knight.c'
X/* Knights Tour - a brain game */
X
X#include
X#ifdef BSD
X#include
X#endif
X#include
X#include
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[]={"'_)//,/(-)/__/__(_<_(__),|/|/_///_/_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