diff --git a/behaviors/war_charge_east.cpp b/behaviors/war_charge_east.cpp new file mode 100644 index 0000000..7629c3b --- /dev/null +++ b/behaviors/war_charge_east.cpp @@ -0,0 +1,393 @@ +#include +#include "behavior.h" + +// g++ -shared war_charge_east.cpp -o war_charge_east.dll -std=c++11 -I../src + +#define KING_POS Coord(2, 2) +#define ARMY_POS Coord(12, 4) +#define CHARGE_DIR EAST + +enum Purpose { NEWBORN, KING, PEASANT, SOLDIER }; + +struct KingMemory{ // 16 bytes + int nbPeasants; + int nbSoldiers; + int date; + Dir last_audience_dir; +}; + +struct PeasantMemory{ // 8 bytes + bool tried_picking_up_food; + bool brings_food; +}; + +struct SoldierMemory{ // 16 bytes + Coord target; + int charge_countdown; + bool commander; +}; + +union JobMemory { // 16 bytes + KingMemory king; + PeasantMemory peasant; + SoldierMemory soldier; +}; + +struct memory_data{ // 104 bytes + // 40 bytes + JobMemory job; + Coord pos; + bool new_born; + int purpose; + Dir last_dir; + Action::Type last_action; + // 64 bytes + char debugStr[64]; +}; + +const char* PURPOSES_STRINGS[] { + "Newborn", + "King", + "Peasant", + "Soldier" +}; + +extern "C" void debugOutput(char *outputString, const char *memory) +{ + memory_data* data = (memory_data*)memory; + sprintf(outputString, "%s\n%s", PURPOSES_STRINGS[data->purpose], data->debugStr); + if(data->purpose == KING) + { + sprintf(outputString, "%s\nRuled the kingdom for %d ticks\npopulation :\n%d peasants\n%d soldiers", + outputString, data->job.king.date, data->job.king.nbPeasants, data->job.king.nbSoldiers); + } +} + +extern "C" void think(Action *action, char *memory, const Info *info) +{ + int i; + PixelType type; + + bool success = info->getSuccess(); + memory_data* data = (memory_data*)memory; + data->debugStr[0] = '\0'; + + // if freshly spawned, init the position variable by looking in which direction is the spawn + if(!data->new_born){ + success = false; + data->new_born = true; + for(i=0; i<4; i++) + { + type = info->getNear(Dir(i)); + if(type == SPAWN) + { + data->pos = Coord(0) - Dir(i); + break; + } + } + } + + // update position if last successful action was moving + if(data->last_action == Action::MOVE){ + if(success) + data->pos += data->last_dir; + else + { + int blockedCount = 0; + action->type = Action::MOVE; + do{ + action->dir = Dir((data->last_dir + rand()%3)%4); + type = info->getNear(action->dir); + ++blockedCount; + if(blockedCount > 3) + { + action->type = Action::WAIT; + break; + } + }while(!PixelProperty::isWalkable(type)); + data->last_dir = action->dir; + data->last_action = action->type; + sprintf(data->debugStr, "moving around obstacle"); + return; + } + } + + // work any workable resource when encountered + if(data->purpose == SOLDIER && data->job.soldier.charge_countdown == 0) + { + action->dir = CHARGE_DIR; + PixelType front = info->getNear(CHARGE_DIR); + if(!PixelProperty::isWalkable(front)) + { + if(PixelProperty::isDestructible(front)) + action->type = Action::ATTACK; + else if(PixelProperty::isResource(front)) + { + if(info->getInventory() != EMPTY) + { + action->type = Action::PUT; + action->dir = Dir((CHARGE_DIR+2)%4); + } + else + action->type = Action::PICK; + } + else + action->type = Action::WORK; + } + else + action->type = Action::MOVE; + data->last_dir = action->dir; + data->last_action = action->type; + sprintf(data->debugStr, "CHAAAAAAAAAARGE !"); + return; + } + else + { + for(i=0; i<4; i++){ + type = info->getNear(Dir(i)); + if(type == BERRIES || type == TREE || type == IRON_ORE || type == ROCK){ + action->type = Action::WORK; + action->dir = Dir(i); + data->last_dir = action->dir; + data->last_action = action->type; + sprintf(data->debugStr, "working on resource"); + return; + }else if(type == FOOD && data->purpose == PEASANT + && !(data->job.peasant.brings_food) && !(data->job.peasant.tried_picking_up_food)){ + action->type = Action::PICK; + action->dir = Dir(i); + data->job.peasant.tried_picking_up_food = true; + data->last_dir = action->dir; + data->last_action = action->type; + sprintf(data->debugStr, "picking up food"); + return; + } + } + } + + // do your job + switch(data->purpose) + { + case NEWBORN : + { + const Com* com = info->getCom(); + if(com != nullptr) // no activity + { + switch(com->data[0]) + { + case 'p': data->purpose = PEASANT; break; + case 's': + data->purpose = SOLDIER; + data->job.soldier.target.x = *((int*)(com->data+2)); + data->job.soldier.target.y = *((int*)(com->data+6)); + data->job.soldier.commander = bool(com->data[10]); + data->job.soldier.charge_countdown = *((int*)(com->data+11)); + break; + default: break; + } + action->type = Action::WAIT; + data->last_action = action->type; + sprintf(data->debugStr, "receiving job : %s", com->data); + return; + } + Coord target = data->pos - KING_POS; + int distance = target.dist(); + if(distance == 0) // i am the new king + { + data->job.king.last_audience_dir = NO_DIR; + data->purpose = KING; + action->type = Action::WAIT; + data->last_action = action->type; + sprintf(data->debugStr, "I AM THE KING, LONG LIVE THE KING"); + return; + } + // if adjacent to the king's position, speak to the king if there is one + if(distance == 1){ + for(i=0; i<4; i++){ + type = info->getNear(Dir(i)); + if(Coord(Dir((i+2)%4)) == target && type == DUDE){ // it is the king + action->dir = Dir(i); + action->type = Action::COMMUNICATE; + action->com_data.data[0] = 'n'; // "give me a purpose" + data->last_dir = action->dir; + data->last_action = action->type; + sprintf(data->debugStr, "asking the king to give me a task"); + return; + } + } + } + // move to the king's position + action->type = Action::MOVE; + do{ + action->dir = Dir( rand() % 4 ); + }while(~(target + action->dir) > distance && distance != 0); + data->last_dir = action->dir; + data->last_action = action->type; + sprintf(data->debugStr, "walking to the king's throne"); + return; + } + break; + case KING : + { + data->job.king.date += 1; + const Com* com = info->getCom(); + if(com == nullptr || data->job.king.last_audience_dir == Dir(com->flag)) // no activity + { + data->job.king.last_audience_dir = NO_DIR; + action->type = Action::WAIT; + data->last_action = action->type; + sprintf(data->debugStr, "waiting for a subject to ask for an audience"); + return; + } + // someone requests an audience to the king + char request = com->data[0]; + if(request == 'n') + { + int population = data->job.king.nbPeasants + data->job.king.nbSoldiers; + if(population < 15 || data->job.king.nbPeasants < (2*population)/3) + { + action->com_data.data[0] = 'p'; // "thou shall be peasant" + data->job.king.nbPeasants += 1; + } + else + { + action->com_data.data[0] = 's'; // "thou shall serve me as a soldier" + Coord target = ARMY_POS; + target.y -= data->job.king.nbSoldiers % 10; + target.x -= data->job.king.nbSoldiers / 10; + Coord* ptr = (Coord*)(action->com_data.data + 2); + *ptr = target; + *((int*)(action->com_data.data+11)) = -1; + data->job.king.nbSoldiers += 1; + + if(data->job.king.nbSoldiers % 10 == 9) + { + action->com_data.data[10] = 1; // "thou shall command the army to march on the corpses of our foes" + *((int*)(action->com_data.data+11)) = 10; + } + } + } + else + action->com_data.data[0] = 'f'; // "you dare disturb me from my royal occupations ? Go "f" yourself !" + + data->job.king.last_audience_dir = Dir(com->flag); + action->dir = Dir(com->flag); + action->type = Action::COMMUNICATE; + data->last_dir = action->dir; + data->last_action = action->type; + sprintf(data->debugStr, "receiving request : %s\ngiving job : %s", com->data, action->com_data.data); + return; + } + case PEASANT : + { + if(data->job.peasant.tried_picking_up_food && success) + data->job.peasant.brings_food = true; + data->job.peasant.tried_picking_up_food = false; + + if(data->job.peasant.brings_food){ + int distance = data->pos.dist(); + if(distance == 1){ + action->type = Action::MOVE; + action->dir = NORTH; + + for(i=0; i<4; i++){ + type = info->getNear(Dir(i)); + if(type == SPAWN){ + action->dir = Dir(i); + action->type = Action::PUT; + data->job.peasant.brings_food = false; + break; + } + } + }else{ + action->type = Action::MOVE; + do{ + action->dir = Dir( rand() % 4 ); + }while(~(data->pos + action->dir) > distance && distance != 0); + + } + data->last_dir = action->dir; + data->last_action = action->type; + sprintf(data->debugStr, "bringing food back to the spawn"); + return; + } + } + break; + case SOLDIER : + { + Coord target = data->pos - data->job.soldier.target; + int distance = target.dist(); + const Com* com = info->getCom(); + if(com != nullptr) + { + int charge_countdown = *((int*)(com->data)); + data->job.soldier.charge_countdown = charge_countdown; + *((int*)(action->com_data.data))= charge_countdown - 1; + action->type = Action::COMMUNICATE; + action->dir = Dir((com->flag+2)%4); + data->last_dir = action->dir; + sprintf(data->debugStr, "receiving orders"); + } + else if(distance == 0) + { + if(data->job.soldier.charge_countdown > 0) + { + if(data->job.soldier.commander) + { + data->job.soldier.commander = false; + *((int*)(action->com_data.data))= data->job.soldier.charge_countdown; + action->type = Action::COMMUNICATE; + action->dir = Dir(SOUTH); + data->last_dir = action->dir; + sprintf(data->debugStr, "Notifying the troops that we are going into battle"); + } + else + { + action->type = Action::WAIT; + data->job.soldier.charge_countdown -= 1; + sprintf(data->debugStr, "Charge in %d...", data->job.soldier.charge_countdown); + } + } + else + { + action->type = Action::WAIT; + sprintf(data->debugStr, "waiting orders"); + } + } + else + { + action->type = Action::MOVE; + do{ + action->dir = Dir( rand() % 4 ); + }while(~(target + action->dir) > distance && distance != 0); + data->last_dir = action->dir; + sprintf(data->debugStr, "going into formation"); + } + data->last_action = action->type; + return; + } + break; + default: + break; + } + + // wander around + int blockedCount = 0; + action->type = Action::MOVE; + bool ok = false; + do{ + action->dir = Dir((data->last_dir + rand()%3)%4); + type = info->getNear(action->dir); + ok = PixelProperty::isWalkable(type) && !((data->pos + Coord(action->dir)).x > 12); // do not interfere with military formations + ++blockedCount; + if(blockedCount > 3) + { + action->type = Action::WAIT; + ok = true; + } + }while(!ok); + + data->last_dir = action->dir; + data->last_action = action->type; + sprintf(data->debugStr, "wandering around"); +} diff --git a/behaviors/war_charge_west.cpp b/behaviors/war_charge_west.cpp new file mode 100644 index 0000000..9c960ab --- /dev/null +++ b/behaviors/war_charge_west.cpp @@ -0,0 +1,393 @@ +#include +#include "behavior.h" + +// g++ -shared war_charge_west.cpp -o war_charge_west.dll -std=c++11 -I../src + +#define KING_POS Coord(2, 2) +#define ARMY_POS Coord(-12, 4) +#define CHARGE_DIR WEST + +enum Purpose { NEWBORN, KING, PEASANT, SOLDIER }; + +struct KingMemory{ // 16 bytes + int nbPeasants; + int nbSoldiers; + int date; + Dir last_audience_dir; +}; + +struct PeasantMemory{ // 8 bytes + bool tried_picking_up_food; + bool brings_food; +}; + +struct SoldierMemory{ // 16 bytes + Coord target; + int charge_countdown; + bool commander; +}; + +union JobMemory { // 16 bytes + KingMemory king; + PeasantMemory peasant; + SoldierMemory soldier; +}; + +struct memory_data{ // 104 bytes + // 40 bytes + JobMemory job; + Coord pos; + bool new_born; + int purpose; + Dir last_dir; + Action::Type last_action; + // 64 bytes + char debugStr[64]; +}; + +const char* PURPOSES_STRINGS[] { + "Newborn", + "King", + "Peasant", + "Soldier" +}; + +extern "C" void debugOutput(char *outputString, const char *memory) +{ + memory_data* data = (memory_data*)memory; + sprintf(outputString, "%s\n%s", PURPOSES_STRINGS[data->purpose], data->debugStr); + if(data->purpose == KING) + { + sprintf(outputString, "%s\nRuled the kingdom for %d ticks\npopulation :\n%d peasants\n%d soldiers", + outputString, data->job.king.date, data->job.king.nbPeasants, data->job.king.nbSoldiers); + } +} + +extern "C" void think(Action *action, char *memory, const Info *info) +{ + int i; + PixelType type; + + bool success = info->getSuccess(); + memory_data* data = (memory_data*)memory; + data->debugStr[0] = '\0'; + + // if freshly spawned, init the position variable by looking in which direction is the spawn + if(!data->new_born){ + success = false; + data->new_born = true; + for(i=0; i<4; i++) + { + type = info->getNear(Dir(i)); + if(type == SPAWN) + { + data->pos = Coord(0) - Dir(i); + break; + } + } + } + + // update position if last successful action was moving + if(data->last_action == Action::MOVE){ + if(success) + data->pos += data->last_dir; + else + { + int blockedCount = 0; + action->type = Action::MOVE; + do{ + action->dir = Dir((data->last_dir + rand()%3)%4); + type = info->getNear(action->dir); + ++blockedCount; + if(blockedCount > 3) + { + action->type = Action::WAIT; + break; + } + }while(!PixelProperty::isWalkable(type)); + data->last_dir = action->dir; + data->last_action = action->type; + sprintf(data->debugStr, "moving around obstacle"); + return; + } + } + + // work any workable resource when encountered + if(data->purpose == SOLDIER && data->job.soldier.charge_countdown == 0) + { + action->dir = CHARGE_DIR; + PixelType front = info->getNear(CHARGE_DIR); + if(!PixelProperty::isWalkable(front)) + { + if(PixelProperty::isDestructible(front)) + action->type = Action::ATTACK; + else if(PixelProperty::isResource(front)) + { + if(info->getInventory() != EMPTY) + { + action->type = Action::PUT; + action->dir = Dir((CHARGE_DIR+2)%4); + } + else + action->type = Action::PICK; + } + else + action->type = Action::WORK; + } + else + action->type = Action::MOVE; + data->last_dir = action->dir; + data->last_action = action->type; + sprintf(data->debugStr, "CHAAAAAAAAAARGE !"); + return; + } + else + { + for(i=0; i<4; i++){ + type = info->getNear(Dir(i)); + if(type == BERRIES || type == TREE || type == IRON_ORE || type == ROCK){ + action->type = Action::WORK; + action->dir = Dir(i); + data->last_dir = action->dir; + data->last_action = action->type; + sprintf(data->debugStr, "working on resource"); + return; + }else if(type == FOOD && data->purpose == PEASANT + && !(data->job.peasant.brings_food) && !(data->job.peasant.tried_picking_up_food)){ + action->type = Action::PICK; + action->dir = Dir(i); + data->job.peasant.tried_picking_up_food = true; + data->last_dir = action->dir; + data->last_action = action->type; + sprintf(data->debugStr, "picking up food"); + return; + } + } + } + + // do your job + switch(data->purpose) + { + case NEWBORN : + { + const Com* com = info->getCom(); + if(com != nullptr) // no activity + { + switch(com->data[0]) + { + case 'p': data->purpose = PEASANT; break; + case 's': + data->purpose = SOLDIER; + data->job.soldier.target.x = *((int*)(com->data+2)); + data->job.soldier.target.y = *((int*)(com->data+6)); + data->job.soldier.commander = bool(com->data[10]); + data->job.soldier.charge_countdown = *((int*)(com->data+11)); + break; + default: break; + } + action->type = Action::WAIT; + data->last_action = action->type; + sprintf(data->debugStr, "receiving job : %s", com->data); + return; + } + Coord target = data->pos - KING_POS; + int distance = target.dist(); + if(distance == 0) // i am the new king + { + data->job.king.last_audience_dir = NO_DIR; + data->purpose = KING; + action->type = Action::WAIT; + data->last_action = action->type; + sprintf(data->debugStr, "I AM THE KING, LONG LIVE THE KING"); + return; + } + // if adjacent to the king's position, speak to the king if there is one + if(distance == 1){ + for(i=0; i<4; i++){ + type = info->getNear(Dir(i)); + if(Coord(Dir((i+2)%4)) == target && type == DUDE){ // it is the king + action->dir = Dir(i); + action->type = Action::COMMUNICATE; + action->com_data.data[0] = 'n'; // "give me a purpose" + data->last_dir = action->dir; + data->last_action = action->type; + sprintf(data->debugStr, "asking the king to give me a task"); + return; + } + } + } + // move to the king's position + action->type = Action::MOVE; + do{ + action->dir = Dir( rand() % 4 ); + }while(~(target + action->dir) > distance && distance != 0); + data->last_dir = action->dir; + data->last_action = action->type; + sprintf(data->debugStr, "walking to the king's throne"); + return; + } + break; + case KING : + { + data->job.king.date += 1; + const Com* com = info->getCom(); + if(com == nullptr || data->job.king.last_audience_dir == Dir(com->flag)) // no activity + { + data->job.king.last_audience_dir = NO_DIR; + action->type = Action::WAIT; + data->last_action = action->type; + sprintf(data->debugStr, "waiting for a subject to ask for an audience"); + return; + } + // someone requests an audience to the king + char request = com->data[0]; + if(request == 'n') + { + int population = data->job.king.nbPeasants + data->job.king.nbSoldiers; + if(population < 15 || data->job.king.nbPeasants < (2*population)/3) + { + action->com_data.data[0] = 'p'; // "thou shall be peasant" + data->job.king.nbPeasants += 1; + } + else + { + action->com_data.data[0] = 's'; // "thou shall serve me as a soldier" + Coord target = ARMY_POS; + target.y -= data->job.king.nbSoldiers % 10; + target.x -= data->job.king.nbSoldiers / 10; + Coord* ptr = (Coord*)(action->com_data.data + 2); + *ptr = target; + *((int*)(action->com_data.data+11)) = -1; + data->job.king.nbSoldiers += 1; + + if(data->job.king.nbSoldiers % 10 == 9) + { + action->com_data.data[10] = 1; // "thou shall command the army to march on the corpses of our foes" + *((int*)(action->com_data.data+11)) = 10; + } + } + } + else + action->com_data.data[0] = 'f'; // "you dare disturb me from my royal occupations ? Go "f" yourself !" + + data->job.king.last_audience_dir = Dir(com->flag); + action->dir = Dir(com->flag); + action->type = Action::COMMUNICATE; + data->last_dir = action->dir; + data->last_action = action->type; + sprintf(data->debugStr, "receiving request : %s\ngiving job : %s", com->data, action->com_data.data); + return; + } + case PEASANT : + { + if(data->job.peasant.tried_picking_up_food && success) + data->job.peasant.brings_food = true; + data->job.peasant.tried_picking_up_food = false; + + if(data->job.peasant.brings_food){ + int distance = data->pos.dist(); + if(distance == 1){ + action->type = Action::MOVE; + action->dir = NORTH; + + for(i=0; i<4; i++){ + type = info->getNear(Dir(i)); + if(type == SPAWN){ + action->dir = Dir(i); + action->type = Action::PUT; + data->job.peasant.brings_food = false; + break; + } + } + }else{ + action->type = Action::MOVE; + do{ + action->dir = Dir( rand() % 4 ); + }while(~(data->pos + action->dir) > distance && distance != 0); + + } + data->last_dir = action->dir; + data->last_action = action->type; + sprintf(data->debugStr, "bringing food back to the spawn"); + return; + } + } + break; + case SOLDIER : + { + Coord target = data->pos - data->job.soldier.target; + int distance = target.dist(); + const Com* com = info->getCom(); + if(com != nullptr) + { + int charge_countdown = *((int*)(com->data)); + data->job.soldier.charge_countdown = charge_countdown; + *((int*)(action->com_data.data))= charge_countdown - 1; + action->type = Action::COMMUNICATE; + action->dir = Dir((com->flag+2)%4); + data->last_dir = action->dir; + sprintf(data->debugStr, "receiving orders"); + } + else if(distance == 0) + { + if(data->job.soldier.charge_countdown > 0) + { + if(data->job.soldier.commander) + { + data->job.soldier.commander = false; + *((int*)(action->com_data.data))= data->job.soldier.charge_countdown; + action->type = Action::COMMUNICATE; + action->dir = Dir(SOUTH); + data->last_dir = action->dir; + sprintf(data->debugStr, "Notifying the troops that we are going into battle"); + } + else + { + action->type = Action::WAIT; + data->job.soldier.charge_countdown -= 1; + sprintf(data->debugStr, "Charge in %d...", data->job.soldier.charge_countdown); + } + } + else + { + action->type = Action::WAIT; + sprintf(data->debugStr, "waiting orders"); + } + } + else + { + action->type = Action::MOVE; + do{ + action->dir = Dir( rand() % 4 ); + }while(~(target + action->dir) > distance && distance != 0); + data->last_dir = action->dir; + sprintf(data->debugStr, "going into formation"); + } + data->last_action = action->type; + return; + } + break; + default: + break; + } + + // wander around + int blockedCount = 0; + action->type = Action::MOVE; + bool ok = false; + do{ + action->dir = Dir((data->last_dir + rand()%3)%4); + type = info->getNear(action->dir); + ok = PixelProperty::isWalkable(type) && !((data->pos + Coord(action->dir)).x < -12); // do not interfere with military formations + ++blockedCount; + if(blockedCount > 3) + { + action->type = Action::WAIT; + ok = true; + } + }while(!ok); + + data->last_dir = action->dir; + data->last_action = action->type; + sprintf(data->debugStr, "wandering around"); +} diff --git a/src/dude.cpp b/src/dude.cpp index 039898a..a1bbebc 100644 --- a/src/dude.cpp +++ b/src/dude.cpp @@ -23,21 +23,27 @@ Dude::Dude(const Coord &_pos, Map *_map, const int &_team) : p_map->getPixel(m_pos).data.dudePtr = this; } +void Dude::perish() +{ + m_dead = true; + Pixel& p = p_map->getPixel(m_pos); + p.type = DEAD_DUDE; +} + void Dude::move(Dir d) { p_map->getPixel(m_pos).type = m_under; //if(PixelProperty::isResource(m_under)) // p_map->getPixel(m_pos).data.nbRes = m_underResCount; p_map->getPixel(m_pos).data.dudePtr = NULL; - - m_pos += Coord(d); + + m_pos = p_map->toreillerLoop(m_pos + Coord(d)); m_under = p_map->getPixel(m_pos).type; //if(PixelProperty::isResource(m_under)) // m_underResCount = p_map->getPixel(m_pos).data.nbRes; p_map->getPixel(m_pos).type = DUDE; p_map->getPixel(m_pos).data.dudePtr = this; - p_map->toreillerLoop(m_pos); } void Dude::receiveComData(Dir dir, const char *data) @@ -61,10 +67,10 @@ void Dude::debugOutput(char *outputString, DebugBehaviorFunction func) PixelType Dude::getNear(Dir d) const { - return p_map->getPixel(Coord(d) + m_pos).type; + return p_map->getPixel(p_map->toreillerLoop(Coord(d) + m_pos)).type; } int Dude::getInfo(Dir d) const { - return p_map->getPixel(Coord(d) + m_pos).data.nbRes; + return p_map->getPixel(p_map->toreillerLoop(Coord(d) + m_pos)).data.nbRes; } diff --git a/src/dude.h b/src/dude.h index 206432c..f54dc54 100644 --- a/src/dude.h +++ b/src/dude.h @@ -30,7 +30,7 @@ public: //life-related function bool isAlive() { return !m_dead; } - void perish() { m_dead = true; } + void perish(); //movement-related function const Coord& getPos() { return m_pos; } diff --git a/src/simulation.cpp b/src/simulation.cpp index 86fd068..cc19479 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -65,6 +65,7 @@ void Simulation::update() } resolveBattles(); + removeDead(); // for each team, spawn dude if condition met for(unsigned int i=0; isetSuccess(false); break; + case DEAD_DUDE: + { + PixelType inventory = target.data.dudePtr->getInventory(); + m_dead_dudes.emplace(target.data.dudePtr); + target.data.dudePtr = nullptr; + if(inventory != EMPTY) + { + target.type = inventory; + target.data.nbRes = 1; + } + else + target.type = GRASS; + dude->setSuccess(false); + } + break; default: dude->setSuccess(false); break; @@ -247,32 +263,51 @@ void Simulation::handleAction(Dude *dude) } } +void Simulation::removeDead() +{ + for(unsigned int i=0; iisAlive() && 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(); + attackerWins = false; }else if(armedAttacker){ if ((rand()%100 + 1) > 80) - attacker->perish(); - else - defender->perish(); + attackerWins = false; }else if(armedDefender){ if ((rand()%100 + 1) > 20) - attacker->perish(); - else - defender->perish(); + attackerWins = false; } - }else - defender->perish(); - }else + } + } + if(attackerWins) + { defender->perish(); + p_map->updatePixel(defender->getPos()); + } + else + { + attacker->perish(); + p_map->updatePixel(attacker->getPos()); + } } + m_battles.clear(); } diff --git a/src/simulation.h b/src/simulation.h index 1ba7c36..906b124 100644 --- a/src/simulation.h +++ b/src/simulation.h @@ -24,8 +24,10 @@ private: std::vector m_dudes; std::vector m_teams; std::set m_battles; + std::set m_dead_dudes; void handleAction(Dude* dude); + void removeDead(); void resolveBattles(); public: