Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Towers of Hanoi game

4 views
Skip to first unread message

ky...@xanth.uucp

unread,
Mar 12, 1987, 1:04:15 AM3/12/87
to

# After reading the last thirty or so articles requesting the sources
# for various games I said to myself, "Self! Wouldn't it be a novel
# and wonderful thing if someone were to actually post SOURCES to this
# newsgroup?!"
#
# Here is a program that does the Towers of Hanoi simulation or lets
# you attempt to solve it yourself. No, its not UltraRogue but it's still
# fun to watch. It will run as is on BSD systems, and ought to run with
# very little tweaking under System V.
#
# kyle jones, odu computer science
# ARPA: ky...@xanth.cs.odu.edu CSNET: ky...@odu.csnet
# UUCP: ky...@xanth.uucp
#
# This is a shell archive.
# Run the file through sh to extract its contents.
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# Makefile
# hanoi.6
# hanoi.c
# hanoi.h
# init.c
# main.c
# move.c
# pegs.c
# This archive created: Thu Mar 12 00:45:15 1987
echo shar: extracting Makefile '(197 characters)'
sed 's/^XX//' << \SHAR_EOF > Makefile
XXCFLAGS = -O
XX
XXhanoi: main.o hanoi.o move.o init.o pegs.o
XX cc -O -o hanoi main.o hanoi.o move.o init.o pegs.o -lcurses -ltermlib
XX
XXmain.o hanoi.o move.o init.o : hanoi.h
XX
XXclean:
XX rm -f *.o hanoi core
SHAR_EOF
if test 197 -ne "`wc -c Makefile`"
then
echo shar: error transmitting Makefile '(should have been 197 characters)'
fi
echo shar: extracting hanoi.6 '(886 characters)'
sed 's/^XX//' << \SHAR_EOF > hanoi.6
XX.TH HANOI ODU
XX.SH NAME
XXhanoi \- Tower of Hanoi simulation
XX.SH SYNOPSIS
XXhanoi [-v | -a] number
XX.SH DESCRIPTION
XX.I Hanoi
XXdoes a visual simulation of the Tower of Hanoi problem, using
XX.I curses(3X).
XXThe program will solve the puzzle itself if given the
XX.I -a
XXoption, otherwise it sets up the puzzle and prompts you for disc moves until
XXyou solve the puzzle.
XX.I Number
XXshould be the number of discs that you want to be in the puzzle.
XXIf the
XX.I -v
XXoption is given
XX.I hanoi
XXwill tell you what move you just made and display a count of moves you've made
XXso far.
XX.PP
XXThe puzzle consists of a number of different sized discs stacked
XXon one of three pegs. The object is to move all the discs (one at a time)
XXfrom this peg to one of the other two pegs,
XX\fIwithout ever placing a larger disc on top on a smaller one.\fR
XX.SH AUTHOR
XXKyle Jones, Old Dominion University Computer Science, Norfolk VA.
SHAR_EOF
if test 886 -ne "`wc -c hanoi.6`"
then
echo shar: error transmitting hanoi.6 '(should have been 886 characters)'
fi
echo shar: extracting hanoi.c '(235 characters)'
sed 's/^XX//' << \SHAR_EOF > hanoi.c
XXhanoi(nrings, from, to)
XXint nrings, from, to;
XX
XX{
XX int other;
XX
XX if (nrings == 1)
XX movering(from, to);
XX else {
XX other = 3 - (from + to);
XX hanoi(nrings-1, from, other);
XX movering(from, to);
XX hanoi(nrings-1, other, to);
XX }
XX return;
XX}
SHAR_EOF
if test 235 -ne "`wc -c hanoi.c`"
then
echo shar: error transmitting hanoi.c '(should have been 235 characters)'
fi
echo shar: extracting hanoi.h '(81 characters)'
sed 's/^XX//' << \SHAR_EOF > hanoi.h
XX#define MAX_RINGS 9
XX
XX#define PEG0_COL 20
XX#define PEG1_COL 40
XX#define PEG2_COL 60
SHAR_EOF
if test 81 -ne "`wc -c hanoi.h`"
then
echo shar: error transmitting hanoi.h '(should have been 81 characters)'
fi
echo shar: extracting init.c '(1138 characters)'
sed 's/^XX//' << \SHAR_EOF > init.c
XX#include <curses.h>
XX#include <signal.h>
XX#include "hanoi.h"
XX
XXextern char *ring[];
XXint goodbye();
XX
XXinit_curses()
XX
XX{
XX if (initscr() == ERR) {
XX fprintf(stderr, "Sorry, but your terminal isn't powerful ");
XX fprintf(stderr, "to run Hanoi.\nIt lacks some important ");
XX fprintf(stderr, "features.");
XX exit(1);
XX }
XX signal(SIGINT, goodbye);
XX return;
XX}
XX
XXinit_pegs(nrings)
XXint nrings;
XX
XX{
XX for (; nrings > 0; nrings--)
XX push(0, nrings);
XX return;
XX}
XX
XXdraw_slab()
XX
XX{
XX move(LINES-2, 0);
XX addstr(" ================[1]=================[2]=================[3]===============");
XX move(LINES-3, 0);
XX addstr(" =================|===================|===================|================");
XX refresh();
XX return;
XX}
XX
XXdraw_pegs()
XX
XX{
XX int y;
XX
XX for (y=LINES-MAX_RINGS-4; y < LINES-3; y++) {
XX mvaddch(y, PEG0_COL, '|');
XX mvaddch(y, PEG1_COL, '|');
XX mvaddch(y, PEG2_COL, '|');
XX }
XX refresh();
XX}
XX
XXdraw_rings(nrings)
XXint nrings;
XX
XX{
XX int y, x;
XX
XX y = LINES - 4;
XX for (; nrings > 0; nrings--, y--) {
XX x = PEG0_COL - nrings;
XX mvaddstr(y, x, ring[nrings]);
XX }
XX refresh();
XX return;
XX}
XX
XXgoodbye()
XX
XX{
XX move(LINES-1, 0);
XX clrtoeol();
XX refresh();
XX endwin();
XX exit(0);
XX}
SHAR_EOF
if test 1138 -ne "`wc -c init.c`"
then
echo shar: error transmitting init.c '(should have been 1138 characters)'
fi
echo shar: extracting main.c '(2145 characters)'
sed 's/^XX//' << \SHAR_EOF > main.c
XX#include <curses.h>
XX#include "hanoi.h"
XX
XXint verbose, automatic;
XX
XXmain(c, v)
XXint c;
XXchar **v;
XX
XX{
XX int nrings;
XX
XX if (c < 2 || c > 3) {
XX fprintf(stderr,"usage: %s [-v|-a] <1-%d>\n", v[0], MAX_RINGS);
XX exit(1);
XX }
XX if (strcmp(v[1], "-v") == 0)
XX verbose++;
XX else if (strcmp(v[1], "-a") == 0)
XX automatic++;
XX nrings = atoi(v[c-1]);
XX if (!nrings || nrings > MAX_RINGS) {
XX fprintf(stderr, "usage: %s [-v] <1-%d>\n", v[0], MAX_RINGS);
XX exit(1);
XX }
XX
XX init_curses();
XX init_pegs(nrings);
XX draw_slab();
XX draw_pegs();
XX draw_rings(nrings);
XX if (automatic) {
XX hanoi(nrings, 0, 1);
XX goodbye();
XX }
XX Interactive();
XX}
XX
XXInteractive()
XX
XX{
XX int from, to, fromdisk, todisk;
XX
XX crmode();
XX noecho();
XX verbose = 1;
XX for (;;) {
XX from = GetNumber("Move disk from peg: ");
XX if (peg_height(from-1) == 0) {
XX Message("No disk on that peg...");
XX sleep(2);
XX continue;
XX }
XX fromdisk = pop(from-1);
XX push(from-1, fromdisk);
XX Light(from-1);
XX to = GetNumber("To peg: ");
XX if (peg_height(to-1) != 0) {
XX todisk = pop(to-1);
XX push(to-1, todisk);
XX if (fromdisk > todisk) {
XX Douse(from-1);
XX Message("Cannot move larger disk onto smaller one.");
XX sleep(2);
XX continue;
XX }
XX }
XX Message("");
XX movering(from-1, to-1);
XX if (!peg_height(0) && (!peg_height(1) || !peg_height(2))) {
XX switch (peg_height(to-1)) {
XX case 1:
XX Message("Phhhhft!"); break;
XX case 2:
XX Message("Ha!"); break;
XX case 3:
XX Message("Well, it's about time!"); break;
XX case 4:
XX Message("Not bad... for a human."); break;
XX case 5:
XX Message("Finally!"); break;
XX case 6:
XX Message("Good, now be gone!"); break;
XX default:
XX Message("It was pure luck!"); break;
XX }
XX getch();
XX goodbye(0);
XX }
XX }
XX}
XX
XXint
XXGetNumber(prompt)
XXchar *prompt;
XX
XX{
XX char c;
XX
XX move(LINES-1, 0);
XX clrtoeol();
XX addstr(prompt);
XX refresh();
XX for (;;) {
XX c = getch();
XX if (c == 'q' || c == 'Q')
XX goodbye();
XX if (c > '0' && c < '4')
XX break;
XX }
XX return (int) (c - '0');
XX}
XX
XXMessage(string)
XXchar *string;
XX
XX{
XX move(LINES-1, 0);
XX clrtoeol();
XX move(LINES-1, 0);
XX standout();
XX addstr(string);
XX standend();
XX refresh();
XX return;
XX}
SHAR_EOF
if test 2145 -ne "`wc -c main.c`"
then
echo shar: error transmitting main.c '(should have been 2145 characters)'
fi
echo shar: extracting move.c '(2530 characters)'
sed 's/^XX//' << \SHAR_EOF > move.c
XX#include <curses.h>
XX#include "hanoi.h"
XX
XXextern int verbose;
XX
XXchar *ring[] = {
XX "0",
XX "111",
XX "22222",
XX "3333333",
XX "444444444",
XX "55555555555",
XX "6666666666666",
XX "777777777777777",
XX "88888888888888888",
XX "9999999999999999999"
XX};
XX
XXstatic char blotter[] = " | ";
XX
XXint pegcol[3] = { PEG0_COL, PEG1_COL, PEG2_COL };
XX
XXmovering(from, to)
XXint from, to;
XX
XX{
XX static int moveno = 0;
XX int ringno, fromheight, toheight, y, x, moveleft, destx, dx, ringsize;
XX int pegtop;
XX char blotbuf[MAX_RINGS*2+2];
XX
XX pegtop = LINES - MAX_RINGS - 5;
XX
XX fromheight = peg_height(from);
XX
XX /*
XX * Get the number of the ring we gotta move
XX */
XX ringno = pop(from);
XX
XX toheight = peg_height(to);
XX
XX if (verbose) {
XX moveno++;
XX move(pegtop - 3, pegcol[1] - 2);
XX printw("%3d", moveno);
XX move(pegtop - 2, pegcol[1] - 7);
XX printw("disc %d to peg %d", ringno, to+1);
XX refresh();
XX }
XX
XX /*
XX * From the ring number compute the size of the ring.
XX */
XX ringsize = 2 * ringno + 1;
XX
XX /*
XX * Center the ring on the peg.
XX */
XX x = pegcol[from] - ringno;
XX
XX /*
XX * Lift ring from peg
XX */
XX strncpy(blotbuf, blotter+(MAX_RINGS-ringno), ringsize);
XX blotbuf[ringsize] = '\0';
XX for (y=LINES-fromheight-3; y > pegtop; y--) {
XX mvaddstr(y, x, blotbuf);
XX mvaddstr(y-1, x, ring[ringno]);
XX refresh();
XX }
XX
XX /*
XX * Decide which direction we have to shift the ring.
XX */
XX destx = pegcol[to] - ringno;
XX moveleft = (x > destx ? 1 : 0);
XX dx = (moveleft ? -1 : 1);
XX move(pegtop, 0);
XX
XX /*
XX * Now shift the ring over to its peg.
XX */
XX for (; x != destx; x+=dx) {
XX if (moveleft)
XX delch();
XX else
XX insch(' ');
XX refresh();
XX }
XX
XX /*
XX * Slip the ring on the top of the peg
XX */
XX move(pegtop, 0);
XX clrtoeol();
XX y++;
XX mvaddstr(y, x, ring[ringno]);
XX refresh();
XX
XX /*
XX * Now slide the ring the rest of the way down the peg.
XX */
XX for (y=pegtop+1; y < LINES - toheight - 4; y++) {
XX strncpy(blotbuf, blotter+(MAX_RINGS-ringno), ringsize);
XX blotbuf[ringsize] = '\0';
XX mvaddstr(y, x, blotbuf);
XX mvaddstr(y+1, x, ring[ringno]);
XX refresh();
XX }
XX
XX /*
XX * Update the peg stack to show that the ring has been moved.
XX */
XX push(to, ringno);
XX return;
XX}
XX
XXLight(peg)
XXint peg;
XX
XX{
XX int ringno, h, x, y;
XX
XX push(peg, ringno = pop(peg));
XX h = peg_height(peg);
XX y = LINES - 3 - h;
XX x = pegcol[peg] - ringno;
XX move(y, x);
XX standout();
XX addstr(ring[ringno]);
XX standend();
XX refresh();
XX}
XX
XXDouse(peg)
XXint peg;
XX
XX{
XX int ringno, h, x, y;
XX
XX push(peg, ringno = pop(peg));
XX h = peg_height(peg);
XX y = LINES - 3 - h;
XX x = pegcol[peg] - ringno;
XX move(y, x);
XX standend();
XX addstr(ring[ringno]);
XX refresh();
XX}
SHAR_EOF
if test 2530 -ne "`wc -c move.c`"
then
echo shar: error transmitting move.c '(should have been 2530 characters)'
fi
echo shar: extracting pegs.c '(236 characters)'
sed 's/^XX//' << \SHAR_EOF > pegs.c
XX#include "hanoi.h"
XX
XXstatic int peg[3][MAX_RINGS];
XXstatic int peg_index[3];
XX
XXint pop(p)
XXint p;
XX
XX{
XX return peg[p][--peg_index[p]];
XX}
XX
XXpush(p, n)
XXint p, n;
XX
XX{
XX peg[p][peg_index[p]++] = n;
XX}
XX
XXpeg_height(p)
XXint p;
XX
XX{
XX return peg_index[p];
XX}
SHAR_EOF
if test 236 -ne "`wc -c pegs.c`"
then
echo shar: error transmitting pegs.c '(should have been 236 characters)'
fi
# End of shell archive
exit 0
0 new messages