Autor Tema: El famoso programa del salto de caballo

0 Usuarios y 1 Visitante están viendo este tema.

08 Septiembre, 2008, 08:11 am
Leído 4799 veces

leonardo09

  • Leonardo Andrés Jofré Flor
  • $$\Large \color{#c88359}\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 786
  • Karma: +0/-0
  • Sexo: Masculino
  • Leonardo Jofré
    • Leonardo Andrés Jofré Flor
Acá estoy desarrollando un programa que resuelve el clásico problema del salto del caballo , pero no me resulta, o sea existe una función en la cual no he podido identificar el error.



Como mi filosofía es el de 100 cabezas pinzan mejor que una, les dejo el código para que sus magníficos cerebros analicen.

#include<stdio.h>
#include<stdlib.h>
#define SIZE 8


int  f_0_c_1_del_mayor_valor(int [][SIZE], int);
int cantidad_de_movimientos_posibles(int [][SIZE],int,int);
int movimiento_heuristico(int [][SIZE],int);
void Mostrar(int[][8],int);
void Contenido(int*,int,int,int);
void Coordenadas(int,int);
void Raya(int,int,int,int,int);

int Libre=0;

int movimiento_vertical_horizontal[8][2] =
{
{-2,1},{-2,-1},{2,1},{2,-1},{-1,-2},{1,-2},{-1,2},{1,2}
};
main()
{
int tablero[8][8]={0};
int numero_de_movimientos = 0,fila_inicial,columna_inicial;
int fila_siguiente,columna_siguiente,mov;

printf("Ingrese la primera posicion del caballo en el tablero:");
columna_inicial=getchar()-97;
scanf("%d",&fila_inicial);
numero_de_movimientos+=1;
tablero[fila_inicial-1][columna_inicial]=numero_de_movimientos;

Mostrar(tablero,8);
for(mov=2;mov<=64;mov++){
fila_siguiente=movimiento_heuristico(tablero,0);
columna_siguiente=movimiento_heuristico(tablero,1);

tablero[fila_siguiente][columna_siguiente]=mov;

Mostrar(tablero,8);
}

getchar();
getchar();
return 0;
}

int movimiento_heuristico(int tablero[][SIZE],int f_0_c_1)
{
int F[8],C[8],Cont[8];int Arg,temp3 = 8;
int count1,count2;
int temp1,temp2;int p_1,p_2;

p_1 =  f_0_c_1_del_mayor_valor(tablero,0);
p_2 = f_0_c_1_del_mayor_valor(tablero,1);

for(count1 = 0; count1<SIZE;count1++)
{
               temp1 = movimiento_vertical_horizontal[count1][0];
               temp2 = movimiento_vertical_horizontal[count1][1];
               
               if((p_1+temp1>7)||(p_1+temp1<0))
               Cont[count1]=10;F[count1]=10;C[count1]=10;
               
               if((p_2+temp2>7)||(p_2+temp2<0))
               Cont[count1]=10;F[count1]=10;C[count1]=10;
               
               Cont[count1]=cantidad_de_movimientos_posibles(tablero,p_1+temp1,p_2+temp2);
               F[count1]=p_1+temp1;C[count1]=p_2+temp2;
               }
               
               for(count2=0;count2<SIZE;count2++)
              {
              if(Cont[count2]<temp3)
              {
                 temp3=Cont[count2];Arg=count2;   
                }
                                                 }
                                                 
    if(f_0_c_1==0)
    return F[Arg];
    if(f_0_c_1==1)
    return C[Arg];
}


int cantidad_de_movimientos_posibles(int tablero[][SIZE],int fila,int columna)
{
int n,cantidad = 0;
int M_V,M_H;

for(n=0;n<SIZE;n++) {
       
        M_V = movimiento_vertical_horizontal[n][0];
        M_H = movimiento_vertical_horizontal[n][1];
if(fila + M_V<8 && fila + M_V >= 0)
if(columna + M_H <8 && columna + M_H >= 0)
if( tablero[fila+M_V][columna+M_H]==0)
cantidad = cantidad+1;
}
    return cantidad;
}



int f_0_c_1_del_mayor_valor(int tablero[][SIZE], int f_0_c_1)
{
int i,j,fila_de_retorno,columna_de_retorno;
int temp = 0;

for(i=0;i<SIZE;i++)
{
for(j=0;j<SIZE;j++)
{
if(tablero[i][j]>temp)
{
temp = tablero[i][j];
fila_de_retorno = i;
columna_de_retorno = j;

}
}
}
if(f_0_c_1==0)
return fila_de_retorno;
    if(f_0_c_1==1)
    return columna_de_retorno;
}

void Mostrar(int T[][8],int n)
{
int i,j,w=3;



Coordenadas(n,w);
Raya(218,194,191,w,n);
for(i=0;i<n-1;i++)
{
Contenido(T[i],i+1,n,w);
Raya(195,197,180,w,n);
}
Contenido(T[i],i+1,n,w);
Raya(192,193,217,w,n);
}

void Contenido(int* F,int k,int n,int w)
{
int i;

printf("\n\t\t%7d %c",k,179);
for(i=0;i<n;i++)
if(F[i]==Libre)
printf("%*c%c",w,' ',179);
else if(F[i]<0)
printf("%*c %c",w-1,250,179);
else
printf("%*d%c",w,F[i],179);
}


void Raya(int i,int m,int f,int w,int n)
{
int h,k;

printf("\n\t\t\t%c",i); for(h=0;h<w;h++) printf("%c",196);
for(k=1;k<n;k++)
{printf("%c",m); for(h=0;h<w;h++) printf("%c",196);}
printf("%c",f);
}

void Coordenadas(int n,int w)
{
int i;

printf("\n\t\t\t"); for(i=0;i<n;i++) printf("%*c ",w,i+65);
}
nunca seré buen matemático

08 Septiembre, 2008, 11:10 am
Respuesta #1

Luis Fuentes

  • el_manco
  • Administrador
  • Mensajes: 58,907
  • País: es
  • Karma: +0/-0
Hola

 Cuando "copy-pegues" un programa en el foro, ponlo entre:

[nobbc]
[/nobbc]

 eso evitará que donde apareca [i] sea interpretado como cursiva, perdiéndose parte de la información del programa. En éste ya lo puse yo.

 En cuanto al programa, varias cosas:

 i) El dato de la columna tómalo igual que el de la fila. Esto:

Citar
columna_inicial=getchar()-97;

es una complicación innecesaria. Mejor:

scanf("%d",&columna_inicial);

 ii) Aquí:

Citar
tablero[fila_inicial-1][columna_inicial]=numero_de_movimientos;

resta 1 a la columna también.

 iii) Aquí:


Citar
               
               if((p_1+temp1>7)||(p_1+temp1<0))
               Cont[count1]=10;F[count1]=10;C[count1]=10;
               
               if((p_2+temp2>7)||(p_2+temp2<0))
               Cont[count1]=10;F[count1]=10;C[count1]=10;
               
               Cont[count1]=cantidad_de_movimientos_posibles(tablero,p_1+temp1,p_2+temp2);
               F[count1]=p_1+temp1;C[count1]=p_2+temp2;
               }
               
               for(count2=0;count2<SIZE;count2++)
              {
              if(Cont[count2]<temp3)
              {
                 temp3=Cont[count2];Arg=count2;   
                }
                                                 }


 Te faltan llaves para agrupar las consecuencias de cada if; deberías además de usar else-if y controlar también que no vayas a una casilla ocupada.

 Algo así:

               if((p_1+temp1>7)||(p_1+temp1<0))
               {
               Cont[count1]=10;F[count1]=10;C[count1]=10;}
               
               else if((p_2+temp2>7)||(p_2+temp2<0))
               {
               Cont[count1]=10;F[count1]=10;C[count1]=10;}
               else if (tablero[p_1+temp1][p_2+temp2]>0)
               {
               Cont[count1]=10;F[count1]=10;C[count1]=10;}
               else
               {
               Cont[count1]=cantidad_de_movimientos_posibles(tablero,p_1+temp1,p_2+temp2);
               F[count1]=p_1+temp1;C[count1]=p_2+temp2;
               }
               }

Saludos.

08 Septiembre, 2008, 10:55 pm
Respuesta #2

leonardo09

  • Leonardo Andrés Jofré Flor
  • $$\Large \color{#c88359}\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 786
  • Karma: +0/-0
  • Sexo: Masculino
  • Leonardo Jofré
    • Leonardo Andrés Jofré Flor
gracias Manco , ahora te explico.
El tema del getcha() es que funciona muy parecido al scanf y también convierte cualquier letra a su entero en ansii, como las columnas en el tablero de ajedrez está dado por letras necesito esa funcion para que la transforme en un entero para poder manipular la matriz dado esos valores, nada mas que eso.

El resto expuesto por ti lo voy a analizar con mucha atención
nunca seré buen matemático

09 Septiembre, 2008, 07:20 am
Respuesta #3

Luis Fuentes

  • el_manco
  • Administrador
  • Mensajes: 58,907
  • País: es
  • Karma: +0/-0
Hola

Citar
El tema del getcha() es que funciona muy parecido al scanf y también convierte cualquier letra a su entero en ansii, como las columnas en el tablero de ajedrez está dado por letras necesito esa funcion para que la transforme en un entero para poder manipular la matriz dado esos valores, nada mas que eso.

Ah. Era para leer la columna en letra. Ok.

Saludos.

12 Septiembre, 2008, 09:36 pm
Respuesta #4

leonardo09

  • Leonardo Andrés Jofré Flor
  • $$\Large \color{#c88359}\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 786
  • Karma: +0/-0
  • Sexo: Masculino
  • Leonardo Jofré
    • Leonardo Andrés Jofré Flor
bueno les dejo el código para aceptar sugerencias:


#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#define SIZE 8
#define Libre 0



void   Mostrar(int[][8],int);
void   Contenido(int*,int,int,int);
void   Coordenadas(int,int);
void   Raya(int,int,int,int,int);


int ultimo_movimiento_f0c1(int [][SIZE], int);
int cantidad_de_movimientos(int [][SIZE], int, int);
void informar(int [][SIZE]);
void sugerencia(int [][SIZE]);

int movimiento_vertical_horizontal[8][2] =
                  {
                  {-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1},{2,1},{1,2}
                  };
                  
/*----------------------------------------------------------------------------*/

main()
{
   int mov = 1 ; int matriz[8][8] = {0}; int f; char c;
      
      Mostrar(matriz,8);
      printf("\n");
      
      informar(matriz);
      printf("\ningrese el movimiento numero %d:",mov);
      scanf("%c",&c);
      scanf("%d",&f);
      getchar();
      
      matriz[f-1][toupper(c)-65] = mov;
      
      system("cls");
      Mostrar(matriz,8);
      mov++;
   while(mov<=64)
   {
      if(mov<=64)
      {   
      printf("\n");
      printf("movimientos posibles:\t");
      informar(matriz);
      printf("\ningrese el movimiento numero %d:",mov);
      scanf("%c",&c);
      scanf("%d",&f);
      getchar();
      
      matriz[f-1][toupper(c)-65] = mov;
      
      system("cls");
      Mostrar(matriz,8);
      mov++;
      }
      else
      {
      break;   
      }
   }
   
   printf("\ncaballo\n"
   "satisfactoriamente ¡felicitaciones!");
   
   
   getchar();
   getchar();
   return 0;
}
/*----------------------------------------------------------------------------*/
void sugerencia(int tablero[][SIZE])
{
   int fila, columna; int k; int a,b,c; int temp = 7;
   
   fila = ultimo_movimiento_f0c1(tablero,0);
   columna = ultimo_movimiento_f0c1(tablero,1);
   
   for(k=0;k<SIZE;k++)
   {
      a = fila +    movimiento_vertical_horizontal[k][0];
      b = columna + movimiento_vertical_horizontal[k][1];
      
      if((a>=0)&&(a<=7)&&(b>=0)&&(b<=7)&&(tablero[a]==0))
      {
         c = cantidad_de_movimientos(tablero,a,b);
         printf("%c%d(%d)\t",b+65,a+1,c);   
      }
   }
      
}
/*----------------------------------------------------------------------------*/


void informar(int tablero[][SIZE])
{
   int fila, columna; int k; int a,b,c;
   
   fila = ultimo_movimiento_f0c1(tablero,0);
   columna = ultimo_movimiento_f0c1(tablero,1);
   
   for(k=0;k<SIZE;k++)
   {
      a = fila +    movimiento_vertical_horizontal[k][0];
      b = columna + movimiento_vertical_horizontal[k][1];
      
      if((a>=0)&&(a<=7)&&(b>=0)&&(b<=7)&&(tablero[a]==0))
      {
         c = cantidad_de_movimientos(tablero,a,b);
         printf("%c%d(%d)\t",b+65,a+1,c);   
      }
   }
      
}
/*----------------------------------------------------------------------------*/

int cantidad_de_movimientos(int tablero[][SIZE], int fila, int columna)
{
   int cantidad_de_retorno = 0; int V,H;
   int k; int a,b,c;
   
   for(k=0;k<SIZE;k++)
   
   {
      V = movimiento_vertical_horizontal[k][0];
      H = movimiento_vertical_horizontal[k][1];
      
      a = fila+V;
      b = columna+H;
      c = tablero[fila+V][columna+H];
      
      if((a<=7)&&(b<=7)&&(a>=0)&&(b>=0)&&(c==0))
      {
         cantidad_de_retorno +=1;   
      }
   }
   
   return cantidad_de_retorno;   
}

/*----------------------------------------------------------------------------*/

int ultimo_movimiento_f0c1(int tablero[][SIZE], int f_0_c_1)
{
   int i, j; int mayor_valor = 0;
   int fila_de_retorno, columna_de_retorno;
   for(i = 0; i < SIZE; i++)
   {
      for(j = 0; j <SIZE; j++)
      {
         if(tablero[j]>mayor_valor)
         {
            mayor_valor = tablero[j];
            fila_de_retorno = i;
            columna_de_retorno = j;
         }
      }
   }
   
   if(f_0_c_1 == 0)
   {
   return fila_de_retorno;   
   }
   
   if(f_0_c_1 == 1)
   {
   return columna_de_retorno;   
   }
}
/*----------------------------------------------------------------------------*/

void Mostrar(int T[][8],int n)
   {
   int      i,j,w=3;

   

   Coordenadas(n,w);
   Raya(218,194,191,w,n);
   for(i=0;i<n-1;i++)
      {
      Contenido(T,i+1,n,w);
      Raya(195,197,180,w,n);
      }
   Contenido(T,i+1,n,w);
   Raya(192,193,217,w,n);
   }
   
/*----------------------------------------------------------------------------*/

void Contenido(int* F,int k,int n,int w)
   {
   int      i;

   printf("\n\t\t%7d %c",k,179);
   for(i=0;i<n;i++)
      if(F==Libre)
         printf("%*c%c",w,' ',179);
      else if(F<0)
         printf("%*c %c",w-1,250,179);
      else
         printf("%*d%c",w,F,179);
   }
   
/*----------------------------------------------------------------------------*/

void Raya(int i,int m,int f,int w,int n)
{
   int h,k;

   printf("\n\t\t\t%c",i); for(h=0;h<w;h++) printf("%c",196);
   for(k=1;k<n;k++)
      {printf("%c",m); for(h=0;h<w;h++) printf("%c",196);}
   printf("%c",f);
   }
   
/*----------------------------------------------------------------------------*/

void Coordenadas(int n,int w)
   {
   int i;

   printf("\n\t\t\t"); for(i=0;i<n;i++) printf("%*c ",w,i+65);
   }

nunca seré buen matemático

13 Septiembre, 2008, 10:11 am
Respuesta #5

Luis Fuentes

  • el_manco
  • Administrador
  • Mensajes: 58,907
  • País: es
  • Karma: +0/-0
Hola

 ¿Te funciona bien?.

Saludos.

13 Septiembre, 2008, 11:15 pm
Respuesta #6

leonardo09

  • Leonardo Andrés Jofré Flor
  • $$\Large \color{#c88359}\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 786
  • Karma: +0/-0
  • Sexo: Masculino
  • Leonardo Jofré
    • Leonardo Andrés Jofré Flor
Me funciona perfecto solo hay que validar la entrada.

La heuristica dice que para completar el salto de caballo hay que saltar al escaque con menos escaques posibles para seguir saltando.

el la sugerencia te da el escaque a saltar y la cantidad de escaques que tiene para seguir saltando
nunca seré buen matemático