Video Christmas Card
Istvan Mohos
istvan at hhb.UUCP
Thu Dec 21 02:14:17 AEST 1989
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.
What was the last time *you* used low-level termcap routines?
(Incidentally, SysV versions of tgetent() seem to be hard-coded to
read in /etc/termcap instead of the environment variable $TERMCAP,
for your terminal description. Do tgetent(), etc. still work with
termio? I don't know.)
------------------------------CUT HERE---------------------------------
/**********************************************************************
* card.c --- Christmas Card From Hanoi --- by Istvan Mohos, 1984
*
* Compile with "/bin/cc card.c -ltermlib -o card"
* Use with ttys at 9600/4800/2400 baud; don't bother at slower speeds.
* Running under SysV and BSD, on Pyramid, VAX, SUN.
* SunWindows flow-control a mess, but OK on console.
*
* Thanks to Bill Tuthill for showing me curses...
**********************************************************************/
#include <stdio.h>
#define WRITENEXT tputs(tgoto(CM,HOR,VER),1,string);\
printf("%s",disk[map[from.deep][from.pole]])
#define ERASEPREV tputs(tgoto(CM,HOR,VER),1,string);\
printf("%s",disk[14])
#define PUTBLANK tputs(tgoto(CM,HOR,VER),1,string);\
printf("%s",disk[0])
string(c)
register char c;
{
putchar(c);
}
static long counter = 1;
struct diskpos
{
int ver;
int hor;
};
static struct diskpos level[16][3] =
{ 7,0, 7,28, 7,55,
8,0, 8,28, 8,55,
9,0, 9,28, 9,55,
10,0, 10,28, 10,55,
11,0, 11,28, 11,55,
12,0, 12,28, 12,55,
13,0, 13,28, 13,55,
14,0, 14,28, 14,55,
15,0, 15,28, 15,55,
16,0, 16,28, 16,55,
17,0, 17,28, 17,55,
18,0, 18,28, 18,55,
19,0, 19,28, 19,55,
20,0, 20,28, 20,55,
21,0, 21,28, 21,55,
22,0, 22,28, 22,55 };
static struct diskpos flyway[17][6] =
{ 7, 0, 7, 0, 7,55, 7,55, 7,28, 7,28,
6, 1, 6, 1, 6,54, 6,54, 6,29, 6,27,
5, 2, 5, 2, 5,53, 5,53, 5,30, 5,26,
4, 4, 4, 4, 4,51, 4,51, 4,32, 4,24,
3, 7, 3, 7, 3,48, 3,48, 3,35, 3,21,
2,13, 2,13, 2,42, 2,42, 2,42, 2,13,
1,19, 3,21, 1,37, 3,35, 3,48, 3, 7,
0,28, 4,24, 0,26, 4,32, 4,51, 4, 4,
1,37, 5,26, 1,19, 5,30, 5,53, 5, 2,
2,42, 6,27, 2,13, 6,29, 6,54, 6, 1,
3,48, 7,28, 3, 7, 7,28, 7,55, 7, 0,
4,51, 8,28, 4, 4, 8,28, 8,55, 8, 0,
5,53, 0, 0, 5, 2, 0, 0, 0, 0, 0, 0,
6,54, 0, 0, 6, 1, 0, 0, 0, 0, 0, 0,
7,55, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,
8,55, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0 };
/* an extra line of 0 initialized above, used for sentinel */
static char *disk[] = {
" ",
" may ",
" every ",
" falling ",
" snowflake ",
" bring peace ",
" may every day ",
" be as christmas ",
" filled with quiet ",
" expectant happiness ",
" joy and understanding ",
" our human souls shining ",
"loving caring for another",
"~~~~~~~~~~~~~~~~~~~~~~~~~",
" | ",};
struct handle {
int deep;
int pole;
};
int map[15][3];
int HOR, VER;
char *term, entry[1024], buf[512], *area;
char *getenv(), *tgetstr(), *tgoto();
char *CL, *CM;
main()
{
int temp, i;
struct handle from, to, lazy;
from.pole=0;
to.pole=2;
lazy.pole=1;
term = getenv("TERM");
if (tgetent(entry, term) != 1)
perror("bad or missing termcap... but MERRY CHRISTMAS !"),
exit(1);
if (tgetnum("li") < 23)
perror("screen too small... but MERRY CHRISTMAS !"), exit(1);
if (tgetnum("co") < 80)
perror("screen too small... but MERRY CHRISTMAS !"), exit(1);
area = buf;
CL = tgetstr("cl", &area);
CM = tgetstr("cm", &area);
/* initialize map matrix */
for ( i=12; i > -1; --i ) {
map[i][0] = i;
map[i][1] = 14;
map[i][2] = 14;
}
map[13][0] = 13;
map[13][1] = 13;
map[13][2] = 13;
map[0][1] = 0;
map[0][2] = 0;
/* print field */
tputs(CL, 1, string);
for ( i=1; i<14; ++i ) {
for ( temp=2; temp > -1; --temp ) {
VER = level[i][temp].ver;
HOR = level[i][temp].hor;
tputs(tgoto(CM,HOR,VER),1,string);
printf("%s",disk[map[i][temp]]);
}
}
tputs(tgoto(CM,26,22),1,string);
printf("<<*>> Merry Christmas! <<*>>");
hanoi(12,from,lazy,to);
exit(0);
}
hanoi (high,from,lazy,to)
int high;
struct handle from,lazy,to;
{
int i;
if ( high != 0 ) {
hanoi(high-1,from,to,lazy);
i=1;
while ( map[i][from.pole] == 14 )
++i;
from.deep = i;
i=1;
while ( map[i][to.pole] == 14 )
++i;
to.deep = i-1;
move_disk( from, to);
map[to.deep][to.pole] = map[from.deep][from.pole];
map[from.deep][from.pole] = 14;
++counter;
tputs(tgoto(CM,12,7),1,string); printf("*");
tputs(tgoto(CM,40,7),1,string); printf("*");
tputs(tgoto(CM,67,7),1,string); printf("*");
tputs(tgoto(CM,33,22),1,string);
if (counter % 2)
printf("Merry Christmas!");
else
printf("Happy New Year! ");
hanoi(high-1,lazy,from,to);
}
}
down_the_pole (from, to)
struct handle from, to;
{
int i;
for ( i=2; i <= to.deep; ++i ) {
VER = level[i][to.pole].ver;
HOR = level[i][to.pole].hor;
tputs(tgoto(CM,HOR,VER),1,string);
printf("%s",disk[map[from.deep][from.pole]]);
VER = level[i-1][to.pole].ver;
HOR = level[i-1][to.pole].hor;
tputs(tgoto(CM,HOR,VER),1,string);
printf("%s",disk[14]);
}
}
fly (from, to)
struct handle from, to;
{
int i;
switch ( from.pole + to.pole * 10 ) {
case 20:
for ( i=1; flyway[i][0].ver + flyway[i][0].hor; ++i ) {
VER = flyway[i][0].ver;
HOR = flyway[i][0].hor;
WRITENEXT;
VER = flyway[i-1][0].ver;
HOR = flyway[i-1][0].hor;
PUTBLANK;
}
break;
case 10:
for ( i=1; flyway[i][1].ver + flyway[i][1].hor; ++i ) {
VER = flyway[i][1].ver;
HOR = flyway[i][1].hor;
WRITENEXT;
VER = flyway[i-1][1].ver;
HOR = flyway[i-1][1].hor;
PUTBLANK;
}
break;
case 2:
for ( i=1; flyway[i][2].ver + flyway[i][2].hor; ++i ) {
VER = flyway[i][2].ver;
HOR = flyway[i][2].hor;
WRITENEXT;
VER = flyway[i-1][2].ver;
HOR = flyway[i-1][2].hor;
PUTBLANK;
}
break;
case 12:
for ( i=1; flyway[i][3].ver + flyway[i][3].hor; ++i ) {
VER = flyway[i][3].ver;
HOR = flyway[i][3].hor;
WRITENEXT;
VER = flyway[i-1][3].ver;
HOR = flyway[i-1][3].hor;
PUTBLANK;
}
break;
case 21:
for ( i=1; flyway[i][4].ver + flyway[i][4].hor; ++i ) {
VER = flyway[i][4].ver;
HOR = flyway[i][4].hor;
WRITENEXT;
VER = flyway[i-1][4].ver;
HOR = flyway[i-1][4].hor;
PUTBLANK;
}
break;
case 1:
for ( i=1; flyway[i][5].ver + flyway[i][5].hor; ++i ) {
VER = flyway[i][5].ver;
HOR = flyway[i][5].hor;
WRITENEXT;
VER = flyway[i-1][5].ver;
HOR = flyway[i-1][5].hor;
PUTBLANK;
}
break;
default: printf("invalid case value\n");
break;
}
}
up_the_pole (from)
struct handle from;
{
int i;
for ( i=from.deep; i; --i ) {
VER = level[i-1][from.pole].ver;
HOR = level[i-1][from.pole].hor;
WRITENEXT;
VER = level[i][from.pole].ver;
HOR = level[i][from.pole].hor;
ERASEPREV;
}
}
move_disk (from, to)
struct handle from, to;
{
up_the_pole(from);
fly(from, to);
down_the_pole(from, to);
}
------------------------------CUT HERE---------------------------------
--
Istvan Mohos
...uunet!pyrdc!pyrnj!hhb!istvan
HHB Systems 1000 Wyckoff Ave. Mahwah NJ 07430 201-848-8000
====================================================================
More information about the Alt.sources
mailing list