#include
#include
#include
#include
#include
#include
/*
numdiscos - Quantidade de discos;
movimentos - Contador para a quantidade de movimentos realizados;
ultposx - Guarda a ultima posicao de x;
ultposy - Guarda a ultima posicao de y;
indice - Indica o disco que sera utilizado;
discos - Matriz que armazena os discos de 1 a 13 dos pinos 1 a 3;
i, j - Contador de Loop;
tempo - Tempo de espera do movimento entre um pino e outro;
maxdiscos - Quantidade maxima de discos;
rodas - Matriz que armazena o desenho dos discos de 1 a 13;
base - Desenho da base dos pinos;
*/
int numdiscos, movimentos, ultposx, ultposy, indice;
int discos[14][4],i,j;
int tempo = 1000;
const int maxdiscos = 13;
const char rodas[14][26] =
{" º ", /* 0 */
" Ü ", /* 1 */
" ÜÜÜ ", /* 2 */
" ÜÜÜÜÜ ", /* 3 */
" ÜÜÜÜÜÜÜ ", /* 4 */
" ÜÜÜÜÜÜÜÜÜ ", /* 5 */
" ÜÜÜÜÜÜÜÜÜÜÜ ", /* 6 */
" ÜÜÜÜÜÜÜÜÜÜÜÜÜ ", /* 7 */
" ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ", /* 8 */
" ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ", /* 9 */
" ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ", /* 10 */
" ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ", /* 11 */
" ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ", /* 12 */
"ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ"}; /* 13 */
const char base[81] = "ÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ";
/*
Procedimento para levar o cursor na posicao deseja da pelo usuario
na tela - 80x25;
x - Posicao da coluna;
y - Posicao da linha;
*/
void gotoxy(int x,int y )
{
COORD coord;
coord.X = (short)x-1;
coord.Y = (short)y-1;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
/*
Imprime os estatus e o desenho dos pinos e dos dicos a cada movimento;
C - Contador para loop;
*/
void faz_torres()
{
int C;
//textcolor(brown);
for (C = 1; C <= maxdiscos; C++)
{
gotoxy(1,C);
printf("%s%s%s",rodas[discos[C][1]],rodas[discos[C][2]],rodas[discos[C][3]]);
}
gotoxy(1, maxdiscos + 1);
printf("%s",base);
//textcolor(white);
gotoxy(1, maxdiscos + 2);
printf("Opcoes: (P)ausa (+)/(-)velocidade");
gotoxy(60, maxdiscos + 2);
printf("Movimentos: %4d",movimentos);
gotoxy(60, maxdiscos + 3);
printf("Velocidade: %4d",tempo);
gotoxy(1, maxdiscos + 3);
//textcolor(yellow + blink);
printf("Pressione qualquer tecla para encerrar...");
//textcolor(white);
}
/*
Da os valores inicias para os disco e da a posicao que ira comecar a
ser desenhado os passos dos movimentos;
C - Contador para loop;
totdiscos - Quantidade de discos;
*/
void ini_discos()
{
int C, totdiscos;
movimentos = 0;
totdiscos = numdiscos;
for (C = maxdiscos; C >= 1; C--)
{
if (totdiscos > 0)
{
discos[C][1] = totdiscos;
totdiscos = totdiscos - 1;
}
discos[C][2] = 0;
discos[C][3] = 0;
}
/*ultposx = 1;
ultposy = 1;*/
ultposx = 4;
ultposy = 18;
}
/*
Calcula qual o disco que sera movido;
disco - Numero do disco que ira ser movido;
C, menor - Contador para loop;
*/
void menor_exceto_zero(int disco)
{
int C, menor;
menor = numdiscos + 1;
indice = maxdiscos;
for (C = maxdiscos; C >= 1; C--)
{
if (discos[C][disco] < menor && discos[C][disco] != 0)
{
menor = discos[C][disco];
indice = C;
}
}
}
/*
Desenha a tabela que mostra os movimentos;
de - Pino onde se encontra o disco;
para - Pino para onde ira o disco;
C - Contador para loop;
*/
void tab_move(int de,int para)
{
int C;
gotoxy(3,17); printf("%c",201);
gotoxy(76,17); printf("%c",187);
for (C = 4; C <= 75; C++)
{
gotoxy(C,17); printf("%c",205);
gotoxy(C,25); printf("%c",205);
}
gotoxy(3,25); printf("%c",200);
gotoxy(76,25); printf("%c",188);
gotoxy(3,18); printf("%c",186);
gotoxy(3,19); printf("%c",186);
gotoxy(3,20); printf("%c",186);
gotoxy(3,21); printf("%c",186);
gotoxy(3,22); printf("%c",186);
gotoxy(3,23); printf("%c",186);
gotoxy(3,24); printf("%c",186);
gotoxy(76,18); printf("%c",186);
gotoxy(76,19); printf("%c",186);
gotoxy(76,20); printf("%c",186);
gotoxy(76,21); printf("%c",186);
gotoxy(76,22); printf("%c",186);
gotoxy(76,23); printf("%c",186);
gotoxy(76,24); printf("%c",186);
//window(5,18,76,24);
gotoxy(ultposx,ultposy);
printf("%d --> %d; ",de,para);
ultposx = ultposx + 9;
if (ultposx == 76)
{
ultposy = ultposy + 1;
ultposx = 4;
}
if (ultposy > 24)
{
system("cls");
ultposy = 18;
}
//ultposx = wherex; ultposy = wherey;
//window(1,1,80,25);
}
/*
Para sair do programa;
*/
void sair()
{
system("cls");
}
/*
Verifica qual a tecla que o usuario apertou durante a execução do
programa e realiza sua funcao caso a tecla corresponda a uma funcao;
"-" - Diminue o tempo de execução;
"+" - Aumenta o tempo de execução;
"P" - Pausa o programa;
"S" - Sai do programa;
*/
void verif_tecla()
{
char tecla;
tecla = getch();
if (tecla == '-')
if (tempo > 0)
tempo = tempo - 250;
else
if (tempo = 0)
tempo = 0;
if (tecla == '+')
if (tempo < 1000)
tempo = tempo + 250;
else
if (tempo = 1000)
tempo = 1000;
if ((tecla == 'p') || (tecla == 'P'))
{
gotoxy(1, maxdiscos + 2);
printf("Qualquer tecla continua... ");
while(!kbhit());
}
if ((tecla == 's') || (tecla == 'S'))
sair();
}
/*
Move os discos nos pinos e mostra seus movimentos;
de - Pino onde se encontra o disco;
para - Pino para onde ira o disco;
moverd - Zera o disco que foi movido;
moverp - Preenche o disco que sera desenhado no pino para onde o mesmo
foi movido;
*/
int mover(int de,int para)
{
int moverd, moverp;
menor_exceto_zero(de);
moverd = indice;
menor_exceto_zero(para);
moverp = indice;
while (discos[moverp][para] != 0)
moverp = moverp - 1;
discos[moverp][para] = discos[moverd][de];
discos[moverd][de] = 0;
if (kbhit())
{
verif_tecla();
}
movimentos = movimentos + 1;
tab_move(de,para);
faz_torres();
::Sleep(tempo);
}
/*
Resolve esse problema da Torre de Hanoi recursivamente;
orig - Pino de origem;
temp - Pino temporario;
dest - Pino de distino;
*/
void realiza_move1(int numdiscos,int orig,int dest,int temp)
{
if (numdiscos == 1)
mover(orig,dest);
else
{
realiza_move1(numdiscos-1,orig,temp,dest);
mover(orig,dest);
realiza_move1(numdiscos-1,temp,dest,orig);
}
}
/*
Resolve esse problema da Torre de Hanoi recursivamente;
orig - Pino de origem;
temp - Pino temporario;
dest - Pino de distino;
*/
void realiza_move2(int numdiscos,int orig,int dest,int temp)
{
if (numdiscos == 1)
{
mover(orig,temp);
mover(temp,dest);
}
else
{
realiza_move2(numdiscos-1,orig,dest,temp);
mover(orig,temp);
realiza_move2(numdiscos-1,dest,orig,temp);
mover(temp,dest);
realiza_move2(numdiscos-1,orig,dest,temp);
}
}
/*
Torre de Hanoi (1)
Inicialmente os discos formam uma torre onde todos são colocados
em um dos pinos em ordem decrescente de tamanho. Devemos transferir
toda a torre para um dos outros pinos de modo que cada movimento
é feito somente com um disco, nunca havendo um disco maior sobre
um disco menor.
*/
void hanoi1()
{
do
{
system("cls");
printf("Digite a quantidade de discos (maximo 13): ");
scanf("%d",&numdiscos);
}
while (numdiscos > maxdiscos || numdiscos < 0);
system("cls");
ini_discos();
faz_torres();
::Sleep(tempo);
realiza_move1(numdiscos,1,3,2);
getch();
}
/*
Torre de Hanoi (2)
Inicialmente os discos formam uma torre onde todos são colocados
em um dos pinos em ordem decrescente de tamanho. Devemos transferir
toda a torre para um dos outros pinos de modo que cada movimento
é feito somente com um disco, onde todos os movimentos devem passar
pelo pino intermediário, nunca havendo um disco maior sobre um disco
menor.
*/
void hanoi2()
{
do
{
system("cls");
printf("Digite a quantidade de discos (maximo 13): ");
scanf("%d",&numdiscos);
}
while (numdiscos > maxdiscos || numdiscos < 0);
system("cls");
ini_discos();
faz_torres();
::Sleep(tempo);
realiza_move2(numdiscos,1,3,2);
getch();
}
/*
Parte principal do programa;
1 = Pino 1;
2 = Pino 2;
3 = Pino 3;
*/
int main()
{
char esc;
do
{
system("cls");
printf("Escolha qual a Torre de Hanoi que voce deseja ver\n");
printf("1 - Normal ((2^n)-1 movimentos) \n");
printf("2 - Variacao ((3^n)-1 movimentos)\n");
esc = getch();
switch(esc)
{
case '1':
{
system("cls");
printf("Inicialmente os discos formam uma torre onde todos sao colocados ");
printf("no primeiro \npino em ordem decrescente de tamanho. Devemos transferir ");
printf("toda a torre para o\nterceiro pino de modo que cada movimento ");
printf("eh feito somente com um disco, nunca\nhavendo um disco maior sobre ");
printf("um disco menor.\n\n\n");
printf("Pressione uma tecla para continuar");
getch();
hanoi1();
break;
}
case '2':
{
system("cls");
printf("Inicialmente os discos formam uma torre onde todos sao colocados ");
printf("no primeiro\npino em ordem decrescente de tamanho. Devemos transferir ");
printf("toda a torre para o\nterceiro pino de modo que cada movimento ");
printf("é feito somente com um disco, onde\ntodos os movimentos devem passar ");
printf("pelo pino intermediário, nunca havendo um disco");
printf("maior sobre um disco menor.\n\n\n");
printf("Pressione uma tecla para continuar");
getch();
hanoi2();
break;
}
default:
{
printf("Opcao invalida.\nPressione uma tecla para continhuar");
getch();
}
}
}
while ((esc < '1') || (esc > '2'));
return 0;
}
               (
geocities.com/br)