icon - innertext javascript
AI simple-JavaScript(usando jQuery para animaciones) (3)
En primer lugar, me gustaría hacerle saber que he estado programando durante algunos años (en su mayoría lenguajes basados en C, desarrollo de iOS, material web, etc.) como un hobby y ahora estoy desarrollando un interés por crear una IA simple (la mayoría la gente comienza con un juego de tic tac toe, sí, pero estoy interesado en hacer algo usando los principios de la programación genetica). La razón por la que me gustaría que los lectores sepan esto es porque agradecería que las respuestas no fueran demasiado complejas (no es demasiado difícil de entender para un niño, ya que todavía no he asistido a cursos universitarios de informática).
Aquí está mi objetivo:
Condiciones
organim: un div CSS
Población: un grupo de organismos (5 o 10).
fuente de alimento: otro CSS div
Proceso
- Se genera una población, cada una parece tener los mismos atributos fenotípicos inicialmente pero difieren en sus habilidades (para esto, velocidad)
- Se genera una sola fuente de alimento (la misma cada vez)
- Después de unos 5 segundos de configuración del entorno (pasos 1 y 2), la población de organismos necesita encontrar una manera de llegar a la fuente de alimentos de manera competitiva
- Solo un organismo puede alcanzar el alimento. Al alcanzarlo, el ambiente se reinicia, excepto el organismo que encontró el alimento que se benefició la vez anterior y su nivel de velocidad podría incrementarse, mientras que los otros que lo hicieron especialmente terrible podrían volverse aún más lentos o terminarse.
- Se repite el proceso; el usuario puede observar los rasgos de la población y ver cuáles están teniendo éxito evolutivamente, etc.
Información Adicional
Como puede ver, los pasos anteriores casi simulan la evolución pero de una manera muy simple (menos condiciones en comparación con las situaciones de la vida real para los animales); Ahora aquí es por qué estoy preguntando aquí: Estoy completamente perdido. Realmente no tengo idea de por dónde empezar (a excepción de la generación de la población, lo más probable es que pueda hacerlo así como hacer que se muevan a través de animaciones de jQuery). Pero ser capaz de atraerlos a una fuente de alimentos es lo que no puedo hacer ahora. Por lo tanto, me gustaría que me ayuden a apuntar en la dirección correcta para esto
Debes dividir tu problema en dos partes:
Parte 1: Los organismos deben poder moverse hacia un punto que usted especifique. Lo que requeriría un temporizador y algunas matemáticas para determinar las coordenadas, debe mover cada organismo para acercarlo un paso más a su objetivo para cada tic del temporizador.
Google debería poder ayudarte a encontrar los cálculos que debes realizar para que esto funcione.
Parte 2: los organismos necesitan seleccionar una fuente de alimento (posiblemente la más cercana) y apuntar a eso, luego usar el método de movimiento descrito en la parte 1.
Para hacer eso, puede almacenar cada uno de sus organismos y fuentes de alimentos en arreglos. Luego, durante cada tic del temporizador, recorre tus organismos y luego dentro de ese bucle, recorre las fuentes de alimentos buscando el más cercano.
Nuevamente, las matemáticas para determinar la distancia entre dos conjuntos de coordenadas se pueden encontrar en Google.
No creo que pueda decir esto más simple de lo que lo hago, pero espero que esto te dé una idea de qué dirección tomar.
Puede ver las diversas implementaciones de Conway''s LIFE para inspirarse. Creo que ya habrás visto algo similar?
Interesante lectura: Autómatas celulares.
Se advierte que esto usa a Raphael para renderizar, y el underscore para el azúcar semántico.
Escribí un programa muy pequeño que cumple con tus requisitos. (Fue divertido).
1 Se genera una población, cada una de las cuales parece poseer inicialmente los mismos atributos fenotípicos pero difieren en sus habilidades (para esto, velocidad).
var Critter = function() {
// default the speed to something random.
this.speed = SPEED + Math.random()*SPEED;
// logic module
var logic = function() { ... }
}
...
// initialize an array of critters.
critters: _.map(_.range(0,COUNT), function() {
return new Critter;
})
Cree una función constructora para su miembro de la población y luego rellene una serie de estos tipos. He asignado un conjunto de recuento de longitud a un conjunto de criaturas. (Cheeky para loop).
Cada critter que crees será similar pero tendrá diferentes habilidades (basadas en Math.random()
) pero contendrán la misma unidad lógica.
2 Se genera una sola fuente de alimento (la misma cada vez)
// trivial Food object.
var Food = function() {
// rectangle with random x, random y, and SIZE as width / height
this.el = paper.rect(Math.random()*WIDTH, Math.random()*HEIGHT, SIZE, SIZE);
};
El constructor de objetos de comida solo coloca un cuadrado al azar en la pantalla
3 Después de unos 5 segundos de configuración del entorno (pasos 1 y 2), la población de organismos necesita encontrar una manera de llegar a la fuente de alimentos de manera competitiva
Configuración del entorno:
_.invoke(this.critters, "start", this.food.el.getBBox(), out_of_bounds);
Para cada critter invocas su método de inicio.
this.start = function(food) {
// create a player (circle);
this.el = paper.circle(Math.random()*WIDTH, Math.random()*HEIGHT, SIZE / 2);
// set an interval to run the logic over and over.
loop = setInterval(_.bind(logic, this, food), 25);
};
Cada critter simplemente se coloca al azar en la pantalla y luego llama su propia lógica una y otra vez en un bucle.
4 Solo un organismo puede alcanzar el alimento. Al alcanzarlo, el ambiente se reinicia, excepto el organismo que encontró el alimento que se benefició la vez anterior y su nivel de velocidad podría incrementarse, mientras que los otros que lo hicieron especialmente terrible podrían volverse aún más lentos o terminarse.
var logic = function(food) {
// if you hit food you win
if (this.el.collision(food)) {
this.win();
}
}
// you won
this.win = function() {
console.log("win");
// increase speed
this.speed += Math.random()*5;
// end round
Game.end();
};
La criatura detectará si tiene la comida en el bucle lógico. Una vez que tiene la comida, llama a su propio método de ganar. Esto termina la ronda de juego actual.
Cuando una criatura gana, obtiene un aumento de velocidad.
El juego se reiniciará solo cuando llames a .end
(después de eliminar todos los bichos actuales)
end: function () {
// tell all critters to end their round
_.invoke(this.critters, "remove");
// remove the food
this.food.el.remove();
// start again !
this.start();
},
5 Se repite el proceso; el usuario puede observar los rasgos de la población y ver cuáles están teniendo éxito evolutivamente, etc.
6 ¿Qué sigue?
- Ajustar números globales y otros números codificados
- Implementar un poco de inteligencia artificial en la función
logic
. - Ir a través de todos los archivos jsfiddles desde / 1 a / 180 y ver cómo se construyó.
- Reclamar que los comentarios no son lo suficientemente detallados.
- Tire mi código y comience de cero ahora que ha visto un ejemplo.
- El código de nacimiento simplemente crea un Critter "básico". No se reproduce a partir de dos bichos existentes y no tiene habilidades adicionales. Esto significa que no hay evolución.
Prima:
Advertencia: el enlace de arriba viaja hacia la comida, pero está haciendo algo mal, creo que hay un bicho peligroso. No creo que me vaya a arreglar eso.
Te explico la lógica de viajar hacia la comida.
// angle between critter and food
var angle = Raphael.angle(
this.el.getBBox().x,
this.el.getBBox().y,
food.x,
food.y) - 135; // the 135 is the default direction (bottom right)
// get a random speed
var rand = Math.random()*this.speed;
// travel towards the food box by rotating your vector by the angle
var points = this.rotateVector([rand, rand], angle);
// move towards the box
this.el.translate(points[0], points[1]);
First rand
crea un vector aleatorio que se ve así:
El Math.random()
determina qué tan lejos / rápido se mueve la criatura. Esto está apuntando hacia la esquina inferior derecha.
Debido a que está apuntando hacia la esquina inferior derecha, tenemos que eliminar 135
grados del ángulo para este vector
Entonces tenemos que calcular el ángulo entre la criatura y la comida. Hacemos esto pasando dos puntos a Raphael.angle
y calcula el ángulo para nosotros.
Ahora tenemos el ángulo y queremos rotar nuestro vector de movimiento en ese ángulo. El vector de movimiento está apuntando hacia arriba (negro) y queremos girarlo por el ángulo a su nueva posición (rojo). En el código esto es this.rotateVector
¡Ahora apuntábamos en la dirección correcta! Solo podemos llamar a this.el.translate(points[0], points[1])