#include "Animal.h" const double SQRT2 = sqrt(2.0); // more efficient than calculating every time ofstream out ("output1.txt"); bool write_out = WRITE_OUTPUT1; ofstream out2 ("output2.txt"); bool write_out2 = WRITE_OUTPUT2; int Animal::AnimalCounter = 0; StochasticLib1 sto1animal(SEED); /*------------------------------------------------------------------------------ FUNCTION: Animal::Animal ARGUMENTS: x,y co-ordinates for new animal, year, prob of being male RETURNS: none NOTES: Animal class default Constructor - used only for initial population ------------------------------------------------------------------------------*/ Animal::Animal(int x1, int y1, int yr, double Pfemale) { id = AnimalCounter; AnimalCounter++; //Unique identifier for each animal // set up all animals to be adults age = sto1animal.IRandom(2,5); //maybe do something more elegant here? x = x1; y = y1; natal_x = 0; natal_y = 0; natal_year = yr; if (yr < 0) { // intial population - pmale indicates sex of animal if (Pfemale > 0.5) sex = 1; else sex = 0; status = 3; success = 1; // set up as a successful breeder who remains in situ } else { // Pfemale indicates proportion of females sex = sto1animal.Bernoulli(Pfemale); status = 2; success = 0; } // default movement parameters pr = 5; prmethod = 2; dp = gb = 1.0; memorysize = 1; // default goal parameters goaltype = 0; // indicates no goal set goalx = 0; goaly = 0; } /*------------------------------------------------------------------------------ FUNCTION: Animal::Animal ARGUMENTS: Animal* = Pointer to parent RETURNS: none NOTES: Animal Copy Constructor ------------------------------------------------------------------------------*/ Animal::Animal(int yr, double Pfemale, const Animal* b) { id = AnimalCounter; AnimalCounter++; //Unique identifier for each animal. age = 0; x = b->x; y = b->y; natal_x = b->x; natal_y = b->y; natal_year = yr; status = 0; success = 0; sex = sto1animal.Bernoulli(Pfemale); // movement parameters pr = b->pr; prmethod = b->prmethod; dp = b->dp; gb = b->gb; memorysize = b->memorysize; // goal parameters goaltype = b->goaltype; goalx = b->goalx; goaly = b->goaly; } /*------------------------------------------------------------------------------ FUNCTION: Animal::various functions to set or update animal attributes ARGUMENTS: RETURNS: NOTES: ------------------------------------------------------------------------------*/ void Animal::set_status(int s) { status = s; } void Animal::set_success(int s) { success = s; } void Animal::set_location(int lx, int ly) { x = lx; y = ly; } void Animal::age_incr(void) { age++; } void Animal::set_goal(int g, int lx, int ly) { if (g >= 0 && g <= 2) { goaltype = g; if (g > 0) goalx = lx; goaly = ly; } else goaltype = 0; } void Animal::set_movement(int p, int m, double d, double g, int ms, int nd) { if (p < 1) pr = 1; else pr = p; if (m < 1 || m > 3) prmethod = 2; else prmethod = m; if (d < 1.0) dp = 1.0; else dp = d; if (g < 1.0) gb = 1.0; else gb = g; if (ms < 1) memorysize = 1; else { if (memorysize > 14) // causes an exception error, so make this the max allowed memorysize = 14; else memorysize = ms; } if (nd < 1) nodatacost = 1000; else nodatacost = nd; } void Animal::set_dp(double d) { if (d < 1.0) dp = 1.0; else dp = d; } /*------------------------------------------------------------------------------ FUNCTION: Animal::various functions to get animal attributes ARGUMENTS: RETURNS: NOTES: ------------------------------------------------------------------------------*/ int Animal::get_id() { return id; } int Animal::get_age() { return age; } int Animal::get_natalyear() { return natal_year; } int Animal::get_sex() { return sex; } int Animal::get_status() { return status; } int Animal::get_success() { return success; } int Animal::get_pr() { return pr; } int Animal::get_prmethod() { return prmethod; } double Animal::get_dp() { return dp; } double Animal::get_gb() { return gb; } int Animal::get_memsize() { return memorysize; } locn Animal::get_location() { locn l; l.x = x; l.y = y; return l; } locn Animal::get_natalloc() { locn l; l.x = natal_x; l.y = natal_y; return l; } locn Animal::get_goal() { locn l; l.x = goalx; l.y = goaly; return l; } int Animal::get_goaltype() { return goaltype; } void Animal::relmove(int dx, int dy) { // make a relative move locn current; current.x = x; current.y = y; if (memory.size() == memorysize) { memory.pop(); // remove oldest memory element } memory.push(current); // record previous location in memory if (write_out) out<<"queue length is "<get_bounds().x; int ymax = pLand->get_bounds().y; if (write_out) { out<locate_square(x,y); if (sq == 0) { // x,y is a NODATA square - this should not occur here // return a negative distance to indicate an error move.dist = -1.0; move.cost = 0.0; return move; } //get weights for directional persistence.... nbr = get_sim_dir(); if (write_out) { out< -1; y2--) { for (x2 = 0; x2 < 3; x2++) out< -1; y2--) { for (x2 = 0; x2 < 3; x2++) out< -1; y2--) { // for (x2 = 0; x2 < 3; x2++) out<set_effcosts(hab); // store the costs } else { // they have been calculated if (write_out) { out<<"*** using previous effective costs ***"< -1; y2--) { for (x2 = 0; x2 < 3; x2++) { out< -1; y2--) { for (x2 = 0; x2 < 3; x2++) { if(x2==1 && y2==1) nbr.cell[x2][y2]=0.0; else { if(x2==1 || y2==1) //not diagonal nbr.cell[x2][y2] = nbr.cell[x2][y2]*goal.cell[x2][y2]*hab.cell[x2][y2]; else // diagonal nbr.cell[x2][y2] = SQRT2*nbr.cell[x2][y2]*goal.cell[x2][y2]*hab.cell[x2][y2]; } if (write_out) { out< -1; y2--) { for (x2 = 0; x2 < 3; x2++) { if (nbr.cell[x2][y2] > 0.0) nbr.cell[x2][y2] = 1.0/nbr.cell[x2][y2]; if (write_out) { out< -1; y2--) { for (x2 = 0; x2 < 3; x2++) { nbr.cell[x2][y2] = nbr.cell[x2][y2]/sum_nbrs; if (write_out) { out< 7.0*M_PI/8.0) { dx = 0; dy = -1; } else { if (fabs(theta) > 5.0*M_PI/8.0) { dy = -1; if (theta > 0) dx = 1; else dx = -1; } else { if (fabs(theta) > 3.0*M_PI/8.0) { dy = 0; if (theta > 0) dx = 1; else dx = -1; } else { if (fabs(theta) > M_PI/8.0) { dy = 1; if (theta > 0) dx = 1; else dx = -1; } else { dy = 1; dx = 0; } } } } // if (write_out) out<<"goalx,goaly: "< 1) dx -= 2; yy = dy; d.cell[xx+1][yy+1] = i1; d.cell[-xx+1][yy+1] = i1; d.cell[xx+1][-yy+1] = i3; d.cell[-xx+1][-yy+1] = i3; } else { // theta points W or E yy = dy+1; if (yy > 1) dy -= 2; xx = dx; d.cell[xx+1][yy+1] = i1; d.cell[xx+1][-yy+1] = i1; d.cell[-xx+1][yy+1] = i3; d.cell[-xx+1][-yy+1] = i3; } } else { // theta points to an ordinal direction d.cell[dx+1][-dy+1] = i2; d.cell[-dx+1][dy+1] = i2; xx = dx+1; if (xx > 1) xx -= 2; d.cell[xx+1][dy+1] = i1; yy = dy+1; if (yy > 1) yy -= 2; d.cell[dx+1][yy+1] = i1; d.cell[-xx+1][-dy+1] = i3; d.cell[-dx+1][-yy+1] = i3; } return d; } /*------------------------------------------------------------------------------ FUNCTION: Animal::get_hab_matrix ARGUMENTS: pointer to landscape, maximumum X and Y values RETURNS: 3x3 array of effective costs NOTES: ------------------------------------------------------------------------------*/ array3x3d Animal::get_hab_matrix(Landscape* pLand,int xbound,int ybound){ array3x3d w; // array of effective costs to be returned int ncells,x4,y4,targetseen; double weight,sumweights; // NW and SE corners of effective cost array relative to the current cell (x,y): int xmin, ymin, xmax, ymax,cost; Square* sq; for (int x2=-1; x2<2; x2++) { // index of relative move in x direction for (int y2=-1; y2<2; y2++) { // index of relative move in x direction w.cell[x2+1][y2+1] = 0.0; // initialise costs array to zeroes // set up corners of perceptual range relative to current cell if (x2==0 && y2==0) { // current cell - do nothing xmin=0; ymin=0; xmax=0; ymax=0; } else { if (x2==0 || y2==0) { // not diagonal (rook move) if (x2==0){ // vertical (N-S) move //out<<"ROOK N-S: x2 = "<= xbound) x4 = x+x3-xbound; else x4 = x+x3; } if ((y+y3) < 0) y4 = y+y3+ybound; else { if ((y+y3) >= ybound) y4 = y+y3-ybound; else y4 = y+y3; } if (write_out && (x4 < 0 || y4 < 0)) { out<<"ERROR: x "<locate_square(x4,y4); if (sq == 0) cost = nodatacost; else cost = sq->get_cost(); if (prmethod==1) { // arithmetic mean w.cell[x2+1][y2+1] += cost; ncells++; } if (prmethod==2) { // harmonic mean if (cost > 0) { w.cell[x2+1][y2+1] += (1/(double)cost); ncells++; } } if (prmethod==3) { // arithmetic mean weighted by inverse distance if (cost>0) { // NB distance is still given by (x3,y3) weight = 1/sqrt((double)(pow((double)x3,2)+pow((double)y3,2))); w.cell[x2+1][y2+1] += weight*(double)cost; ncells++; sumweights += weight; } } if (write_out2) out2<get_target() > 50) targetseen++; } #endif } //end of y3 loop } //end of x3 loop // if (write_out) out<<"ncells in PR = "<