mirror of
				https://github.com/brmlab/brmlife.git
				synced 2025-10-29 23:43:59 +01: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 = 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 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 | ||||
|  |  | |||
							
								
								
									
										37
									
								
								main.cc
									
										
									
									
									
								
							
							
						
						
									
										37
									
								
								main.cc
									
										
									
									
									
								
							|  | @ -19,6 +19,24 @@ | |||
| 
 | ||||
| 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 | ||||
| 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<class agent *> 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<class agent *>::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<class agent *>::iterator agent = agents.begin(); agent != agents.end(); agent++) | ||||
| 			(*agent)->on_tick(); | ||||
| 		drop_agents(); /* Some agents might have died. */ | ||||
| 
 | ||||
| 		/* Update agents' senses. */ | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										6
									
								
								main.h
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								main.h
									
										
									
									
									
								
							|  | @ -1,6 +1,12 @@ | |||
| #ifndef BRMLIFE__MAIN_H | ||||
| #define BRMLIFE__MAIN_H | ||||
| 
 | ||||
| #include <list> | ||||
| 
 | ||||
| class agent; | ||||
| 
 | ||||
| extern int agent_id; | ||||
| extern int tick_id; | ||||
| extern std::list<class agent *> agents; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										21
									
								
								map.cc
									
										
									
									
									
								
							
							
						
						
									
										21
									
								
								map.cc
									
										
									
									
									
								
							|  | @ -4,6 +4,7 @@ | |||
| #include <iostream> | ||||
| 
 | ||||
| #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<herb *> (agent)) != NULL; | ||||
| } | ||||
| 
 | ||||
| char | ||||
|  |  | |||
							
								
								
									
										1
									
								
								map.h
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								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 &); | ||||
|  |  | |||
							
								
								
									
										5
									
								
								world.h
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								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 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Petr Baudis
						Petr Baudis