diff options
-rw-r--r-- | include/brain/neural_network.h | 3 | ||||
-rw-r--r-- | include/spacebot.h | 4 | ||||
-rw-r--r-- | main/main.cpp | 11 | ||||
-rw-r--r-- | src/brain/neural_network.cpp | 19 | ||||
-rw-r--r-- | src/game_state.cpp | 43 | ||||
-rw-r--r-- | src/spacebot.cpp | 13 |
6 files changed, 78 insertions, 15 deletions
diff --git a/include/brain/neural_network.h b/include/brain/neural_network.h index b2c441f..ccd65eb 100644 --- a/include/brain/neural_network.h +++ b/include/brain/neural_network.h @@ -14,7 +14,8 @@ class NeuralNetwork { public: NeuralNetwork(std::istream &&networkConfigFile, int numberOfSensors, int numberOfOutputs); - + NeuralNetwork(std::istream &&networkConfigFile, std::vector<bool> sensorInitialValues, int numberOfOutputs); + void setInput(int inputIndex, double activation); int findMaxOutputIndex() const; diff --git a/include/spacebot.h b/include/spacebot.h index 079b33e..9f7f83e 100644 --- a/include/spacebot.h +++ b/include/spacebot.h @@ -6,11 +6,11 @@ class Spacebot { public: - Spacebot(std::string outputPath); + Spacebot(std::string outputPath, std::string brainFilename); void writeNextMove(); private: std::string _outputFilename; - std::string _networkConfigFilename; + std::string _brainFilename; GameState _gameState; void writeMove(const Move& move); diff --git a/main/main.cpp b/main/main.cpp index 578620c..ce6bc43 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -5,12 +5,19 @@ int main(int argc, char* argv[]) { - if (argc < 2) { + if (argc < 2) + { std::cout << "usage: " << argv[0] << " <output folder>" << std::endl; return 1; } - Spacebot bot(argv[1]); + std::string brainFilename = "brain.nn"; + if (argc >= 3) + { + brainFilename = argv[2]; + } + + Spacebot bot(argv[1], std::move(brainFilename)); bot.writeNextMove(); return 0; diff --git a/src/brain/neural_network.cpp b/src/brain/neural_network.cpp index 15eedca..30da46c 100644 --- a/src/brain/neural_network.cpp +++ b/src/brain/neural_network.cpp @@ -17,6 +17,24 @@ NeuralNetwork::NeuralNetwork(std::istream &&networkConfigFile, int numberOfSenso parseFile(std::move(networkConfigFile)); } +NeuralNetwork::NeuralNetwork(std::istream &&networkConfigFile, std::vector<bool> sensorInitialValues, int numberOfOutputs) +{ + _biasNode = std::make_shared<BiasNode>(); + + for (int i=0; i<sensorInitialValues.size(); ++i) + { + auto sensor = std::make_shared<Sensor>(i); + sensor->setActivation(sensorInitialValues.at(i) ? 1 : 0); + _sensors.push_back(sensor); + } + for (int i=0; i<numberOfOutputs; ++i) + { + _outputs.push_back(std::make_shared<Neuron>(i)); + } + + parseFile(std::move(networkConfigFile)); +} + void NeuralNetwork::parseFile(std::istream &&file) { double weight; @@ -123,6 +141,7 @@ void NeuralNetwork::setInput(int inputIndex, double activation) if (sensor->id() == inputIndex) { sensor->setActivation(activation); + break; } } } diff --git a/src/game_state.cpp b/src/game_state.cpp index 5fed683..e6deae7 100644 --- a/src/game_state.cpp +++ b/src/game_state.cpp @@ -2,9 +2,11 @@ #include <iostream> #include <fstream> #include <limits> +#include <bitset> const int OPENING_LINES = 6; const int GAME_AREA_LINES = 25; +const int GAME_WIDTH = 19; void moveToNextChar(int &x, int &y, int &width, char &nextChar, std::istream &mapFile) { @@ -91,5 +93,44 @@ void GameState::logState() std::vector<bool> GameState::toBitArray() const { - return std::vector<bool>(); + std::vector<bool> result; + + std::vector<bool> alienNodes((GAME_AREA_LINES-2) * (GAME_WIDTH-2), false); + for (auto alien : _aliens) + { + alienNodes.at((alien.y()-1)*(GAME_WIDTH-2)+(alien.x()-1)) = true; + } + result.insert(result.end(), alienNodes.begin(), alienNodes.end()); + + std::vector<bool> bulletNodes((GAME_AREA_LINES-2) * (GAME_WIDTH-2), false); + for (auto bullet : _bullets) + { + bulletNodes.at((bullet.y()-1)*(GAME_WIDTH-2)+(bullet.x()-1)) = true; + } + result.insert(result.end(), bulletNodes.begin(), bulletNodes.end()); + + std::vector<bool> missileNodes((GAME_AREA_LINES-2) * (GAME_WIDTH-2), false); + for (auto missile : _missiles) + { + missileNodes.at((missile.y()-1)*(GAME_WIDTH-2)+(missile.x()-1)) = true; + } + result.insert(result.end(), missileNodes.begin(), missileNodes.end()); + + std::vector<bool> shieldNodes(2 * (GAME_WIDTH-2), false); + for (auto shield : _shields) + { + int row = shield.y() > GAME_AREA_LINES/2 ? 1 : 0; + shieldNodes.at(row*(GAME_WIDTH-2)+(shield.x()-1)) = true; + } + + for (auto spaceship : _spaceships) + { + std::bitset<5> spaceshipBits(spaceship.x()); + for (int i=0; i<spaceshipBits.size(); ++i) + { + result.push_back(spaceshipBits[i]); + } + } + + return result; } diff --git a/src/spacebot.cpp b/src/spacebot.cpp index 1f8f2b8..418756c 100644 --- a/src/spacebot.cpp +++ b/src/spacebot.cpp @@ -3,9 +3,9 @@ #include "brain/neural_network.h" #include <fstream> -Spacebot::Spacebot(std::string outputPath) +Spacebot::Spacebot(std::string outputPath, std::string brainFilename) : _outputFilename(outputPath+"/move.txt"), - _networkConfigFilename("brain.nn"), + _brainFilename(brainFilename), _gameState(std::ifstream(outputPath+"/map.txt")) { } @@ -20,15 +20,10 @@ Move Spacebot::chooseMove() { auto sensorInputs = _gameState.toBitArray(); - NeuralNetwork network(std::ifstream(_networkConfigFilename), - sensorInputs.size(), + NeuralNetwork network(std::ifstream(_brainFilename), + sensorInputs, static_cast<int>(Move::BUILD_SHIELD)); - for (int i=0; i<sensorInputs.size(); ++i) - { - network.setInput(i, sensorInputs[i] ? 1 : 0); - } - int moveInt = network.findMaxOutputIndex(); return static_cast<Move>(moveInt); } |