Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><a href="http://jsfiddle.net/Raynos/D3mVX/182/" rel="nofollow noreferrer">Live Example</a></p> <p>Be warned this uses <a href="http://raphaeljs.com/" rel="nofollow noreferrer">Raphael</a> for rendering, and <a href="http://documentcloud.github.com/underscore/" rel="nofollow noreferrer">underscore</a> for semantic sugar.</p> <p>I wrote a very small program that kind of meets your requirements. (It was fun). </p> <blockquote> <p>1 A population is generated, each appearing to possess the same phenotypic attributes initially but differ in their skills (for this, speed).</p> </blockquote> <pre><code>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; }) </code></pre> <p>Create a constructor function for your population member then populate an array of these guys. I've mapped an array of length count to an array of critters. (Cheeky for loop).</p> <p>Each critter you create will be similar but have different skills (based on <code>Math.random()</code>) but they will contain the same logic unit.</p> <blockquote> <p>2 A single food source is generated (the same each time)</p> </blockquote> <pre><code>// 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); }; </code></pre> <p>The food object constructor just places a square randomly on the screen</p> <blockquote> <p>3 After about 5 seconds of the environment being set up (steps 1 and 2), the population of organisms need to find a way to get to the food source competitively</p> </blockquote> <p>Setting the environment up:</p> <p><code>_.invoke(this.critters, "start", this.food.el.getBBox(), out_of_bounds);</code></p> <p>For each critter you invoke their start method.</p> <pre><code>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); }; </code></pre> <p>Each critter simply places itself randomly on the screen then calls its own logic over and over in a loop.</p> <blockquote> <p>4 Only one organism may reach the food item. Upon reaching it, the environment is reset except the organism who found the food item the previous time is now benefitted and its speed level might increment while the others who did particularly terrible may get even slower or be terminated</p> </blockquote> <pre><code>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(); }; </code></pre> <p>The critter will detect whether it has the food in the logic loop. Once it has the food it calls its own win method. This ends the current game round. </p> <p>When a critter wins it gets a speed boost. </p> <p>The game will restart itself when you call <code>.end</code> (after removing all current critters)</p> <pre><code>end: function () { // tell all critters to end their round _.invoke(this.critters, "remove"); // remove the food this.food.el.remove(); // start again ! this.start(); }, </code></pre> <blockquote> <p>5 Process is repeated; the user may observe the traits of the population and see which ones are succeeding evolutionarily, etc.</p> </blockquote> <p><a href="http://jsfiddle.net/Raynos/D3mVX/182/" rel="nofollow noreferrer">Watch the live example :)</a></p> <p><strong>6 What's next:</strong></p> <ul> <li>Tweak global numbers and other hard coded numbers</li> <li>Implement some AI in the <code>logic</code> function. </li> <li>Go through all the jsfiddles from /1 to /180 and see how it was build up.</li> <li>Complain that comments are not detailed enough</li> <li>Throw my code away and start from scratch now that you've seen an example.</li> <li>The birth code just creates a "basic" Critter. It doesn't breed from two existing critters and doesn't have increased skills. This means no evolution.</li> </ul> <p><strong>Bonus:</strong></p> <p><a href="http://jsfiddle.net/Raynos/D3mVX/181/" rel="nofollow noreferrer">Travels towards food</a></p> <p><strong>Warning:</strong> The above link does travel towards the food but it's doing something wrong, there's a dodgy bug in there I think. I don't think I'll get round to fixing that.</p> <p>I'll explain the logic to travel towards the food</p> <pre><code> // 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]); </code></pre> <p>First <code>rand</code> creates a random vector that looks like this:</p> <p><img src="https://i.stack.imgur.com/QOP3e.png" alt="enter image description here"></p> <p>The <code>Math.random()</code> determines how far / fast the critter moves. This is pointing towards the bottom right corner. </p> <p>Because it's pointing towards bottom right corner we have to remove <code>135</code> degrees from the angle for this vector</p> <p><img src="https://i.stack.imgur.com/UENXc.gif" alt="enter image description here"></p> <p>We then have to calculate the angle between the critter and the food. We do this by passing in two points to <code>Raphael.angle</code> and it calculates the angle for us.</p> <p><img src="https://i.stack.imgur.com/BBjKN.gif" alt="enter image description here"></p> <p>Now we have the angle and we want to rotate our movement vector by that angle. The movement vector is currently pointing up (black) and we want to rotate it by the angle to it's new position (red). In the code this is <code>this.rotateVector</code></p> <p><img src="https://i.stack.imgur.com/oZoUO.gif" alt="enter image description here"></p> <p>Now were pointing in the right direction ! We can just call <code>this.el.translate(points[0], points[1])</code></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload