Evolution of Bugs

This is a small program meant to simulate the evolution of bugs. Black tiles are empty space and white tiles are walls that bugs cannot go through. The colored tiles represent bugs and the orange tiles are crumbs that the bugs can eat, which appear at random throughout the simulation. Bugs all need to eat, so weak bugs die of starvation. This allows the better species to survive and mutate, simulating evolution. The bugs only evolve through how they think.

Mind of a Bug

The bugs have simple minds which are state machines so they can remember one thing, an integer from 0 to 7 (their state). They can choose what they do based on their state, what they see, and a random number. Their mind is represented as two 3D tables of numbers which are used as lookup tables to figure out what the bug will do in a certain situation and what it will store in its memory. The bugs can only do a few simple things: These simple things allow the bugs to learn through trial and error. The way they learn is described in the next section.

Evolution

The smarter bugs eat, survive and clone, but the clones are slightly different than the original bug (Each cell in the bug's lookup tables has a 1% chance of changing to a new random value). The smarter clones survive and create their own clones, whereas the weaker clones die and never reproduce, causing the smartest bugs to be the ones that survive.
Crumbs are the food that allows the bugs to survive and clone. The crumbs are distributed equally to all places on the board at the beginning of the simulation. But, while the simulation is running, more food appears near the bottom than at the top.
I noticed that at the beginning of the game most bugs are stupid, staying in the same place or avoiding food, but later on the bugs get more interesting and learn very good strategies to survive.

Graph of Bugs over Time

After looking at the bugs for some time, I began graphing the amount of bugs over the period of about 1 hour, though I sped up the simulation speed to 32x faster so I only needed to wait about 2 minutes.
At the beginning of the game there were about 150 bugs added to the board. Then, at 33 seconds in (1000 ticks), all the bugs that didn't eat died of starvation, which causes the amount of bugs to drop to about 30. After that, the bugs on the board should only be the ones that had learned to eat, so the bugs that also learned to clone are the ones that bring the bug population back up to about 50. From then on, the amount of bugs is relatively stable because the amount of food that the bugs eat is at the maximum for the bugs to survive.
In older versions where cloning was easier, the bugs would eat almost all the food, clone a lot, and have a happy time. Then, the food would run out and many bugs would starve. This same problem still has some effect in the current version.

Immortal Bugs

Midway through coding this and before bugs could reproduce, evolve or even eat, I found that certain bugs would stick themselves against walls and become immortal. I was very confused. Without being able to eat, bugs should only have been able to live for about 33 seconds, but these bugs had survived for over a minute. Eventually, I found the issue. Here is how the bugs were simulated when moving forward:
  1. Make the bug get more hungry
  2. If the bug is too hungry, it is removed from the board to simulate death but the bug can do one last thing when it is not on the board anymore
  3. Move forward
    1. Remove the bug from the board
    2. If the bug can move forward, add the bug to the board in front of it's old position. If it is blocked, place the bug back on the board in it's old position
The problem was that the bug would be removed from the board to simulate dying of starvation, but because it could do one more thing, it banged into a wall and was added back onto the board right where it had been. I was outsmarted by the bugs.

Bug Species

The color of the bugs represent the bug's species. Similar colors of bug mean similar species (they think in similar ways). The color is actually a simhash of the bug's mental lookup tables. To calculate the color of a bug, the bug's lookup tables are assembled into a list of numbers, which is then split into 8 vectors. The dot product of each vector is calculated with the global random vector, a vector that is always the same. The sign of each dot product is used as a bit in the final simhash of the bug which is a 16-bit integer. The algorithm is shown below with h representing the simhash, v representing the vector of the bug's mind, and g representing the global random vector.
h =
([v1, v2, v3, …] · g > 0)
+ ([v24, v25, v26, …] · g > 0) × 2
+ ([v48, v49, v50, …] · g > 0) × 22
+ ([v72, v73, v74, …] · g > 0) × 23
Note: The two lookup tables are both 8 bit simhashes, so to generate the single 16 bit simhash, they are joined.