What is Hanoi Tower?
see http://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%8E%E3%82%A4%E3%81%AE%E5%A1%94
When you faced "Do you want to read previous data file? (Y/N) " at the first time, press 'n'.
You can control the progress speed by pressing up and down arrow key.
Below is source code which does not use recursion routine.
--------------
//Hanoi Tower.c <-- ハノイの塔
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <Windows.h>
#define ESC 27
#define LEFT 75
#define RIGHT 77
#define UP 72
#define DOWN 80
#define EXTENDASCII -32
void gotoxy(int, int);
void prtscr(int**); // print current screen
void prtchar(int, int, int);
void prtspace(int, int);
void move(int, int**);
void delay();
void prttime(int);
int calnext(int, int**);
int start(int);
int goal(int);
int speed=50;
int y0=1, x0=3; // char will be printed at (x, y) = (x[0]+x0, y+y0)
int x[]={3, 7, 11};
int xdis=4, ldis=17, ydis=20; //xdis : distance between poll, ldis : dist. btw section, ydis : total height of show
int num=12; //number of discs
int sect=1; //number of layer sections to show
int clay[3]; //current number of discs at each layer, next number of...
clock_t mysec[3];
/****************************************************/
main ()
{
int i, j, **twr; //twr : 2-dimension array for each numbers in towers
long cnt=0;
int mov; //0~5 : 0>>1, 1>>0, 1>>2, 2>>1, 2>>0, 0>>2
int f_read=0;
char ch;
char fname[20]="my_hanoi.txt";
FILE *fp;
printf("Do you want to read previous data file? (Y/N) ");
ch=getch();
if(ch=='Y' || ch=='y')
{
f_read=1;
fp=fopen(fname, "r"); //save & exit
fscanf(fp, "%d", &num);
}
else
{
printf("\nEnter number of initial layers (n<80) : ");
scanf("%d", &num);
}
sect=1+(num-1)/ydis;
twr=(int **)calloc(3,sizeof(int*));
for (i=0; i<3; i++) //tower0--start, tower1--temp, tower2--destination
{
twr[i]=(int *)calloc(num,sizeof(int));
}
if (f_read==1) //read previous data from file
{
fscanf(fp, "%ld %d %d", &cnt, &mov, &mysec[0]);
for (i=0; i<3; i++)
{
fscanf(fp, "%d", &clay[i]);
for (j=0; j<clay[i]; j++)
fscanf(fp, "%d", &twr[i][j]);
}
fclose(fp);
}
else
{
clay[0]=num;
mov=(num%2)*5; //num=odd --> 5; 0>>2, num=even --> 0; 0>>1
for (j=0; j<num; j++)
twr[0][j]=num-j;
}
prtscr(twr);
mysec[1]=clock();
//logic start!!!
do
{
if(kbhit())
{
ch=getch();
if(ch==ESC)
{
mysec[1]=clock()-mysec[1]; //eclipsed time at this trial
mysec[2]=mysec[0]+mysec[1]; //accumulated eclipsed time so far
gotoxy (20,y0+num+2);
printf("Do you want to save data at file? (Y/N) ");
ch=getch();
if(ch=='Y' || ch=='y')
{
printf("\nThis trial : ");prttime(mysec[1]);
printf("\nTotal accumulation : ");prttime(mysec[2]);printf("\n");
fp=fopen(fname, "w"); //save & exit
fprintf(fp, "%d\n %ld\n %d\n %d\n", num, cnt, mov, mysec[2]);
for (i=0; i<3; i++)
{
fprintf(fp, "%d\n", clay[i]);
for (j=0; j<clay[i]; j++)
fprintf(fp, "%d\n", twr[i][j]);
}
fclose(fp);
ch=getch();
exit(0);
}
else exit(0);
}
else //if(ch==EXTENDASCII)
{
switch(ch)
{
case UP:
speed=(speed+10<1000) ? speed+10 : speed;
break;
case DOWN:
speed=(speed-10>9) ? speed-10 : speed;
break;
}
}
}
gotoxy (1,y0+num+2);
printf("count=%d ", cnt);
delay();
move(mov, twr);
// prtscr(twr);
cnt++;
mov=calnext(mov,twr);
}while(clay[2]<num);
gotoxy (1,y0+num+2);
printf("count=%d\n\n", cnt);
free (twr);
scanf("%c", &ch);
getchar();
return;
}
int calnext(int a, int **twr)
{
int i, j, k, st, ds, ans;
int nxt[2][3];
int ncnt=0;
for (k=0; k<6; k++)
{
if ((k^a)!=1) //should not be (0,1), (2,3), (4,5)
{
i=start(k);
j=goal(k);
if(clay[i]!=0) //start layer <>0
{
if(clay[j]==0)
{
if((clay[i]==1 && twr[i][0]>1) || clay[i]!=1) //should not be (0,1)>>(1,0)
{
nxt[ncnt][0]=k;
nxt[ncnt][1]=clay[j];
nxt[ncnt][2]=twr[i][clay[i]-1];
ncnt++;
}
}
else
{
st=twr[i][clay[i]-1]; // top number of start tower
ds=twr[j][clay[j]-1]; // top number of goal tower
if((st<ds) && (st%2 != ds%2))
{
nxt[ncnt][0]=k;
nxt[ncnt][1]=clay[j];
nxt[ncnt][2]=twr[i][clay[i]-1];
ncnt++;
}
}
}
}
}
if (ncnt==0)
{
gotoxy (1,y0+num+1);
printf("mov= %d ",a);
for(i=0; i<3; i++)
{
printf("error!!!!!!!! clay[%d]= %d\n",i,clay[i]);
}
exit(0);
}
if (ncnt>1)
{
if (nxt[0][1]==nxt[1][1])
ans=(nxt[0][2]>nxt[1][2]) ? nxt[0][0]:nxt[1][0];
else
ans=(nxt[0][1]>nxt[1][1]) ? nxt[0][0]:nxt[1][0];
}
else
ans=nxt[0][0];
gotoxy (1,y0+num+3);
printf("ncnt= %d speed= %d",ncnt, speed);
return(ans);
}
void move(int a, int **twr)
{
int i, j;
i=start(a);
j=goal(a);
twr[j][clay[j]]=twr[i][clay[i]-1];
prtspace(clay[i]-1,i);
prtchar(clay[j],j,twr[j][clay[j]]);
clay[j]++;
clay[i]--;
}
int start(int a)
{
int stt = ((a/2)+(a%2))%3; //a=0~5, org=0,1,1,2,2,0
return(stt);
}
int goal(int a)
{
int dst = ((a+2)/2-a%2)%3; //a=0~5, dst=1,0,2,1,0,2
return(dst);
}
void prtscr(int **twr)
{
int i, j;
system("cls");
for(j=0; j<3; j++)
{
for(i=0; i<clay[j]; i++)
{
if(twr[j][i]!=0)
{
prtchar(i,j,twr[j][i]);
}
}
}
}
void prtchar(int i, int j, int val)
{
int k=i/ydis;
gotoxy(x[j]+k*ldis,y0+(num-(i-k*ydis)));
printf("%d",val);
}
void prtspace(int i, int j)
{
int k=i/ydis;
gotoxy(x[j]+k*ldis,y0+(num-(i-k*ydis)));
printf(" ");
}
void gotoxy(int x, int y)
{
COORD Cur;
Cur.X=x;
Cur.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Cur);
}
void delay()
{
int i,j;
for(i=0; i<1000000/speed; i++)
for(j=0; j<i; j++)
;
}
void prttime(int t)
{
int d, h, m, s;
s=t/1000;
d=s/3600/24;
s=s-d*3600*24;
h=s/3600;
s=s-h*3600;
m=s/60;
s=s%60;
printf("%d days %02d:%02d:%02d",d,h,m,s);
}
//end of source