[comp.sources.games] v12i015: xmascard - a video christmas card, Part01/01

billr@saab.CNA.TEK.COM (Bill Randle) (12/22/90)

Submitted-by: Istvan Mohos <uunet!pyrdc!pyrnj!hhb!istvan>
Posting-number: Volume 12, Issue 15
Archive-name: xmascard/Part01
Environment: termcap

	[I got this off the net last year anf just now checked it
	 out. I though it worth reposting here.  -br]

[From the author:
Found this while dusting off programs in a long forgotten directory...
a video Christmas Card, implementing the recursive "Towers of Hanoi"
algorithm (to twelve levels), disguised as tiers of a Christmas tree.]

#! /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 xmascard.c
# Wrapped by billr@saab on Fri Dec 21 13:12:34 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(627 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XFound this while dusting off programs in a long forgotten directory...
Xa video Christmas Card, implementing the recursive "Towers of Hanoi"
Xalgorithm (to twelve levels), disguised as tiers of a Christmas tree.
XWhat was the last time *you* used low-level termcap routines?
X(Incidentally, SysV versions of tgetent() seem to be hard-coded to
Xread in /etc/termcap instead of the environment variable $TERMCAP,
Xfor your terminal description.  Do tgetent(), etc. still work with
Xtermio?  I don't know.)
X
X        Istvan Mohos
X        ...uunet!pyrdc!pyrnj!hhb!istvan
X        HHB Systems 1000 Wyckoff Ave. Mahwah NJ 07430 201-848-8000
X
END_OF_FILE
if test 627 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(175 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# simple makefile for xmascard
XCC = cc
XCFLAGS = -O
X# this may need to be -ltermlib on some systems
XLIBS = -ltermcap
X
Xxmascard: xmascard.c
X	$(CC) $(CFLAGS) -o xmascard $(LIBS)
END_OF_FILE
if test 175 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'xmascard.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xmascard.c'\"
else
echo shar: Extracting \"'xmascard.c'\" \(8351 characters\)
sed "s/^X//" >'xmascard.c' <<'END_OF_FILE'
X/**********************************************************************
X *  card.c --- Christmas Card From Hanoi --- by Istvan Mohos, 1984
X *
X *  Compile with "/bin/cc card.c -ltermlib -o card"
X *  Use with ttys at 9600/4800/2400 baud; don't bother at slower speeds.
X *  Running under SysV and BSD, on Pyramid, VAX, SUN.
X *  SunWindows flow-control a mess, but OK on console.
X *
X *  Thanks to Bill Tuthill for showing me curses...
X **********************************************************************/
X
X#include <stdio.h>
X
X#define WRITENEXT tputs(tgoto(CM,HOR,VER),1,string);\
X                      printf("%s",disk[map[from.deep][from.pole]])
X#define ERASEPREV tputs(tgoto(CM,HOR,VER),1,string);\
X                      printf("%s",disk[14])
X#define PUTBLANK  tputs(tgoto(CM,HOR,VER),1,string);\
X                      printf("%s",disk[0])
X
Xstring(c)
Xregister char c;
X{
X    putchar(c);
X}
X
Xstatic long counter = 1;
Xstruct diskpos
X{
X    int ver;
X    int hor;
X};
X
Xstatic struct diskpos level[16][3] =
X{  7,0,         7,28,           7,55,
X   8,0,         8,28,           8,55,
X   9,0,         9,28,           9,55,
X  10,0,        10,28,          10,55,
X  11,0,        11,28,          11,55,
X  12,0,        12,28,          12,55,
X  13,0,        13,28,          13,55,
X  14,0,        14,28,          14,55,
X  15,0,        15,28,          15,55,
X  16,0,        16,28,          16,55,
X  17,0,        17,28,          17,55,
X  18,0,        18,28,          18,55,
X  19,0,        19,28,          19,55,
X  20,0,        20,28,          20,55,
X  21,0,        21,28,          21,55,
X  22,0,        22,28,          22,55 };
X
Xstatic struct diskpos flyway[17][6] =
X{  7, 0,    7, 0,    7,55,    7,55,    7,28,    7,28,
X   6, 1,    6, 1,    6,54,    6,54,    6,29,    6,27,
X   5, 2,    5, 2,    5,53,    5,53,    5,30,    5,26,
X   4, 4,    4, 4,    4,51,    4,51,    4,32,    4,24,
X   3, 7,    3, 7,    3,48,    3,48,    3,35,    3,21,
X   2,13,    2,13,    2,42,    2,42,    2,42,    2,13,
X   1,19,    3,21,    1,37,    3,35,    3,48,    3, 7,
X   0,28,    4,24,    0,26,    4,32,    4,51,    4, 4,
X   1,37,    5,26,    1,19,    5,30,    5,53,    5, 2,
X   2,42,    6,27,    2,13,    6,29,    6,54,    6, 1,
X   3,48,    7,28,    3, 7,    7,28,    7,55,    7, 0,
X   4,51,    8,28,    4, 4,    8,28,    8,55,    8, 0,
X   5,53,    0, 0,    5, 2,    0, 0,    0, 0,    0, 0,
X   6,54,    0, 0,    6, 1,    0, 0,    0, 0,    0, 0,
X   7,55,    0, 0,    7, 0,    0, 0,    0, 0,    0, 0,
X   8,55,    0, 0,    8, 0,    0, 0,    0, 0,    0, 0 };
X/* an extra line of 0 initialized above, used for sentinel */
X
Xstatic char *disk[]  = {
X"                         ",
X"           may           ",
X"          every          ",
X"         falling         ",
X"        snowflake        ",
X"       bring peace       ",
X"      may every day      ",
X"     be as christmas     ",
X"    filled with quiet    ",
X"   expectant happiness   ",
X"  joy and understanding  ",
X" our human souls shining ",
X"loving caring for another",
X"~~~~~~~~~~~~~~~~~~~~~~~~~",
X"            |            ",};
X
Xstruct handle {
X    int deep;
X    int pole;
X};
X
Xint  map[15][3];
Xint  HOR, VER;
Xchar *term, entry[1024], buf[512], *area;
Xchar *getenv(), *tgetstr(), *tgoto();
Xchar *CL, *CM;
X
Xmain()
X{
X    int temp, i;
X    struct handle from, to, lazy;
X    from.pole=0;
X    to.pole=2;
X    lazy.pole=1;
X
X    term = getenv("TERM");
X    if (tgetent(entry, term) != 1)
X       perror("bad or missing termcap... but MERRY CHRISTMAS !"),
X       exit(1);
X    if (tgetnum("li") < 23)
X       perror("screen too small... but MERRY CHRISTMAS !"), exit(1);
X    if (tgetnum("co") < 80)
X       perror("screen too small... but MERRY CHRISTMAS !"), exit(1);
X    area = buf;
X    CL = tgetstr("cl", &area);
X    CM = tgetstr("cm", &area);
X
X    /* initialize map matrix */
X    for  (  i=12;  i > -1;  --i  ) {
X        map[i][0]  = i;
X        map[i][1]  = 14;
X        map[i][2]  = 14;
X    }
X    map[13][0] = 13;
X    map[13][1] = 13;
X    map[13][2] = 13;
X    map[0][1] = 0;
X    map[0][2] = 0;
X
X    /* print field */
X    tputs(CL, 1, string);
X
X    for (  i=1;  i<14;  ++i  ) {
X        for ( temp=2;  temp > -1; --temp ) {
X            VER = level[i][temp].ver;
X            HOR = level[i][temp].hor;
X            tputs(tgoto(CM,HOR,VER),1,string);
X            printf("%s",disk[map[i][temp]]);
X        }
X    }
X    tputs(tgoto(CM,26,22),1,string);
X    printf("<<*>>  Merry Christmas! <<*>>");
X    hanoi(12,from,lazy,to);
X    exit(0);
X}
X
Xhanoi (high,from,lazy,to)
Xint high;
Xstruct handle from,lazy,to;
X{
X    int i;
X
X    if ( high != 0 ) {
X        hanoi(high-1,from,to,lazy);
X        i=1;
X        while ( map[i][from.pole] == 14 )
X            ++i;
X        from.deep = i;
X
X        i=1;
X        while ( map[i][to.pole] == 14 )
X            ++i;
X        to.deep = i-1;
X
X        move_disk( from, to);
X
X        map[to.deep][to.pole] = map[from.deep][from.pole];
X        map[from.deep][from.pole] = 14;
X        ++counter;
X        tputs(tgoto(CM,12,7),1,string); printf("*");
X        tputs(tgoto(CM,40,7),1,string); printf("*");
X        tputs(tgoto(CM,67,7),1,string); printf("*");
X        tputs(tgoto(CM,33,22),1,string);
X        if (counter % 2)
X            printf("Merry Christmas!");
X        else
X            printf("Happy New Year! ");
X        
X        hanoi(high-1,lazy,from,to);
X    }
X}
X
Xdown_the_pole (from, to)
Xstruct handle from, to;
X{
X    int i;
X
X    for (  i=2;  i <= to.deep;  ++i  ) {
X        VER = level[i][to.pole].ver;
X        HOR = level[i][to.pole].hor;
X        tputs(tgoto(CM,HOR,VER),1,string);
X        printf("%s",disk[map[from.deep][from.pole]]);
X
X        VER = level[i-1][to.pole].ver;
X        HOR = level[i-1][to.pole].hor;
X        tputs(tgoto(CM,HOR,VER),1,string);
X        printf("%s",disk[14]);
X    }
X}
X
Xfly (from, to)
Xstruct handle from, to;
X{
X    int i;
X
X    switch  ( from.pole + to.pole * 10 ) {
X        case 20:
X            for (  i=1;  flyway[i][0].ver + flyway[i][0].hor;  ++i  ) {
X                VER = flyway[i][0].ver;
X                HOR = flyway[i][0].hor;
X                WRITENEXT;
X
X                VER = flyway[i-1][0].ver;
X                HOR = flyway[i-1][0].hor;
X                PUTBLANK;
X            }
X            break;
X
X        case 10:
X            for (  i=1;  flyway[i][1].ver + flyway[i][1].hor;  ++i  ) {
X                VER = flyway[i][1].ver;
X                HOR = flyway[i][1].hor;
X                WRITENEXT;
X
X                VER = flyway[i-1][1].ver;
X                HOR = flyway[i-1][1].hor;
X                PUTBLANK;
X            }
X            break;
X
X        case 2:
X            for (  i=1;  flyway[i][2].ver + flyway[i][2].hor;  ++i  ) {
X                VER = flyway[i][2].ver;
X                HOR = flyway[i][2].hor;
X                WRITENEXT;
X
X                VER = flyway[i-1][2].ver;
X                HOR = flyway[i-1][2].hor;
X                PUTBLANK;
X            }
X            break;
X
X        case 12:
X            for (  i=1;  flyway[i][3].ver + flyway[i][3].hor;  ++i  ) {
X                VER = flyway[i][3].ver;
X                HOR = flyway[i][3].hor;
X                WRITENEXT;
X
X                VER = flyway[i-1][3].ver;
X                HOR = flyway[i-1][3].hor;
X                PUTBLANK;
X            }
X            break;
X
X        case 21:
X            for (  i=1;  flyway[i][4].ver + flyway[i][4].hor;  ++i  ) {
X                VER = flyway[i][4].ver;
X                HOR = flyway[i][4].hor;
X                WRITENEXT;
X
X                VER = flyway[i-1][4].ver;
X                HOR = flyway[i-1][4].hor;
X                PUTBLANK;
X            }
X            break;
X
X        case 1:
X            for (  i=1;  flyway[i][5].ver + flyway[i][5].hor;  ++i  ) {
X                VER = flyway[i][5].ver;
X                HOR = flyway[i][5].hor;
X                WRITENEXT;
X
X                VER = flyway[i-1][5].ver;
X                HOR = flyway[i-1][5].hor;
X                PUTBLANK;
X            }
X            break;
X
X        default: printf("invalid case value\n");
X            break;
X   }
X}
X
Xup_the_pole (from)
Xstruct handle from;
X{
X    int i;
X
X    for (  i=from.deep;  i;  --i  ) {
X        VER = level[i-1][from.pole].ver;
X        HOR = level[i-1][from.pole].hor;
X        WRITENEXT;
X
X        VER = level[i][from.pole].ver;
X        HOR = level[i][from.pole].hor;
X        ERASEPREV;
X    }
X}
X
Xmove_disk (from, to)
Xstruct handle from, to;
X{
X    up_the_pole(from);
X    fly(from, to);
X    down_the_pole(from, to);
X}
END_OF_FILE
if test 8351 -ne `wc -c <'xmascard.c'`; then
    echo shar: \"'xmascard.c'\" unpacked with wrong size!
fi
# end of 'xmascard.c'
fi
echo shar: End of shell archive.
exit 0