📜 ⬆️ ⬇️

Development of a simulator of the evolution of single-celled organisms "The strongest survives"


In this post, I will tell you about my experience of writing a simulation game of the evolution of unicellular organisms on a rectangular plane. In addition to the development of algorithms for the simulator, we will discuss the problems I encountered while developing this project in C #, as well as porting it to work in the browser. At the end of the article there will be a link to the version ready for the game and all the sources. If I am interested in you - I ask for cat.

Inspiration


Before we get started - I want to briefly tell about the projects that inspired me to write this simulator. The first analogy you could spend on the screenshot in the header of the post, because my project looks quite like the game "Life" , invented by the mathematician John Convom in 1970. I was more inspired by this and this article of other habouriors. In order not to chase the respected reader by reference, I will briefly describe what is being said in these articles: the first is the modification of Conway’s game with the addition of natural selection, and the second is the simulation of intelligent life based on neural networks.

Determination of requirements


I didn’t want to write another clone of the game “Life”, and I liked the idea of ​​natural selection so much that I decided to concentrate on evolution. The name came of itself - “The strongest survives”.

Here are the requirements that I set myself when developing:
')

In TSS, cells have many indicators on which their next state depends. They can analyze the environment and make decisions based on these data that will help them survive. Their priorities when viewing the surroundings are affected by modifiers recorded in the genome. For example, there is a parameter aggression. When a cell sees another cell with a foreign genome, it adds to the desire to move in that direction this modifier (aggression). It’s the same with hunger, collectivity, poison and dead cells. After calculations, the side with the highest amount of modifiers is selected.

The basic rules of the game :



A cell can make one move every tick. More precisely, it examines the area around, as shown in the picture and selects the priority direction: up, down, left, right, or stand still.

Also the cell can multiply. Reproduction occurs by dividing, once per tick, if the cell has enough energy. At the same time, there should be an empty space nearby, where a new cell with the same genome is created, or a cell with a mutated genome. At the same time, its energy level is divided equally between the parent and daughter cells. The level of energy required for reproduction is determined by the user, but the “reproductiveness” parameter acts as a modifier. This parameter is stored in the genome. The higher it is - the less energy the cage needs for reproduction.


Somehow I imagined this game at the time. In general, something like that happened.

The essence of the gameplay


The gameplay is that the user is provided with an editor for the constants of the universe, in which he can change the habitat conditions of the organisms and watch how they adapt. It does not sound very impressive, but there are quite a few values ​​available to the player (about 30), changing which you can get a lot of unique variations of the result. You can read more about each constant in the manual in the game folder or under the spoiler.

Constants of the universe
MaxCountOfCellTypes - the maximum number of cell genomes.

Mutation_Enable - allows you to enable or disable cell mutation during reproduction.

Mutation_AttackChildrenMutantsOfFirstGeneration — if this property is disabled, the cells cannot attack their first-generation descendants when they mutate.

Mutation_AttackParentIfCellIsYouMutant - if this property is disabled, the mutated cells can not attack their ancestors of the first generation.

Mutation_ChangedValuesAtOne - shows how many times the values ​​that are responsible for the behavior of cells change during each mutation. For example, if the value is 10, then 10 times will be selected and changed to 1 random property of the cell responsible for the behavior. It can be from 1 to 200.

Mutation_ChancePercent - the chance of a mutation during reproduction.

CellAge_Max - the maximum age of the cell.

CellAge_AdultCell is the age of an adult cell. In cells of children, the level of aggression is no higher than CellGenome_Child_Aggression and they cannot reproduce.

EnergyLevel_CreatingCell - the energy level of the cells, when they are generated at the start.

EnergyLevel_NeededForReproduction - the level of energy at which a cell can multiply. May vary due to CellGenome_ReproductionRange.

EnergyLevel_MaxForCell is the maximum energy level that a cell can accumulate.

EnergyLevel_DeadCell - the energy level obtained from dead cells.

EnergyLevel_DefFood - energy level obtained from food.

EnergyLevel_PoisonedFood - energy level obtained from the poison.

EnergyLevel_MovesFriendly - the energy level received by the cell when a relative moves toward it or it moves toward it. As a rule, it is much less than the energy level of an ordinary meal. Promotes the creation of colonies.

EnergyLevel_MovesAggression - shows how much energy a cell takes from alien cells during an attack.

CellsCount_MaxWithOneType - the maximum number of cells on the field with the same genome.

CellGenome_Child_Aggression - the level of aggression in the cells of children.

CellsCount_MaxAtField - the maximum number of cells per field.

EnergyEntropyPerSecond - the level of energy that a cell loses at each tick.

Special_FoodCountForTick - the amount of food generated with each tick of the universe.

Special_PoisonCountForTick - the amount of poison generated with each tick of the universe.

CellGenome_HungerRange - the range of hunger values ​​during cell generation.

CellGenome_AggressionRange - the range of aggression values ​​during cell generation.

CellGenome_ReproductionRange - the range of values ​​of reproduction during cell generation. The higher the value, the less energy the cage needs for reproduction.

CellGenome_FriendlyRange - the range of values ​​of collectivity during cell generation.

CellGenome_PoisonRange - the range of values ​​of craving for poison when a cell is generated. Usually negative.

CellGenome_CorpseRange - the range of values ​​for craving for dead cells when a cell is generated.

This is what the editor looks like in the web version.


And in the Windows version, you can also edit the place where food or poison is generated.

Development and result


As a result of several months of development, I wrote 4 versions of my game. The first two are for testing and debugging the logic of the simulator universe, the third is a release version for Windows, the fourth is a version for browsers. Now I will quickly run through the first two and later I will talk about the features of the main versions.

WindowsForms version



This is the first working version of my program. This version has not yet implemented most of the game logic and it has many bugs. Rendering is not here, everything is displayed in the text field in the form of characters. Such a textual output worked very slowly (1-2 ticks per second), but, nevertheless, there is something tube in it.

Text console version



Oddly enough - the second version of the program. I wrote it for the laboratory. In this and subsequent versions, the game logic is identical.

WPF version



I spent the most time on this version, but it is the most elaborated one. Rendering frames here takes 20-30 ms and does not depend on the size of the field, and the tick itself is processed fairly quickly. The user can create a huge playing field (at least 2000x2000 cells). It is possible to view information about each cell, just by clicking on it.
Demonstration of the program.


When writing this version of my project I had to solve many problems. I will describe the most memorable decisions here.

1) Manual rendering . Since I decided to write a bicycle - I did the drawing without the engine, using standard WPF tools for drawing primitives. But this allowed me to optimize the rendering as much as possible under my program.

When I just started drawing, the entire canvas was redrawn from scratch with each frame, which was very good for performance. But then I wrote an algorithm that kept the last frame in the buffer and when drawing a new one - I painted over the places where the objects were, but now they don’t, and on the place where they appeared, I drew an object. I don’t know how fast it would work on the engine, but here the productivity has increased significantly and ceased to depend on the size of the field.
The lack of the engine also simplified porting to the browser, where I used the same algorithm.

But in this way there are also disadvantages - often there are noise on the image, this is especially noticeable in the WPF version.

2) Dynamic Class Editor . In order not to alter the form a hundred times, on which the edit fields of the universe settings were displayed, I used reflection and wrote a dynamic editor that read the fields of the transmitted object (in this case, an object with settings) and built a form to edit them.


This is how this editor looked like in the WPF version.

Web version


Some time after writing the WPF version, I wanted to port it to the browser. You can see the result in the header of the article, or by going to the site personally and trying it.

I knew a bit of Javascript, but I didn’t want to rewrite a half thousand lines of game logic code on it. But there was a solution - I decided to use Bridge.NET, an open C # compiler in Javascript. Yes, dear reader, you understood everything correctly - now we write under the browser in C #. Thanks to this compiler, I was able to use a language that I knew well. It only remained to rewrite the rendering and the rest of the code associated with the display. Due to lavascript Javascript , the web version is less functional than the Windows version, but serves as a good demonstration of the operation of the simulator.

It is fair to say that, nevertheless, knowledge of Javascript and HTML was very useful to me due to the peculiarities of the browsers.

Results


In developing this project, I strongly pulled my programming skills in general. At the moment, all versions of the game are available on this site tss-game.cc.ua . If you yourself want to start developing or just see the code - this is my github , here you can find all versions of my program with extensive comments. I hope you were interested in reading about my experience, perhaps this article will inspire you to something similar, as other articles inspired me in my time.

Source: https://habr.com/ru/post/327792/


All Articles