LoveBrains is a simulator of artificial intelligence based on a plugin system. It provides an 2D environment that allows you to create any kind of simulation. The engine uses Artificial Neural Network and Genetic Algorithm with the aim of learning how to get the best score.
##Basic survival plugin: Preview
LoveBrains documentation (doxygen)
In order to compile LoveBrains, this is very simple :
$ mkdir build
$ cd build
$ cmake .. && make
Programming :
-
C++11
-
GCC (C++11)
-
Oriented Object Programming
Concept :
In order to create a simulation, you have to code a plugin. Each plugin must be stored at the root of the directory called "mods". There is an API that allows you to create your own objects, colliders, behaviors and sensors. In fact, each simulation needs some objects. The objects can interact with the environment with the help of the colliders. Each collider has to have a behavior which will modify the object. If you create an object which has an artificial neural network you will need to create sensors. They will give informations about the environment to the neural network and help it to take a decision. A plugin is not simple, you have to think about it before coding it !
This is an example of Makefile that compile the basic survival plugin :
cmake_minimum_required(VERSION 2.6)
# Enable C++ 11
set (CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++")
project ("basic_survival")
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build (Debug or Release)" FORCE)
endif()
set(API_HEADERS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../api/include/)
set(ANNLIB_HEADERS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../api/lib/ANNLibrary/include/)
set(SOURCES_DIR src/)
set(SOURCES ${SOURCES_DIR}/exemple.cc)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${API_HEADERS_DIR} ${ANNLIB_HEADERS_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/GANNEngine/include/)
add_library(${PROJECT_NAME} MODULE ${SOURCES})
# Detect and add SFML
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH})
#Find any version 2.X of SFML
#See the FindSFML.cmake file for additional details and instructions
find_package(SFML 2 REQUIRED network audio graphics window system)
if(SFML_FOUND)
include_directories(${SFML_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} ${SFML_LIBRARIES} ${SFML_DEPENDENCIES})
endif()
target_link_libraries(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/GANNEngine/libGANNEngine.a)
You can compile your own plugin with the same CMakelists.txt.
When you want to code a plugin, you have to add some objects to the simulator. In order to create an object that will be compatible with LoveBrains, it has to inherit from the interface called "IObject" (What is the IObject interface ?).
If you want to create an artificial intelligence, the class has to inherit from the interface called "IBrain" (What is the IBrain interface ?).
// IObject example.
class Food : public Graphics::IObject
{
public:
Food();
~Food();
bool isDead() const;
bool hasBrain() const;
std::string getType() const;
void setPosition(sf::Vector2f const& position);
void setIsDead(bool isDead);
void setElapsedTime(sf::Time& time);
Graphics::IObject *Clone(void);
void Update(void);
private:
bool _dead;
sf::Vector2f _position;
};
// IBrain example.
class AIObject : public Graphics::IBrain
{
public:
AIObject();
~AIObject();
// Graphics::IObject.
bool isDead() const;
bool hasBrain() const;
std::string getType() const;
// Graphics::IBrain.
double getFitness() const;
// Graphics::IObject.
void setPosition(sf::Vector2f const& position);
void setIsDead(bool isDead);
void setElapsedTime(sf::Time& time);
// Graphics::IBrain.
void setFitness(double fitness);
void setBrain(GANN::ANN const& brain);
void setInput(unsigned int index, double value);
Graphics::IObject *Clone(void);
void Update(void);
private:
bool _dead;
double _fitness;
sf::Vector2f _position;
GANN::ANN _brain;
};
The way to create a plugin is very simple. First you have to define a class that inherit from the interface called "IPlugin" (What is the IPlugin interface ?). The plugin will be able to add some objects, colliders and sensors to the objects factory of LoveBrains.
// IPlugin example.
class Plugin : public Plugin::IPlugin
{
public:
Plugin();
~Plugin();
std::vector<Graphics::IObject *>& getObjects(void);
std::vector<Graphics::ICollider *>& getColliders(void);
std::vector<Graphics::ISensor *>& getSensors(void);
private:
};
Be careful ! There is a function that will be needed by LoveBrains in order to create your plugin !
extern "C"
{
Plugin::IPlugin *CreatePlugin(void)
{
// Replace "PluginClass" by your plugin class name.
return (new PluginClass());
}
}
If you want to add your plugin in LoveBrains, it's very simple ! You have to copy your ".so" file at the root of the directory called "mods".
As you can see, there are two files with LoveBrains. First, the simulator configurations file and then the environment configurations file. In this part, I will show you how to set the simulator with its file.
# Simulator Configuration file
# The crossing rate is a characteristic of the genetic algorithm.
# The range is between 0 and 1.
# It will determine the percentage of parent's genes that will be add to the child.
crossing_rate: 0.7
# The mutation rate is a characteristic of the genetic algortihm.
# The range is between 0 and 1.
# It will determine the percentage of chance that has the individual to mutate.
mutation_rate: 0.1
# The selection rate is a characteristic of the genetic algorithm.
# The range is between 0 and 1.
# It will determine the percentage of individuals that will be removed in the next generation.
selection_rate: 0.9
# It will determine the score that we want to reach.
expected_fitness: 10000
# The tournament pool size is a characteristic of the genetic algorithm.
# The range is between 1 and POPULATION_SIZE.
# It will determine the size of pool in the tournament. The tournament will randomly create a pool of pool_size individuals. The engine will take the best individual in this pool and add it to the parents. At the end of the tournament, there is a list of parents that will be used to generate the childs for the next generation.
tournament pool_size: 5
# It will determine how many epochs that you want to do. -1 says to the engine that there is not maximum epochs.
max epochs: -1
# It will determine the interval between each report of the population.
report interval: 10
# It will determine the size of the population. Be careful ! The size of the population means the number of artificial intelligences in the environment. The size of the population has to be the same as the number of artificial intelligences in the environment configurations.
population size: 50
# It will determine the topology of the neural network. Be careful about it, it's in relation with your simulation.
neural network: 2-2-5
# It will determine if the simulator is in "tournament" mode or not.
tournament: false
# It will determine the display mode.
# Values : NONE, 2D
display mode: 2D
# It will determine the activation function for the intern layers of the neural network.
# Value : sigmoid, threshold
activation function: sigmoid
# It will determine the activation function for the output layer of the neural network.
# Values : sigmoid, threshold
outputs activation function: sigmoid
# It will determine the size of the window.
environment size: 1280x720
The environment configurations file provides the informations about the environment. You have to write the type of the object, the number of object in the environment and if it will be generated by the physics engine when one of them dies.
# This is a file that provides objets for the simulation
# type, number of object, generation condition.
# Object of type "basic_food" is given in the basic survival plugin.
basic_food, 60, true
# Object of type "basic_survival_ai" is given in the basic survival plugin.
basic_survival_ai, 50, false
First you have to set the tournament mode in the simulator configurations file. The effect of this option is that LoveBrains will generate some AI with the neural networks given at the root of the directory called "brains". At the end of the simulation, it will create a file "tournament.txt" which contains the score of each AI created with a file.
# Simulator configurations file.
[...]
tournament: true
[...]
You will find an example of plugin in the directory "mods" which is called "basic_survival". It is ready to be compiled and runned in the simulator. You have to move the file "basic_survival.so" at the root of the directory called "mods".
I have coded the basic survival plugin in streaming : click here
LoveBrains by Robin Guillaume is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
Based on a work at https://github.com/cesumilo/LoveBrains.