mirror of
https://github.com/brmlab/brmlife.git
synced 2025-08-02 18:03:37 +02:00
Evolve herbs dynamically based on energy
This commit is contained in:
parent
4d697adc83
commit
0e1243f86f
7 changed files with 83 additions and 19 deletions
28
agent.cc
28
agent.cc
|
@ -143,4 +143,30 @@ agent::~agent()
|
||||||
conn->cancel();
|
conn->cancel();
|
||||||
conn = NULL;
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
4
agent.h
4
agent.h
|
@ -42,7 +42,7 @@ public:
|
||||||
void die(void);
|
void die(void);
|
||||||
|
|
||||||
void on_action_takes(void);
|
void on_action_takes(void);
|
||||||
void on_tick(void);
|
virtual void on_tick(void);
|
||||||
void on_senses_update(void);
|
void on_senses_update(void);
|
||||||
|
|
||||||
~agent();
|
~agent();
|
||||||
|
@ -58,6 +58,8 @@ public:
|
||||||
attr.attack = 0;
|
attr.attack = 0;
|
||||||
attr.defense = 0;
|
attr.defense = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void on_tick(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
37
main.cc
37
main.cc
|
@ -19,6 +19,24 @@
|
||||||
|
|
||||||
int tick_id = 0;
|
int tick_id = 0;
|
||||||
|
|
||||||
|
int agent_id = 0;
|
||||||
|
std::list<class agent *> agents;
|
||||||
|
|
||||||
|
static void
|
||||||
|
drop_agents(void)
|
||||||
|
{
|
||||||
|
for (std::list<class agent *>::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
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -42,13 +60,10 @@ main(int argc, char *argv[])
|
||||||
int flags = fcntl(lfd, F_GETFL, 0);
|
int flags = fcntl(lfd, F_GETFL, 0);
|
||||||
fcntl(lfd, F_SETFL, flags | O_NONBLOCK);
|
fcntl(lfd, F_SETFL, flags | O_NONBLOCK);
|
||||||
|
|
||||||
std::list<class agent *> agents;
|
|
||||||
int aid = 0;
|
|
||||||
|
|
||||||
/* Spawn herbs. */
|
/* Spawn herbs. */
|
||||||
|
|
||||||
for (int i = 0; i < herbs; i++) {
|
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);
|
agents.push_back(a);
|
||||||
a->spawn();
|
a->spawn();
|
||||||
}
|
}
|
||||||
|
@ -60,23 +75,14 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
/* Drop disconnected agents. */
|
/* Drop disconnected agents. */
|
||||||
|
|
||||||
for (std::list<class agent *>::iterator agent = agents.begin(); agent != agents.end(); agent++)
|
drop_agents();
|
||||||
{
|
|
||||||
next_agent:
|
|
||||||
if ((*agent)->conn && (*agent)->conn->error) {
|
|
||||||
delete *agent;
|
|
||||||
agent = agents.erase(agent);
|
|
||||||
if (agent != agents.end())
|
|
||||||
goto next_agent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Accept new agents. */
|
/* Accept new agents. */
|
||||||
|
|
||||||
int cfd = accept(lfd, NULL, NULL);
|
int cfd = accept(lfd, NULL, NULL);
|
||||||
if (cfd >= 0) {
|
if (cfd >= 0) {
|
||||||
class connection *conn = new class connection(cfd);
|
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);
|
agents.push_back(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +96,7 @@ next_agent:
|
||||||
map.on_tick();
|
map.on_tick();
|
||||||
for (std::list<class agent *>::iterator agent = agents.begin(); agent != agents.end(); agent++)
|
for (std::list<class agent *>::iterator agent = agents.begin(); agent != agents.end(); agent++)
|
||||||
(*agent)->on_tick();
|
(*agent)->on_tick();
|
||||||
|
drop_agents(); /* Some agents might have died. */
|
||||||
|
|
||||||
/* Update agents' senses. */
|
/* Update agents' senses. */
|
||||||
|
|
||||||
|
|
6
main.h
6
main.h
|
@ -1,6 +1,12 @@
|
||||||
#ifndef BRMLIFE__MAIN_H
|
#ifndef BRMLIFE__MAIN_H
|
||||||
#define BRMLIFE__MAIN_H
|
#define BRMLIFE__MAIN_H
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
class agent;
|
||||||
|
|
||||||
|
extern int agent_id;
|
||||||
extern int tick_id;
|
extern int tick_id;
|
||||||
|
extern std::list<class agent *> agents;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
21
map.cc
21
map.cc
|
@ -4,6 +4,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "agent.h"
|
#include "agent.h"
|
||||||
|
#include "main.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -24,6 +25,26 @@ tile::on_agent_leave(class agent &a)
|
||||||
void
|
void
|
||||||
tile::on_tick(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<herb *> (agent)) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char
|
char
|
||||||
|
|
1
map.h
1
map.h
|
@ -19,6 +19,7 @@ public:
|
||||||
char *str(void);
|
char *str(void);
|
||||||
|
|
||||||
class tile &tile_in_dir(int dir_x, int dir_y);
|
class tile &tile_in_dir(int dir_x, int dir_y);
|
||||||
|
bool herb_here(void);
|
||||||
|
|
||||||
virtual bool on_agent_enter(class agent &);
|
virtual bool on_agent_enter(class agent &);
|
||||||
virtual void on_agent_leave(class agent &);
|
virtual void on_agent_leave(class agent &);
|
||||||
|
|
5
world.h
5
world.h
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
struct world {
|
struct world {
|
||||||
const static int newborn_energy = 5000;
|
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 move_cost = -50;
|
||||||
const static int attack_cost = -400;
|
const static int attack_cost = -400;
|
||||||
|
@ -13,12 +13,13 @@ struct world {
|
||||||
const static int attack_idle_cost = -15; /* ... * attr.attack */
|
const static int attack_idle_cost = -15; /* ... * attr.attack */
|
||||||
const static int defense_idle_cost = -15; /* ... * attr.defense */
|
const static int defense_idle_cost = -15; /* ... * attr.defense */
|
||||||
const static int sun_energy = 10;
|
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 int dead_body_energy = 2000;
|
||||||
const static double dead_body_energy_carryover = 0.5;
|
const static double dead_body_energy_carryover = 0.5;
|
||||||
const static int dead_decay = -10;
|
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
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue