This commit is contained in:
Anselme FRANÇOIS 2016-06-04 13:51:58 +02:00
commit ab7da98bde
6 changed files with 84 additions and 20 deletions

View File

@ -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;
}
};

View File

@ -2,7 +2,7 @@
#include "map.h"
#include <cstring>
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

View File

@ -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

View File

@ -32,13 +32,18 @@ Simulation::~Simulation()
void Simulation::update()
{
std::random_shuffle(m_dudes.begin(), m_dudes.end());
for (int i=0; i<m_dudes.size(); ++i){
for (unsigned int i=0; i<m_dudes.size(); ++i){
Dude *dude = m_dudes[i];
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; i<m_teams.size(); ++i){
for(unsigned int i=0; i<m_teams.size(); ++i){
Team &t = m_teams[i];
if(t.updateSpawn())
{
@ -77,8 +82,8 @@ void Simulation::handleAction(Dude *dude)
if(PixelProperty::isDestructible(target.type))
{
dude->setSuccess(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
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)
if(dude->getCom() == nullptr){
dude->receiveComData(action.dir, target.data.knowledge + offset);
else
{
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();
}
}

View File

@ -2,6 +2,8 @@
#define SIMULATION_H
#include <vector>
#include <set>
#include <tuple>
#include "behavior.h"
#include "team.h"
@ -10,9 +12,21 @@ class MapScene;
class Simulation
{
private:
typedef std::pair<Dude*,Dude*> 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<Dude*> m_dudes;
std::vector<Team> m_teams;
std::set<Battle,battleComparator> m_battles;
void handleAction(Dude* dude);
void resolveBattles();
public:
Simulation(MapScene *_map, std::vector<BehaviorFunction> &_behaviors);
~Simulation();
@ -23,7 +37,6 @@ public:
* @brief update runs one step of simulation
*/
void update();
void handleAction(Dude* dude);
};
#endif // SIMULATION_H