diff options
author | Paul Oliver <contact@pauloliver.dev> | 2024-02-29 19:20:22 +0100 |
---|---|---|
committer | Paul Oliver <contact@pauloliver.dev> | 2024-02-29 19:20:52 +0100 |
commit | af7e23ab119eba7c0579796abd288c027edabfa9 (patch) | |
tree | fcd18c9405f33bed0e5f706a8a5d249ee3a63201 /include |
Diffstat (limited to 'include')
-rw-r--r-- | include/Agent.hpp | 54 | ||||
-rw-r--r-- | include/App.hpp | 57 | ||||
-rw-r--r-- | include/NR_Utils.hpp | 79 | ||||
-rw-r--r-- | include/Stage.hpp | 44 |
4 files changed, 234 insertions, 0 deletions
diff --git a/include/Agent.hpp b/include/Agent.hpp new file mode 100644 index 0000000..efb95e7 --- /dev/null +++ b/include/Agent.hpp @@ -0,0 +1,54 @@ +#ifndef __AGENT_HPP__ +#define __AGENT_HPP__ + +#include <Stage.hpp> +#include <SFML/Graphics.hpp> +#include <HyperNeat/Organism.hpp> +#include <HyperNeat/NeuralNet.hpp> +#include <HyperNeat/NoveltyMetric.hpp> + +namespace hyperneat { + class NeuralNetPrms; + class Genome; + class Population; +} + +namespace hn = hyperneat; + +class Agent { +public: + void create(Stage& stage); + void recreate(const Stage& stage, bool createNNet); + void setPoints(const Stage& stage, bool passToOrg); + void setBehavior(const Stage& stage); + void update(const Stage& stage, bool withNS); + void drawOn(sf::RenderWindow& surface); + void incrementCheckPoint(Stage& stage); + +private: + double distanceTravelled(const Stage& stage); + float distanceToCheckpoint(const Stage::CheckPoint& cp) const; + + hn::Organism* _organism = nullptr; + bool _isOld = false; + + sf::CircleShape _shape; + b2Body* _body = nullptr; + hn::Vector<sf::Vector2f> _eyeSight; + + const Stage::CheckPoint* _currCheckPoint = nullptr; + const Stage::CheckPoint* _nextCheckPoint = nullptr; + + size_t _completedCircuits = 0; + size_t _lifetime = 0; + double _distance = 0.0; + bool _isOnTrap = false; + + static size_t _currentLifetime; + + friend class ContactListener; + friend class TrapCallback; + friend class App; +}; + +#endif // __AGENT_HPP__ diff --git a/include/App.hpp b/include/App.hpp new file mode 100644 index 0000000..7c58c7b --- /dev/null +++ b/include/App.hpp @@ -0,0 +1,57 @@ +#ifndef __APP_HPP__ +#define __APP_HPP__ + +#include <Stage.hpp> +#include <Agent.hpp> +#include <CppnExplorer.hpp> +#include <HyperNeat/Population.hpp> +#include <HyperNeat/NeuralNetPrms.hpp> +#include <HyperNeat/NoveltyMetric.hpp> +#include <HyperNeat/PopulationPrms.hpp> + +namespace hn = hyperneat; + +class App { +public: + int startup(); + int execute(); + void update(); + void draw(); + void shutdown(); + +private: + bool _draw = true; + bool _runningWOGfx = true; + bool _isPaused = true; + bool _isVSyncEnabled = true; + + sf::RenderWindow _window; + + Stage _stage; + hn::Vector<Agent> _agents; + ssize_t _selectedIdx = -1; + sf::Clock _clock; + sf::Clock _globalClock; + float _secondsToRun = 0.0f; + sf::CircleShape _champ; + sf::CircleShape _selected; + + hn::CppnExplorer _cppnEx; + + sf::Font _font; + + sf::Text _updates; + sf::Text _champFitness; + sf::Text _avergFitness; + + hn::NeuralNetPrms _nnPrms; + hn::PopulationPrms _popPrms; + hn::Population _population; + + bool _doNoveltySearch = false; + size_t _completedCircuits = 0; + hn::NoveltyMetricPrms _noveltyPrms; + hn::Vector<sf::CircleShape> _noveltyMarks; +}; + +#endif // __APP_HPP__ diff --git a/include/NR_Utils.hpp b/include/NR_Utils.hpp new file mode 100644 index 0000000..3f4c84e --- /dev/null +++ b/include/NR_Utils.hpp @@ -0,0 +1,79 @@ +#ifndef __NR_UTILS_HPP__ +#define __NR_UTILS_HPP__ + +#include <sstream> + +#include <Box2D.h> +#include <SFML/Graphics.hpp> + +constexpr double PI = 3.14159265; +constexpr double IN_RADIANS = 180.0 / PI; +constexpr double IN_DEGREES = PI / 180.0; + +const sf::Uint32 AGENT_RAD = 5; +const sf::Uint32 AGENT_RES = 16; +constexpr float AGENT_SIGHT = 100.0f; +constexpr float AGENT_SPEED = 500.0f; +const sf::Color AGENT_COLOR = { 128, 0, 255, 128 }; +const sf::Color SIGHT_COLOR = { 128, 128, 128, 32 }; +const sf::Color CHAMP_COLOR = { 204, 153, 255 }; +const sf::Color SELECTED_COLOR = { 204, 53, 55 }; +const sf::Color WALL_COLOR = { 204, 153, 255 }; +const sf::Color FACTORY_COLOR = { 204, 153, 255 }; +const sf::Color TEXT_COLOR = { 204, 153, 255 }; +const sf::Color CHECKPNT_COLOR = { 128, 128, 128, 128 }; +const sf::Color BG_COLOR = { 16, 0, 32 }; + +const float _TIME_STEP = 1.0f / 60.0f; +const int32 _VEL_ITERS = 6; +const int32 _POS_ITERS = 2; + +const sf::Uint32 WIN_SIZE = 600; +const sf::VideoMode VIDEO_MODE = sf::VideoMode(WIN_SIZE, WIN_SIZE); +const sf::String WIN_TITLE = "NeuroRacers v0.1"; +const sf::Uint32 WIN_STYLE = sf::Style::Close; +const sf::ContextSettings WIN_SETTINGS = sf::ContextSettings(0, 0, 4); + +ssize_t pMod(ssize_t n, ssize_t d); +float dist(const b2Vec2& a, const b2Vec2 b); +float dotP(const b2Vec2& a, const b2Vec2 b); + +class RayCastCallback : public b2RayCastCallback { +public: + float32 ReportFixture(b2Fixture* fixture, const b2Vec2& point, const b2Vec2& normal, float32 fraction); + + const b2Fixture* _fixture = nullptr; + float32 _fraction = 0.0f; +}; + +class QueryCallback : public b2QueryCallback { +public: + bool ReportFixture(b2Fixture* fixture); + + const b2Fixture* _fixture = nullptr; +}; + +class TrapCallback : public b2QueryCallback { +public: + bool ReportFixture(b2Fixture* fixture); + + const b2Fixture* _fixture = nullptr; +}; + +class Stage; +class ContactListener : public b2ContactListener { +public: + void BeginContact(b2Contact* contact); + + Stage* _stage = nullptr; +}; + +template <typename T> +std::string toString(const T& value) +{ + std::stringstream stream; + stream << value; + return stream.str(); +} + +#endif // __NR_UTILS_HPP__ diff --git a/include/Stage.hpp b/include/Stage.hpp new file mode 100644 index 0000000..aef99e3 --- /dev/null +++ b/include/Stage.hpp @@ -0,0 +1,44 @@ +#ifndef __STAGE_HPP__ +#define __STAGE_HPP__ + +#include <fstream> +#include <iostream> + +#include <NR_Utils.hpp> +#include <Hyperneat/Utils/Vector.hpp> + +namespace hn = hyperneat; + +class Stage { +public: + int load(const std::string& fileName); + void update(); + void drawOn(sf::RenderWindow& surface) const; + +private: + class CheckPoint { + public: + void calculateSegment(const CheckPoint& prev); + + sf::VertexArray _line = sf::VertexArray(sf::Lines); + double _value = 0.0; + double _segment = 0.0; + b2Body* _body = nullptr; + }; + + b2World _world = { { 0.0f, 0.0f } }; + ContactListener _listener; + + hn::Vector<sf::VertexArray> _walls; + hn::Vector<b2Body*> _wallBodies; + hn::Vector<b2AABB> _traps; + hn::Vector<sf::RectangleShape> _trapRects; + hn::Vector<CheckPoint> _checkPoints; + + sf::CircleShape _factory = sf::CircleShape(AGENT_RAD + 2, AGENT_RES); + + friend class App; + friend class Agent; +}; + +#endif // __STAGE_HPP__ |