Merge branch 'master' of https://git.epicsparrow.com/epicsparrow/PixelWars
This commit is contained in:
commit
ab7da98bde
@ -75,7 +75,7 @@ struct Coord
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct CoordHash{
|
struct CoordHash{
|
||||||
size_t operator()(const Coord& val) const{
|
std::size_t operator()(const Coord& val) const{
|
||||||
return val.x+10000*val.y;
|
return val.x+10000*val.y;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
Dude::Dude(const Coord &_pos, Map *_map, int &_team) :
|
Dude::Dude(const Coord &_pos, Map *_map, const int &_team) :
|
||||||
m_pos(_pos),
|
m_pos(_pos),
|
||||||
p_map(_map),
|
p_map(_map),
|
||||||
m_team(_team),
|
m_team(_team),
|
||||||
@ -49,6 +49,7 @@ void Dude::update(BehaviorFunction func)
|
|||||||
{
|
{
|
||||||
func(&m_action, m_memory, (Info*)this);
|
func(&m_action, m_memory, (Info*)this);
|
||||||
m_receivedComData = false;
|
m_receivedComData = false;
|
||||||
|
memcpy(m_com_data.data, 0, COM_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
PixelType Dude::getNear(Dir d) const
|
PixelType Dude::getNear(Dir d) const
|
||||||
|
19
src/dude.h
19
src/dude.h
@ -20,22 +20,31 @@ private:
|
|||||||
int m_underResCount;
|
int m_underResCount;
|
||||||
|
|
||||||
public:
|
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; }
|
const Action& getAction() { return m_action; }
|
||||||
int getTeam(){ return m_team; }
|
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; }
|
void perish() { m_dead = true; }
|
||||||
|
|
||||||
|
//movement-related function
|
||||||
const Coord& getPos() { return m_pos; }
|
const Coord& getPos() { return m_pos; }
|
||||||
void move(Dir d);
|
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 bool getSuccess() const { return m_success; }
|
||||||
virtual PixelType getInventory() const { return m_inventory; }
|
virtual PixelType getInventory() const { return m_inventory; }
|
||||||
virtual const Com* getCom() const { return m_receivedComData ? &m_com_data : nullptr; }
|
virtual const Com* getCom() const { return m_receivedComData ? &m_com_data : nullptr; }
|
||||||
virtual PixelType getNear(Dir d) const;
|
virtual PixelType getNear(Dir d) const;
|
||||||
virtual int getInfo(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
|
#endif // DUDE_H
|
||||||
|
@ -11,7 +11,7 @@ struct Pixel
|
|||||||
int nbRes; // RESOURCES
|
int nbRes; // RESOURCES
|
||||||
char *knowledge; // LIBRARY
|
char *knowledge; // LIBRARY
|
||||||
int teamId; // SPAWN
|
int teamId; // SPAWN
|
||||||
Dude* dudePtr; // DUDE
|
Dude *dudePtr; // DUDE
|
||||||
};
|
};
|
||||||
|
|
||||||
PixelType type;
|
PixelType type;
|
||||||
|
@ -32,13 +32,18 @@ Simulation::~Simulation()
|
|||||||
void Simulation::update()
|
void Simulation::update()
|
||||||
{
|
{
|
||||||
std::random_shuffle(m_dudes.begin(), m_dudes.end());
|
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];
|
Dude *dude = m_dudes[i];
|
||||||
m_teams[dude->getTeam()].update(dude); //get action for this dude from behavior function in team
|
if (dude->isAlive()){
|
||||||
handleAction(dude);
|
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 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];
|
Team &t = m_teams[i];
|
||||||
if(t.updateSpawn())
|
if(t.updateSpawn())
|
||||||
{
|
{
|
||||||
@ -77,8 +82,8 @@ void Simulation::handleAction(Dude *dude)
|
|||||||
if(PixelProperty::isDestructible(target.type))
|
if(PixelProperty::isDestructible(target.type))
|
||||||
{
|
{
|
||||||
dude->setSuccess(true);
|
dude->setSuccess(true);
|
||||||
if (target.type == DUDE) // TODO: add fight between dude and targetDude
|
if (target.type == DUDE) //DONE
|
||||||
NULL;
|
m_battles.insert(Battle(dude,target.data.dudePtr));
|
||||||
else // DONE
|
else // DONE
|
||||||
{
|
{
|
||||||
if(target.type == SPAWN)
|
if(target.type == SPAWN)
|
||||||
@ -190,17 +195,23 @@ void Simulation::handleAction(Dude *dude)
|
|||||||
{
|
{
|
||||||
Dude *targetDude = target.data.dudePtr;
|
Dude *targetDude = target.data.dudePtr;
|
||||||
// TODO check conflicts between writers
|
// TODO check conflicts between writers
|
||||||
targetDude->receiveComData(Dir((action.dir+2)%4), targetDude->getAction().com_data.data);
|
if(targetDude->getCom() == nullptr){
|
||||||
dude->setSuccess(true);
|
targetDude->receiveComData(Dir((action.dir+2)%4), targetDude->getAction().com_data.data);
|
||||||
|
dude->setSuccess(true);
|
||||||
|
}else
|
||||||
|
dude->setSuccess(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LIBRARY:
|
case LIBRARY:
|
||||||
{
|
{
|
||||||
int offset = (action.com_data.flag & 3)*COM_SIZE;
|
int offset = (action.com_data.flag & 3)*COM_SIZE;
|
||||||
if(action.com_data.flag & Com::READ)
|
if(action.com_data.flag & Com::READ)
|
||||||
dude->receiveComData(action.dir, target.data.knowledge + offset);
|
if(dude->getCom() == nullptr){
|
||||||
else
|
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);
|
memcpy(target.data.knowledge + offset, action.com_data.data, COM_SIZE);
|
||||||
dude->setSuccess(true);
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#define SIMULATION_H
|
#define SIMULATION_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
#include <tuple>
|
||||||
#include "behavior.h"
|
#include "behavior.h"
|
||||||
#include "team.h"
|
#include "team.h"
|
||||||
|
|
||||||
@ -10,9 +12,21 @@ class MapScene;
|
|||||||
class Simulation
|
class Simulation
|
||||||
{
|
{
|
||||||
private:
|
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;
|
MapScene *p_map;
|
||||||
std::vector<Dude*> m_dudes;
|
std::vector<Dude*> m_dudes;
|
||||||
std::vector<Team> m_teams;
|
std::vector<Team> m_teams;
|
||||||
|
std::set<Battle,battleComparator> m_battles;
|
||||||
|
|
||||||
|
void handleAction(Dude* dude);
|
||||||
|
void resolveBattles();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Simulation(MapScene *_map, std::vector<BehaviorFunction> &_behaviors);
|
Simulation(MapScene *_map, std::vector<BehaviorFunction> &_behaviors);
|
||||||
~Simulation();
|
~Simulation();
|
||||||
@ -23,7 +37,6 @@ public:
|
|||||||
* @brief update runs one step of simulation
|
* @brief update runs one step of simulation
|
||||||
*/
|
*/
|
||||||
void update();
|
void update();
|
||||||
void handleAction(Dude* dude);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SIMULATION_H
|
#endif // SIMULATION_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user