summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/brain/neural_network.cpp110
-rw-r--r--src/brain/neuron.cpp14
-rw-r--r--src/game_state.cpp122
-rw-r--r--src/spacebot.cpp21
4 files changed, 154 insertions, 113 deletions
diff --git a/src/brain/neural_network.cpp b/src/brain/neural_network.cpp
index 0c23771..c8177e8 100644
--- a/src/brain/neural_network.cpp
+++ b/src/brain/neural_network.cpp
@@ -12,13 +12,13 @@ NeuralNetwork::NeuralNetwork(std::istream &&networkConfigFile, unsigned int numb
for (unsigned int i=0; i<numberOfSensors; ++i)
{
- auto sensor = std::make_shared<Sensor>();
- _sensors.push_back(sensor);
+ auto sensor = std::make_shared<Sensor>(i);
+ _sensors.push_back(sensor);
}
for (unsigned int i=0; i<numberOfOutputs; ++i)
{
- auto output = findOrAddNeuron(i);
- _outputs.push_back(output);
+ auto output = findOrAddNeuron(i);
+ _outputs.push_back(output);
}
parseFile(std::move(networkConfigFile));
@@ -34,14 +34,14 @@ NeuralNetwork::NeuralNetwork(std::istream &&networkConfigFile, std::vector<bool>
for (unsigned int i=0; i<sensorInitialValues.size(); ++i)
{
- auto sensor = std::make_shared<Sensor>();
- sensor->setActivation(sensorInitialValues[i] ? 1 : 0);
- _sensors.push_back(sensor);
+ auto sensor = std::make_shared<Sensor>(i);
+ sensor->setActivation(sensorInitialValues[i] ? 1 : 0);
+ _sensors.push_back(sensor);
}
for (unsigned int i=0; i<numberOfOutputs; ++i)
{
- auto output = findOrAddNeuron(i);
- _outputs.push_back(output);
+ auto output = findOrAddNeuron(i);
+ _outputs.push_back(output);
}
parseFile(std::move(networkConfigFile));
@@ -55,29 +55,28 @@ void NeuralNetwork::parseFile(std::istream &&file)
unsigned int destId;
while (file.get(srcType) &&
- file >> srcId &&
- file.ignore(std::numeric_limits<std::streamsize>::max(), 'n') &&
- file >> destId &&
- file >> weight &&
- file.ignore(std::numeric_limits<std::streamsize>::max(), '\n'))
+ file >> srcId &&
+ file.ignore(std::numeric_limits<std::streamsize>::max(), 'n') &&
+ file >> destId &&
+ file >> weight &&
+ file.ignore(std::numeric_limits<std::streamsize>::max(), '\n'))
{
+ std::shared_ptr<NeuralNode> source;
+ std::shared_ptr<Neuron> destination;
+ switch (srcType)
+ {
+ case 's':
+ source = findOrAddSensor(srcId);
+ break;
+ case 'b':
+ source = _biasNode;
+ break;
+ default:
+ source = findOrAddNeuron(srcId);
+ }
+ destination = findOrAddNeuron(destId);
- std::shared_ptr<NeuralNode> source;
- std::shared_ptr<Neuron> destination;
- switch (srcType)
- {
- case 's':
- source = findOrAddSensor(srcId);
- break;
- case 'b':
- source = _biasNode;
- break;
- default:
- source = findOrAddNeuron(srcId);
- }
- destination = findOrAddNeuron(destId);
-
- addLink(source, destination, weight);
+ addLink(source, destination, weight);
}
}
@@ -92,8 +91,8 @@ std::shared_ptr<Sensor> NeuralNetwork::findOrAddSensor(unsigned int id)
{
while (_sensors.size() <= id)
{
- auto sensor = std::make_shared<Sensor>();
- _sensors.push_back(sensor);
+ auto sensor = std::make_shared<Sensor>(_sensors.size());
+ _sensors.push_back(sensor);
}
return _sensors.at(id);
@@ -103,8 +102,8 @@ std::shared_ptr<Neuron> NeuralNetwork::findOrAddNeuron(unsigned int id)
{
while (_neurons.size() <= id)
{
- auto neuron = std::make_shared<Neuron>();
- _neurons.push_back(neuron);
+ auto neuron = std::make_shared<Neuron>(_neurons.size());
+ _neurons.push_back(neuron);
}
return _neurons.at(id);
@@ -121,12 +120,12 @@ unsigned int NeuralNetwork::findMaxOutputIndex() const
auto maxIterations = _neurons.size()*10;
for (unsigned int iteration=0; anyNodeChanged && iteration<maxIterations; ++iteration)
{
- anyNodeChanged = false;
- for (auto const& neuron : _neurons)
- {
- bool activationChanged = neuron->calculateActivation();
- anyNodeChanged = anyNodeChanged || activationChanged;
- }
+ anyNodeChanged = false;
+ for (auto const& neuron : _neurons)
+ {
+ bool activationChanged = neuron->calculateActivation();
+ anyNodeChanged = anyNodeChanged || activationChanged;
+ }
}
int currentMaxIndex = 0;
@@ -134,12 +133,31 @@ unsigned int NeuralNetwork::findMaxOutputIndex() const
for (unsigned int i=1; i<_outputs.size(); ++i)
{
- double activation = _outputs.at(i)->activation();
- if (activation >= currentMaxActivation)
- {
- currentMaxActivation = activation;
- currentMaxIndex = i;
- }
+ double activation = _outputs.at(i)->activation();
+ if (activation >= currentMaxActivation)
+ {
+ currentMaxActivation = activation;
+ currentMaxIndex = i;
+ }
}
return currentMaxIndex;
}
+
+bool NeuralNetwork::linkExists(std::string srcIdentifier, std::string destIdentifier, double weight) const
+{
+ std::shared_ptr<Neuron> dest;
+
+ for (auto const& node : _neurons)
+ {
+ if (node->identifier() == destIdentifier)
+ {
+ dest = node;
+ }
+ }
+
+ if (!dest)
+ {
+ return false;
+ }
+ return dest->hasInputWithWeight(srcIdentifier, weight);
+}
diff --git a/src/brain/neuron.cpp b/src/brain/neuron.cpp
index d1dd338..c7dba2c 100644
--- a/src/brain/neuron.cpp
+++ b/src/brain/neuron.cpp
@@ -12,7 +12,7 @@ bool Neuron::calculateActivation()
double newActivation = 0;
for (auto const& link : _inputLinks)
{
- newActivation += link.weightedActivation();
+ newActivation += link.weightedActivation();
}
newActivation = sigmoid(newActivation);
@@ -26,3 +26,15 @@ void Neuron::addInput(NeuralLink&& link)
{
_inputLinks.push_back(std::move(link));
}
+
+bool Neuron::hasInputWithWeight(std::string srcIdentifier, double weight) const
+{
+ for (auto const& link : _inputLinks)
+ {
+ if (link.inputIdentifier() == srcIdentifier && link.weight() == weight)
+ {
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/src/game_state.cpp b/src/game_state.cpp
index 29bd75b..952c2f3 100644
--- a/src/game_state.cpp
+++ b/src/game_state.cpp
@@ -61,17 +61,17 @@ int GameState::addEntity(int x, int y, char type)
_shields.push_back(Shield(x,y));
return 1;
case Spaceship::ENEMY_MAP_CHAR:
- _enemySpaceship = std::unique_ptr<Spaceship>(new Spaceship(x+1, y));
- return 3;
+ _enemySpaceship = std::unique_ptr<Spaceship>(new Spaceship(x+1, y));
+ return 3;
case Spaceship::PLAYER_MAP_CHAR:
- _playerSpaceship = std::unique_ptr<Spaceship>(new Spaceship(x+1, y));
+ _playerSpaceship = std::unique_ptr<Spaceship>(new Spaceship(x+1, y));
return 3;
case Building::MISSILE_CONTROLLER_CHAR:
- _missileControllers.push_back(Building(x+1, y));
- return 3;
+ _missileControllers.push_back(Building(x+1, y));
+ return 3;
case Building::ALIEN_FACTORY_CHAR:
- _alienFactories.push_back(Building(x+1, y));
- return 3;
+ _alienFactories.push_back(Building(x+1, y));
+ return 3;
}
return 1;
}
@@ -96,11 +96,11 @@ void GameState::logState() const
}
if (_playerSpaceship)
{
- std::cout << "Player Spaceship" << _playerSpaceship->coords() << std::endl;
+ std::cout << "Player Spaceship" << _playerSpaceship->coords() << std::endl;
}
if (_enemySpaceship)
{
- std::cout << "Enemy Spaceship" << _enemySpaceship->coords() << std::endl;
+ std::cout << "Enemy Spaceship" << _enemySpaceship->coords() << std::endl;
}
}
@@ -110,25 +110,25 @@ int getPyramidOffset(int bottomWidth, int maxWidth, int x, int y, int resultIfLe
int currentRowOffset = 0;
for (int i=0; i<y; ++i)
{
- currentRowOffset += currentRowWidth;
- currentRowWidth += 2;
- if (currentRowWidth > maxWidth)
- {
- currentRowWidth = maxWidth;
- }
+ currentRowOffset += currentRowWidth;
+ currentRowWidth += 2;
+ if (currentRowWidth > maxWidth)
+ {
+ currentRowWidth = maxWidth;
+ }
}
if (x > currentRowWidth/2)
{
- return resultIfRight;
+ return resultIfRight;
}
else if (x < -currentRowWidth/2)
{
- return resultIfLeft;
+ return resultIfLeft;
}
else
{
- return currentRowOffset + currentRowWidth/2 + x;
+ return currentRowOffset + currentRowWidth/2 + x;
}
}
@@ -154,80 +154,80 @@ std::vector<bool> GameState::toBitArray() const
int playerY = GAME_AREA_LINES-3;
if (_playerSpaceship)
{
- playerX = _playerSpaceship->x();
+ playerX = _playerSpaceship->x();
}
for (auto const& alien : _aliens)
{
- if (alien.y() > playerY-4 || alien.y() < playerY-7 || alien.x() > playerX+4 || alien.x() < playerX-4)
- {
- continue;
- }
+ if (alien.y() > playerY-4 || alien.y() < playerY-7 || alien.x() > playerX+4 || alien.x() < playerX-4)
+ {
+ continue;
+ }
- result.at(alienOffset + getRectangularOffset(9, alien.x()-playerX, playerY-4-alien.y())) = true;
+ result.at(alienOffset + getRectangularOffset(9, alien.x()-playerX, playerY-4-alien.y())) = true;
}
for (auto const& bullet : _bullets)
{
- if (bullet.y() >= playerY || bullet.y() < playerY-3 || bullet.x() > playerX+2 || bullet.x() < playerX-2)
- {
- continue;
- }
+ if (bullet.y() >= playerY || bullet.y() < playerY-3 || bullet.x() > playerX+2 || bullet.x() < playerX-2)
+ {
+ continue;
+ }
- result.at(bulletOffset + getRectangularOffset(5, bullet.x()-playerX, playerY-1-bullet.y())) = true;
+ result.at(bulletOffset + getRectangularOffset(5, bullet.x()-playerX, playerY-1-bullet.y())) = true;
}
for (auto const& shield : _shields)
{
- if (shield.y() < playerY-3 || shield.x() < playerX-1 || shield.x() > playerX+1)
- {
- continue;
- }
+ if (shield.y() < playerY-3 || shield.x() < playerX-1 || shield.x() > playerX+1)
+ {
+ continue;
+ }
- result.at(shieldOffset + shield.x()-playerX+1) = true;
+ result.at(shieldOffset + shield.x()-playerX+1) = true;
}
if (_missiles.size() > 0)
{
- result.at(missileOffset) = true;
+ result.at(missileOffset) = true;
}
if (_missiles.size() < 1)
{
- result.at(missileOffset + 1) = true;
+ result.at(missileOffset + 1) = true;
}
if (_playerSpaceship)
{
- if (playerX <= GAME_WIDTH/3)
- {
- result.at(positionOffset) = true;
- }
- else if (playerX >= GAME_WIDTH*2/3)
- {
- result.at(positionOffset+2) = true;
- }
- else
- {
- result.at(positionOffset+1) = true;
- }
+ if (playerX <= GAME_WIDTH/3)
+ {
+ result.at(positionOffset) = true;
+ }
+ else if (playerX >= GAME_WIDTH*2/3)
+ {
+ result.at(positionOffset+2) = true;
+ }
+ else
+ {
+ result.at(positionOffset+1) = 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;
- }
+ 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;
+ }
}
return result;
diff --git a/src/spacebot.cpp b/src/spacebot.cpp
index 15f2221..17d20b5 100644
--- a/src/spacebot.cpp
+++ b/src/spacebot.cpp
@@ -20,12 +20,23 @@ void Spacebot::writeNextMove()
Move Spacebot::chooseMove()
{
auto sensorInputs = _gameState.toBitArray();
-
- NeuralNetwork network(std::ifstream(_brainFilename),
- sensorInputs,
- 7);
- return static_cast<Move>(network.findMaxOutputIndex());
+ if (!sensorInputs.at(51) || !sensorInputs.at(53))
+ {
+ return Move::BUILD_SHIELD;
+ }
+ else if (sensorInputs.at(55))
+ {
+ return Move::SHOOT;
+ }
+ else if (sensorInputs.at(60) && !sensorInputs.at(59))
+ {
+ return Move::BUILD_MISSILE_CONTROLLER;
+ }
+ else
+ {
+ return Move::NOTHING;
+ }
}
void Spacebot::writeMove(const Move& move)