diff --git a/src/coord.h b/src/coord.h index 63b0b2f..9d4a8a7 100644 --- a/src/coord.h +++ b/src/coord.h @@ -75,7 +75,7 @@ struct Coord }; struct CoordHash{ - size_t operator()(const Coord& val) const{ + std::size_t operator()(const Coord& val) const{ return val.x+10000*val.y; } }; diff --git a/src/dude.cpp b/src/dude.cpp index 0f2c853..94de427 100644 --- a/src/dude.cpp +++ b/src/dude.cpp @@ -2,7 +2,7 @@ #include "map.h" #include -Dude::Dude(const Coord &_pos, Map *_map, int &_team) : +Dude::Dude(const Coord &_pos, Map *_map, const int &_team) : m_pos(_pos), p_map(_map), m_team(_team), @@ -49,6 +49,7 @@ void Dude::update(BehaviorFunction func) { func(&m_action, m_memory, (Info*)this); m_receivedComData = false; + memcpy(m_com_data.data, 0, COM_SIZE); } PixelType Dude::getNear(Dir d) const diff --git a/src/dude.h b/src/dude.h index 48e8dc4..8eaa6e7 100644 --- a/src/dude.h +++ b/src/dude.h @@ -20,22 +20,31 @@ private: int m_underResCount; public: - Dude(const Coord &_pos, Map *_map, int &_team); + Dude(const Coord &_pos, Map *_map, const int &_team); + //general use functions + void update(BehaviorFunction func); const Action& getAction() { return m_action; } int getTeam(){ return m_team; } - void setSuccess(bool success) { m_success = success; } - void setInventory(PixelType item) { m_inventory = item; } + + //life-related function + bool isAlive() { return !m_dead; } void perish() { m_dead = true; } + + //movement-related function const Coord& getPos() { return m_pos; } void move(Dir d); - void receiveComData(Dir dir, const char *data); - void update(BehaviorFunction func); + //function inherited from Info virtual bool getSuccess() const { return m_success; } virtual PixelType getInventory() const { return m_inventory; } virtual const Com* getCom() const { return m_receivedComData ? &m_com_data : nullptr; } virtual PixelType getNear(Dir d) const; virtual int getInfo(Dir d) const; + + // setter for the variable returned by functions of Info + void setSuccess(bool success) { m_success = success; } + void setInventory(PixelType item) { m_inventory = item; } + void receiveComData(Dir dir, const char *data); }; #endif // DUDE_H diff --git a/src/map.h b/src/map.h index edc7a60..40aabae 100644 --- a/src/map.h +++ b/src/map.h @@ -11,7 +11,7 @@ struct Pixel int nbRes; // RESOURCES char *knowledge; // LIBRARY int teamId; // SPAWN - Dude* dudePtr; // DUDE + Dude *dudePtr; // DUDE }; PixelType type; diff --git a/src/simulation.cpp b/src/simulation.cpp index 1a15961..147194d 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -32,13 +32,18 @@ Simulation::~Simulation() void Simulation::update() { std::random_shuffle(m_dudes.begin(), m_dudes.end()); - for (int i=0; igetTeam()].update(dude); //get action for this dude from behavior function in team - handleAction(dude); + if (dude->isAlive()){ + m_teams[dude->getTeam()].update(dude); //get action for this dude from behavior function in team + handleAction(dude); + } } + + resolveBattles(); + // for each team, spawn dude if condition met - for(int i=0; isetSuccess(true); - if (target.type == DUDE) // TODO: add fight between dude and targetDude - NULL; + if (target.type == DUDE) //DONE + m_battles.insert(Battle(dude,target.data.dudePtr)); else // DONE { if(target.type == SPAWN) @@ -190,17 +195,23 @@ void Simulation::handleAction(Dude *dude) { Dude *targetDude = target.data.dudePtr; // TODO check conflicts between writers - targetDude->receiveComData(Dir((action.dir+2)%4), targetDude->getAction().com_data.data); - dude->setSuccess(true); + if(targetDude->getCom() == nullptr){ + targetDude->receiveComData(Dir((action.dir+2)%4), targetDude->getAction().com_data.data); + dude->setSuccess(true); + }else + dude->setSuccess(false); break; } case LIBRARY: { int offset = (action.com_data.flag & 3)*COM_SIZE; if(action.com_data.flag & Com::READ) - dude->receiveComData(action.dir, target.data.knowledge + offset); - else - { + if(dude->getCom() == nullptr){ + dude->receiveComData(action.dir, target.data.knowledge + offset); + dude->setSuccess(true); + }else + dude->setSuccess(false); + else{ memcpy(target.data.knowledge + offset, action.com_data.data, COM_SIZE); dude->setSuccess(true); } @@ -211,3 +222,33 @@ void Simulation::handleAction(Dude *dude) } } } + +// TODO: verify if battle resolution work +void Simulation::resolveBattles(){ + for (Battle battle : m_battles){ + Dude *attacker = battle.first, *defender = battle.second; + if (defender->isAlive() && defender->getAction().type == Action::ATTACK){ + if (attacker->getPos() == defender->getPos() + Coord(defender->getAction().dir)){ + bool armedAttacker = attacker->getInventory() == PixelType::SWORD, armedDefender = defender->getInventory() == PixelType::SWORD; + if (armedAttacker == armedDefender){ + if ((rand()%100 + 1) > 50) + attacker->perish(); + else + defender->perish(); + }else if(armedAttacker){ + if ((rand()%100 + 1) > 80) + attacker->perish(); + else + defender->perish(); + }else if(armedDefender){ + if ((rand()%100 + 1) > 20) + attacker->perish(); + else + defender->perish(); + } + }else + defender->perish(); + }else + defender->perish(); + } +} diff --git a/src/simulation.h b/src/simulation.h index 75650d8..9f11efe 100644 --- a/src/simulation.h +++ b/src/simulation.h @@ -2,6 +2,8 @@ #define SIMULATION_H #include +#include +#include #include "behavior.h" #include "team.h" @@ -10,9 +12,21 @@ class MapScene; class Simulation { private: + typedef std::pair Battle; + struct battleComparator{ + bool operator() (Battle a, Battle b){ + return ((a == b) || (a.first == b.second && b.first == a.second)); + } + }; + MapScene *p_map; std::vector m_dudes; std::vector m_teams; + std::set m_battles; + + void handleAction(Dude* dude); + void resolveBattles(); + public: Simulation(MapScene *_map, std::vector &_behaviors); ~Simulation(); @@ -23,7 +37,6 @@ public: * @brief update runs one step of simulation */ void update(); - void handleAction(Dude* dude); }; #endif // SIMULATION_H