diff --git a/agent.cc b/agent.cc index a595140..fb71fbc 100644 --- a/agent.cc +++ b/agent.cc @@ -143,4 +143,30 @@ agent::~agent() conn->cancel(); conn = NULL; } -}; +} + + +static void +spawn_herb(class tile &t) +{ + if (t.agent) + return; + class herb *h = new class herb(agent_id++, t.map); + agents.push_back(h); + h->spawn_at(t); +} + +void +herb::on_tick(void) +{ + agent::on_tick(); + + assert(tile); + if (energy > 4 * world::herb_energy) { + spawn_herb(tile->tile_in_dir(1, 0)); + spawn_herb(tile->tile_in_dir(0, 1)); + spawn_herb(tile->tile_in_dir(-1, 0)); + spawn_herb(tile->tile_in_dir(0, -1)); + die(); + } +} diff --git a/agent.h b/agent.h index d080b44..968ec27 100644 --- a/agent.h +++ b/agent.h @@ -42,7 +42,7 @@ public: void die(void); void on_action_takes(void); - void on_tick(void); + virtual void on_tick(void); void on_senses_update(void); ~agent(); @@ -58,6 +58,8 @@ public: attr.attack = 0; attr.defense = 0; } + + void on_tick(void); }; #endif diff --git a/main.cc b/main.cc index f157c8c..95eaf37 100644 --- a/main.cc +++ b/main.cc @@ -19,6 +19,24 @@ int tick_id = 0; +int agent_id = 0; +std::list agents; + +static void +drop_agents(void) +{ + for (std::list::iterator agent = agents.begin(); agent != agents.end(); agent++) + { +next_agent: + if (((*agent)->conn && (*agent)->conn->error) || (*agent)->dead) { + delete *agent; + agent = agents.erase(agent); + if (agent != agents.end()) + goto next_agent; + } + } +} + int main(int argc, char *argv[]) { @@ -42,13 +60,10 @@ main(int argc, char *argv[]) int flags = fcntl(lfd, F_GETFL, 0); fcntl(lfd, F_SETFL, flags | O_NONBLOCK); - std::list agents; - int aid = 0; - /* Spawn herbs. */ for (int i = 0; i < herbs; i++) { - class agent *a = new class herb(aid++, map); + class agent *a = new class herb(agent_id++, map); agents.push_back(a); a->spawn(); } @@ -60,23 +75,14 @@ main(int argc, char *argv[]) /* Drop disconnected agents. */ - for (std::list::iterator agent = agents.begin(); agent != agents.end(); agent++) - { -next_agent: - if ((*agent)->conn && (*agent)->conn->error) { - delete *agent; - agent = agents.erase(agent); - if (agent != agents.end()) - goto next_agent; - } - } + drop_agents(); /* Accept new agents. */ int cfd = accept(lfd, NULL, NULL); if (cfd >= 0) { class connection *conn = new class connection(cfd); - class agent *a = new class agent(aid++, conn, map); + class agent *a = new class agent(agent_id++, conn, map); agents.push_back(a); } @@ -90,6 +96,7 @@ next_agent: map.on_tick(); for (std::list::iterator agent = agents.begin(); agent != agents.end(); agent++) (*agent)->on_tick(); + drop_agents(); /* Some agents might have died. */ /* Update agents' senses. */ diff --git a/main.h b/main.h index 487982c..be92079 100644 --- a/main.h +++ b/main.h @@ -1,6 +1,12 @@ #ifndef BRMLIFE__MAIN_H #define BRMLIFE__MAIN_H +#include + +class agent; + +extern int agent_id; extern int tick_id; +extern std::list agents; #endif diff --git a/map.cc b/map.cc index 0a9c392..681b5c0 100644 --- a/map.cc +++ b/map.cc @@ -4,6 +4,7 @@ #include #include "agent.h" +#include "main.h" #include "map.h" bool @@ -24,6 +25,26 @@ tile::on_agent_leave(class agent &a) void tile::on_tick(void) { + int herbs = 0; + herbs += tile_in_dir(1, 0).herb_here(); + herbs += tile_in_dir(0, 1).herb_here(); + herbs += tile_in_dir(-1, 0).herb_here(); + herbs += tile_in_dir(0, -1).herb_here(); + herbs += herb_here(); + + if (herbs) { + if (herb_here()) { agent->chenergy(world::soil_energy / herbs); } + if (tile_in_dir(1, 0).herb_here()) { tile_in_dir(1, 0).agent->chenergy(world::soil_energy / herbs); } + if (tile_in_dir(0, 1).herb_here()) { tile_in_dir(0, 1).agent->chenergy(world::soil_energy / herbs); } + if (tile_in_dir(-1, 0).herb_here()) { tile_in_dir(-1, 0).agent->chenergy(world::soil_energy / herbs); } + if (tile_in_dir(0, -1).herb_here()) { tile_in_dir(0, -1).agent->chenergy(world::soil_energy / herbs); } + } +} + +bool +tile::herb_here(void) +{ + return agent && (dynamic_cast (agent)) != NULL; } char diff --git a/map.h b/map.h index e80e27a..9f7027e 100644 --- a/map.h +++ b/map.h @@ -19,6 +19,7 @@ public: char *str(void); class tile &tile_in_dir(int dir_x, int dir_y); + bool herb_here(void); virtual bool on_agent_enter(class agent &); virtual void on_agent_leave(class agent &); diff --git a/world.h b/world.h index daf8419..1ca46a0 100644 --- a/world.h +++ b/world.h @@ -3,7 +3,7 @@ struct world { const static int newborn_energy = 5000; - const static int herb_energy = 1500; + const static int herb_energy = 1000; const static int move_cost = -50; const static int attack_cost = -400; @@ -13,12 +13,13 @@ struct world { const static int attack_idle_cost = -15; /* ... * attr.attack */ const static int defense_idle_cost = -15; /* ... * attr.defense */ const static int sun_energy = 10; + const static int soil_energy = 10; /* ... times five for lone herbs, times one for dense forests */ const static int dead_body_energy = 2000; const static double dead_body_energy_carryover = 0.5; const static int dead_decay = -10; - const static int herb_rate = 20; /* one herb per herb_rate tiles */ + const static int herb_rate = 15; /* initially, one herb per herb_rate tiles */ }; #endif