Ayuda con programa urgente!

Iniciado por Albertocn, 8 Diciembre 2013, 17:52 PM

0 Miembros y 2 Visitantes están viendo este tema.

vangodp

#20
Puedes ser amable de decir como valido cada caso con 4 for?
Soy todo oídos :D
El algoritmo es la casualidad.
la posición actual de la x mira arriba, abajo, izquierda y derecha buscando el mejor camino.
Primero busca el numero 2 que se supone ser no explorado, el 1 es que ya ha estado ahí y 0 no lo puede atravesar(pared).
Si no hay remedio pasa por el uno otra vez pero prefiere el 2.
Hasta llegar al final que aun no esta echo.
Pretendo mejorarlo pero un novato lo tiene muy limitado como yo.
Lo voy mejorando como para leer el mapa desde un archivo.
No perder mucho tiempo en salir de un camino ya explorado.
A ver si lo paso a SDL que me mola. :D
Si encuentra 2 o mas caminos iguales elige al azar, por eso cuando entra en una calle sin salida se vuelve algo lento, tengo que hacer que al llegar al final recuerde el camino o lo que sea.

ivancea96

#21
Código (cpp) [Seleccionar]

int a[4] = {arriba, izquierda, derecha, abajo};
void (*f[])() = {go_arriba, go_izquierda, go_derecha, go_abajo};
if(a[0] + a[1] + a[2] + a[3] > 0){
int primos = {2, 3, 5, 7};
int mayor=0;
int temp=1;
int cont=1;
for(int i=0;i<4;i++)
   if(a[i] > mayor){mayor=a[i];temp=primos[i];} //Miramos cual es el mayor
for(int i=0; i<4; i++)
   if(temp%primos[i]!=0 && a[i]==mayor){temp*=primos[i]; ++cont;} //Miramos cuales son iguales al mayor
switch(cont){
   case 1: for(int i=0;i<4;i++) if(temp%primos[i] == 0){(*f[i])();break;}break;
   case 2: //Aqui sería ver cuales son los elegidos, y elegir al azar cual usar.
   case 3: //idem
}
}


En fin, no se si tengo algún fallo por ahí. De ser así, y si te gusta el algoritmo, puedes corregirlo. Te dejo para, si lo usases, lo continues tú jaja

EDITO: Los 4 for eran una posibilidad, pero preferí esa, que me pareció más rápida.

vangodp

Lo voy echar un ojo ;)
Gracias, a ver si lo achicamos :D

vangodp


Hola ivan, hola a todos.
Tengo una duda.
¿Que hace esta linea?
void (*f[])() = {go_arriba, go_izquierda, go_derecha, go_abajo};
Algunas cosas me son algo confusas por la inesperiencia que tengo?
Si no puedes explicarme al menos dime de que se trata y ya lo investigo por mi cuenta :D
Suerte!

ivancea96

Código (cpp) [Seleccionar]
void (*f[])() = {go_arriba, go_izquierda, go_derecha, go_abajo};

Para poder ordenar, metí todas las funciones en un array de funciones.
Cuando se pone algo como:
Código (cpp) [Seleccionar]
char (*ptrchar) (int);
ptrchar = prueba;
char prueba(int a){ //pasar funcion como parametro
    return (char)a;


ptrchar es un puntero a una función char. ¿Qué variables recibe sa función? "char (*ptrchar) (int);". En vez de int, podríamos poner (char, int[]), por ejemplo. En fin.

Es la primera vez que uso en la práctica lo de puntero a funciones, así que no se si irá bien del todo jaja. Pero puedes echarle un vistazo :o

leosansan

#25
¡Pedazo de código!

Cita de: vangodp en 16 Diciembre 2013, 16:09 PM
;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-)

UUUUFFFFFFFFFFFFF !!!!!!!!!!!!!.................... tanto trabajo merece la pena que se cite entero por largo que sea. Enhora buena por  tu paciencia para desarrollar semejante pedazo de código. ¿De dónde sacas tanto tiempo y ánimos?. Yo cuando voy por la línea 100 ya me parece que me paso  :o

Pero vamos por partes. Te cito


Cita de: vangodp en 16 Diciembre 2013, 16:09 PM
Eh mejorado un poco el código :D
Lo eh echo auto suficiente jaja
Este se busca la salida solo XD
Puedes cambiar el mapa a gusto.
Es algo ineficiente aun, lo estoy puliendo cosillas como cuando encuentra una calle sin salida, le tarda algo en volver al camino, pero lo encuentra.


Lo de mejorar supongo que no te referías al código que postee anteriormente. Estaba desarrollado para un laberinto concreto que puso el autor del tema y hacía lo que se le pedía: buscar la salida y la encontraba.  :silbar: :silbar:

Lo de ineficiente lo dices tú, yo soy demasiado pardillo aún en este mundillo para poner calificativos y mucho menos despectivos. Lo que no dejo de alabar es tu curro con el dichoso código.

Lo de que encuentra una salida no me parece. Lo tuve corriendo varios, pero varios, minutos y nada de nada. Fijándome un poco observe que el laberinto que propones en tu código no tiene solución: es un callejón sin salida, al menos yo la busque a simple vista y ningún camino conducía a la salida.

Tarda, pero tarda un *uevo no ya en salir, sino en moverse hacia alguna dirección concreta. Yo diría que más que buscar la salida, deambula sin tino concreto.


Cita de: vangodp en 16 Diciembre 2013, 16:09 PM
Esta echo en dev cpp orwell
Pronto subo la 2.0 o mejor lo mejoren vosotros si quieren  ;-)
Se debe de poner 0 en los bordes o puede ser bug :D

Dichosita manía con el DevC++, por muy Orwell que sea y no es por que no lo haya probado, que sí que lo he hecho, pero con lo chulo que es el Code::Blocks.
:rolleyes:

Espero que no cunda el desánimo, a mí me suele  ocurrir xD, y te animes a por una versión más depurada.

Y, en tu caso, lo del bug si no hay ceros en los bordes es porque los índices de la matriz que usas se sobrepasarían. Haz la prueba y veras que el mensaje que manda el programa es el de índices fuera de rango. Ello se debe a las condiciones que pones en los caminos lleva más allá del rango permitido, que ya de por sí es excesivo.

Conste que todo lo que te planteo amigo vangodp es con el mayor de los respetos y cariño hacía tí y hacía el curro que te has pegado.

Y ahora respecto al código un par de observaciones:

* Las dimensiones de la matriz no se corresponden con su tamaño. Una cosa es que pongas ceros, yo también lo hago, ya te comentaré, y otra es que trates de evitar un error lógico del código con esa artimaña.

* Creo sinceramente que consideras demasiadas opciones, o mejor dicho, las desmenuzas en demasía, lo que da origen a una cantidad interminable de "if". No paro de repetirlo, lo sé, pero te has pegado un curro de cuidado. Por un lado el obtener todas esas posibilidades y luego la paciencia de plasmarlo o escribirlo. Este es mi post más largo y ya estoy cansado, con lo que me imagino que tú no veas.

* Algo que no me termina de convencer es el uso de la aleatoriedad para elegir los movimientos, porque ello conduce a una secuencia casi interminable de pasos: tan  pronto da dos pasitos a la derecha como tres a la izquierda, sube tres y baja cuatro, etc. La consecuencia de esa aleatoriedad es que hace intervenir a la Estadística y ésta nos confirma que más bien irá rondando de forma continua cada nueva posición, lo que hace muy ineficiente el método.

Todo ello me ha animado a intentar, ya te comenté que soy muy nuevo en este mundillo, un método alternativo sin aleatorios y teniendo en cuenta que sólo hay cuatro posibles movimientos -ABAJO:DERECHA_ARRIBA_IZQUIERDA-, en ese orden de preferencia ya que partimos de que la salida está en la parte superior izquierda y la llegada en la inferior derecha, por lo que lo razonable es dar preferencia a los movimientos hacia abajo y a la derecha, respecto a los de hacia arriba y a la izquierda ya que estos últimos, así de entrada, tienden a alejarnos del objetivo. Ello no quiere decir que no los use ya que son necesarios  para caminar hacia atrás en caso de encerrona. Eso sí, no son movimientos al azar ni por capricho. Lo que hago es comparar cada posible movimiento hacia una posición con los otros tres posibles y camino hacia el de menor valor.

¿Hacia el de menor valor?. Pues sí, porque yo uso una segunda matriz numérica y cada pasito que doy incremento el valor del elemento de la matriz, y así voy buscando continuamente los de menos valor.

Y ya está bien de rollo y para botón una muestra de solución al laberinto que planteaste, con alguna pequeña modificación para que tuviera solución:


Citar


               Movimientos = 168

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 I 2 X X X X X X X X X X X X X X X X X X X X X X X 0
0 X 0 X 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 X 0
0 X 0 X X X X X X X X X X X X X 0 0 0 0 0 0 0 0 0 X 0
0 X 0 X 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 X 0
0 X 0 X X X X X X X X X X X X X 0 0 0 2 2 2 2 2 2 X 0
0 X 0 0 0 0 0 0 0 0 0 0 0 0 0 X 0 0 0 2 0 0 0 0 0 X 0
0 X 0 X X X X X X X X X X 0 0 X 0 0 0 0 0 0 0 0 0 X 0
0 X 0 X 0 0 0 0 0 0 0 0 X 0 0 X X X X X X X X X 0 X 0
0 X 0 X X X X X X X 0 0 X 0 0 0 0 0 0 0 0 0 0 X 0 X 0
0 X 0 0 0 0 0 0 0 X 0 0 X X X X X X X X X X X X 0 X 0
0 X X X X X X X 0 X 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 X 0
0 0 0 0 0 0 0 X 0 X 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 X 0
0 0 0 0 0 0 0 X X X 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 X 0
0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 2 2 2 2 2 2 2 2 2 2 X 0
0 2 2 2 2 2 2 2 2 2 2 2 2 0 0 2 0 0 0 0 0 0 0 0 0 X 0
0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 0 X 0 X 0
0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 2 0 X 0 X 0
0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 2 0 X 0 X 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 X X X X X 0
0 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 X 0 0 0 0 0
0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 X X X X X 0
0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 X X 0 0 F 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Presione una tecla para continuar . . .

Process returned 0 (0x0)   execution time : 0.586 s


Observa que de de I y llega a F.

Y el  código que me van a comer y con algunas explicaciones incluidas:


Código (cpp) [Seleccionar]

#include <stdio.h>
#include <stdlib.h>

void mostrar_b(int b[][27]);
void mostrar(char a[][28]);

int main (){
   char a[24][28]={
   "000000000000000000000000000",
   "012222222222222222222222220",
   "020200000000000000000000020",
   "020222222222222200000000020",
   "020200000000000000000000020",
   "020222222222222200022222220",
   "020000000000000200020000020",
   "020222222222200200000000020",
   "020200000000200222222222020",
   "020222222200200000000002020",
   "020000000200222222222222020",
   "022222220200000000000000020",
   "000000020200222222222222220",
   "000000022200200000000000020",
   "000000000000200222222222220",
   "022222222222200200000000020",
   "020000000000000222222202020",
   "020000000000000200000202020",
   "022222222222222200000202020",
   "000000000000000200000222220",
   "020222222222222222222200000",
   "020000000000000000000222220",
   "022222222222222222222220010",
   "000000000000000000000000000"
   };
   int i,j,cont=0;
    int b[24][27];
       for( i=0;i<24;i++) {
           for( j=0;j<27;j++) {
               b[i][j]=(int)(a[i][j]-48);
               if (b[i][j]==0)
                   b[i][j]=9;
       }
   }
   i=1,j=1;
   b[1][1]=3;
   a[i][j]='I';
   //mostrar_b(b);//activalo para ver como se rellena la matriz de numeros
   mostrar (a);
   system ("cls");
   while (1){
//De los cuatro que rodean al b[i][j] tomo uno y comparo los otros tres
       if     (i+1<24 && b[i+1][j]>0 && b[i+1][j]<=b[i-1][j]
                 && b[i+1][j]<=b[i][j-1] && b[i+1][j]<=b[i][j+1]){
               a[i+1][j]='X';     //   en esta condicion
               if (b[i+1][j]==1){ //elijo  hacua ABAJO si es menor o igual
                   a[i+1][j]='F'; //que los otros tres que rodean a b[i][j]
                   break;
               }
               b[i+1][j]++;
               i++;
       }
       else if (j+1<27 && b[i][j+1]>0 && b[i][j+1]<=b[i][j-1]
                 && b[i][j+1]<=b[i-1][j] && b[i][j+1]<=b[i+1][j]){
               a[i][j+1]='X';     //    en esta condicion
               if (b[i][j+1]==1){ //elijo  hacia la DERECHA si es menor o igual
                   a[i][j+1]='F'; //que los otros tres que rodean a b[i][j]
                   break;
               }
               b[i][j+1]++;
               j++;
       }
       else if (i-1>=0 && b[i-1][j]>0 && b[i-1][j]<=b[i+1][j]
                 && b[i-1][j]<=b[i][j-1] && b[i-1][j]<=b[i][j+1]){
               a[i-1][j]='X';     //    en esta condicion
               if (b[i-1][j]==1){ //elijo  hacia la ARRIBA si es menor o igual
                   a[i-1][j]='F'; //que los otros tres que rodean a b[i][j]
                   break;
               }
               b[i-1][j]++;
               i--;
       }
       else if (j-1>0 && b[i][j-1]>0 && b[i][j-1]<=b[i][j+1]
                 && b[i][j-1]<=b[i-1][j] && b[i][j-1]<=b[i+1][j]){
               a[i][j-1]='X';     //    en esta condicion
               if (b[i][j-1]==1){ //elijo  hacia la IZQUIERDA si es menor o igual
                   a[i][j-1]='F';  //que los otros tres que rodean a b[i][j]
                   break;
               }
               b[i][j-1]++;
               if (j-1>0){
               j--;
               }
       }
       //mostrar_b( b);//activalo para ver como se rellena la matriz de numeros
       cont++;//
   }
   printf ("\n\n\t\tMovimientos = %d\n\n",cont);
   mostrar_b(b);//activalo para ver como queda al fimal la matriz de numeros
   mostrar(a);
   return 0;
}

void mostrar_b(int b[][27]){
   system ("cls");
   int i,j;
   for( i=0;i<24;i++) {
       for( j=0;j<27;j++) {
           printf("%d ",b[i][j]);
           fflush(stdout);
       }
       puts("");
   }
   system ("pause");
}

void mostrar(char a[][28]){
   system ("cls");
   int i,j;
   for( i=0;i<24;i++) {
       for( j=0;j<27;j++) {
           printf("%c ",a[i][j]);
           fflush(stdout);
       }
       puts("");
   }
   puts("");
   system ("pause");
}


Mis observaciones respecto al mismo:

* Está poco testeado, apenas una decena de variantes sobre ese laberinto.

* Queda por pulir la presentación final a fin de que sólo salga el camino directo y no los delante y atrás de cuando se queda rodeado por una muralla. Por cierto, observa que aunque eso ocurra saldrá de la misma el solito  ;-) ;-)

* Los cuatro casos son muy semejantes por lo que pienso que podría reducirse el código con una función. Aunque para lo corto que es no se si merece la pena.

* La idea propuesta es la más cortita respecto a otras soluciones que hacían lo mismo pero con más código, incluso me planteo el uso de una sola función para  ambas matrices.

Espero no haberla pifiado demasiado . :silbar: :silbar:

Como he dicho, estoy aún en pañales así que serán bienvenidas correcciones, observaciones y sugerencias y, ¿por qué no?, espero ansiosamente que alguien más haga aportaciones con códigos seguramente mucho más eficientes e ingeniosos que el mío. Se me ocurre con recursividad y esas cosas.

Y ya está. UUUFFFFF....... menudo rollo les he metido.Sorry, nada como tener un ratito de tiempo libre.
:laugh: :laugh:

P.D: Se pueden tener más soluciones cambiando el orden de los if y eslse  .

Saluditos! ..... !!!!        

vangodp

#26
Bueno lo de depurar el código na que decir, por que la razón tiene quien la tiene jaja.
Estoy seguro que el código se puede mejorar, incluyendo el tuyo como bien lo comentas y creo que en su día también lo hice ¡Creo! XD
Al final dejas señalado lo que podías haber mejorado pero no lo has echo por que no te salio lo mismo me pasa jaja. XD
Lo del aleatorio no abro mano XDD. Si no, no seria una búsqueda es mas como una trampa saber el camino ¿no?
Se supone que no sabes el camino, y si llegas a un punto con 3 o mas elecciones¿Que harás, vas hacia el final?  :laugh:
Estoy de acuerdo contigo sobre que cuando entra en un punto sin salida el se queda perdido por lo que comentas.Pero eso tiene solucion ¡Creame!XD
Lo del final si podías ver que no lo hice pero te lo pongo aquí ya que no dejas pasar una XD:

Código (cpp) [Seleccionar]
if( mapa[y][x] == 'F' ){
cout << "TACHANNNN!!!!XDLOLOL";
break;
}


Sobre lo del camino sin salida bien puede ser que si al llegar al final y no encuentra nada, lo rellene con ceros envés de unos, marcando así que ese camino no pueda volver a entrar. XDD

Son fallos tontos los que me estas señalando se lo dije que deje muchas cosas por hacer jeje
La cosa es que por no seguir deje mucho que hacer pero bueno :rolleyes:
No voy a comentar tu código (¡aun!)por que no lo vi, pero lo mirare con lupa jeje.
Sobre el Dev estoy seguro que hay un millón de compiladores mejor, esta el vim vs emacs de toda la vida y un millón de ellos mas y no creas que no los probé todos jaja.
Pero seguiré con el Dev por que me parece muy muy sencillo y me va bien no me gusta que me de chuletas los programas XD.
Me costo como que 2 días hacer este código, no digo escribiéndole ya que eso me tardo unas 3 o 4 horas XD.
Voy a subir una nueva versión con esos problemas arreglados,  por supuesto tendré tu código en cuenta...si puedo aprender algo seguro lo haré ademas pinta muy bien.
Seguro que podemos afinar ese laberinto y hacerle que encuentre la salida muy rápidamente :D
¡Gracias por comentar, eres grande! ;)

leosansan

#27
Cita de: vangodp en 20 Diciembre 2013, 14:24 PM

¡Gracias por comentar, eres grande! ;)


De eso nada, un aficionadillo simplemente. Estoy seguro que en conocimientos del lenguaje me ganas sobrado. En ese aspecto siento envidia sana de rir3760. ¡Que tío más grande!, ese si que domina el C/C++ hasta decir basta. Si no fuera porque ya soy mayor diría aquello que de mayor quiero ser como él.

Pero otra cosa es el ingenio para que afloren ideas simples a problemas aparentemente complicados, como el caso que nos ocupa. Lástima que no se anime mas gente y que aporten nuevas ideas o caminos.


Cita de: vangodp en 20 Diciembre 2013, 14:24 PM
..................................................................
Lo del aleatorio no abro mano XDD. Si no, no seria una búsqueda es mas como una trampa saber el camino ¿no?
Se supone que no sabes el camino, y si llegas a un punto con 3 o mas elecciones¿Que harás, vas hacia el final?  :laugh:
...........................................

Ahí estás lo bueno de mi último código. No parto de un camino predeterminado,sino que voy eligiendo en cada posición la óptima, es más si te fijas en la solución que aporto veras que en uno de los caminos que sigue la X llega a un callejón donde delante arriba y abajo está bloqueada y ¡ voilâ ! se da la vuelta y retrocede sobre sus propios pasos buscando un nuevo camino:

Citar
0 X 0 X 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 X 0 X X X X X X X X X X X X X 0 0 0   <===aki retrocede y luego sube
0 X 0 X 0 0 0 0 0 0 0 0 0 0 0 0 0

 ¿Y como lo hago?. Con lo que ya te comenté de usar a la vez otra matriz con números que según vas pasando por las casillas se incrementan, de manera que en cada movimiento voy seleccionando la posición mas favorable  ;-) ;-) ;-) ¡¡¡ Como me quiero!!!  >:D >:D >:D

Para ver mejor el cómo funciona, activa las líneas del código que te deje marcadas y veras la forma en  que actúa la matriz de números y como se seccionan las casillas. Lo dejé expresamente para ti, ya que supuse te interesaría el tema.

Un fuerte abrazo y Felices Navidades.


Saluditos! ..... !!!!        

vangodp

#28
ok! lo prometo que le echare un ojo. $_$  :P
Pero lo hare con tiempo y detenidamente :D
Y no soy mejor ni mas grande que nadie, creo que 2 mejor que uno :DD
Lo de hacer que aprenda sobre la marcha esta muy bien :D
Otra cosa seria hacer que si reconoce el camino no vuelva a tomar el camino equivocado, eso seria una pasada. XDD
Pronto abriremos una empresa de IA y haremos armas para el ejercito jajaj
Me aguarde :DD
¡Saludos!
   .....CONTINUARA... XD

http://www.youtube.com/watch?v=_FMzr46JZhE

leosansan

#29
Cita de: vangodp en 20 Diciembre 2013, 17:01 PM
ok! lo prometo que le echare un ojo. $_$  :P
.......................................................................
Otra cosa seria hacer que si reconoce el camino no vuelva a tomar el camino equivocado, eso seria una pasada. XDD
..................................................................


Pues es justamente lo que hace el programa. Ejecútalo y lo veras, pero no te olvides de activar las líneas de código que están  desactivadas para verlo. Las desactivo porque una vez comprobado que todo funciona, o al menos eso parece, vaya como un tiro. Recuerda el tiempo de ejecución en hallar el camino de salida y eso a pesar de que recula en un par de ocasiones:

Citar

Process returned 0 (0x0)   execution time : 0.586 s


No está nada mal para un aficionado.

  Felices Navidades y Próspero Año Nuevo.    
Saluditos! ..... !!!!