Tower of Hanoi

Started by aruljothi, Mar 31, 2009, 11:18 AM

Previous topic - Next topic

aruljothi

#include<stdio.h>
void initialize (int disks, int peg_A[8], int peg_B[8], int peg_C[8]);
void get_number_of_disks(int *disks);
void print_status(int disks, int peg_A[8], int peg_B[8], int peg_C[8]);
void print_no_disk(char *choice_from);
int validate_move_from(char *choice_from, int peg_A[8], int peg_B[8],
int
peg_C[8]);
int validate_move_to(int disks, char choice_from, char *choice_to, int
*index_from, int peg_A[8], int peg_B[8], int peg_C[8]);
void disk_on_top(int disks, int *top_of_stack_to, char choice_to, int
peg_A[8],
int peg_B[8], int peg_C[8]);
void move_disk(int disks, char choice_from, char choice_to, int
index_from, int peg_A[8], int peg_B[8], int peg_C[8]);

int main (void)
{       int peg_A[8];   /*initial number of asterisks in peg_A*/
        int peg_B[8];   /*initial number of asterisks in peg_B*/
        int peg_C[8];           /*initial number of asterisks in
peg_C*/
        int disks;              /*desired number of disks*/
        int index_from;         /*position of the disk in a peg*/
        char choice_from;       /*the peg where a disk will be
removed*/
        char choice_to;         /*the peg where a disk will be
transferred*/

        printf("
Instructions on playing TOWERS OF HANOI:

There are
three pegs, labeled A, B, and C.

Initially, peg A contains a certain
amount of disks, each one with a different size.

The disks are
stacked
in increasing size so that a disk is always on top of a larger one,
forming a tower.

The goal of the game is to move all the disks from
peg
A to peg C.

You may move only one disk at a time.

You may move
the
top disk from any peg to the top of the stack at another peg.

The
only
limitation is that you may not place a disk on top of one which is
smaller.

YOU MAY STOP THE GAME ANYTIME BY ENTERING Q (THEN PRESSING
THE
ENTER KEY)

");
        get_number_of_disks(&disks);
        initialize(disks, peg_A, peg_B, peg_C);
        print_status(disks, peg_A, peg_B, peg_C);
        while (peg_C[disks-1]!=3)
        {       validate_move_from(&choice_from, peg_A, peg_B, peg_C);
                if(choice_from=='Q' || choice_from=='q')
                        break;
                validate_move_to(disks, choice_from, &choice_to,
&index_from, peg_A, peg_B, peg_C);
                if(choice_to=='Q' || choice_to=='q')
                        break;
                move_disk(disks, choice_from, choice_to, index_from,
peg_A, peg_B, peg_C);
                print_status(disks, peg_A, peg_B, peg_C); }
        if(peg_C[disks-1]==3)
                printf("Congratulations! You won...

");
        return 0; }

/*initializes the contents of the pegs*/
void initialize (int disks, int peg_A[8], int peg_B[8], int peg_C[8])
{       int i;
        for(i=0; i<disks; i++)
        {       peg_A=(disks-i)*2 + 1;
                peg_B=1;
                peg_C=1;}}

/*gets the desired number of disks(min of 3, max of 8)*/
void get_number_of_disks(int *disks)
{       printf("Enter the desired number of disks(min of 3, max of 8):
");
        scanf("%d", disks);
        while(*disks>8 || *disks<3)
        {       printf("Invalid input!
Enter the desired number of
disks(min of 3, max of 8): ");
                scanf("%d", disks); }}

/*displays the present position of the disks*/
void print_status(int disks, int peg_A[8], int peg_B[8], int peg_C[8])
{       int number_spaces;        /*number of spaces*/
        int number_asterisk;      /*number of spaces*/
        int i=1;                  /*counter*/
        printf("
");
        for(i=1; i<=disks; i++)
        {       for(number_spaces=1; number_spaces<=
(disks+3)-(peg_A[disks-i]/2); number_spaces++)
                        printf(" ");
                for(number_asterisk=1; number_asterisk <=
peg_A[disks-i];
number_asterisk++)
                        printf("*");
                for(number_spaces=1; number_spaces<=
(disks+3)-(peg_A[disks-i]/2); number_spaces++)
                        printf(" ");
                for(number_spaces=1; number_spaces<=
(disks+3)-(peg_B[disks-i]/2); number_spaces++)
                        printf(" ");
                for(number_asterisk=1; number_asterisk <=
peg_B[disks-i];
number_asterisk++)
                        printf("*");
                for(number_spaces=1; number_spaces<=
(disks+3)-(peg_B[disks-i]/2); number_spaces++)
                        printf(" ");
                for(number_spaces=1; number_spaces<=
(disks+3)-(peg_C[disks-i]/2); number_spaces++)
                        printf(" ");
                for(number_asterisk=1; number_asterisk <=
peg_C[disks-i];
number_asterisk++)
                        printf("*");
                printf("
");}
        for(i=1; i<=(disks*2 + 7)*3; i++)
                printf("*");
        printf("
");
        for(i=1; i<=disks+3; i++)
                printf(" ");
        printf("A");
        for(i=1; i<=(disks + 3)*2; i++)
                printf(" ");
        printf("B");
        for(i=1; i<=(disks + 3)*2; i++)
                printf(" ");
        printf("C

"); }

/*prints that there's no disk and asks the user to enter another
input*/
void print_no_disk(char *choice_from)
{       printf("There's no disk!
Choose a peg with disk(s).
Move a
disk
from what peg?: ");
        scanf("%s", choice_from); }

/*asks the user to enter the name of the peg from where a disk will be
removed*/
/*validates input*/
int validate_move_from(char *choice_from, int peg_A[8], int peg_B[8],
int
peg_C[8])
{       printf("Move a disk FROM what peg?: ");
        scanf("%c", choice_from);
        if (*choice_from=='Q' || *choice_from=='q')
                return 0;
        while(peg_A[0] == 1 && (*choice_from == 'A' || *choice_from
=='a'))
                print_no_disk(choice_from);
        while(peg_B[0] == 1 && (*choice_from == 'B' || *choice_from
=='b'))
                print_no_disk(choice_from);
        while(peg_C[0] == 1 && (*choice_from == 'C' || *choice_from
=='c'))
                print_no_disk(choice_from);
        while(*choice_from<'A' || (*choice_from>'C' &&
*choice_from<'a')
|| *choice_from>'c')
                {printf("(A, B, C or Q only): ");
                scanf("%c", choice_from);
                if (*choice_from=='Q' || *choice_from=='q')
                        return 0;
                while(peg_A[0] == 1 && (*choice_from == 'A' ||
*choice_from =='a'))
                        print_no_disk(choice_from);
                while(peg_B[0] == 1 && (*choice_from == 'B' ||
*choice_from =='b'))
                        print_no_disk(choice_from);
                while(peg_C[0] == 1 && (*choice_from == 'C' ||
*choice_from =='c'))
                        print_no_disk(choice_from); }
        return 0;}

/*asks the user to enter the name of the peg to which a disk will be
placed*/
/*also validates input*/
int validate_move_to(int disks, char choice_from, char *choice_to, int
*index_from, int peg_A[8], int peg_B[8], int peg_C[8])
{       int i;
        int top_of_stack_from,        /*the disk to be removed*/
        top_of_stack_to;              /*the smallest disk in a certain
peg*/
        for (i=disks-1; i>=0; i--)
        {        if ((choice_from=='A' || choice_from=='a') &&
peg_A!=1)
                {       top_of_stack_from = peg_A;
                        *index_from=i;
                        break; }
                else if ((choice_from=='B' || choice_from=='b') &&
peg_B!=1)
                {       top_of_stack_from = peg_B;
                        *index_from=i;
                        break; }
                else if ((choice_from=='C' || choice_from=='c') &&
peg_C!=1)
                {       top_of_stack_from = peg_C;
                        *index_from=i;
                        break; }}
        printf("Move the disk TO: ");
        scanf("%c", choice_to);
        if (*choice_to=='Q' || *choice_to=='q')
                return 0;
        disk_on_top(disks, &top_of_stack_to, *choice_to, peg_A, peg_B,
peg_C);
        while(*choice_to<'A' || (*choice_to>'C' && *choice_to<'a') ||
*choice_to>'c')
        {       printf("(A, B, or C only): ");
                scanf("%c", choice_to);
        if (*choice_to=='Q' || *choice_to=='q')
                return 0;
        disk_on_top(disks, &top_of_stack_to, *choice_to, peg_A, peg_B,
peg_C); }
        while(top_of_stack_to-top_of_stack_from<0)
        {       printf("That is an INVALID move!
Choose a peg with a
larger disk.
Move the disk TO: ");
                scanf("%c", choice_to);
                if (*choice_to=='Q' || *choice_to=='q')
                        return 0;
                while(*choice_to<'A' || (*choice_to>'C' &&
*choice_to<'a')
|| *choice_to>'c')
                {       printf("(A, B, or C only): ");
                        scanf("%c", choice_to);
                        if (*choice_to=='Q' || *choice_to=='q')
                                return 0;
                        disk_on_top(disks, &top_of_stack_to,
*choice_to,
peg_A, peg_B, peg_C); }}
        return 0; }

/*determines the top  of stack of a certain peg where a disk will be
placed*/
void disk_on_top(int disks, int *top_of_stack_to, char choice_to, int
peg_A[8],
int peg_B[8], int peg_C[8])
{       int i;
        for (i=disks-1; i>=0; i--)
        {        if ((choice_to=='A' || choice_to=='a') && peg_A!=1)
                {        *top_of_stack_to = peg_A;
                        break; }
                else if ((choice_to=='B' || choice_to=='b') &&
peg_B!=1)
                {        *top_of_stack_to = peg_B;
                        break; }
                else if ((choice_to=='C' || choice_to=='c') &&
peg_C!=1)
                {        *top_of_stack_to = peg_C;
                        break; }
                else     *top_of_stack_to=17; }}

/*moves the chosen disk to the desired peg*/
void move_disk(int disks, char choice_from, char choice_to, int
index_from, int
peg_A[8], int peg_B[8], int peg_C[8])
{       int i, temp, index_to;
        for (i=0; i<disks; i++)
        {       if ((choice_to=='A' || choice_to=='a') && peg_A==1)
                {        index_to=i;
                        break; }
                else if ((choice_to=='B' || choice_to=='b') &&
peg_B==1)
                {        index_to=i;
                        break; }
                else if ((choice_to=='C' || choice_to=='c') &&
peg_C==1)
                {        index_to=i;
                        break; }}
        if ((choice_from=='A' || choice_from=='a') && (choice_to=='B'
||
choice_to=='b'))
        {       temp = peg_B[index_to];
                peg_B[index_to] = peg_A[index_from];
                peg_A[index_from] = temp; }
        else if ((choice_from=='A' || choice_from=='a') &&
(choice_to=='C'
|| choice_to=='c'))
        {       temp = peg_C[index_to];
                peg_C[index_to] = peg_A[index_from];
                peg_A[index_from] = temp; }
        else if ((choice_from=='B' || choice_from=='b') &&
(choice_to=='C'
|| choice_to=='c'))
        {       temp = peg_C[index_to];
                peg_C[index_to] = peg_B[index_from];
                peg_B[index_from] = temp; }
        else if ((choice_from=='B' || choice_from=='b') &&
(choice_to=='A'
|| choice_to=='a'))
        {       temp = peg_A[index_to];
                peg_A[index_to] = peg_B[index_from];
                peg_B[index_from] = temp; }
        else if ((choice_from=='C' || choice_from=='c') &&
(choice_to=='A'
|| choice_to=='a'))
        {       temp = peg_A[index_to];
                peg_A[index_to] = peg_C[index_from];
                peg_C[index_from] = temp; }
        else if ((choice_from=='C' || choice_from=='c') &&
(choice_to=='B'
||choice_to=='b'))
        {       temp = peg_B[index_to];
                peg_B[index_to] = peg_C[index_from];
                peg_C[index_from] = temp; }}