Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: CrashNebula en 26 Mayo 2013, 12:04 pm



Título: [ANSI C] Torre de hanoi
Publicado por: CrashNebula en 26 Mayo 2013, 12:04 pm
Estoy trabajando con las torres de hanoi. Quisiera que me ayudaran a descifrar
por qué mi código no funciona como debería. Debo hacerla mediante funciones
recursivas y no puedo utilizar métodos iterativos.

Las funciones donde probablemente tenga el error son la g_MoverDiscos o g_TorreDeHanoiRecursiva.

En mi programa utilicé 3 arreglos unidimensionales para la "torres".
Uno que se llama Origen que se imprime a la izquierda, otro que se
llama intermedio que se imprime en el centro y el final se llama destino.

Dados 3 discos este debería ser el output del programa

1  0  0      0  0  0     0  0  0     0  0  0     0  0  0    0  0  0    0  0  0   0  0  1         
2  0  0      2  0  0     0  0  0     0  1  0     0  1  0    0  0  0    0  0  2   0  0  2
3  0  0      3  0  1     3  2  1     3  2  0     0  2  3    1  2  3    1  0  3   0  0  3
Inicio       paso 1      paso 2   paso 3     paso 4    paso 5    paso 6    paso 7

Esto es lo que me está imprimiendo
1  0  0      0  0  0     0  0  0     0  0  0     0  0  0    0  0  0    0  0  0   0  0  1         
2  0  0      2  0  0     0  0  0     0  0  1     0  0  1    0  0  0    0  2  0   0  0  2
3  0  0      3  0  1     3  2  1     0  3  2     0  3  2    2  3  1    0  3  1   0  0  3
Inicio       paso 1      paso 2   paso 3     paso 4    paso 5    paso 6    paso 7
                                           Error1       Error2     Error3    Error4     Correcto

Mientras escribia esto note que los errores  parecen de impresion. :o.
Cualquier ayuda es útil muchas gracias.

Aqui debajo pondre las funciones donde creo que tengo el problema


Código:
#define kMAX 30
void g_MoverDiscos(int liFilas,int liNDiscos,
                   int liTorreOrigen[kMAX],int liTorreDestino[kMAX])
{
    int liPosOrigen =0;
    int liPosDestino=liFilas-1;

    //Busqueda de la posicio del menor disco en el origen
    while(liTorreOrigen[liPosOrigen]==0 && liPosOrigen<liFilas-1)
    {
        liPosOrigen++;
    }

    //Busqueda de la posicion del tope de la torre destino
    while(liTorreDestino[liPosDestino]!=0 && liPosDestino>0)//Menor o igual
    {
        liPosDestino--;
    }
    liTorreDestino[liPosDestino]=liTorreOrigen[liPosOrigen];//Transferencia del disco
    liTorreOrigen[liPosOrigen]=0;//Al moverse el disco esta posicion se hace cero.
}


void g_TorreDeHanoiRecursivo(int liFilas, int liNDiscos,int liTorreOrigen[kMAX],
                             int liTorreIntermedia[kMAX],int liTorreDestino[kMAX])
{

    if(liNDiscos==1)
    {

        g_MoverDiscos(liFilas, liNDiscos, liTorreOrigen, liTorreDestino);
        system("cls");
        g_ImprimirDiscos(liFilas, liTorreOrigen,
                         liTorreIntermedia, liTorreDestino);

    }//END if
    else
    {
        g_TorreDeHanoiRecursivo(liFilas, liNDiscos-1,liTorreOrigen,
                                liTorreDestino,liTorreIntermedia);

        g_MoverDiscos(liFilas, liNDiscos, liTorreOrigen, liTorreDestino);
        system("cls");
        g_ImprimirDiscos(liFilas, liTorreOrigen,
                          liTorreDestino,liTorreIntermedia);


        g_TorreDeHanoiRecursivo(liFilas, liNDiscos-1,liTorreIntermedia,
                                liTorreOrigen,liTorreDestino);
    }//END else
}//END g_TorreDeHanoiRecursivo



///
/// Estas son las demás funciones de mi programa (todas estas están bien)
///

Código:
/// Esta es para leer los discos
int giLeerDiscos(void)
{
    int liN;
    do
    {
        printf("\nIndique la cantidad de discos: ");
        scanf("%d",&liN);
        if(liN<1||liN>kMAX_DISCOS)
        {
            system("cls");
            printf("ERROR.OPCION NO ES VALIDA. VUELVA A INTENTAR\n\n");
        }
    }while(liN<1||liN>kMAX_DISCOS);
    return liN;
}


//Funcion incializa los arreglos a la condicion  que deben tener antes de jugar
void g_CondicionInicialHanoi(int liNDiscos,int liTorreOrigen[kMAX],
                             int liTorreIntermedia[kMAX],int liTorreDestino[kMAX])
{
    int i;
    for (i=0;i<liNDiscos;i++)
    {
        liTorreOrigen[i]=i+1;       //Se colocan los discos desde el 1 en manera ascendente
        liTorreIntermedia[i]=0;     //Se hace cero
        liTorreDestino[i]=0;        //Se hace cero
    }
}


void g_ImprimirDiscos(int liFilas,int liTorreOrigen[kMAX],
                        int liTorreIntermedia[kMAX],int liTorreDestino[kMAX])
{
    int i;

    for (i=0;i<liFilas;i++)
    {

        printf("%d\t",liTorreOrigen[i]);
        printf("%d\t",liTorreIntermedia[i]);
        printf("%d\t",liTorreDestino[i]);
        printf("\n");
    }
}

int  main()
{
    int liTorreOrigen[kMAX];
    int liTorreIntermedia[kMAX];
    int liTorreDestino[kMAX];
    int liNDiscos;
    int liFilas; // Es igual al numero inicial de discos. Define el espacio
                 // de juego.


    liNDiscos=giLeerDiscos();
    liFilas=liNDiscos;
    //Condicion inicial del juego
    g_CondicionInicialHanoi(liNDiscos,liTorreOrigen,
                            liTorreIntermedia,liTorreDestino);

    //Imprimir condicion inicial del juego
    system("cls");
    g_ImprimirDiscos(liNDiscos,liTorreOrigen,
                     liTorreIntermedia,liTorreDestino);
    g_TorreDeHanoiRecursivo(liFilas, liNDiscos,liTorreOrigen,
                            liTorreIntermedia,liTorreDestino);
    printf("\n");
return 0;
}






Título: Re: [ANSI C] Torre de hanoi
Publicado por: amchacon en 26 Mayo 2013, 13:40 pm
Si es recursivo no hay que hacer tanto.

El algoritmo para mover torres de un poste A a un poste C es el siguiente:

Citar
si discos == 1

  Mover disco A to C

sino

  Mover todos los discos salvo el grande (n-1) al poste B
  Mover el disco A al poste C
  Mover el resto de los discos de B a C

Simplementa hay que implementarlo al pie de la letra:

Código
  1. void Mover(char Inicial,char Auxiliar,char Destino,int N)
  2. {
  3.   if (N == 1)
  4.       printf ("Moviendo disco %c al poste %c",Inicial,Destino);
  5.   else
  6.  {
  7.     Mover(Inicial,Destino,Auxiliar,n-1); // Mover todos los discos -1 al auxiliar
  8.     printf("Moviendo disco %c al poste %c",Inicial,Destino); // Moviendo el grande al final
  9.    Mover(Auxiliar,Destino,Inicial,n-1); // Moviendo los discos desde el auxiliar al final
  10.  }
  11. }
  12.  

Ponle de nombre a los postes A,B,C y haz la prueba.


Título: Re: [ANSI C] Torre de hanoi
Publicado por: CrashNebula en 26 Mayo 2013, 18:30 pm
Si es recursivo no hay que hacer tanto.

El algoritmo para mover torres de un poste A a un poste C es el siguiente:

Simplementa hay que implementarlo al pie de la letra:

Código
  1. void Mover(char Inicial,char Auxiliar,char Destino,int N)
  2. {
  3.   if (N == 1)
  4.       printf ("Moviendo disco %c al poste %c",Inicial,Destino);
  5.   else
  6.  {
  7.     Mover(Inicial,Destino,Auxiliar,n-1); // Mover todos los discos -1 al auxiliar
  8.     printf("Moviendo disco %c al poste %c",Inicial,Destino); // Moviendo el grande al final
  9.    Mover(Auxiliar,Destino,Inicial,n-1); // Moviendo los discos desde el auxiliar al final
  10.  }
  11. }
  12.  

Ponle de nombre a los postes A,B,C y haz la prueba.


Se me olvido especificar que la version que debo hacer es la que presenta los
 movimientos de los discos y no la narrada.
Lo que quiero decir es que la version que tengo  es un paso previo a esto:

http://www.youtube.com/watch?feature=player_embedded&v=xXTle8JYhys


Título: Re: [ANSI C] Torre de hanoi
Publicado por: CrashNebula en 28 Mayo 2013, 17:43 pm
bump