Genetic algorithm - a way to optimize any function. But, in our case, I was just interested in the principle of its work, a kind of evolution modeling. Well, to evolve yourself.
We have an abstract field in which there are organisms (blue and turquoise cells), food (green) and poison (red).
The creatures have only 64 genes, but you can enter only 10 first.
When a command is executed, each gene is processed, the remainder of its division by 8 is obtained from it, and it will be used when the bot executes a specific command that fits into the original range.
The creation of 8 positions of the head, its position is taken into account when executing commands.
Commands [0, 7] - walking direction.
Commands [8, 15] - direction of rotation.
Commands [16, 23] - the direction of inspection, if he sees poison / food, he eats.
Commands [24, 31] - safe inspection; if he sees poison, he processes into food and eats; if he sees food, he eats.
Commands [32, 39] - direction of safe walking (if there is a wall or other creature ahead, it changes direction).
The execution of commands takes place in a cycle, in which the maximum number of iterations is 10.
Walking teams are the final ones. If the creature has executed the command eight, then the figure eight is added to the iterator of the command execution, and it is increased by one. This is done for more randomness.
The field consists of primitives and, in fact, is a matrix of objects of the base class, which has one of the types Type. The primitive is the base class from which the CreationC class is inherited.
enum Type { Void, Food, Poison, Wall, Crt }; //
Realization of objects:
class Prim { protected: Type _type; int _x; // int _y; int _healthPointChange; // / Color _color; // public: Type GetType(); void SetType(Type); int GetX(); int GetY(); void SetX(int); void SetY(int); Prim(); Prim(Type); ~Prim(); int getHPC(); void setHPC(int); Color& getColor(); void setColor(float, float, float); };
Realization of creatures:
class CreationC : public Prim { enum direction { lU, up, uR, right, rD, dowm, dL, left }; // AreaCLA* _world; // , direction _head; // short int _hp; vector<UNI> _commandList; // UNI _itForCommand; // Prim*** _area; // boost::signal <void()> _eatingFood;// boost::signal <void()> _eatingPoison;// //....................................... void _Step(UNI); // bool _See(UNI); // void _Roll(UNI); // void _AddSlots();// void _Eat(UNI); // bool _isNextCellClose(UNI); // public: void Mutation();//, bool IsAlive();// void Execute();//, short int GetHP(); CreationC(vector<UNI>& gens, AreaCLA*, int x, int y); CreationC(); vector<UNI>& GetCommandList(); ~CreationC(); };
The number of creatures depends on the size of the field, initially, let's say there are N bots, of which N / 8 will remain alive. Mutates N / 32, for more variety (mutants - turquoise).
class AreaCLA { Prim*** _map; int _heigh; // int _width;// UNI _countOfFood; // UNI _countOfPoison;// UNI _FPCount;// CreationC** _crtns; // int _crtnsCount; // int _maxCrtnsCount; int _minCrtnsCount; void _cicle(); // void _refresh(); // - void _Reborn(); // void _delCrt(int, int, int); // public: AreaCLA() ~AreaCLA(); void SetFood(COORD coord); void SetPoison(COORD coord); void SetWall(COORD coord); void SetVoid(COORD coord); void Start(); // void minFood(); // - void minPoison();// - }; void AreaCLA::_cicle() { for (int i = 0; i < _crtnsCount; i++) { if (!_crtns[i]) continue; _crtns[i]->Execute(); // if (!_crtns[i]->IsAlive()) // delCrt(i, _crtns[i]->GetX(), _crtns[i]->GetY()); // <- if (_crtnsCount == this->_minCrtnsCount)// . return; if (_countOfCtrnsChenged) { i--; _countOfCtrnsChenged = 0; continue; } } }
It took about 20 hours to write this code, in between sleep and study. On the exhaust we have a concise program simulating evolution, which is constantly adorning on my desktop: the limit that my little animals reach is interesting.
To whom it is interesting - I attach a link to the githab . Latest version: Evolution 1.0.
Source: https://habr.com/ru/post/317262/
All Articles