|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T p
Length: 12931 (0x3283) Types: TextFile Names: »puzzle.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Puzzle/puzzle.c«
/* * Puzzle, By Henk-Jan Visscher. * * compile: * cc -O puzzle.c -o puzzle -ltermcap * strip puzzle * * NB : change UID in own UID. */ #include <stdio.h> #include <signal.h> #include <sys/types.h> #include <sgtty.h> #include <pwd.h> extern char *tgoto (); #define scr_init() tputs (IS, 0, xputc) #define clear() tputs (CL, 0, xputc) #define rev_begin() tputs (SO, 0, xputc) #define rev_end() tputs (SE, 0, xputc) #define cursor(y, x) tputs (tgoto (CM, x, y), 0, xputc) #define hi_begin() tputs (HI, 0, xputc) #define hi_end() tputs (HE, 0, xputc) #define home() tputs (HO, 0, xputc) #define bell() xputc ('\007') #define flush() fflush (stdout) #define UID 320 #define BORDER -1 #define EMPTY 0 #define SMALL 1 #define WIDTH 2 #define HIGH 3 #define BIG 4 #define CLEAR 0 #define DRAW 1 #define ACCENT 2 char *CL, *SO, *SE, *IS, *CM, *HI, *HE, *HO, ch; short x, y; int moves; struct sgttyb sg, save; struct field { short hx, hy, type; } field [6] [7]; struct mem { short nx, ny, ox, oy; } tb [9999]; struct mem sol [] = { { 1, 1, 2, 1 } , { 1, 2, 1, 1 } , { 2, 3, 1, 3 } , { 3, 2, 3, 1 } , { 4, 2, 3, 2 } , { 4, 1, 4, 2 } , { 3, 1, 4, 1 } , { 3, 2, 3, 1 } , { 1, 3, 2, 3 } , { 2, 3, 3, 3 } , { 2, 2, 2, 3 } , { 2, 1, 2, 2 } , { 2, 3, 1, 3 } , { 2, 2, 2, 3 } , { 3, 1, 2, 1 } , { 4, 2, 3, 2 } , { 3, 2, 3, 1 } , { 3, 3, 3, 2 } , { 2, 3, 3, 3 } , { 3, 3, 4, 3 } , { 1, 3, 2, 3 } , { 2, 3, 3, 3 } , { 1, 1, 1, 2 } , { 2, 1, 2, 2 } , { 3, 1, 2, 1 } , { 2, 1, 1, 1 } , { 4, 1, 3, 1 } , { 3, 1, 2, 1 } , { 3, 2, 3, 1 } , { 3, 3, 3, 2 } , { 3, 2, 4, 2 } , { 2, 2, 3, 2 } , { 1, 2, 2, 2 } , { 1, 4, 1, 3 } , { 1, 3, 1, 2 } , { 2, 4, 1, 4 } , { 4, 4, 3, 4 } , { 4, 3, 4, 4 } , { 4, 4, 4, 5 } , { 4, 2, 4, 3 } , { 4, 3, 4, 4 } , { 3, 2, 4, 2 } , { 3, 4, 3, 3 } , { 3, 3, 3, 2 } , { 1, 4, 2, 4 } , { 1, 2, 1, 3 } , { 1, 3, 1, 4 } , { 2, 2, 1, 2 } , { 3, 2, 2, 2 } , { 4, 2, 3, 2 } , { 4, 4, 4, 3 } , { 4, 3, 4, 2 } , { 4, 5, 4, 4 } , { 4, 4, 4, 3 } , { 2, 4, 3, 4 } , { 2, 2, 2, 3 } , { 2, 3, 2, 4 } , { 3, 2, 2, 2 } , { 4, 2, 3, 2 } , { 3, 2, 3, 3 } , { 3, 1, 3, 2 } , { 2, 1, 3, 1 } , { 3, 1, 4, 1 } , { 1, 1, 2, 1 } , { 2, 1, 3, 1 } , { 1, 2, 1, 1 } , { 2, 2, 2, 1 } , { 3, 3, 2, 3 } , { 2, 3, 1, 3 } , { 4, 3, 3, 3 } , { 3, 3, 2, 3 } , { 3, 2, 3, 3 } , { 4, 1, 4, 2 } , { 3, 1, 4, 1 } , { 2, 1, 3, 1 } , { 2, 3, 2, 2 } , { 2, 2, 2, 1 } , { 2, 4, 2, 3 } , { 2, 3, 2, 2 } , { 1, 4, 2, 4 } , { 1, 3, 1, 4 } , { 1, 4, 1, 5 } , { 1, 1, 1, 2 } , { 1, 2, 1, 3 } , { 2, 1, 1, 1 } , { 1, 1, 1, 2 } , { 2, 2, 2, 1 } , { 2, 4, 2, 3 } , { 1, 5, 2, 5 } , { 1, 3, 1, 4 } , { 1, 2, 1, 3 } , { 2, 1, 1, 1 } , { 2, 3, 2, 2 } , { 2, 2, 2, 1 } , { 1, 3, 2, 3 } , { 2, 3, 2, 4 } , { 1, 4, 1, 3 } , { 2, 5, 1, 5 } , { 2, 4, 2, 5 } , { 2, 1, 2, 2 } , { 2, 2, 2, 3 } , { 3, 1, 2, 1 } , { 4, 1, 3, 1 } , { 4, 2, 4, 1 } , { 3, 3, 3, 2 } , { 3, 4, 3, 3 } , { 2, 5, 3, 5 } , { 3, 5, 4, 5 } , { 1, 5, 2, 5 } , { 2, 5, 3, 5 } , { 1, 3, 1, 4 } , { 1, 1, 1, 2 } , { 2, 3, 2, 4 } , { 2, 1, 2, 2 } , { 3, 1, 2, 1 } , { 2, 1, 1, 1 } , { 4, 1, 3, 1 } , { 3, 1, 2, 1 } , { 3, 2, 3, 1 } , { 3, 3, 3, 2 } , { 3, 5, 3, 4 } , { 3, 4, 4, 4 } , { 2, 4, 3, 4 } , { 2, 2, 2, 3 } , { 2, 3, 2, 4 } , { 3, 2, 2, 2 } , { 4, 4, 4, 3 } , { 4, 3, 4, 2 } , { 4, 5, 4, 4 } , { 4, 4, 4, 3 } , { 3, 4, 4, 4 } , { 2, 4, 3, 4 } , { 1, 4, 2, 4 } , { 1, 2, 1, 3 } , { 1, 3, 1, 4 } , { 2, 2, 1, 2 } , { 4, 2, 3, 2 } , { 3, 2, 3, 3 } , { 3, 1, 3, 2 } , { 2, 1, 3, 1 } , { 3, 1, 4, 1 } , { 1, 1, 2, 1 } , { 2, 1, 3, 1 } , { 1, 2, 1, 1 } , { 3, 3, 2, 3 } , { 2, 3, 1, 3 } , { 4, 3, 3, 3 } , { 3, 3, 2, 3 } , { 3, 2, 3, 3 } , { 3, 1, 3, 2 } , { 3, 2, 4, 2 } , { 1, 1, 2, 1 } , { 0, 0, 0, 0 } }; main () { init (); layout (); initfield (); for (;;) move (); } init () { int leave (); #ifdef SIGTSTP int sigtstp(); #endif SIGTSTP int xputc (); char buffer [1024]; static char save_buf [100]; char *ptr = save_buf; extern char *tgetstr (); signal (SIGINT, leave); signal (SIGQUIT, leave); #ifdef SIGTSTP signal (SIGTSTP, sigtstp); #endif SIGTSTP gtty (1, &sg); save = sg; sg.sg_flags |= CBREAK; sg.sg_flags &= ~ECHO; stty (1, &sg); switch (tgetent (buffer, getenv ("TERM"))) { case -1: fprintf (stderr, "can't open \"termcap\" file.\n"); exit (1); case 0: fprintf (stderr, "can't find entry for term.type.\n"); exit (1); } IS = tgetstr ("is", &ptr); CL = tgetstr ("cl", &ptr); CM = tgetstr ("cm", &ptr); SO = tgetstr ("so", &ptr); SE = tgetstr ("se", &ptr); HI = tgetstr ("hi", &ptr); HE = tgetstr ("he", &ptr); HO = tgetstr ("ho", &ptr); if (!CL || !CM || !SO || !SE || !HI || !HE || !HO) { fprintf (stderr, "not a right terminal.\n"); stty (1, &save); exit (1); } if (IS != (char *) 0) scr_init (); ch = ' '; } #ifdef SIGTSTP sigtstp() { signal (SIGTSTP, SIG_IGN); stty (1, &save); cursor (23, 0); flush (); kill (0, SIGSTOP); signal (SIGTSTP, sigtstp); stty (1, &sg); redraw (); } #endif SIGTSTP leave () { stty (1, &save); cursor (23, 0); exit (0); } fill (x, y, px, py, mode) short x, y, px, py, mode; { short i, j; for (i = y; i < y+py; i++) { cursor (i, x); if (mode != CLEAR) rev_begin (); if (mode == ACCENT) hi_begin (); for (j = x; j < x+px; j++) putchar ((mode == ACCENT) ? ch : ' '); if (mode != CLEAR) rev_end (); if (mode == ACCENT) hi_end (); } } /* VARARGS3 */ pline (yc, xc, format, arg) short yc, xc; char *format; int arg; { cursor (yc, xc); printf (format, arg); } layout () { clear (); fill (7, 2, 34, 20, DRAW); fill (18, 2, 12, 2, CLEAR); fill (11, 4, 26, 16, CLEAR); pline (3, 46, "PUZZLE (By HJ Visscher)"); pline (5, 46, "Purpose :"); pline (6, 46, "----------"); pline (7, 46, "Try to move the biggest"); pline (8, 46, "piece through the hole at"); pline (9, 46, "the top."); pline (11, 46, "Commands :"); pline (12, 46, "------------"); pline (13, 46, "y k u \\"); pline (14, 46, " \\ | / \\"); pline (15, 46, "h - * - l |- To Move"); pline (16, 46, " / | \\ /"); pline (17, 46, "b j n /"); pline (19, 46, "Q - Quit T - Take back"); pline (20, 46, "R - Redraw ? - Solution"); pline (21, 46, "N - New Game A - Extra accent"); } redraw () { short i, j; layout (); for (i = 1; i < 5; i++) for (j = 1; j < 6; j++) if (field [i] [j]. hx == i && field [i] [j]. hy == j) change (DRAW, i, j, field [i] [j]. type); change (ACCENT, x, y, field [x] [y]. type); pline (22, 20, "Moves : %04d", moves); home (); } clfield () { short i, j; static struct field empty_field; for (i = 0; i < 6; i++) for (j = 0; j < 7; j++) field [i] [j] = empty_field; for (i = 0; i < 6; i++) field [i] [0]. type = field [i] [6]. type = BORDER; for (j = 0; j < 7; j++) field [0] [j]. type = field [5] [j]. type = BORDER; } change (task, xc, yc, kind) short task, xc, yc, kind; { field [xc] [yc]. hx = (task == CLEAR) ? 0 : xc; field [xc] [yc]. hy = (task == CLEAR) ? 0 : yc; field [xc] [yc]. type = (task == CLEAR) ? EMPTY : kind; switch (kind) { case SMALL: fill (7+xc*6, 2+yc*3, 4, 2, task); return; case WIDTH: field [xc+1] [yc]. hx = (task == CLEAR) ? 0 : xc; field [xc+1] [yc]. hy = (task == CLEAR) ? 0 : yc; fill (7+xc*6, 2+yc*3, 10, 2, task); return; case HIGH: field [xc] [yc+1]. hx = (task == CLEAR) ? 0 : xc; field [xc] [yc+1]. hy = (task == CLEAR) ? 0 : yc; fill (7+xc*6, 2+yc*3, 4, 5, task); return; case BIG: field [xc+1] [yc]. hx = field [xc] [yc+1]. hx = field [xc+1] [yc+1]. hx = (task == CLEAR) ? 0 : xc; field [xc+1] [yc]. hy = field [xc] [yc+1]. hy = field [xc+1] [yc+1]. hy = (task == CLEAR) ? 0 : yc; fill (7+xc*6, 2+yc*3, 10, 5, task); return; } } initfield () { clfield (); change (ACCENT, 1, 1, SMALL); change (DRAW, 2, 2, SMALL); change (DRAW, 3, 2, SMALL); change (DRAW, 4, 1, SMALL); change (DRAW, 1, 2, HIGH); change (DRAW, 1, 4, HIGH); change (DRAW, 4, 2, HIGH); change (DRAW, 4, 4, HIGH); change (DRAW, 2, 3, WIDTH); change (DRAW, 2, 4, BIG); x = y = 1; moves = 0; pline (22, 20, "Moves : %04d", moves); home (); } move () { char c; short nx, ny, px, py; short movem, kind; c = getchar (); px = (field [x] [y]. type == BIG||field [x] [y]. type == WIDTH) ? 2 : 1; py = (field [x] [y]. type == BIG||field [x] [y]. type == HIGH) ? 2 : 1; movem = 0; switch (c) { case 'A' : ch = (ch == ' ') ? ':' : ' '; change (ACCENT, x, y, field [x] [y]. type); home (); return; case 'Q' : clear (); leave (); case 'R' : redraw (); return; case '?' : solution (); return; case 'T' : takeback (); return; case 'N' : new (); return; case 'h' : nx = field [x-1] [y]. hx; ny = field [x-1] [y]. hy; if (nx == EMPTY && py == 2) { nx = field [x-1] [y+1]. hx; ny = field [x-1] [y+1]. hy; } movem = 1; break; case 'j' : nx = field [x] [y+py]. hx; ny = field [x] [y+py]. hy; if (nx == EMPTY && px == 2) { nx = field [x+1] [y+py]. hx; ny = field [x+1] [y+py]. hy; } movem = 1; break; case 'k' : nx = field [x] [y-1]. hx; ny = field [x] [y-1]. hy; if (nx == EMPTY && px == 2) { nx = field [x+1] [y-1]. hx; ny = field [x+1] [y-1]. hy; } movem = 1; break; case 'l' : nx = field [x+px] [y]. hx; ny = field [x+px] [y]. hy; if (nx == EMPTY && py == 2) { nx = field [x+px] [y+1]. hx; ny = field [x+px] [y+1]. hy; } movem = 1; break; case 'y' : nx = field [x-1] [y-1]. hx; ny = field [x-1] [y-1]. hy; break; case 'u' : nx = field [x+px] [y-1]. hx; ny = field [x+px] [y-1]. hy; if (nx == EMPTY) { nx = field [x+1] [y-1]. hx; ny = field [x+1] [y-1]. hy; } break; case 'b' : nx = field [x-1] [y+py]. hx; ny = field [x-1] [y+py]. hy; if (nx == EMPTY) { nx = field [x-1] [y+1]. hx; ny = field [x-1] [y+1]. hy; } break; case 'n' : nx = field [x+px] [y+py]. hx; ny = field [x+px] [y+py]. hy; if (nx == EMPTY) { nx = field [x+1] [y+1]. hx; ny = field [x+1] [y+1]. hy; } break; default : bell (); return; } if (nx != EMPTY) { change (DRAW, x, y, field [x] [y]. type); change (ACCENT, nx, ny, field [nx] [ny]. type); home (); x = nx; y = ny; return; } if (!movem) { bell (); return; } kind = field [x] [y]. type; change (CLEAR, x, y, kind); nx = x + (c == 'l') - (c == 'h'); ny = y + (c == 'j') - (c == 'k'); if (!space (nx, ny, kind)) { if (c == 'k' && kind == BIG && x == 2 && y == 1) solved (); change (ACCENT, x, y, kind); bell (); home (); return; } change (ACCENT, nx, ny, kind); pline (22, 20, "Moves : %04d", ++moves); home (); tb [moves]. ox = x; tb [moves]. oy = y; tb [moves]. nx = nx; tb [moves]. ny = ny; x = nx; y = ny; } space (xc, yc, kind) short xc, yc, kind; { if (field [xc] [yc]. type) return (0); switch (kind) { case SMALL : return (1); case WIDTH : return (field [xc+1] [yc]. type == EMPTY); case HIGH : return (field [xc] [yc+1]. type == EMPTY); case BIG : return (field [xc+1] [yc]. type == EMPTY && field [xc] [yc+1]. type == EMPTY && field [xc+1] [yc+1]. type == EMPTY); } /* NOTREACHED */ } solved () { fill (11, 4, 26, 16, CLEAR); fill (15, 10, 18, 5, ACCENT); fill (17, 11, 14, 3, DRAW); pline (12, 19, "SOLVED !!!"); leave (); } xputc (c) char c; { putchar (c); } solution () { struct passwd *pw, *getpwuid(); short i, kind; char *crypt (); if ((pw = getpwuid (UID)) == (struct passwd *) 0) { pline (22, 20, "Sorry.... "); home (); return; } cursor (22, 20); printf ("Password: "); flush (); if (strcmp (crypt (getpass(""), pw->pw_passwd), pw->pw_passwd)) { pline (22, 20, "Sorry.... "); home (); return; } new (); pline (22, 20, "Moves : %04d ", moves); for (i = 0; sol [i]. nx; i++) { kind = field [sol [i]. nx] [sol [i]. ny]. type; change (CLEAR, sol [i]. nx, sol [i]. ny, kind); change (DRAW, (x = sol [i]. ox), (y = sol [i]. oy), kind); pline (22, 28, "%04d", ++moves); home (); } solved (); } takeback () { int count; short i, kind; char buffer [BUFSIZ]; pline (22, 15, "How many moves ? "); stty (1, &save); gets (buffer); count = atoi (buffer); stty (1, &sg); if (moves - count < 0) { pline (22, 15, " Sorry "); home (); return; } pline (22, 15, " "); for (i = 0; i < count; i++) { kind = field [tb [moves]. nx] [tb [moves]. ny]. type; change (DRAW, x, y, field [x] [y]. type); change (CLEAR, tb [moves]. nx, tb [moves]. ny, kind); change (ACCENT, (x = tb [moves]. ox), (y = tb [moves]. oy), kind); pline (22, 20, "Moves : %04d", --moves); home (); } } new () { fill (11, 4, 26, 16, CLEAR); initfield (); }