games-request@tekred.TEK.COM (02/19/88)
Submitted by: Henk <mcvax!cs.vu.nl!Henk@uunet.uu.net>
Comp.sources.games: Volume 3, Issue 83
Archive-name: puzzle
[Note that this program requires some non-standard(?) termcap
entries (hi, he) for highlighting (in addition to so & se),
as well as ho (home). Since my terminal termcaps don't support
hi & he I couldn't try this program, although I did compile it
OK. -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 puzzle.c
# Wrapped by billr@saab on Thu Feb 18 16:47:07 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\" \(535 characters\)
sed "s/^X//" >README <<'END_OF_README'
XPUZZLE (By HJ Visscher)
X
XPurpose :
XTry to move the biggest piece through the hole at the top.
X
XCommands :
Xy k u \\
X \\ | / \\
Xh - * - l |- To Move
X / | \\ /
Xb j n /
X
XQ - Quit
XT - Take back
XR - Redraw
X? - Solution
XN - New Game
XA - Extra accent
X
XThe solution I included is not the perfect solution. That solution
Xonly requires 116 moves (instead of 152), but while writing this program
XI didn't know this solution. Anyone intrested in this solution can mail
Xme for it.
X
XHenk
Xmcvax!cs.vu.nl!Henk@uunet.uu.net
END_OF_README
if test 535 -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\" \(82 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
X# Simple makefile for puzzle
Xpuzzle: puzzle.c
X cc -o puzzle -O puzzle.c -ltermcap
END_OF_Makefile
if test 82 -ne `wc -c <Makefile`; then
echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f puzzle.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"puzzle.c\"
else
echo shar: Extracting \"puzzle.c\" \(12931 characters\)
sed "s/^X//" >puzzle.c <<'END_OF_puzzle.c'
X /*
X * Puzzle, By Henk-Jan Visscher.
X *
X * compile:
X * cc -O puzzle.c -o puzzle -ltermcap
X * strip puzzle
X *
X * NB : change UID in own UID.
X */
X
X#include <stdio.h>
X#include <signal.h>
X#include <sys/types.h>
X#include <sgtty.h>
X#include <pwd.h>
X
Xextern char *tgoto ();
X
X#define scr_init() tputs (IS, 0, xputc)
X#define clear() tputs (CL, 0, xputc)
X#define rev_begin() tputs (SO, 0, xputc)
X#define rev_end() tputs (SE, 0, xputc)
X#define cursor(y, x) tputs (tgoto (CM, x, y), 0, xputc)
X#define hi_begin() tputs (HI, 0, xputc)
X#define hi_end() tputs (HE, 0, xputc)
X#define home() tputs (HO, 0, xputc)
X#define bell() xputc ('\007')
X#define flush() fflush (stdout)
X
X#define UID 320
X
X#define BORDER -1
X#define EMPTY 0
X#define SMALL 1
X#define WIDTH 2
X#define HIGH 3
X#define BIG 4
X
X#define CLEAR 0
X#define DRAW 1
X#define ACCENT 2
X
Xchar *CL, *SO, *SE, *IS, *CM, *HI, *HE, *HO, ch;
Xshort x, y;
Xint moves;
X
Xstruct sgttyb sg, save;
X
Xstruct field {
X short hx, hy, type;
X} field [6] [7];
X
Xstruct mem {
X short nx, ny, ox, oy;
X} tb [9999];
X
Xstruct mem sol [] = {
X { 1, 1, 2, 1 } , { 1, 2, 1, 1 } , { 2, 3, 1, 3 } , { 3, 2, 3, 1 } ,
X { 4, 2, 3, 2 } , { 4, 1, 4, 2 } , { 3, 1, 4, 1 } , { 3, 2, 3, 1 } ,
X { 1, 3, 2, 3 } , { 2, 3, 3, 3 } , { 2, 2, 2, 3 } , { 2, 1, 2, 2 } ,
X { 2, 3, 1, 3 } , { 2, 2, 2, 3 } , { 3, 1, 2, 1 } , { 4, 2, 3, 2 } ,
X { 3, 2, 3, 1 } , { 3, 3, 3, 2 } , { 2, 3, 3, 3 } , { 3, 3, 4, 3 } ,
X { 1, 3, 2, 3 } , { 2, 3, 3, 3 } , { 1, 1, 1, 2 } , { 2, 1, 2, 2 } ,
X { 3, 1, 2, 1 } , { 2, 1, 1, 1 } , { 4, 1, 3, 1 } , { 3, 1, 2, 1 } ,
X { 3, 2, 3, 1 } , { 3, 3, 3, 2 } , { 3, 2, 4, 2 } , { 2, 2, 3, 2 } ,
X { 1, 2, 2, 2 } , { 1, 4, 1, 3 } , { 1, 3, 1, 2 } , { 2, 4, 1, 4 } ,
X { 4, 4, 3, 4 } , { 4, 3, 4, 4 } , { 4, 4, 4, 5 } , { 4, 2, 4, 3 } ,
X { 4, 3, 4, 4 } , { 3, 2, 4, 2 } , { 3, 4, 3, 3 } , { 3, 3, 3, 2 } ,
X { 1, 4, 2, 4 } , { 1, 2, 1, 3 } , { 1, 3, 1, 4 } , { 2, 2, 1, 2 } ,
X { 3, 2, 2, 2 } , { 4, 2, 3, 2 } , { 4, 4, 4, 3 } , { 4, 3, 4, 2 } ,
X { 4, 5, 4, 4 } , { 4, 4, 4, 3 } , { 2, 4, 3, 4 } , { 2, 2, 2, 3 } ,
X { 2, 3, 2, 4 } , { 3, 2, 2, 2 } , { 4, 2, 3, 2 } , { 3, 2, 3, 3 } ,
X { 3, 1, 3, 2 } , { 2, 1, 3, 1 } , { 3, 1, 4, 1 } , { 1, 1, 2, 1 } ,
X { 2, 1, 3, 1 } , { 1, 2, 1, 1 } , { 2, 2, 2, 1 } , { 3, 3, 2, 3 } ,
X { 2, 3, 1, 3 } , { 4, 3, 3, 3 } , { 3, 3, 2, 3 } , { 3, 2, 3, 3 } ,
X { 4, 1, 4, 2 } , { 3, 1, 4, 1 } , { 2, 1, 3, 1 } , { 2, 3, 2, 2 } ,
X { 2, 2, 2, 1 } , { 2, 4, 2, 3 } , { 2, 3, 2, 2 } , { 1, 4, 2, 4 } ,
X { 1, 3, 1, 4 } , { 1, 4, 1, 5 } , { 1, 1, 1, 2 } , { 1, 2, 1, 3 } ,
X { 2, 1, 1, 1 } , { 1, 1, 1, 2 } , { 2, 2, 2, 1 } , { 2, 4, 2, 3 } ,
X { 1, 5, 2, 5 } , { 1, 3, 1, 4 } , { 1, 2, 1, 3 } , { 2, 1, 1, 1 } ,
X { 2, 3, 2, 2 } , { 2, 2, 2, 1 } , { 1, 3, 2, 3 } , { 2, 3, 2, 4 } ,
X { 1, 4, 1, 3 } , { 2, 5, 1, 5 } , { 2, 4, 2, 5 } , { 2, 1, 2, 2 } ,
X { 2, 2, 2, 3 } , { 3, 1, 2, 1 } , { 4, 1, 3, 1 } , { 4, 2, 4, 1 } ,
X { 3, 3, 3, 2 } , { 3, 4, 3, 3 } , { 2, 5, 3, 5 } , { 3, 5, 4, 5 } ,
X { 1, 5, 2, 5 } , { 2, 5, 3, 5 } , { 1, 3, 1, 4 } , { 1, 1, 1, 2 } ,
X { 2, 3, 2, 4 } , { 2, 1, 2, 2 } , { 3, 1, 2, 1 } , { 2, 1, 1, 1 } ,
X { 4, 1, 3, 1 } , { 3, 1, 2, 1 } , { 3, 2, 3, 1 } , { 3, 3, 3, 2 } ,
X { 3, 5, 3, 4 } , { 3, 4, 4, 4 } , { 2, 4, 3, 4 } , { 2, 2, 2, 3 } ,
X { 2, 3, 2, 4 } , { 3, 2, 2, 2 } , { 4, 4, 4, 3 } , { 4, 3, 4, 2 } ,
X { 4, 5, 4, 4 } , { 4, 4, 4, 3 } , { 3, 4, 4, 4 } , { 2, 4, 3, 4 } ,
X { 1, 4, 2, 4 } , { 1, 2, 1, 3 } , { 1, 3, 1, 4 } , { 2, 2, 1, 2 } ,
X { 4, 2, 3, 2 } , { 3, 2, 3, 3 } , { 3, 1, 3, 2 } , { 2, 1, 3, 1 } ,
X { 3, 1, 4, 1 } , { 1, 1, 2, 1 } , { 2, 1, 3, 1 } , { 1, 2, 1, 1 } ,
X { 3, 3, 2, 3 } , { 2, 3, 1, 3 } , { 4, 3, 3, 3 } , { 3, 3, 2, 3 } ,
X { 3, 2, 3, 3 } , { 3, 1, 3, 2 } , { 3, 2, 4, 2 } , { 1, 1, 2, 1 } ,
X { 0, 0, 0, 0 }
X};
X
Xmain ()
X{
X init ();
X layout ();
X initfield ();
X for (;;)
X move ();
X}
X
Xinit ()
X{
X int leave ();
X#ifdef SIGTSTP
X int sigtstp();
X#endif SIGTSTP
X int xputc ();
X char buffer [1024];
X static char save_buf [100];
X char *ptr = save_buf;
X extern char *tgetstr ();
X
X signal (SIGINT, leave);
X signal (SIGQUIT, leave);
X#ifdef SIGTSTP
X signal (SIGTSTP, sigtstp);
X#endif SIGTSTP
X
X gtty (1, &sg);
X save = sg;
X sg.sg_flags |= CBREAK;
X sg.sg_flags &= ~ECHO;
X stty (1, &sg);
X
X switch (tgetent (buffer, getenv ("TERM"))) {
X case -1:
X fprintf (stderr, "can't open \"termcap\" file.\n");
X exit (1);
X case 0:
X fprintf (stderr, "can't find entry for term.type.\n");
X exit (1);
X }
X
X IS = tgetstr ("is", &ptr);
X CL = tgetstr ("cl", &ptr);
X CM = tgetstr ("cm", &ptr);
X SO = tgetstr ("so", &ptr);
X SE = tgetstr ("se", &ptr);
X HI = tgetstr ("hi", &ptr);
X HE = tgetstr ("he", &ptr);
X HO = tgetstr ("ho", &ptr);
X if (!CL || !CM || !SO || !SE || !HI || !HE || !HO) {
X fprintf (stderr, "not a right terminal.\n");
X stty (1, &save);
X exit (1);
X }
X if (IS != (char *) 0) scr_init ();
X ch = ' ';
X}
X
X#ifdef SIGTSTP
Xsigtstp()
X{
X signal (SIGTSTP, SIG_IGN);
X stty (1, &save);
X cursor (23, 0);
X flush ();
X kill (0, SIGSTOP);
X signal (SIGTSTP, sigtstp);
X stty (1, &sg);
X redraw ();
X}
X#endif SIGTSTP
X
Xleave ()
X{
X stty (1, &save);
X cursor (23, 0);
X exit (0);
X}
X
Xfill (x, y, px, py, mode)
Xshort x, y, px, py, mode;
X{
X short i, j;
X
X for (i = y; i < y+py; i++)
X {
X cursor (i, x);
X if (mode != CLEAR) rev_begin ();
X if (mode == ACCENT) hi_begin ();
X for (j = x; j < x+px; j++)
X putchar ((mode == ACCENT) ? ch : ' ');
X if (mode != CLEAR) rev_end ();
X if (mode == ACCENT) hi_end ();
X }
X}
X
X/* VARARGS3 */
Xpline (yc, xc, format, arg)
Xshort yc, xc;
Xchar *format;
Xint arg;
X{
X cursor (yc, xc);
X printf (format, arg);
X}
X
Xlayout ()
X{
X clear ();
X fill (7, 2, 34, 20, DRAW);
X fill (18, 2, 12, 2, CLEAR);
X fill (11, 4, 26, 16, CLEAR);
X pline (3, 46, "PUZZLE (By HJ Visscher)");
X pline (5, 46, "Purpose :");
X pline (6, 46, "----------");
X pline (7, 46, "Try to move the biggest");
X pline (8, 46, "piece through the hole at");
X pline (9, 46, "the top.");
X pline (11, 46, "Commands :");
X pline (12, 46, "------------");
X pline (13, 46, "y k u \\");
X pline (14, 46, " \\ | / \\");
X pline (15, 46, "h - * - l |- To Move");
X pline (16, 46, " / | \\ /");
X pline (17, 46, "b j n /");
X pline (19, 46, "Q - Quit T - Take back");
X pline (20, 46, "R - Redraw ? - Solution");
X pline (21, 46, "N - New Game A - Extra accent");
X}
X
Xredraw ()
X{
X short i, j;
X
X layout ();
X for (i = 1; i < 5; i++)
X for (j = 1; j < 6; j++)
X if (field [i] [j]. hx == i && field [i] [j]. hy == j)
X change (DRAW, i, j, field [i] [j]. type);
X change (ACCENT, x, y, field [x] [y]. type);
X pline (22, 20, "Moves : %04d", moves);
X home ();
X}
X
Xclfield ()
X{
X short i, j;
X static struct field empty_field;
X
X for (i = 0; i < 6; i++)
X for (j = 0; j < 7; j++)
X field [i] [j] = empty_field;
X for (i = 0; i < 6; i++)
X field [i] [0]. type = field [i] [6]. type = BORDER;
X for (j = 0; j < 7; j++)
X field [0] [j]. type = field [5] [j]. type = BORDER;
X}
X
Xchange (task, xc, yc, kind)
Xshort task, xc, yc, kind;
X{
X field [xc] [yc]. hx = (task == CLEAR) ? 0 : xc;
X field [xc] [yc]. hy = (task == CLEAR) ? 0 : yc;
X field [xc] [yc]. type = (task == CLEAR) ? EMPTY : kind;
X switch (kind) {
X case SMALL:
X fill (7+xc*6, 2+yc*3, 4, 2, task);
X return;
X case WIDTH:
X field [xc+1] [yc]. hx = (task == CLEAR) ? 0 : xc;
X field [xc+1] [yc]. hy = (task == CLEAR) ? 0 : yc;
X fill (7+xc*6, 2+yc*3, 10, 2, task);
X return;
X case HIGH:
X field [xc] [yc+1]. hx = (task == CLEAR) ? 0 : xc;
X field [xc] [yc+1]. hy = (task == CLEAR) ? 0 : yc;
X fill (7+xc*6, 2+yc*3, 4, 5, task);
X return;
X case BIG:
X field [xc+1] [yc]. hx = field [xc] [yc+1]. hx =
X field [xc+1] [yc+1]. hx =
X (task == CLEAR) ? 0 : xc;
X field [xc+1] [yc]. hy = field [xc] [yc+1]. hy =
X field [xc+1] [yc+1]. hy =
X (task == CLEAR) ? 0 : yc;
X fill (7+xc*6, 2+yc*3, 10, 5, task);
X return;
X }
X}
X
Xinitfield ()
X{
X clfield ();
X change (ACCENT, 1, 1, SMALL);
X change (DRAW, 2, 2, SMALL);
X change (DRAW, 3, 2, SMALL);
X change (DRAW, 4, 1, SMALL);
X change (DRAW, 1, 2, HIGH);
X change (DRAW, 1, 4, HIGH);
X change (DRAW, 4, 2, HIGH);
X change (DRAW, 4, 4, HIGH);
X change (DRAW, 2, 3, WIDTH);
X change (DRAW, 2, 4, BIG);
X x = y = 1;
X moves = 0;
X pline (22, 20, "Moves : %04d", moves);
X home ();
X}
X
Xmove ()
X{
X char c;
X short nx, ny, px, py;
X short movem, kind;
X
X c = getchar ();
X
X px = (field [x] [y]. type == BIG||field [x] [y]. type == WIDTH) ? 2 : 1;
X py = (field [x] [y]. type == BIG||field [x] [y]. type == HIGH) ? 2 : 1;
X movem = 0;
X switch (c) {
X case 'A' : ch = (ch == ' ') ? ':' : ' ';
X change (ACCENT, x, y, field [x] [y]. type);
X home ();
X return;
X case 'Q' : clear ();
X leave ();
X case 'R' : redraw ();
X return;
X case '?' : solution ();
X return;
X case 'T' : takeback ();
X return;
X case 'N' : new ();
X return;
X case 'h' : nx = field [x-1] [y]. hx;
X ny = field [x-1] [y]. hy;
X if (nx == EMPTY && py == 2) {
X nx = field [x-1] [y+1]. hx;
X ny = field [x-1] [y+1]. hy;
X }
X movem = 1;
X break;
X case 'j' : nx = field [x] [y+py]. hx;
X ny = field [x] [y+py]. hy;
X if (nx == EMPTY && px == 2) {
X nx = field [x+1] [y+py]. hx;
X ny = field [x+1] [y+py]. hy;
X }
X movem = 1;
X break;
X case 'k' : nx = field [x] [y-1]. hx;
X ny = field [x] [y-1]. hy;
X if (nx == EMPTY && px == 2) {
X nx = field [x+1] [y-1]. hx;
X ny = field [x+1] [y-1]. hy;
X }
X movem = 1;
X break;
X case 'l' : nx = field [x+px] [y]. hx;
X ny = field [x+px] [y]. hy;
X if (nx == EMPTY && py == 2) {
X nx = field [x+px] [y+1]. hx;
X ny = field [x+px] [y+1]. hy;
X }
X movem = 1;
X break;
X case 'y' : nx = field [x-1] [y-1]. hx;
X ny = field [x-1] [y-1]. hy;
X break;
X case 'u' : nx = field [x+px] [y-1]. hx;
X ny = field [x+px] [y-1]. hy;
X if (nx == EMPTY) {
X nx = field [x+1] [y-1]. hx;
X ny = field [x+1] [y-1]. hy;
X }
X break;
X case 'b' : nx = field [x-1] [y+py]. hx;
X ny = field [x-1] [y+py]. hy;
X if (nx == EMPTY) {
X nx = field [x-1] [y+1]. hx;
X ny = field [x-1] [y+1]. hy;
X }
X break;
X case 'n' : nx = field [x+px] [y+py]. hx;
X ny = field [x+px] [y+py]. hy;
X if (nx == EMPTY) {
X nx = field [x+1] [y+1]. hx;
X ny = field [x+1] [y+1]. hy;
X }
X break;
X default : bell ();
X return;
X }
X
X if (nx != EMPTY) {
X change (DRAW, x, y, field [x] [y]. type);
X change (ACCENT, nx, ny, field [nx] [ny]. type);
X home ();
X x = nx; y = ny;
X return;
X }
X
X if (!movem) {
X bell ();
X return;
X }
X
X kind = field [x] [y]. type;
X change (CLEAR, x, y, kind);
X nx = x + (c == 'l') - (c == 'h');
X ny = y + (c == 'j') - (c == 'k');
X if (!space (nx, ny, kind)) {
X if (c == 'k' && kind == BIG && x == 2 && y == 1) solved ();
X change (ACCENT, x, y, kind);
X bell ();
X home ();
X return;
X }
X change (ACCENT, nx, ny, kind);
X pline (22, 20, "Moves : %04d", ++moves);
X home ();
X tb [moves]. ox = x;
X tb [moves]. oy = y;
X tb [moves]. nx = nx;
X tb [moves]. ny = ny;
X x = nx; y = ny;
X}
X
Xspace (xc, yc, kind)
Xshort xc, yc, kind;
X{
X if (field [xc] [yc]. type) return (0);
X switch (kind) {
X case SMALL : return (1);
X case WIDTH : return (field [xc+1] [yc]. type == EMPTY);
X case HIGH : return (field [xc] [yc+1]. type == EMPTY);
X case BIG : return (field [xc+1] [yc]. type == EMPTY &&
X field [xc] [yc+1]. type == EMPTY &&
X field [xc+1] [yc+1]. type == EMPTY);
X }
X /* NOTREACHED */
X}
X
Xsolved ()
X{
X fill (11, 4, 26, 16, CLEAR);
X fill (15, 10, 18, 5, ACCENT);
X fill (17, 11, 14, 3, DRAW);
X pline (12, 19, "SOLVED !!!");
X leave ();
X}
X
Xxputc (c)
Xchar c;
X{
X putchar (c);
X}
X
Xsolution ()
X{
X struct passwd *pw, *getpwuid();
X short i, kind;
X char *crypt ();
X
X if ((pw = getpwuid (UID)) == (struct passwd *) 0) {
X pline (22, 20, "Sorry.... ");
X home ();
X return;
X }
X cursor (22, 20);
X printf ("Password: ");
X flush ();
X if (strcmp (crypt (getpass(""), pw->pw_passwd), pw->pw_passwd)) {
X pline (22, 20, "Sorry.... ");
X home ();
X return;
X }
X new ();
X pline (22, 20, "Moves : %04d ", moves);
X for (i = 0; sol [i]. nx; i++) {
X kind = field [sol [i]. nx] [sol [i]. ny]. type;
X change (CLEAR, sol [i]. nx, sol [i]. ny, kind);
X change (DRAW, (x = sol [i]. ox), (y = sol [i]. oy), kind);
X pline (22, 28, "%04d", ++moves);
X home ();
X }
X solved ();
X}
X
Xtakeback ()
X{
X int count;
X short i, kind;
X char buffer [BUFSIZ];
X
X pline (22, 15, "How many moves ? ");
X stty (1, &save);
X gets (buffer);
X count = atoi (buffer);
X stty (1, &sg);
X if (moves - count < 0) {
X pline (22, 15, " Sorry ");
X home ();
X return;
X }
X pline (22, 15, " ");
X for (i = 0; i < count; i++) {
X kind = field [tb [moves]. nx] [tb [moves]. ny]. type;
X change (DRAW, x, y, field [x] [y]. type);
X change (CLEAR, tb [moves]. nx, tb [moves]. ny, kind);
X change (ACCENT, (x = tb [moves]. ox), (y = tb [moves]. oy), kind);
X pline (22, 20, "Moves : %04d", --moves);
X home ();
X }
X}
X
Xnew ()
X{
X fill (11, 4, 26, 16, CLEAR);
X initfield ();
X}
END_OF_puzzle.c
if test 12931 -ne `wc -c <puzzle.c`; then
echo shar: \"puzzle.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0