As a follow-up of my previous non-off-the-bat Ant Colony Simulator, we have this one that works off-the-bat... quite; the code for when the ants find and take the food isn't really done but it would be almost impossible to do it anyway, if someone wants to contribute directly to the code, please do it in GitHub.
scent.cpp
#ifndef SCENT_CPP_INCLUDED
#define SCENT_CPP_INCLUDED
class AntScent
{
private:
short power;
short angle;
short ScentType;
public:
short addPower()
{
power += 1;
return power;
}
short affectAngle(short vel)
{
angle = (vel + angle) / 2;
return angle;
}
void ChangeType(short NewType)
{
ScentType = NewType;
}
short decreasePower()
{
power -= 1;
return power;
}
};
#endif // SCENT_CPP_INCLUDED
antFactory.cpp
#pragma once
#include "scent.cpp"
#include "randbool.h"
#include <iostream>
#include <vector>
#include <cstdlib>
#include "foodFactory.cpp"
#include "board.cpp"
#include "tile.h"
#define DEBUG
#ifndef ANTFACTORY_CPP_INCLUDED
#define ANTFACTORY_CPP_INCLUDED
class Ant
{
private:
int x;
int y;
Board* pertainingBoard;
tile* Position;
int index;
AntScent NewDropScent;
bool bFoundFood = false;
short AntSize;
bool bIsCarryingFood;
std::pair<int, int> newPos;
std::pair<bool, Food*> FoodPos;
public:
Ant(int nx, int ny, int i, Board* pb)
{
x = nx;
y = ny;
index = i;
pertainingBoard = pb;
pertainingBoard->addAnt(this);
}
std::pair<int, int> moveThisAnt(std::pair<bool, bool> dir, std::pair<bool, bool> move)
{
if (move.first)
{
if (dir.first)
x += 1;
else
x -= 1;
}
if (move.second)
{
if (dir.second)
y += 1;
else
y -= 1;
}
#ifdef DEBUG
std::cout << "Ant moved to x:" << x << ", y:" << y << std::endl;
#endif // DEBUG
std::pair<int, int> result;
result.first = x;
result.second = y;
return result;
}
void TickThisAnt()
{
if (! bFoundFood)
{
Wander();
if (! pertainingBoard->bPosHasTile(x, y))
{
pertainingBoard->addTile(Position);
}
Position = pertainingBoard->PosTile(x, y).second;
FoodPos = pertainingBoard->posHasFood(x, y);
if (FoodPos.first)
{
FoodPos.second->BeTaken(AntSize);
bIsCarryingFood = true;
bFoundFood = true;
}
}
else
{
Wander();
}
}
void FoundFood()
{
bFoundFood = true;
}
std::pair<int, int> Wander()
{
bool bool1 = MyRandomBoolean();
bool bool2 = MyRandomBoolean();
bool bool3 = MyRandomBoolean();
bool bool4 = MyRandomBoolean();
return moveThisAnt(std::pair<bool,bool>(bool1, bool2), std::pair<bool, bool>(bool3, bool4));
}
void resetFood()
{
bIsCarryingFood = false;
}
};
class AntFactory
{
private:
int foodAcumulated = 0;
int XPos;
int YPos;
std::vector<Ant> AntGenerated;
Board* MyBoard;
public:
Ant* MakeAnt()
{
Ant z(XPos, YPos, AntGenerated.size() + 1, MyBoard);
AntGenerated.push_back(z);
return &AntGenerated[AntGenerated.size() - 1];
}
AntFactory(int nx, int ny, Board* PB)
{
MyBoard = PB;
XPos = nx;
YPos = ny;
MyBoard->addAFactory(this);
}
Ant DelAnt(int AntIndex)
{
Ant theresult = AntGenerated[AntIndex];
AntGenerated.erase(AntGenerated.begin() + AntIndex);
return theresult;
}
void WeFoundFood()
{
for (unsigned int i = 0; i < AntGenerated.size(); i++)
AntGenerated[i].FoundFood();
}
void TickAnts()
{
for (unsigned int i = 0; i < AntGenerated.size(); i++)
{
AntGenerated[i].TickThisAnt();
}
}
void takeFood(int amount, Ant* giver) {
foodAcumulated += amount;
giver->resetFood();
WeFoundFood();
}
};
#endif //ANTFACTORY_CPP_INCLUDED
food.cpp
#pragma once
#include <utility>
class Food
{
private:
short FoodSize;
int x;
int y;
int index;
public:
Food(int nx, int ny, int i, short ns)
{
x = nx;
y = ny;
index = i;
FoodSize = ns;
}
short BeTaken(short BiteSize)
{
if (FoodSize > BiteSize)
{
FoodSize -= BiteSize;
return BiteSize;
}
else
{
FoodSize = 0;
return FoodSize;
}
}
std::pair<int, int> getPos() {
return std::pair<int, int>(x, y);
}
};
foodFactory.cpp
#pragma once
#include <iostream>
#include <vector>
#include <cstdlib>
#include "food.cpp"
#include "board.cpp"
#define DEBUG
FoodFactory::FoodFactory(int nx, int ny, Board* PB)
{
XPos = nx;
YPos = ny;
MyBoard = PB;
MyBoard->addFFactory(this);
}
Food* FoodFactory::SplatFood()
{
XPos = -200 + (rand() % (int)(200 - -200 + 1));
YPos = -200 + (rand() % (int)(200 - -200 + 1));
Food z(XPos, YPos, (FoodGenerated.size() + 1), (5 + (rand() % (int)(50 - 5 + 1))));
FoodGenerated.push_back(z);
#ifdef DEBUG
std::cout << "Food created at x:" << XPos << ", y:" << YPos << std::endl;
#endif
return &FoodGenerated[FoodGenerated.size()];
}
int FoodFactory::HowMuchFoodGenerated()
{
return FoodGenerated.size();
}
std::pair<bool, Food*> FoodFactory::FindFoodAt(int xp, int yp)
{
for (unsigned int i = 0; i < FoodGenerated.size(); i++)
if (FoodGenerated[i].getPos().first == xp && FoodGenerated[i].getPos().second == yp)
return std::pair<bool, Food*>(true, &FoodGenerated[i]);
return std::pair<bool, Food*>(false, &FoodGenerated[0]);
}
foodFactory.h
#ifndef FOODFACTORY_H_INCLUDED
#define FOODFACTORY_H_INCLUDED
#include "food.cpp"
class FoodFactory
{
private:
int XPos;
int YPos;
std::vector<Food> FoodGenerated;
Board* MyBoard;
public:
FoodFactory(int nx, int ny, Board* PB);
Food* SplatFood();
int HowMuchFoodGenerated();
std::pair<bool, Food*> FindFoodAt(int xp, int yp);
};
#endif // FOODFACTORY_H_INCLUDED
main.cpp
#include "scent.cpp"
#include "board.cpp"
#include "foodFactory.cpp"
#include "antFactory.cpp"
#include <fstream>
#include <cstdlib>
int main()
{
Board Root;
FoodFactory Feeder1(42, 21, &Root);
Feeder1.SplatFood();
AntFactory Anter1(-12, 95, &Root);
Ant* Ant1 = Anter1.MakeAnt();
Ant* Ant2 = Anter1.MakeAnt();
Ant* Ant3 = Anter1.MakeAnt();
while(true)
{
Anter1.TickAnts();
if (! std::cin.good())
{
break;
}
}
return 0;
}
tile.cpp
#pragma once
#include "board.cpp"
#include "antFactory.cpp"
#include "curses.h"
#ifndef TILE
#define TILE
class tile
{
private:
int x;
int y;
AntScent tileScent;
Board* MyBoard;
public:
tile(int nx, int ny, Board* PB)
{
x = nx;
y = ny;
MyBoard = PB;
MyBoard->addTile(this);
}
tile(Board* PB)
{
x = 0;
y = 0;
MyBoard = PB;
}
std::pair<int, int> getPosition()
{
return std::pair<int, int>(x, y)
}
void changeScent(AntScent newscent)
{
tileScent = newscent;
}
};
#endif // TILE
randbool.cpp
#pragma once
#ifndef RANDBOOL
#define RANDBOOL
#include <cstdlib>
bool MyRandomBoolean() {
return rand() % 2 == 1;
}
#endif // RANDBOOL
randbool.h
#ifndef RANDBOOL_H_INCLUDED
#define RANDBOOL_H_INCLUDED
bool MyRandomBoolean();
#endif // RANDBOOL_H_INCLUDED
tile.h
#ifndef TILE_H_INCLUDED
#define TILE_H_INCLUDED
#include "scent.cpp"
class Board;
class tile
{
private:
int x;
int y;
AntScent tileScent;
Board* MyBoard;
public:
tile(int nx, int ny, Board* PB);
tile(Board* PB);
std::pair<int, int> getPosition();
void changeScent(AntScent newscent);
};
#endif // TILE_H_INCLUDED
board.cpp
#pragma once
#include <vector>
#include "tile.h"
#include "foodFactory.h"
class AntFactory;
class Ant;
class Board
{
private:
std::vector<tile*> BoardTiles;
std::vector<FoodFactory*> FFactories;
std::vector<AntFactory*> AFactories;
std::vector<Ant*> BoardAnts;
public:
void addAFactory(AntFactory* AFactory)
{
AFactories.push_back(AFactory);
}
bool bPosHasTile(int x, int y) {
for (int i = 0; i < BoardTiles.size(); i++)
if (BoardTiles[i]->getPosition().first == x && BoardTiles[i]->getPosition().second == y)
return true;
return false;
}
std::pair<bool, tile*> PosTile(int x, int y)
{
for (int i = 0; i < BoardTiles.size(); i++)
if (BoardTiles[i]->getPosition().first == x && BoardTiles[i]->getPosition().second == y)
return std::pair<bool, tile*>(true, BoardTiles[i]);
return std::pair<bool, tile*>(false, BoardTiles[0]);
}
void addFFactory(FoodFactory* FFactory)
{
FFactories.push_back(FFactory);
}
void addTile(tile* Tl)
{
BoardTiles.push_back(Tl);
}
void addAnt(Ant* mAnt)
{
BoardAnts.push_back(mAnt);
}
tile* getTile(int i)
{
return BoardTiles[i];
}
std::pair<bool, Food*> posHasFood(int x, int y)
{
std::pair<bool, Food*> result;
for (int n = 0; n < FFactories.size(); n++)
{
result = FFactories[n]->FindFoodAt(x, y);
if (result.first)
return result;
return FFactories[0]->FindFoodAt(x, y);
}
}
};