#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;
}

    Source: geocities.com/br/joselitofilho

               ( geocities.com/br)