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