summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Worthe <justin.worthe@gmail.com>2015-08-01 22:50:00 +0200
committerJustin Worthe <justin.worthe@gmail.com>2015-08-01 22:50:00 +0200
commit2e6ecf423c8228ac8de4badf4fc2d037a876b7ff (patch)
tree82624e97a3d1ee47db05e320bf0014726f68c09d
parent1f40ce6f3c710d6339d2001a56f401b6a9dcd525 (diff)
Reading network from file
-rw-r--r--brain.nn4
-rw-r--r--include/brain/neural_link.h2
-rw-r--r--include/brain/neural_network.h14
-rw-r--r--include/brain/neuron.h2
-rw-r--r--include/game_state.h2
-rw-r--r--include/spacebot.h6
-rw-r--r--src/brain/neural_link.cpp4
-rw-r--r--src/brain/neural_network.cpp103
-rw-r--r--src/brain/neuron.cpp5
-rw-r--r--src/game_state.cpp5
-rw-r--r--src/spacebot.cpp28
-rw-r--r--test/neural_network.cpp8
12 files changed, 162 insertions, 21 deletions
diff --git a/brain.nn b/brain.nn
new file mode 100644
index 0000000..e0c854f
--- /dev/null
+++ b/brain.nn
@@ -0,0 +1,4 @@
+s0 n3 0.5
+n3 n1 1
+b0 n0 0.4
+b0 n3 0.5 \ No newline at end of file
diff --git a/include/brain/neural_link.h b/include/brain/neural_link.h
index 42ee2f9..5a63ba4 100644
--- a/include/brain/neural_link.h
+++ b/include/brain/neural_link.h
@@ -7,7 +7,7 @@
class NeuralLink
{
public:
- NeuralLink(double weight);
+ NeuralLink(std::shared_ptr<NeuralNode> input, double weight);
double weightedActivation() const;
private:
diff --git a/include/brain/neural_network.h b/include/brain/neural_network.h
index 308cb56..b2c441f 100644
--- a/include/brain/neural_network.h
+++ b/include/brain/neural_network.h
@@ -3,9 +3,12 @@
#include <memory>
#include <istream>
#include <vector>
+#include <string>
#include "brain/neural_node.h"
#include "brain/sensor.h"
+#include "brain/bias_node.h"
+#include "brain/neuron.h"
class NeuralNetwork
{
@@ -19,8 +22,15 @@ public:
int numberOfOutputs() const { return _outputs.size(); }
private:
- std::vector<std::shared_ptr<NeuralNode>> _nodes;
std::vector<std::shared_ptr<Sensor>> _sensors;
- std::vector<std::shared_ptr<NeuralNode>> _outputs;
+ std::shared_ptr<BiasNode> _biasNode;
+ std::vector<std::shared_ptr<Neuron>> _hiddenNodes;
+ std::vector<std::shared_ptr<Neuron>> _outputs;
+
+ void parseFile(std::istream &&file);
+
+ void addLink(std::shared_ptr<NeuralNode> source, std::shared_ptr<Neuron> destination, double weight);
+ std::shared_ptr<Sensor> findOrAddSensor(int id);
+ std::shared_ptr<Neuron> findOrAddNeuron(int id);
};
diff --git a/include/brain/neuron.h b/include/brain/neuron.h
index 1607cf0..810ce5b 100644
--- a/include/brain/neuron.h
+++ b/include/brain/neuron.h
@@ -13,6 +13,8 @@ public:
virtual ~Neuron() {}
virtual double activation() const;
+ void addInput(std::shared_ptr<NeuralLink> link);
+
private:
std::vector<std::shared_ptr<NeuralLink>> _inputLinks;
double sigmoid(double input) const;
diff --git a/include/game_state.h b/include/game_state.h
index 905bbc9..482dd7d 100644
--- a/include/game_state.h
+++ b/include/game_state.h
@@ -20,6 +20,8 @@ public:
const std::vector<PlayerMissile>& missiles() const { return _missiles; }
const std::vector<Shield>& shields() const { return _shields; }
const std::vector<Spaceship>& spaceships() const { return _spaceships; }
+
+ std::vector<bool> toBitArray() const;
private:
std::vector<Alien> _aliens;
diff --git a/include/spacebot.h b/include/spacebot.h
index 9b89383..079b33e 100644
--- a/include/spacebot.h
+++ b/include/spacebot.h
@@ -9,8 +9,10 @@ public:
Spacebot(std::string outputPath);
void writeNextMove();
private:
- std::string outputFilename;
- GameState gameState;
+ std::string _outputFilename;
+ std::string _networkConfigFilename;
+ GameState _gameState;
+
void writeMove(const Move& move);
Move chooseMove();
};
diff --git a/src/brain/neural_link.cpp b/src/brain/neural_link.cpp
index d217236..f8d2b29 100644
--- a/src/brain/neural_link.cpp
+++ b/src/brain/neural_link.cpp
@@ -1,7 +1,7 @@
#include "brain/neural_link.h"
-NeuralLink::NeuralLink(double weight)
- :_weight(weight)
+NeuralLink::NeuralLink(std::shared_ptr<NeuralNode> input, double weight)
+ :_input(input), _weight(weight)
{
}
diff --git a/src/brain/neural_network.cpp b/src/brain/neural_network.cpp
index 2d3b902..15eedca 100644
--- a/src/brain/neural_network.cpp
+++ b/src/brain/neural_network.cpp
@@ -3,6 +3,8 @@
NeuralNetwork::NeuralNetwork(std::istream &&networkConfigFile, int numberOfSensors, int numberOfOutputs)
{
+ _biasNode = std::make_shared<BiasNode>();
+
for (int i=0; i<numberOfSensors; ++i)
{
_sensors.push_back(std::make_shared<Sensor>(i));
@@ -11,6 +13,107 @@ NeuralNetwork::NeuralNetwork(std::istream &&networkConfigFile, int numberOfSenso
{
_outputs.push_back(std::make_shared<Neuron>(i));
}
+
+ parseFile(std::move(networkConfigFile));
+}
+
+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));
+
+ std::shared_ptr<NeuralNode> source;
+ std::shared_ptr<Neuron> destination;
+ switch (srcType)
+ {
+ case 's':
+ source = findOrAddSensor(srcId);
+ break;
+ 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;
+ }
+
+ addLink(source, destination, weight);
+ }
+
+}
+
+void NeuralNetwork::addLink(std::shared_ptr<NeuralNode> source, std::shared_ptr<Neuron> destination, double weight)
+{
+ auto link = std::make_shared<NeuralLink>(source, weight);
+ destination->addInput(link);
+}
+
+std::shared_ptr<Sensor> NeuralNetwork::findOrAddSensor(int id)
+{
+ std::shared_ptr<Sensor> result;
+ for (auto node : _sensors)
+ {
+ if (node->id() == id)
+ {
+ result = node;
+ break;
+ }
+ }
+ if (!result)
+ {
+ result = std::make_shared<Sensor>(id);
+ _sensors.push_back(result);
+ }
+ return result;
+}
+
+std::shared_ptr<Neuron> NeuralNetwork::findOrAddNeuron(int id)
+{
+ std::shared_ptr<Neuron> result;
+ for (auto node : _hiddenNodes)
+ {
+ if (node->id() == id)
+ {
+ result = node;
+ break;
+ }
+ }
+ if (result)
+ {
+ return result;
+ }
+ for (auto node : _outputs)
+ {
+ if (node->id() == id)
+ {
+ result = node;
+ break;
+ }
+ }
+ if (result)
+ {
+ return result;
+ }
+
+ result = std::make_shared<Neuron>(id);
+ _hiddenNodes.push_back(result);
+ return result;
}
void NeuralNetwork::setInput(int inputIndex, double activation)
diff --git a/src/brain/neuron.cpp b/src/brain/neuron.cpp
index 8c2e47c..7ea02c6 100644
--- a/src/brain/neuron.cpp
+++ b/src/brain/neuron.cpp
@@ -22,3 +22,8 @@ double Neuron::activation() const
}
return sigmoid(activationSum);
}
+
+void Neuron::addInput(std::shared_ptr<NeuralLink> link)
+{
+ _inputLinks.push_back(link);
+}
diff --git a/src/game_state.cpp b/src/game_state.cpp
index d99ca12..5fed683 100644
--- a/src/game_state.cpp
+++ b/src/game_state.cpp
@@ -88,3 +88,8 @@ void GameState::logState()
std::cout << "Spaceship" << spaceship.coords() << std::endl;
}
}
+
+std::vector<bool> GameState::toBitArray() const
+{
+ return std::vector<bool>();
+}
diff --git a/src/spacebot.cpp b/src/spacebot.cpp
index 5f87df9..1f8f2b8 100644
--- a/src/spacebot.cpp
+++ b/src/spacebot.cpp
@@ -1,11 +1,12 @@
#include "spacebot.h"
#include "move_string_mapper.h"
-#include <random>
+#include "brain/neural_network.h"
#include <fstream>
Spacebot::Spacebot(std::string outputPath)
- : outputFilename(outputPath+"/move.txt"),
- gameState(std::ifstream(outputPath+"/map.txt"))
+ : _outputFilename(outputPath+"/move.txt"),
+ _networkConfigFilename("brain.nn"),
+ _gameState(std::ifstream(outputPath+"/map.txt"))
{
}
@@ -17,17 +18,24 @@ void Spacebot::writeNextMove()
Move Spacebot::chooseMove()
{
- int min = static_cast<int>(Move::NOTHING);
- int max = static_cast<int>(Move::BUILD_SHIELD);
- std::random_device rd;
- std::mt19937 gen(rd());
- std::uniform_int_distribution<int> dis(min, max);
- return static_cast<Move>(dis(gen));
+ auto sensorInputs = _gameState.toBitArray();
+
+ NeuralNetwork network(std::ifstream(_networkConfigFilename),
+ sensorInputs.size(),
+ 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);
}
void Spacebot::writeMove(const Move& move)
{
- std::ofstream resultStream(outputFilename);
+ std::ofstream resultStream(_outputFilename);
resultStream << MoveStringMapper().toString(move) << std::endl;
return;
}
diff --git a/test/neural_network.cpp b/test/neural_network.cpp
index 6040c83..dd029d6 100644
--- a/test/neural_network.cpp
+++ b/test/neural_network.cpp
@@ -25,14 +25,14 @@ SCENARIO("network is read from istream")
GIVEN("a valid config file")
{
std::stringstream file;
- file << "s0 n2 0.5" << std::endl;
- file << "n2 n1 1" << std::endl;
+ file << "s0 n3 0.5" << std::endl;
+ file << "n3 n1 1" << std::endl;
file << "b0 n0 0.4" << std::endl;
- file << "b0 n2 0.5" << std:: endl;
+ file << "b0 n3 0.5" << std:: endl;
WHEN("the network is initialized")
{
- NeuralNetwork network(std::move(file), 1, 2);
+ NeuralNetwork network(std::move(file), 1, 3);
THEN("the network is constructed correctly")
{