Estoy creando un juego de las "Motos de luz". Manejas una moto que deja un rastro de color a su paso y tienes que intentar matar al otro (haciendo que se estrelle contra una pared).
El caso es que quiero crearle una IA, el problema esque siempre que llega a la esquina superior izquierda. Empieza a cabecear de forma rara hasta suicidarse (la amarilla es la maquina):
La funcion que gestiona los movimientos de la maquina es la siguiente:
void InteligenciaArtificial(Vehiculo &Jugador2) { int color; int color2; bool Movido = false; // Si se choca en el eje X if (Jugador2.MovimientoX != 0) // Si se mueve en el eje x { color = getpixel(screen,Jugador2.X+50*Jugador2.MovimientoX, Jugador2.Y); // Comprobamos si hay algun obstaculo if ((color != 0)&& (color != palette_color[15])) { color = getpixel(screen,Jugador2.X, Jugador2.Y+50); color2= getpixel(screen,Jugador2.X, Jugador2.Y-50); if ((color!= 0)&& (color != palette_color[15])&& (color2 != 0)&& (color2!= palette_color[15])) Jugador2.MovimientoY = 1; else Jugador2.MovimientoY = -1; Jugador2.MovimientoX = 0; Movido = true; // return; } } // Si se choca en el eje Y if ((Jugador2.MovimientoY != 0)&& (Movido == false)) { color = getpixel(screen,Jugador2.X, Jugador2.Y+50*Jugador2.MovimientoY); if ((color != 0)&& (color != palette_color[15])) { color = getpixel(screen,Jugador2.X+50, Jugador2.Y); color2= getpixel(screen,Jugador2.X-50, Jugador2.Y); if ((color!= 0)&& (color != palette_color[15])&& (color2 != 0)&& (color2 != palette_color[15])) Jugador2.MovimientoX = 1; else Jugador2.MovimientoX = -1; Jugador2.MovimientoY = 0; Movido = true; //return; } } }
La función GetPixel es una función de la librería gráfica que te devuelve el color de un determinado adyacente. Lo uso para determinar si el siguiente pixel es un obstaculo o solo parte del fondo.
Saludos!
Editado: El límite del ancho de las imágenes es de 500 pixeles, sobrepasar este límite puede descolocar la web e incumple las Normas de la Comunidad, antes de volver a postear por favor revíselas.| AORV
Ya he desarrollado el sistema
Ya he desarrollado el sistema de distancias:
Funciona de maravilla (bueno quitando que lo unico que hace es dar vueltas al campo y que es muy pasiva xD). ¡Muchas gracias! ^^
Mi creacciónes particulares:
http://www.scenebeta.com/noticia/la-serpiente
http://www.scenebeta.com/node/22535
Me alegro que funcione.
El siguiente paso, como en casi toda IA para juegos, es hacer una búsqueda recursiva del arbol de movimientos. Al final, aunque parezca raro, es un algoritmo minimax como podría ser la IA de un juego de ajedrez. En este link por ejemplo te explican una forma de hacerlo en Haskell (es un lenguaje un poco raro pero se entiende el algoritmo). Básicamente la idea es tomar como heurística el número de puntos que controla tu moto, es decir, los puntos a los que llegas antes que el enemigo. Por ejemplo, si tu controlas el 99% del tablero es porque, probablemente, el enemigo esté encerrado. Así que, aunque el algoritmo busque controlar el máximo del tablero, en realidad lo que va a parecer que hace es encerrar al otro.
Saludos.
EDIT: He encontrado un link que te explica un poco mejor el algoritmo. No lo he leido, pero creo que viene a ser lo mismo, solo que más explicado y sin código. Además tienes el Armagetron Advanced, que es opensource, así que le puedes echar un ojo a su IA. Por cierto, si no estás acostumbrado a los algoritmos de búsqueda te recomiendo que antes te metas en wikipedia (por ejemplo) y le eches un ojo a algoritmos de búsqueda (recursividad, algoritmo de fuerza bruta, algoritmo minimax, poda alfa-beta, etc etc) porque sino te va a ser más dificil entenderlo todo.
Dennis Ritchie. Padre de C y cocreador de UNIX.
R.I.P.
Normal.
Es normal que te haga eso, ya que si x<50 && y<50 tiene obstáculos tanto en x como en y, asi que va intentando esquivarlos pero siempre igual: girar a la izquierda, luego a la derecha, luego a la izquierda... La solución más simple es que el giro sea aleatorio:
Es una solución más tonta que la que intentas hacer pero debería funcionar. Ahora bien, yo cambiaría el valor de 50 por algo un poco más pequeño.
Si quieres una solución más inteligente, debes comenzar por implementar una función del tipo:
Que te devuelva, para la posición y dirección del jugador, la distancia a la que está el siguiente obstáculo en píxeles. Esto es solo un simple if y un par de for pero te facilitará las cosas. Así, en la función de InteligenciaArtificial puedes usarla para saber si hay un obstáculo (Obstaculo(jugador)<50), y si lo hay, en qué dirección tendrías que moverte (la dirección que minimice la función Obstáculo).
Por supuesto, no llegaría a ser inteligente ni mucho menos, pero con eso ya tienes para empezar.
Saludos y pregunta si no entiendes algo.
Dennis Ritchie. Padre de C y cocreador de UNIX.
R.I.P.
Más que tonta, es un poco
Más que tonta, es un poco chapucera no? xD
He probado tu solución palabra por palabra (bueno, en vez de hacer un aleatorio con floats lo he hecho con enteros). Siempre hace lo mismo:
Sale, llega al primer obstaculo y va hacia arriba. Llega a la esquina de arriba y da MEDIA VUELTA. Es decir, gira dos veces a la derecha y hace un cambio de sentido. Repite el mismo procedimiento en la esquina inferior izquierda. Cuando llega a la inferior derecha, vuelve a subir y muere.
Lo curioso es que los numeros son aleatorios, luego no debería seguir ese patrón... Los aleatorios deberían funcionar creo yo:
Mirare la solución de las distancias, cuando la tenga te la digo.
PD: El numero 50 es para hacer las pruebas (para ver las maniobras con más antelación).
Editado: El límite del ancho de las imágenes es de 500 pixeles, sobrepasar este límite puede descolocar la web e incumple las Normas de la Comunidad, antes de volver a postear por favor revíselas.| AORV
Mi creacciónes particulares:
http://www.scenebeta.com/noticia/la-serpiente
http://www.scenebeta.com/node/22535
Por curiosidad.
Ya que tienes la otra solución da igual, pero en el código he cometido un error ya que no miro en la posición x-50 ni y-50. Por ejemplo, si va en la dirección x, se mira el punto x+50, y:
Pero que pasa si va en sentido contrario? Creo que es por eso por lo que se da la vuelta, a no ser que te hayas dado cuenta y lo hayas arreglado. En cualquier caso, la otra solución es mejor así que da igual :)
Dennis Ritchie. Padre de C y cocreador de UNIX.
R.I.P.
Si va en sentido contrario,
Si va en sentido contrario, Jugador2.MovimientoX será -1. Y por tanto será x-50 :)
PD: Miro los links y te contesto a lo otro : P
Tienes razón.
La primera vez sí que vi la multiplicación, pero ayer estaba algo empanado xD.
En fin, si tienes algún problema con el algoritmo avisa :)
Dennis Ritchie. Padre de C y cocreador de UNIX.
R.I.P.
Pienso
Que la variable "movido = true" deberia de ir al principio del bloque de la instruccion deñ bloque if..else, ya que es cuando el jugador empieza a moverse, pero sobre tu error, La verdad es que yo no se nada, pero parece que elerror ha de estar dentro del bloque del movimeinto Y.
De todas formas, eso opino.
Manual del Perfecto Votante Para un voto libre y justo!.
TheGCProjects