From 70ec00285128f8f9f5fa0e848950212e6a235d43 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Fri, 14 Aug 2015 22:12:56 +0200 Subject: Added missing sensors --- src/brain/neural_network.cpp | 81 +++++++++++++++++++++----------------------- src/brain/neuron.cpp | 7 ++-- src/building.cpp | 6 ++++ src/game_state.cpp | 77 ++++++++++++++++++++++++++++++++++++----- src/spacebot.cpp | 6 ++-- 5 files changed, 118 insertions(+), 59 deletions(-) create mode 100644 src/building.cpp (limited to 'src') diff --git a/src/brain/neural_network.cpp b/src/brain/neural_network.cpp index d6a5e15..9061194 100644 --- a/src/brain/neural_network.cpp +++ b/src/brain/neural_network.cpp @@ -1,5 +1,6 @@ #include "brain/neural_network.h" #include "brain/neuron.h" +#include NeuralNetwork::NeuralNetwork(std::istream &&networkConfigFile, int numberOfSensors, int numberOfOutputs) { @@ -11,7 +12,9 @@ NeuralNetwork::NeuralNetwork(std::istream &&networkConfigFile, int numberOfSenso } for (int i=0; i(i); + auto output = std::make_shared(i); + _outputs.push_back(output); + _neurons[i] = output; } parseFile(std::move(networkConfigFile)); @@ -21,15 +24,17 @@ NeuralNetwork::NeuralNetwork(std::istream &&networkConfigFile, std::vector { _biasNode = std::make_shared(); - for (int i=0; i(i); - sensor->setActivation(sensorInitialValues.at(i) ? 1 : 0); + sensor->setActivation(sensorInitialValues[i] ? 1 : 0); _sensors[i] = sensor; } for (int i=0; i(i); + auto output = std::make_shared(i); + _outputs.push_back(output); + _neurons[i] = output; } parseFile(std::move(networkConfigFile)); @@ -38,14 +43,18 @@ NeuralNetwork::NeuralNetwork(std::istream &&networkConfigFile, std::vector void NeuralNetwork::parseFile(std::istream &&file) { double weight; - for (std::string src, dest; - file >> src && file >> dest && file >> weight; ) - { - char srcType = src.at(0); - int srcId = std::stoi(src.substr(1)); - char destType = dest.at(0); - int destId = std::stoi(dest.substr(1)); + char srcType; + int srcId; + int destId; + while (file.get(srcType) && + file >> srcId && + file.ignore(std::numeric_limits::max(), 'n') && + file >> destId && + file >> weight && + file.ignore(std::numeric_limits::max(), '\n')) + { + std::shared_ptr source; std::shared_ptr destination; switch (srcType) @@ -56,21 +65,11 @@ void NeuralNetwork::parseFile(std::istream &&file) case 'b': source = _biasNode; break; - case 'n': - source = findOrAddNeuron(srcId); - break; default: - throw 1; - } - switch (destType) - { - case 'n': - destination = findOrAddNeuron(destId); - break; - default: - throw 1; + source = findOrAddNeuron(srcId); } - + destination = findOrAddNeuron(destId); + addLink(source, destination, weight); } @@ -78,34 +77,30 @@ void NeuralNetwork::parseFile(std::istream &&file) void NeuralNetwork::addLink(std::shared_ptr source, std::shared_ptr destination, double weight) { - auto link = std::make_shared(source, weight); - destination->addInput(link); + std::unique_ptr link(new NeuralLink(source, weight)); + destination->addInput(std::move(link)); } std::shared_ptr NeuralNetwork::findOrAddSensor(int id) { - bool sensorExists = _sensors.count(id) > 0; - if (!sensorExists) + auto sensor = _sensors[id]; + if (!sensor) { - _sensors[id] = std::make_shared(id); + sensor = std::make_shared(id); + _sensors[id] = sensor; } - return _sensors.at(id); + return sensor; } std::shared_ptr NeuralNetwork::findOrAddNeuron(int id) { - bool isOutput = _outputs.count(id) > 0; - if (isOutput) - { - return _outputs.at(id); - } - - bool hiddenNeuronExists = _hiddenNodes.count(id) > 0; - if (!hiddenNeuronExists) + auto neuron = _neurons[id]; + if (!neuron) { - _hiddenNodes[id] = std::make_shared(id); + neuron = std::make_shared(id); + _neurons[id] = neuron; } - return _hiddenNodes.at(id); + return neuron; } void NeuralNetwork::setInput(int inputIndex, double activation) @@ -117,13 +112,13 @@ int NeuralNetwork::findMaxOutputIndex() const { double currentMaxActivation = 0; int currentMaxIndex = 0; - for (std::pair> outputPair : _outputs) + for (unsigned int i=0; i<_outputs.size(); ++i) { - double activation = outputPair.second->activation(); + double activation = _outputs[i]->activation(); if (activation >= currentMaxActivation) { currentMaxActivation = activation; - currentMaxIndex = outputPair.first; + currentMaxIndex = i; } } return currentMaxIndex; diff --git a/src/brain/neuron.cpp b/src/brain/neuron.cpp index 7ea02c6..527e7da 100644 --- a/src/brain/neuron.cpp +++ b/src/brain/neuron.cpp @@ -9,21 +9,20 @@ Neuron::Neuron(int id) double Neuron::sigmoid(double input) const { double slope = 4.924273; - double constant = 2.4621365; return (1/(1+(std::exp(-(slope*input))))); } double Neuron::activation() const { double activationSum = 0; - for (auto link : _inputLinks) + for (auto const& link : _inputLinks) { activationSum += link->weightedActivation(); } return sigmoid(activationSum); } -void Neuron::addInput(std::shared_ptr link) +void Neuron::addInput(std::unique_ptr&& link) { - _inputLinks.push_back(link); + _inputLinks.push_back(std::move(link)); } diff --git a/src/building.cpp b/src/building.cpp new file mode 100644 index 0000000..8da322d --- /dev/null +++ b/src/building.cpp @@ -0,0 +1,6 @@ +#include "building.h" + +Building::Building(int x, int y) + :GameEntity(x, y) +{ +} diff --git a/src/game_state.cpp b/src/game_state.cpp index a302bfc..eb02005 100644 --- a/src/game_state.cpp +++ b/src/game_state.cpp @@ -3,6 +3,7 @@ #include #include #include +#include const int OPENING_LINES = 6; const int GAME_AREA_LINES = 25; @@ -65,25 +66,31 @@ int GameState::addEntity(int x, int y, char type) case Spaceship::PLAYER_MAP_CHAR: _playerSpaceship = std::unique_ptr(new Spaceship(x+1, y)); return 3; + case Building::MISSILE_CONTROLLER_CHAR: + _missileControllers.push_back(Building(x+1, y)); + return 3; + case Building::ALIEN_FACTORY_CHAR: + _alienFactories.push_back(Building(x+1, y)); + return 3; } return 1; } -void GameState::logState() +void GameState::logState() const { - for (auto alien : _aliens) + for (auto const& alien : _aliens) { std::cout << "Alien " << alien.coords() << std::endl; } - for (auto bullet : _bullets) + for (auto const& bullet : _bullets) { std::cout << "Enemy Bullet" << bullet.coords() << std::endl; } - for (auto missile : _missiles) + for (auto const& missile : _missiles) { std::cout << "Player Missile" << missile.coords() << std::endl; } - for (auto shield : _shields) + for (auto const& shield : _shields) { std::cout << "Shield" << shield.coords() << std::endl; } @@ -129,7 +136,7 @@ int getRectangularOffset(int width, int x, int y) std::vector GameState::toBitArray() const { - std::vector result(171); + std::vector result(172); int alienOffset = 0; //Aliens are 0 to 100 int bulletOffset = 101; //Bullets are 101 to 135 @@ -147,7 +154,7 @@ std::vector GameState::toBitArray() const } - for (auto alien : _aliens) + for (auto const& alien : _aliens) { if (alien.y() >= playerY || alien.y() < playerY-9) { @@ -157,7 +164,7 @@ std::vector GameState::toBitArray() const result.at(alienOffset + getPyramidOffset(3, alien.x()-playerX, playerY-1-alien.y(), 99, 100)) = true; } - for (auto bullet : _bullets) + for (auto const& bullet : _bullets) { if (bullet.y() >= playerY || bullet.y() < playerY-5 || bullet.x() > playerX+3 || bullet.x() < playerX-3) { @@ -166,6 +173,60 @@ std::vector GameState::toBitArray() const result.at(bulletOffset + getRectangularOffset(7, bullet.x()-playerX, playerY-1-bullet.y())) = true; } + + for (auto const& shield : _shields) + { + if (shield.y() < playerY-3 || shield.x() < playerX-2 || shield.x() > playerX+2) + { + continue; + } + + result.at(shieldOffset + getRectangularOffset(5, shield.x()-playerX, playerY-1-shield.y())) = true; + } + + if (_missiles.size() > 0) + { + result.at(missileOffset) = true; + } + if (_missiles.size() < 1) + { + result.at(missileOffset + 1) = true; + } + + if (_playerSpaceship) + { + result.at(positionOffset + playerX-2) = true; + } + + result.at(canBuildOffset) = true; + for (auto const& missileController : _missileControllers) + { + if (missileController.y() < playerY) + { + continue; + } + result.at(existingBuildingsOffset + 0) = true; + if (_missiles.size() < 2) + { + result.at(missileOffset+1) = true; + } + if (abs(missileController.x() - playerX) < 3) + { + result.at(canBuildOffset) = false; + } + } + for (auto const& alienFactory : _alienFactories) + { + if (alienFactory.y() < playerY) + { + continue; + } + result.at(existingBuildingsOffset + 1) = true; + if (abs(alienFactory.x() - playerX) < 3) + { + result.at(canBuildOffset) = false; + } + } return result; } diff --git a/src/spacebot.cpp b/src/spacebot.cpp index 23cce0c..15f2221 100644 --- a/src/spacebot.cpp +++ b/src/spacebot.cpp @@ -20,14 +20,12 @@ void Spacebot::writeNextMove() Move Spacebot::chooseMove() { auto sensorInputs = _gameState.toBitArray(); - std::cout << sensorInputs.size() << std::endl; NeuralNetwork network(std::ifstream(_brainFilename), sensorInputs, - static_cast(Move::BUILD_SHIELD)); + 7); - int moveInt = network.findMaxOutputIndex(); - return static_cast(moveInt); + return static_cast(network.findMaxOutputIndex()); } void Spacebot::writeMove(const Move& move) -- cgit v1.2.3