#include "field.h"
ostream& operator<<(ostream& C, const Point &p)
{
C <<"("<
> :: iterator pos = grid.begin(); pos != grid.end(); pos++)
remove_agent(pos->first);
}
// put agent a to the cell p
void Field::plant_agent(const Point &p, Agent *a)
{
//check if the point is valid
if(p.x >= sx || p.y >= sy || p.x < 0 || p.y < 0 ) return;
//place the agent
map >::iterator iter = grid.find(p);
iter->second.insert(pair(a->priority(),a));
//increment the number of agents
++Field::no_agents;
}
// return the total number of agents currently on the field
long Field::n_of_agents() const
{
return Field::no_agents;
}
// return the number of agents in the cell p
long Field::n_of_agents(const Point &p) const
{
return grid.find(p)->second.size();
}
// return a pointer to the i-th agent in the cell p
const Agent* Field::get_agent(const Point &p, long i) const
{
if (i < 0 || i >= n_of_agents(p)) return NULL;
multimap::const_iterator pos;
long j = 0;
for( pos = grid.find(p)->second.begin(); j!= i; ++pos)
++j;
return pos->second;
}
// if i>=0 or i= n_of_agents(p)) return ;
multimap::iterator pos;
long j = 0;
for(pos = grid.find(p)->second.begin(); j!= i; ++pos)
++j;
delete pos->second;
grid.find(p)->second.erase(pos);
--no_agents;
}
// remove all agents from the cell p
void Field::remove_agent(const Point &p)
{
long i = 0;
for(multimap::iterator pos = grid.find(p)->second.begin(); pos!= grid.find(p)->second.end(); ++pos)
{
i++;
delete pos->second;
}
grid.find(p)->second.clear();
no_agents = no_agents - i;
}
// remove all agents in the region r
void Field::remove_agent(const Region &r)
{
for(int x = r.first.x; x < r.second.x; x++)
for(int y = r.first.y;y < r.second.y; y++)
remove_agent(Point(x,y));
}
// returns the state of agent with highest priority in cell p
// or ’ ’ if there is no agent
char Field::get_state(const Point &p) const
{
if(n_of_agents(p) > 0 )
{
multimap :: const_reverse_iterator it = grid.find(p)->second.rbegin();
return it->second->state();
}
return ' ';
}
void Field::step(long n)
{
while (n > 0 ) {
//no_agents in the new field (used when performing act)
long tmp_no_agents = 0;
//vector to hold the surr , mypos , point ,level for each agent
vector temp(no_agents);
//iterator used to traverse all cells
map > ::iterator pos;
//vector to hold the surr for each agent
vector< vector > surr(no_agents);
//vector to hold the level of each agent in his cell
vector level(no_agents);
//vector to hold all agents
vector agents(no_agents);
//vector to hold myposition for each agent
vector > mypos(no_agents);
//vector to hold the Point belonging to each agent.
vectorpnt(no_agents);
long index = 0;
//looping through each cell
for(pos = grid.begin(); pos != grid.end(); pos++)
{
//vector to hold the surrounding for each cell
vectoragent_surr(8);
//if the cell is not empty
if(n_of_agents(pos->first) > 0 )
{
int counter = 0;
//collecting the surrounding environment info of the current cell
for(int y = pos->first.y+1; y >= pos->first.y-1; y--)
for(int x = pos->first.x-1; x <= pos->first.x+1; x++)
{
if(!(x == pos->first.x && y == pos->first.y))
{
if(y < 0 || x < 0 || y >= sy || x >= sx)
{
agent_surr[counter++] = '*';
}
else
{
agent_surr[counter++] = get_state(Point(x,y));
}
}
}
long lev = n_of_agents(pos->first) ;
vector _mypos(n_of_agents(pos->first));
long cnt = 0;
//storing mypos for the current cell
for(multimap :: reverse_iterator it = pos->second.rbegin(); it != pos->second.rend(); it++)
_mypos[cnt++] = it->second->state();
//storing the collected info for each agent in the cell
for(multimap :: const_iterator it = pos->second.begin(); it != pos->second.end() ; it++)
{
//adding the agent to list of agents
temp[index].agent = it->second;
//adding the cell of the agent
temp[index].p = pos->first;
//adding the surrounding environment info for the current agent
temp[index].surr = agent_surr;
//adding the level of the agent
temp[index].level = --lev;
//adding myposition for the current agent
temp[index].mypos = _mypos;
++index;
}
}
}
//temporary datastructue to hold the info of the new grid
map > tmpGrid;
//initializing the temp grid
for(int ix=0; ixact(temp[i].surr, temp[i].mypos, temp[i].level);
switch(ans.first)
{
//DO NOTHING
//insert the agent to the temporary grid
case Agent::STAY : tmpGrid.find(temp[i].p)->second.insert(pair(temp[i].agent->priority(),temp[i].agent)); tmp_no_agents++; break;
//REMOVE AGENT
case Agent::DIE : delete temp[i].agent; break;
//Store the new position of the agent
case Agent::MOVE :
p = getP( ans.second[0] ,temp[i].p);
if(p.x >= sx || p.y >= sy || p.x < 0 || p.y < 0 )
delete temp[i].agent;
else
{
//insert the agent in the new position in the temporary grid
tmpGrid.find(p)->second.insert(pair(temp[i].agent->priority(),temp[i].agent));
tmp_no_agents++;
}
break;
case Agent::CLONE :
//place the agent in the new grid
tmp_no_agents++;
tmpGrid.find(temp[i].p)->second.insert(pair(temp[i].agent->priority(),temp[i].agent));
//clone the agent and place it in all specified directions.
for(vector :: iterator it = ans.second.begin(); it != ans.second.end(); it++)
{
p = getP(*it, temp[i].p);
if(p.x < sx && p.y < sy && p.x >= 0 && p.y >= 0 )
{
tmp_no_agents++;
Agent *a = temp[i].agent->clone();
tmpGrid.find(p)->second.insert(pair(a->priority(),a));
}
}
break;
}
}
//assign the temporary grid to the *this grid
grid = tmpGrid;
no_agents = tmp_no_agents;
--n;
}
return ;
}
// print the states of each cell in the region returned by range()
ostream & operator<<(ostream &os, const Field &s)
{
int y = s.sy - 1;
while( y >= 0 )
{
for(int x = 0; x