Wednesday, June 16, 2010

The Origin of the Species

I finished Dinosaur Island managing to exceed the score required to 'win'. Silliosaurus, most majestic of the Imbecephalosaurians thrived on Dinoisland unperturbed by the predators and rocks and only occasionally abandoning their herbivorous tendencies to engage in cannibalism (5th on the high score chart with 315,000 points). This success lead to overpopulation which created an evolutionary pressure that spawned Crazyodon which rose to a level of glory only seen by 3 previous species (4th on the high score chart with 895,750 points).

The breakthrough came when I realised that you could not convert a column, row coordinate system to an (x, y) without first accounting for the fact that in a column row system the direction 'UP' or 'NORTH' corresponds to the negative direction rather than the positive. This wasn't an easy mistake to spot because the column part worked flawlessly and my interface was consistent so the only visible symptom was that plants rarely were where Silliosaurus thought. 

After that bug got straightened out Silliosaurus flew past the 100,000 points required to win but managed to show an alarming tendency towards cannibalism. When two Silliosaurs collide one will die and since they are herbivorous the surviving dinosaur would not gain any calories. Since a new born Silliosaur would start adjacent to its parent and they shared the same path finding algorithm they often collided while hunting the same piece of food. My first attempts at fixing the problem didn't help all that much, I introduced a factor into the decision making code that would make food regions that contained another Silliosaur or that another Silliosaur was moving into less attractive. This factor was just a negative weighting that subtracted a value from the expected profit calculation that I hoped would encourage Silliosaurs to spread out. It did help but not a lot and increasing the weighting over and over didn't improve things a lot. This is when Silliosaurus plateaued at around 300,000.

I decided that I'd need some drastic changes to head off this problem and forked Silliosaurus to create Crazyodon. Crazyodon uses a prescriptive model where there is a strict set of criteria that a plant has to pass before even being considered for its food value. A Crazydon will mark its favourite unclaimed plant and all the plants within a given radius of it off limits to other Crazydon. This had a much more dramatic effect leading to a diverging behaviour where two Crazydons would often go in completely opposite directions. This didn't fix the problem entirely because only destinations were being considered rather than paths so two Crazyodons would still sometimes collide on their way to different regions. This didn't faze me too much as Crazyodon far exceeded my performance expectations and would even lead me to revising my graphical interface.

Crazyodons were so fecund and so good at roaming that they would often leave my (admittedly small) display area. I tried a few automated routines that would progressively zoom out the view when objects were detected outside the bounds. This actually was quite easy to do with pygame but I couldn't find a solution that I was happy with. In the end I implemented proper keyboard event handling to allow the user to pan the screen as well as zoom in and out. Very fancy.

Right now I think I'm dinosaured out for the moment but I hope in a few weeks I might get enthused about creating a carnivorous dino. In the mean time I'm turning my attention back to Xbox 360 forensics.

P.S The Crazyodon run I did to generate the above screenshot ended up scoring 827,000 points and took as long to run as writing this blog post did. Full screenshot here.

No comments:

Post a Comment