Goose Management Model ODdox  1.02
Hunters_all.cpp
Go to the documentation of this file.
1 /*
2 *******************************************************************************************************
3 Copyright (c) 2013, Christopher John Topping, University of Aarhus
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without modification, are permitted provided
7 that the following conditions are met:
8 
9 Redistributions of source code must retain the above copyright notice, this list of conditions and the
10 following disclaimer.
11 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
12 the following disclaimer in the documentation and/or other materials provided with the distribution.
13 
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
15 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
17 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
19 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 ********************************************************************************************************
23 */
32 //---------------------------------------------------------------------------
33 
34 #define __DEBUG_DENSITY
35 
36 
37 #include <math.h>
38 #include <iostream>
39 #include <fstream>
40 #include <vector>
41 #include <list>
42 #include "../Landscape/ls.h"
43 #include "../BatchALMaSS/PopulationManager.h"
44 #include "../GooseManagement/GooseMemoryMap.h"
45 #include "../GooseManagement/Goose_Base.h"
46 #include "../BatchALMaSS/CurveClasses.h"
47 #include "../Hunters/Hunters_all.h"
48 #include "../GooseManagement/Goose_Population_Manager.h"
49 #include "../GooseManagement/GoosePinkFooted_All.h"
50 #include "../GooseManagement/GooseGreylag_All.h"
51 #include "../GooseManagement/GooseBarnacle_All.h"
52 
53 #include "../BatchALMaSS/BoostRandomGenerators.h"
54 
55 
56 extern boost::variate_generator<base_generator_type&, boost::uniform_real<> > g_rand_uni;
57 extern boost::variate_generator<base_generator_type&, boost::uniform_int<> > g_rand_uni2; // 0-9999
58 
59 /* Links to globals */
60 extern PopulationManagerList g_PopulationManagerList;
61 
62 /* Links to the goose population */
68 
69 /* Here we have the input variable for hunting seasons on our game species */
71 static CfgInt cfg_gooseopenseasonstart("GOOSE_OPENSEASON_START", CFG_CUSTOM, 243);
73 static CfgInt cfg_gooseopenseasonend("GOOSE_OPENSEASON_END", CFG_CUSTOM, 364); // 30
75 static CfgFloat cfg_huntermaxprotectedpct( "HUNTER_MAXPROTECTECTEDPCT" , CFG_CUSTOM, 0.1);
77 static CfgInt cfg_hunter_magazinecapacity("HUNTER_MAGAZINECAPACITY", CFG_CUSTOM, 2);
79 static CfgInt cfg_huntlength("GOOSE_HUNTER_HUNT_LENGTH", CFG_CUSTOM, 180); // default is 3 hours
81 static CfgBool cfg_Hunters_RecordBag("HUNTERS_RECORDBAG", CFG_CUSTOM, false);
83 static CfgBool cfg_Hunters_Distribute("HUNTERS_DISTRIBUTE", CFG_CUSTOM, false);
85 static CfgInt cfg_Hunters_Distribute_Ruleset("HUNTERS_DISTRIBUTE_RULESET", CFG_CUSTOM, 0);
87 static CfgInt cfg_Hunters_Distribute_NonResRuleset("HUNTERS_DISTRIBUTE_NONRESRULESET", CFG_CUSTOM, 0);
89 static CfgInt cfg_Hunters_NonresidentPct("HUNTERS_NONRESIDENTPCT", CFG_CUSTOM, 30);
91 static CfgFloat cfg_Hunters_MaxDensity("HUNTERS_MAXDENSITY", CFG_CUSTOM, 0.1);
93 static CfgFloat cfg_Hunters_MaxDensityPower("HUNTERS_MAXDENSITYPOWER", CFG_CUSTOM, 0.741); // 1.0 here will give linear, e.g. with 0.2 will allow 1 hunter per 5ha, 0.741 with 0.3 will do the same but only allow 30 hunters in 500 ha (instead of 100).
95 static CfgFloat cfg_hunterlocONE("HUNTERS_HUNTERLOCPROB_ONE", CFG_CUSTOM, 0.297);
97 static CfgFloat cfg_hunterlocTWO("HUNTERS_HUNTERLOCPROB_TWO", CFG_CUSTOM, 0.616);
99 static CfgFloat cfg_hunterlocTHREE("HUNTERS_HUNTERLOCPROB_THREE", CFG_CUSTOM, 0.806);
101 static CfgFloat cfg_hunterlocFOUR("HUNTERS_HUNTERLOCPROB_FOUR", CFG_CUSTOM, 0.854);
103 static CfgFloat cfg_hunterhuntdayprobscaler( "HUNTER_HUNTDAYPROBSCALER", CFG_CUSTOM, 2.0 );
105 static CfgFloat cfg_largefieldgooseproximity("HUNTER_LARGEFIELDGOOSEPROXIMITYCHANCE", CFG_CUSTOM, 0.5);
107 static CfgInt cfg_largefieldgooseproximitysizecutoff("HUNTER_LARGEFIELDGOOSEPROXIMITYCHANCESIZECUTOFF", CFG_CUSTOM, 20000);
109 static CfgInt cfg_hunterrefractionperiod("HUNTER_REFRACTIONPERIOD", CFG_CUSTOM, 7);
111 static CfgInt cfg_hunter_pinkfootbaglimit("HUNTER_PINKFOOTBAGLIMIT", CFG_CUSTOM, 9999);
113 static CfgInt cfg_hunter_greylagbaglimit("HUNTER_GREYLAGBAGLIMIT", CFG_CUSTOM, 9999);
114 
115 //*******************************************************************************************************************/
116 // Class Hunter_Population_Manager
117 //*******************************************************************************************************************/
118 
120 {
121  // Load List of Animal Classes
122  m_ListNames[0] = "Goose Hunter";
123  m_ListNameLength = 1;
124  // We need one vector for each life stage
125  for (unsigned i=0; i<(10-m_ListNameLength); i++)
126  {
127  TheArray.pop_back();
128  }
129  BeforeStepActions[ 0 ] = 4; // 0 = Shuffle, 1 = SortX, 2 = SortY, 3=SortXIndex, 4 = do nothing, 5 = shuffle 1 in 500 times
137  m_HuntingSeasonEnd = -1;
139 }
140 
142 {
143  // close down output
145  {
146  m_HuntingBagRecord->close();
147  delete m_HuntingBagRecord;
148  }
149 }
150 
152 {
153 // FarmManager* FManager = m_TheLandscape->SupplyFarmManagerPtr();
156  ifstream huntercoords("./HunterHomeLocations.txt", ios::in);
157  if (!huntercoords.is_open()) {
158  m_TheLandscape->Warn( "Hunter_Population_Manager::DistributeHunters()", "HunterHomeLocations.txt missing" );
159  exit( 1 );
160  }
161  int no_hunters;
162  huntercoords >> no_hunters;
163  vector<HunterInfo>* OurHunters = new vector<HunterInfo>;
164  OurHunters->resize( no_hunters );
165  for (int i = 0; i < no_hunters; i++)
166  {
167  huntercoords >> (*OurHunters)[ i ].refID >> (*OurHunters)[ i ].homeX >> (*OurHunters)[ i ].homeY;
172  (*OurHunters)[ i ].FarmHuntRef.resize( GetNoHuntLocs() );
173  for (int hl = 0; hl<(*OurHunters)[i].FarmHuntRef.size(); hl++) (*OurHunters)[i].FarmHuntRef[hl] = -1;
174  //(*OurHunters)[ i ].CheckedFarms.resize( FManager->GetNoFarms() );
175  }
176  huntercoords.close();
177  // Do the distribution
179  // Now save the results
180  SaveDistributedHunters(OurHunters, no_hunters);
181  SaveFarmHunters(OurHunters, no_hunters);
182  g_msg->Warn("Normal exit after hunter distribution. No of records written to Hunter_Hunting_Locations.txt was: ", no_hunters);
183  exit(0);
184 }
185 
187 {
189  double chance = g_rand_uni();
190  if (chance < cfg_hunterlocONE.value()) return 1;
191  if (chance < cfg_hunterlocTWO.value()) return 2;
192  if (chance < cfg_hunterlocTHREE.value()) return 3;
193  if (chance < cfg_hunterlocFOUR.value()) return 4;
194  return 5;
195 
196 }
197 
198 void Hunter_Population_Manager::SaveDistributedHunters( vector<HunterInfo>* a_hunterlist, int a_no_hunters )
199 {
200  ofstream huntlocs("./Hunter_Hunting_Locations.txt", ios::out);
201  huntlocs << a_no_hunters << endl;
202  huntlocs << "HunterID" << '\t' << "HunterType" << '\t' << "HuntingDays" << '\t' << "WeekdayHunterChance" << '\t' << "GooseLookChance" << '\t' << "Efficiency" << '\t';
203  huntlocs << "HomeX" << '\t' << "HomeY" << '\t';
204  huntlocs << "NoFarmrefs" << '\t' << "FarmRef1" << '\t' << "FarmRef2" << '\t' << "FarmRef3" << '\t' << "FarmRef4" << '\t' << "FarmRef5" << '\t' << "FarmRef6" << '\t' << "FarmRef7" << '\t' << "FarmRef8" << '\t' << "FarmRef9" << '\t' << "FarmRef10" << endl;
205 
206  //<< '\t' << "FarmCentroidX" << '\t' << "FarmCentroidY" << '\t' << "FarmTotalSize" << '\t' << "FarmArableSize" << '\t' << "FarmType" << '\t' << "NoFields" << '\t' << "NoOpenFields" << '\t' << "ValidFarmX" << '\t' << "ValidFarmY" << endl;
207  /*FarmManager* FManager = m_TheLandscape->SupplyFarmManagerPtr();*/
208  for (int i = 0; i < a_no_hunters; i++)
209  {
210  int nolocs = int((*a_hunterlist)[i].FarmHuntRef.size());
211  huntlocs << (*a_hunterlist)[ i ].refID << '\t' << 0 << '\t' << 0 << '\t' << 0 << '\t' << 0 << '\t' << 0 << '\t';
212  huntlocs << (*a_hunterlist)[ i ].homeX << '\t' << (*a_hunterlist)[ i ].homeY << '\t' << nolocs;
213  for (int j = 0; j < nolocs; j++)
214  {
215  int ref = (*a_hunterlist)[ i ].FarmHuntRef[ j ];
216  /*
217  APoint pt = FManager->GetFarmCentroid(ref);
218  int FarmASize = FManager->GetFarmArableSize(ref);
219  int FarmTSize = FManager->GetFarmTotalSize(ref);
220  int FarmType = FManager->GetFarmType(ref);
221  int OpenFields = FManager->GetFarmNoOpenFields(ref, (int)cfg_GooseMinForageOpenness.value());
222  int NoFields = FManager->GetFarmNoFields(ref);
223  APoint valid = FManager->GetFarmValidCoords(ref);*/
224  huntlocs << '\t' << ref;
225  }
226  for (int j = 10; j > nolocs; j--) huntlocs << '\t' << "NA";
227  huntlocs << endl;
228  }
229  huntlocs.close();
230 }
231 
232 
233 void Hunter_Population_Manager::SaveFarmHunters( vector<HunterInfo>* a_hunterlist, int a_no_hunters ) {
234  FarmManager* FManager = m_TheLandscape->SupplyFarmManagerPtr();
235  ofstream huntlocs("./Hunter_Hunting_Locations_Farms.txt", ios::out);
236  huntlocs << "FarmRef" << '\t' << "FarmCentroidX" << '\t' << "FarmCentroidY" << '\t' << "FarmType" << '\t' << "FarmSize" << '\t'
237  << "FarmArableSize" << '\t' << "NoFields" << '\t' << "NoOpenFields" << '\t' <<"AreaOpenFields" << '\t' << "NoHunters" << endl;
238  vector<farminfo*> FarmList;
239  for (int i = 0; i < a_no_hunters; i++)
240  {
241  for (int j = 0; j < (*a_hunterlist)[ i ].FarmHuntRef.size(); j++)
242  {
243  int ref = (*a_hunterlist)[ i ].FarmHuntRef[ j ];
244  int found = -1;
245  for (int f = 0; f < (int)FarmList.size(); f++) {
246  if (FarmList[f]->m_farmref == ref) {
247  found = f;
248  break;
249  }
250  }
251  if (found == -1) {
252  farminfo* fi = new farminfo;
253  fi->m_farmcentroid = FManager->GetFarmCentroid( (*a_hunterlist)[ i ].FarmHuntRef[ j ] );
254  fi->m_farmvalid = FManager->GetFarmValidCoords( (*a_hunterlist)[ i ].FarmHuntRef[ j ] );
255  fi->m_farmarable = FManager->GetFarmArableSize( (*a_hunterlist)[ i ].FarmHuntRef[ j ] );
256  fi->m_farmsize = FManager->GetFarmTotalSize( (*a_hunterlist)[ i ].FarmHuntRef[ j ] );
257  fi->m_farmtype = FManager->GetFarmType( (*a_hunterlist)[ i ].FarmHuntRef[ j ] );
258  fi->m_openfields = FManager->GetFarmNoOpenFields( (*a_hunterlist)[ i ].FarmHuntRef[ j ], (int)cfg_goose_MinForageOpenness.value() );
259  fi->m_areaopenfields = FManager->GetFarmAreaOpenFields( (*a_hunterlist)[ i ].FarmHuntRef[ j ], (int)cfg_goose_MinForageOpenness.value() );
260  fi->m_nofields = FManager->GetFarmNoFields( (*a_hunterlist)[ i ].FarmHuntRef[ j ] );
261  fi->m_farmref = (*a_hunterlist)[ i ].FarmHuntRef[ j ];
262  fi->m_NoHunters = 1;
263  FarmList.push_back(fi);
264  }
265  else FarmList[found]->m_NoHunters++;
266  }
267  }
268  // Now we don't want any gaps so check all farms and then check them against our list of hunted farms
269  int nofarms = FManager->GetNoFarms();
270  for (int fa = 0; fa < nofarms; fa++) {
271  int found = -1;
272  Farm* farmp = FManager->GetFarmPtrIndex(fa);
273  int ref = farmp->GetFarmNumber();
274  cout << ref << '\t';
275  for (int hf = 0; hf < FarmList.size( ); hf++)
276  {
277  if (FarmList[hf]->m_farmref == ref) {
278  found = hf;
279  cout << ref << '\t' << found << endl;
280  break;
281  }
282  }
283  if (found == -1) {
284  APoint pt = FManager->GetFarmCentroid( ref );
285  huntlocs << ref << '\t' << pt.m_x << '\t' << pt.m_y << '\t' << FManager->GetFarmType(ref) << '\t' << FManager->GetFarmTotalSize(ref) << '\t'
286  << FManager->GetFarmArableSize(ref) << '\t' << FManager->GetFarmNoFields(ref) << '\t'
287  << FManager->GetFarmNoOpenFields(ref, (int)cfg_goose_MinForageOpenness.value()) << '\t' << FManager->GetFarmAreaOpenFields(ref, (int)cfg_goose_MinForageOpenness.value()) << '\t' << 0 << endl;
288  }
289  else {
290  huntlocs << ref << '\t' << FarmList[found]->m_farmcentroid.m_x << '\t' << FarmList[found]->m_farmcentroid.m_y << '\t' << FarmList[found]->m_farmtype << '\t' << FarmList[found]->m_farmsize << '\t'
291  << FarmList[found]->m_farmarable << '\t' << FarmList[found]->m_nofields << '\t' << FarmList[found]->m_openfields << '\t' << FarmList[found]->m_areaopenfields << '\t' << FarmList[found]->m_NoHunters << endl;
292  }
293 
294  }
295  huntlocs.close();
296 }
297 
298 
299 
300 bool Hunter_Population_Manager::CheckDensity(int a_ref, vector<int> * a_illegalfarms, vector<FarmOccupcancyData>* a_FarmOccupancy)
301 {
309  FarmManager* FManager = m_TheLandscape->SupplyFarmManagerPtr();
311  //double area = m_TheLandscape->SupplyFarmManagerPtr()->GetFarmTotalSize( a_ref ) / 10000.0;
312  double area = m_TheLandscape->SupplyFarmManagerPtr()->GetFarmAreaOpenFields( a_ref, (int)cfg_goose_MinForageOpenness.value()) / 10000.0;
314  for (int f = 0; f < a_FarmOccupancy->size(); f++) {
315  // test if we have this one
316  if ((*a_FarmOccupancy)[f].m_FarmRef == a_ref) {
317  double newhunters = (*a_FarmOccupancy)[f].m_no_hunters + 1.0;
318  if ( (newhunters/ area) < cfg_Hunters_MaxDensity.value()) {
319  (*a_FarmOccupancy)[f].m_no_hunters++; // Add ourselves
320  return true; // The farm was OK
321  }
322  else {
323  FManager->AddToIllegalList(a_ref, a_illegalfarms);
324  return false;
325  }
326  }
327  }
328  // If we reach here it must be a new farm
329  // New farm, so is it big enough for one hunter?
330  if (1.0 / area > cfg_Hunters_MaxDensity.value())
331  {
332  // Need to add to the illegal list
333  FManager->AddToIllegalList(a_ref, a_illegalfarms);
334  return false;
335  }
336  else {
338  pt.m_FarmRef = a_ref;
339  pt.m_no_hunters = 1;
340  a_FarmOccupancy->push_back(pt);
341  return true;
342  }
343 }
344 
345 
346 void Hunter_Population_Manager::DistributeHuntersByRules(vector<HunterInfo>* a_hunterlist, int a_no_hunters, int a_ruleset)
347 {
364  FarmManager* FManager = m_TheLandscape->SupplyFarmManagerPtr();
365  // Now we distribute the hunters to farms depending on which rule set we are using
366 
367 
368  FManager->CalcCentroids(); // Makes sure that farm centres are calculated
369  if (a_ruleset == 0)
370  {
372  for (int i = 0; i < a_no_hunters; i++)
373  {
374  // It is certain that some will be allocated to the same farm twice or more at some point, so we need to stop this.
375  for (int h = 0; h < int((*a_hunterlist)[i].FarmHuntRef.size()); h++)
376  {
377  int theref = -1;
378  do {
379  // The line below actuall does the interesting bit
380  theref = FManager->GetRandomFarmRefnum();
381  } while (FManager->IsDuplicateRef(theref, &(*a_hunterlist)[i]));
382  (*a_hunterlist)[i].FarmHuntRef[h] = theref;
383  }
384  }
385  }
386  else if (a_ruleset == 1)
387  {
389  vector<int>* list = new vector<int>;
390  list->resize(1);
391  (*list)[0] = 0;
392  for (int i = 0; i < a_no_hunters; i++)
393  {
394  // It is certain that some will be allocated to the same farm twice or more at some point, so we need to stop this.
395  for (int h = 0; h < int((*a_hunterlist)[i].FarmHuntRef.size()); h++)
396  {
397  // The line below actuall does the interesting bit
398  (*a_hunterlist)[i].FarmHuntRef[h] = FManager->FindClosestFarm((*a_hunterlist)[i], &list[0]);
399  }
400  }
401  }
402  else if (a_ruleset == 2)
403  {
405  for (int i = 0; i < a_no_hunters; i++)
406  {
407  // It is certain that some will be allocated to the same farm twice or more at some point, so we need to stop this.
408  for (int h = 0; h < int((*a_hunterlist)[i].FarmHuntRef.size()); h++)
409  {
410  int theref = -1;
411  do {
412  // The line below actually does the interesting bit
413  theref = FManager->FindOpennessFarm((int)cfg_goose_MinForageOpenness.value());
414  } while (FManager->IsDuplicateRef(theref, &(*a_hunterlist)[i]));
415  (*a_hunterlist)[i].FarmHuntRef[h] = theref;
416  }
417  }
418  }
419  else if (a_ruleset == 3)
420  {
422  vector<int>* illegalfarms = new vector<int>;
423  vector<FarmOccupcancyData>* FarmOccupancy = new vector<FarmOccupcancyData>;
424  for (int i = 0; i < a_no_hunters; i++)
425  {
426  for (int h = 0; h < int((*a_hunterlist)[i].FarmHuntRef.size()); h++)
427  {
428  bool found1 = false;
429  int theref = -1;
430  // While a farm is not allocated
431  int iteration = 0;
432  while (!found1) {
433  if (++iteration > FManager->GetNoFarms())
434  {
435  g_msg->Warn("Hunter_Population_Manager::DistributeHunters() - unable to allocate hunter, rule set ", cfg_Hunters_Distribute_Ruleset.value());
436  exit(0);
437  }
438  // Choose a new farm ref to test
439  theref = FManager->FindFarmWithRandom(illegalfarms);
440  found1 = CheckDensity(theref, illegalfarms, FarmOccupancy);
441 
442  }
443  (*a_hunterlist)[i].FarmHuntRef[h] = theref;
444 #ifdef __DEBUG_DENSITY
445  double areaHa = FManager->GetFarmTotalSize(theref) / 10000.0;
446  double nohunters = 0;
447  for (int g = 0; g < a_no_hunters; g++)
448  {
449 
450  for (int hs = 0; hs < int((*a_hunterlist)[g].FarmHuntRef.size()); hs++)
451  {
452  if ((*a_hunterlist)[g].FarmHuntRef[hs] == theref) nohunters++;
453  }
454  }
455  if (nohunters / areaHa > cfg_Hunters_MaxDensity.value())
456  {
457  g_msg->Warn("Hunter_Population_Manager::DistributeHunters() - debug density error, rule set ", cfg_Hunters_Distribute_Ruleset.value());
458  exit(0);
459  }
460  for (int frm = 0; frm < FarmOccupancy->size(); frm++)
461  {
462 
463  nohunters = 0;
464  for (int g = 0; g < a_no_hunters; g++)
465  {
466 
467  for (int hs = 0; hs < int((*a_hunterlist)[g].FarmHuntRef.size()); hs++)
468  {
469  if ((*a_hunterlist)[g].FarmHuntRef[hs] == (*FarmOccupancy)[frm].m_FarmRef) nohunters++;
470  }
471  }
472  if ((*FarmOccupancy)[frm].m_no_hunters != nohunters)
473  {
474  g_msg->Warn("Hunter_Population_Manager::DistributeHunters() - debug density error, rule set ", cfg_Hunters_Distribute_Ruleset.value());
475  exit(0);
476  }
477  }
478 #endif
479 
480  }
481  }
482  }
483  else if (a_ruleset == 4)
484  {
486  vector<int>* list = new vector<int>;
487  list->resize(1);
488  (*list)[0] = 0;
489  for (int i = 0; i < a_no_hunters; i++)
490  {
491  for (int f = 0; f < int((*a_hunterlist)[i].FarmHuntRef.size()); f++)
492  {
493  (*a_hunterlist)[i].FarmHuntRef[f] = FManager->FindClosestFarmOpenness((*a_hunterlist)[i], list, (int)cfg_goose_MinForageOpenness.value());
494  }
495  }
496  }
497  else if (a_ruleset == 5) {
499  // First calculate the hunter densities
500  // This depends on the way we want to do this, one way is total farm area, the other is open farm area.
501  // Both ways are listed here.
502  vector<int>* illegalfarms = new vector<int>;
503  vector<FarmOccupcancyData>* FarmOccupancy = new vector<FarmOccupcancyData>;
504  // When we enter this no hunters will be allocated, so we need to keep a list uptodate as we go along
505  // For each hunter
506  for (int i = 0; i < a_no_hunters; i++) {
507  for (int h = 0; h < int((*a_hunterlist)[i].FarmHuntRef.size()); h++)
508  {
509  bool found1 = false;
510  // While a farm is not allocated
511  int iteration = 0;
512  int theref = -1;
513  while (!found1)
514  {
515  if (++iteration > FManager->GetNoFarms())
516  {
517  g_msg->Warn("Hunter_Population_Manager::DistributeHunters() - unable to allocate hunter, rule set ", cfg_Hunters_Distribute_Ruleset.value());
518  exit(0);
519  }
520  // Choose a new farm ref to test
521  theref = FManager->FindClosestFarm((*a_hunterlist)[i], illegalfarms);
522  found1 = CheckDensity(theref, illegalfarms, FarmOccupancy);
523  }
524  (*a_hunterlist)[i].FarmHuntRef[h] = theref;
525 #ifdef __DEBUG_DENSITY
526  double areaHa = FManager->GetFarmTotalSize(theref) / 10000.0;
527  double nohunters = 0;
528  for (int g = 0; g < a_no_hunters; g++)
529  {
530 
531  for (int hs = 0; hs < int((*a_hunterlist)[g].FarmHuntRef.size()); hs++)
532  {
533  if ((*a_hunterlist)[g].FarmHuntRef[hs] == theref) nohunters++;
534  }
535  }
536  if (nohunters / areaHa > cfg_Hunters_MaxDensity.value())
537  {
538  g_msg->Warn("Hunter_Population_Manager::DistributeHunters() - debug density error, rule set ", cfg_Hunters_Distribute_Ruleset.value());
539  exit(0);
540  }
541  for (int frm = 0; frm < FarmOccupancy->size(); frm++)
542  {
543 
544  nohunters = 0;
545  for (int g = 0; g < a_no_hunters; g++)
546  {
547 
548  for (int hs = 0; hs < int((*a_hunterlist)[g].FarmHuntRef.size()); hs++)
549  {
550  if ((*a_hunterlist)[g].FarmHuntRef[hs] == (*FarmOccupancy)[frm].m_FarmRef) nohunters++;
551  }
552  }
553  if ((*FarmOccupancy)[frm].m_no_hunters != nohunters)
554  {
555  g_msg->Warn("Hunter_Population_Manager::DistributeHunters() - debug density error, rule set ", cfg_Hunters_Distribute_Ruleset.value());
556  exit(0);
557  }
558  }
559 #endif
560  }
561  }
562  }
563  else if (a_ruleset == 6) {
565  vector<int>* illegalfarms = new vector<int>;
566  vector<FarmOccupcancyData>* FarmOccupancy = new vector<FarmOccupcancyData>;
567  int TheOpenness = (int)cfg_goose_MinForageOpenness.value();
568  // When we enter this no hunters will be allocated, so we need to keep a list uptodate as we go along
569  // For each hunter
570  for (int i = 0; i < a_no_hunters; i++) {
571  for (int h = 0; h < int((*a_hunterlist)[i].FarmHuntRef.size()); h++) {
572  int Farms = FManager->GetNoFarms();
573  bool found1 = false;
574  int iteration = 0;
575  int theref = -1;
576  do {
577  if (++iteration > Farms) {
578  g_msg->Warn("Hunter_Population_Manager::DistributeHunters() - unable to allocate hunter, rule set ", cfg_Hunters_Distribute_Ruleset.value());
579  exit(0);
580  }
581  // Choose a new farm ref to test
582  do {
583  // The line below actually does the interesting bit
584  theref = FManager->FindFarmWithOpenness(illegalfarms, TheOpenness);
585  if (theref == -1) {
586  g_msg->Warn("Hunter_Population_Manager::DistributeHunters() - unable to allocate hunter, in openness, rule set ", cfg_Hunters_Distribute_Ruleset.value());
587  exit(0);
588  }
589  if (illegalfarms->size() >= Farms - ((*a_hunterlist)[ i ].FarmHuntRef.size())) {
590  g_msg->Warn("Hunter_Population_Manager::DistributeHunters() - unable to allocate hunter, all farms illegal, rule set ", cfg_Hunters_Distribute_Ruleset.value());
591  exit(0);
592  }
593  } while (FManager->IsDuplicateRef(theref, &(*a_hunterlist)[i]));
594  found1 = CheckDensity(theref, illegalfarms, FarmOccupancy);
595  } while (!found1);
596  (*a_hunterlist)[i].FarmHuntRef[h] = theref;
597 #ifdef __DEBUG_DENSITY
598  double areaHa = FManager->GetFarmTotalSize(theref) / 10000.0;
599  double nohunters = 0;
600  for (int g = 0; g < a_no_hunters; g++)
601  {
602 
603  for (int hs = 0; hs < int((*a_hunterlist)[g].FarmHuntRef.size()); hs++)
604  {
605  if ((*a_hunterlist)[g].FarmHuntRef[hs] == theref) nohunters++;
606  }
607  }
608  if (nohunters / areaHa > cfg_Hunters_MaxDensity.value())
609  {
610  g_msg->Warn("Hunter_Population_Manager::DistributeHunters() - debug density error, rule set ", cfg_Hunters_Distribute_Ruleset.value());
611  exit(0);
612  }
613  for (int frm = 0; frm < FarmOccupancy->size(); frm++)
614  {
615 
616  nohunters = 0;
617  for (int g = 0; g < a_no_hunters; g++)
618  {
619 
620  for (int hs = 0; hs < int((*a_hunterlist)[g].FarmHuntRef.size()); hs++)
621  {
622  if ((*a_hunterlist)[g].FarmHuntRef[hs] == (*FarmOccupancy)[frm].m_FarmRef) nohunters++;
623  }
624  }
625  if ((*FarmOccupancy)[frm].m_no_hunters != nohunters)
626  {
627  g_msg->Warn("Hunter_Population_Manager::DistributeHunters() - debug density error, rule set ", cfg_Hunters_Distribute_Ruleset.value());
628  exit(0);
629  }
630  }
631 #endif
632  }
633  }
634  delete illegalfarms;
635  }
636  else if (a_ruleset == 7) {
638  // First calculate the hunter densities
639  // This depends on the way we want to do this, one way is total farm area, the other is open farm area.
640  // Both ways are listed here.
641  vector<int>* illegalfarms = new vector<int>;
642  vector<FarmOccupcancyData>* FarmOccupancy = new vector<FarmOccupcancyData>;
643  // When we enter this no hunters will be allocated, so we need to keep a list uptodate as we go along
644  // For each hunter
645  for (int i = 0; i < a_no_hunters; i++)
646  {
647  for (int h = 0; h < int((*a_hunterlist)[i].FarmHuntRef.size()); h++)
648  {
649  bool found1 = false;
650  int theref = -1;
651  // While a farm is not allocated
652  int iteration = 0;
653  while (!found1)
654  {
655  if (++iteration > FManager->GetNoFarms())
656  {
657  g_msg->Warn("Hunter_Population_Manager::DistributeHunters() - unable to allocate hunter, rule set ", cfg_Hunters_Distribute_Ruleset.value());
658  exit(0);
659  }
660  // Choose a new farm ref to test
661  theref = FManager->FindClosestFarmOpenness((*a_hunterlist)[i], illegalfarms, (int)cfg_goose_MinForageOpenness.value());
662  found1 = CheckDensity(theref, illegalfarms, FarmOccupancy);
663  }
664  (*a_hunterlist)[i].FarmHuntRef[h] = theref;
665 #ifdef __DEBUG_DENSITY
666  double areaHa = FManager->GetFarmTotalSize(theref) / 10000.0;
667  double nohunters = 0;
668  for (int g = 0; g < a_no_hunters; g++)
669  {
670 
671  for (int hs = 0; hs < int((*a_hunterlist)[g].FarmHuntRef.size()); hs++)
672  {
673  if ((*a_hunterlist)[g].FarmHuntRef[hs] == theref) nohunters++;
674  }
675  }
676  if (nohunters / areaHa > cfg_Hunters_MaxDensity.value())
677  {
678  g_msg->Warn("Hunter_Population_Manager::DistributeHunters() - debug density error, rule set ", cfg_Hunters_Distribute_Ruleset.value());
679  exit(0);
680  }
681  for (int frm = 0; frm < FarmOccupancy->size(); frm++)
682  {
683 
684  nohunters = 0;
685  for (int g = 0; g < a_no_hunters; g++)
686  {
687 
688  for (int hs = 0; hs < int((*a_hunterlist)[g].FarmHuntRef.size()); hs++)
689  {
690  if ((*a_hunterlist)[g].FarmHuntRef[hs] == (*FarmOccupancy)[frm].m_FarmRef) nohunters++;
691  }
692  }
693  if ((*FarmOccupancy)[frm].m_no_hunters != nohunters)
694  {
695  g_msg->Warn("Hunter_Population_Manager::DistributeHunters() - debug density error, rule set ", cfg_Hunters_Distribute_Ruleset.value());
696  exit(0);
697  }
698  }
699 #endif
700  }
701  }
702  }
703  else if (a_ruleset == 8) {
705  vector<int>* list = new vector<int>;
706  list->resize(1);
707  (*list)[0] = 0;
708  for (int i = 0; i < a_no_hunters; i++) {
709  for (int h = 0; h < int((*a_hunterlist)[i].FarmHuntRef.size()); h++) {
710  (*a_hunterlist)[i].FarmHuntRef[h] = FManager->FindClosestFarmOpennessProb((*a_hunterlist)[i], &list[0], -1); // -1 means no openness will be used
711  }
712  }
713  }
714  else if (a_ruleset == 9) {
716  vector<int>* list = new vector<int>;
717  list->resize(1);
718  (*list)[0] = 0;
719  for (int i = 0; i < a_no_hunters; i++) {
720  for (int h = 0; h < int((*a_hunterlist)[i].FarmHuntRef.size()); h++) {
721  (*a_hunterlist)[i].FarmHuntRef[h] = FManager->FindClosestFarmOpennessProb((*a_hunterlist)[i], &list[0], (int)cfg_goose_MinForageOpenness.value());
722  }
723  }
724  }
725  else if (a_ruleset == 10) {
727  RuleSet10Based( a_no_hunters, NULL, a_hunterlist, NULL, 10 );
728  }
729  else if (a_ruleset == 11) {
732  // Need to read in the areas real areas for the farms
733  vector<int>* farmsizes = new vector<int>;
734  //read the input file
735  ifstream ifile( "FarmTotalSizeData.txt", ios::in );
736  //check if there is an input file
737  if (!ifile.is_open()) {
738  cout << "Cannot open input file " << "FarmTotalSizeData.txt" << endl;
739  char ch;
740  cin >> ch; //so that it doesn't close immediately
741  exit( 1 );
742  }
743  //get the number of farms
744  int noFarms;
745  ifile >> noFarms; // Could do a check here that this is the right number of farms
746  if (noFarms != m_TheLandscape->SupplyNumberOfFarms()) {
747  cout << "Number of farms does not match farm number in ALMaSS " << noFarms << " != " << m_TheLandscape->SupplyNumberOfFarms() << endl;
748  char ch;
749  cin >> ch; //so that it doesn't close immediately
750  exit( 1 );
751  }
752  //read the data and assign values to the farm's variables
753  for (int f = 0; f < noFarms; f++) {
754  int data;
755  ifile >> data; // this is the farm number
756  ifile >> data;
757  farmsizes->push_back( data );
758  }
759  ifile.close();
760  // OK farm size data read in, lets continue
761  RuleSet10Based( a_no_hunters, farmsizes, a_hunterlist, NULL, 11 );
762  delete farmsizes;
763  }
764  else if (a_ruleset == 12) {
768  // Need to read in the areas real areas for the farms
769  vector<APoint>* roostlocs = new vector<APoint>;
770  //read the input file
771  ifstream ifile( "GooseRoosts.txt", ios::in );
772  //check if there is an input file
773  if (!ifile.is_open()) {
774  cout << "Cannot open input file " << "GooseRoosts.txt" << endl;
775  char ch;
776  cin >> ch; //so that it doesn't close immediately
777  exit( 1 );
778  }
779  //get the number of farms
780  int noroosts;
781  ifile >> noroosts; // Could do a check here that this is the right number of farms
782  //read the data and assign values to the roost locs
783  for (int r = 0; r < noroosts; r++) {
784  APoint data;
785  int species;
786  ifile >> species >> data.m_x >> data.m_y;
787  roostlocs->push_back( data );
788  }
789  ifile.close();
790  // OK farm size data read in, lets continue
791  RuleSet10Based( a_no_hunters, NULL, a_hunterlist, roostlocs, 12 );
792  delete roostlocs;
793  }
794  else {
795  g_msg->Warn("Hunter_Population_Manager::DistributeHunters() - Unknown hunter distribution rule set", cfg_Hunters_Distribute_Ruleset.value());
796  exit(0);
797  }
798 }
799 
800 void Hunter_Population_Manager::RuleSet10Based( int a_no_hunters, vector<int>* a_farmsizes, vector<HunterInfo>* a_hunterlist, vector<APoint>* a_roostlocs, int a_ruleset ) {
801  FarmManager* FManager = m_TheLandscape->SupplyFarmManagerPtr();
802  vector<int>* illegalfarms = new vector<int>;
803  vector<FarmOccupcancyData>* FarmOccupancy = new vector<FarmOccupcancyData>;
804  for (int i = 0; i < a_no_hunters; i++) {
805  for (int h = 0; h < int( (*a_hunterlist)[ i ].FarmHuntRef.size() ); h++) {
806  bool found1 = false;
807  int theref = -1;
808  // While a farm is not allocated
809  int iteration = 0;
810  while (!found1) {
811  if (++iteration > FManager->GetNoFarms()) {
812  g_msg->Warn( "Hunter_Population_Manager::DistributeHunters() - unable to allocate hunter, rule set ", cfg_Hunters_Distribute_Ruleset.value() );
813  exit( 0 );
814  }
815  // Choose a new farm ref to test
816  if (a_ruleset == 10) {
817  theref = FManager->FindClosestFarmOpennessProb( (*a_hunterlist)[ i ], illegalfarms, (int)cfg_goose_MinForageOpenness.value() );
818  found1 = CheckDensity( theref, illegalfarms, FarmOccupancy );
819  }
820  else if (a_ruleset == 11) {
821  // Choose a new farm ref to test
822  theref = FManager->FindClosestFarmOpennessProbSmallIsBest( (*a_hunterlist)[ i ], illegalfarms, (int)cfg_goose_MinForageOpenness.value(), a_farmsizes );
823  found1 = CheckDensity( theref, illegalfarms, FarmOccupancy );
824  }
825  else if (a_ruleset == 12) {
826  // Choose a new farm ref to test
827  theref = FManager->FindClosestFarmOpennessProbNearRoostIsBest( (*a_hunterlist)[ i ], illegalfarms, (int)cfg_goose_MinForageOpenness.value(), a_roostlocs );
828  found1 = CheckDensity( theref, illegalfarms, FarmOccupancy );
829  }
830  }
831  (*a_hunterlist)[ i ].FarmHuntRef[ h ] = theref;
832  }
833  }
834  delete illegalfarms;
835 }
836 
838 {
850  int no_hunters;
851  struct_Hunter sh;
852  sh.m_L = m_TheLandscape;
853  ifstream hunterinifile("./Hunter_Hunting_Locations.txt", ios::in);
854  if (!hunterinifile.is_open()) {
855  m_TheLandscape->Warn( "Hunter_Population_Manager::Init", "Hunter_Hunting_Locations.txt missing" );
856  exit( 1 );
857  }
858  hunterinifile >> no_hunters;
859  // Now we skip the header line:
860  string line;
861  for (int i = 0; i < 19; i++) hunterinifile >> line;
862  if (line != "FarmRef10") {
863  m_TheLandscape->Warn( "Hunter_Population_Manager::Init", "Header line missing from Hunter_Hunting_Locations.txt" );
864  exit( 1 );
865  }
866  /*
867  * Reads the hunter data line by hunter line.\n
868  * Each hunter entry is of the following format:\n
869  * - Hunter type (0 = Goose Hunter) (int)
870  * - x/y home location (int)
871  * - Hunting day limit, ie how many days the hunter will go out (int)
872  * - Active hunting days of the week, 1 = everyday, 0 weekends only (int)
873  * - Efficiency (% hits) when geese are present (double)
874  * - Daily chance of checking for geese (prob 0.0-1.0) (double)
875  * - Number of hunting locations (int)
876  * - Farm reference numbers where they hunt (up to 10).
877  *
878  */
879  for (int h = 0; h < no_hunters; h++)
880  {
881  int no_huntlocs;
882  hunterinifile >> sh.m_ref >> sh.m_HType >> sh.m_huntingdayslimit >> sh.m_weekend >> sh.m_goosecountchance >> sh.m_efficiency >> sh.m_home.m_x >> sh.m_home.m_y >> no_huntlocs;
883  // resize our vectors
884  // TODO one day - create another struct to make this a single vector - just to make the code a little more tidy
885  sh.m_farms.resize(no_huntlocs);
886  sh.m_huntlocrefs.resize(no_huntlocs);
887  sh.m_huntlocs.resize(no_huntlocs);
888  for (int i = 0; i < no_huntlocs; i++)
889  {
890  hunterinifile >> sh.m_huntlocrefs[i];
891  APoint fp = m_TheLandscape->SupplyFarmManagerPtr()->GetFarmCentroid( sh.m_huntlocrefs[ i ] );
892  sh.m_huntlocs[ i ].m_x = fp.m_x;
893  sh.m_huntlocs[ i ].m_y = fp.m_y;
894  // Need to get the farm* from farmref
895  sh.m_farms[i] = m_TheLandscape->SupplyFarmManagerPtr()->GetFarmPtr(sh.m_huntlocrefs[i]);
896  }
897  for (int i = 0; i < 10-no_huntlocs; i++)
898  {
899  hunterinifile >> line; // Skip the NA's
900  }
901  if (sh.m_HType == toh_GooseHunter) sh.m_preyPM = g_PopulationManagerList.GetPopulation(TOP_Goose);
902  else
903  {
904  g_msg->Warn("Hunter_Population_Manager::Init unknown hunter type: ", sh.m_HType);
905  exit(0);
906  }
907  CreateObjects( sh.m_HType, NULL, &sh, 1 );
908  }
909  hunterinifile.close();
910 
911  m_daytime = 0; // Make sure we start the simulation at dawn (as the geese do).
912  // Initialise output
914  {
915  m_HuntingBagRecord = new ofstream("HuntingBagRecord.txt", ios::out);
916  (*m_HuntingBagRecord) << "Year" << '\t' << "Day" << '\t' << "Hour" << '\t' << "Minute" << '\t' << "Season" << '\t' <<
917  "HunterRef" << '\t' << "PolygonRef" << '\t' << "x-coord" << '\t' << "y-coord" << '\t' << "GameType" << endl;
918  }
919  ofstream ofile("HuntingOpportunities.txt", ios::out);
920  ofile << "Year" << '\t' << "HunterRef" << '\t' << "HuntingDays" << '\t' << "TotalBag" << '\t' << "NumberOfShots" << '\t' <<
921  "GameType0" << '\t' << "GameType1" << '\t' << "GameType2" << '\t' << "GameType3" << '\t' << "GameType4" << '\t' << "GameType5" << endl;
922  ofile.close();
923 }
924 
925 void Hunter_Population_Manager::CreateObjects(int a_ob_type, TAnimal* /* pvo */, struct_Hunter* p_data,int a_number)
926 {
927  GooseHunter* GHunter = NULL;
928  for (int i=0; i<a_number; i++)
929  {
930  switch (a_ob_type)
931  {
932  case toh_GooseHunter:
933  if (g_PopulationManagerList.GetPopulation(TOP_Goose) == NULL) break; // Don't make goose hunters if we are not running geese
934  GHunter = new GooseHunter(p_data, this);
935  TheArray[a_ob_type].push_back(GHunter);
936  break;
937  default:
938  char ob[ 255 ];
939  sprintf( ob, "%d", (int) a_ob_type);
940  m_TheLandscape->Warn("Goose_Population_Manager::CreateObjects() unknown object type - ", ob);
941  exit(1);
942  break;
943  }
944  }
945 }
946 
948 {
949  int today = m_TheLandscape->SupplyDayInYear();
950  if (m_daytime == 0)
951  {
952  // Start of day so do some housekeeping.
953  // Reset all clocks
954  for (unsigned i=0; i<m_ListNameLength; i++)
955  {
956  int sz = (int) TheArray[i].size();
957  for (int j=0; j<sz; j++)
958  {
959  GooseHunter* h = (GooseHunter*) TheArray[i][j];
960  h->ResetClock();
961  h->OnMorning();
962  if (h->IsOutHunting()) {
963  g_msg->Warn("Hunter_Population_Manager::DoFirst() - hunter out hunting at midnight at ref ", h->GetHuntField());
964  g_msg->Warn("Hunter_Population_Manager::DoFirst() - hunter clock is ", h->GetClock());
965  g_msg->Warn("Hunter_Population_Manager::DoFirst() - hunter is leader ", h->IsLeader());
966  g_msg->Warn("Day in year is: ", m_TheLandscape->SupplyDayInYear());
967  g_msg->Warn("Year is: ", m_TheLandscape->SupplyYearNumber());
968  exit(0);
969  }
970  }
971  }
972  // Clear all active hunting location information
973  for (unsigned i = 0; i < m_ActiveHuntingLocationsPolyrefs.size(); i++) {
975  }
978  // If end of season, reset bags etc.
979  // Here we only need to ask the first hunter in each list, the answer is the same for the rest
980  for (unsigned i = 0; i < m_ListNameLength; i++) {
981  if ((int)TheArray[ i ].size() > 0) {
982  Hunter* h = (Hunter*)TheArray[ i ][ 0 ];
983  if (h->IsSeasonEnd( today ) && m_SeasonNumber > 0) {
984  ofstream ofile( "HuntingOpportunities.txt", ios::app | ios::out);
985  int year = m_TheLandscape->SupplyYearNumber()-1; // This makes it zero based and cuts out the hidden year.
986  int sz = (int)TheArray[ i ].size();
987  for (int j = 0; j < sz; j++) {
988  h = (Hunter*)TheArray[ i ][ j ];
989  ofile << year << '\t';
990  h->SaveMyData( &ofile );
991  h->ResetSeasonData();
992  }
993  ofile.close();
994  }
995  }
996  }
997  }
998  m_daytime = ( m_daytime + 10 ) % 1440; // We have 10 minutes timesteps
999  if (today == 183 && m_daytime == 1430) m_SeasonNumber++;
1000 }
1001 
1002 void Hunter_Population_Manager::RecordHuntingSuccess(int a_poly, int a_birds, int a_hunter)
1003 {
1008  APoint pt = m_TheLandscape->SupplyCentroid(a_poly);
1009  (*m_HuntingBagRecord) << m_TheLandscape->SupplyYear() << '\t' << m_TheLandscape->SupplyDayInYear() << '\t' << g_date->GetHour() << '\t' <<
1010  g_date->GetMinute() << '\t' << GetSeasonNumber() << '\t' << a_hunter << '\t' << a_poly << '\t' << pt.m_x << '\t' << pt.m_y << '\t' << a_birds << endl;
1011 
1012 
1013 }
1014 
1015 
1016 APoint Hunter_Population_Manager::GetHunterHome(int a_index, int a_list)
1017 {
1018  return dynamic_cast<Hunter*>(TheArray[a_list][a_index])->GetHome();
1019 }
1020 
1021 APoint Hunter_Population_Manager::GetHunterHuntLoc(int a_index, int a_list, unsigned a_ref)
1022 {
1023  return dynamic_cast<Hunter*>(TheArray[a_list][a_index])->GetHuntLoc(a_ref);
1024 }
1025 
1026 
1028 {
1034  for (unsigned i = 0; i < m_ActiveHuntingLocationsPolyrefs.size(); i++) {
1035  if (a_polyref == m_ActiveHuntingLocationsPolyrefs[i])
1036  {
1037  for (int h = 1; h < m_ActiveHuntingLocationsHunters[i]->size(); h++)
1038  {
1039  switch (a_signal)
1040  {
1041  case hlm_shoot:
1042  (*m_ActiveHuntingLocationsHunters[i])[h]->OnShoot();
1043  break;
1044  case hlm_gohome:
1045  (*m_ActiveHuntingLocationsHunters[i])[h]->OnGoHome();
1046  break;
1047  default:
1048  g_msg->Warn("Hunter_Population_Manager::HunterLeaderMessage unknown leader message: ", a_signal);
1049  exit(0);
1050  }
1051  }
1052  return;
1053  }
1054  }
1055  g_msg->Warn("Hunter_Population_Manager::HunterLeaderMessage polyref does not match any of the active polygons in list: ", a_polyref);
1056  exit(0);
1057 }
1058 
1060 {
1061  bool found = false;
1062  for (unsigned i = 0; i < m_ActiveHuntingLocationsPolyrefs.size(); i++) {
1063  if (a_polyref == m_ActiveHuntingLocationsPolyrefs[ i ]) {
1064  found = true;
1065  break;
1066  }
1067  }
1068  return found;
1069 }
1070 
1071 //*******************************************************************************************************************/
1072 // Class Hunter
1073 //*******************************************************************************************************************/
1074 
1075 Hunter::Hunter(struct_Hunter* p_data, Hunter_Population_Manager* p_PPM) : TAnimal(p_data->m_home.m_x, p_data->m_home.m_y, p_data->m_L)
1076 {
1077  m_OurPopulationManager = p_PPM;
1078  Init(p_data);
1079 }
1080 
1082 {
1083  ;
1084 }
1085 
1087 {
1088  m_Home = p_data->m_home;
1089  m_HuntLocs = p_data->m_huntlocs;
1090  m_HuntLocRefs = p_data->m_huntlocrefs;
1091  m_NoHuntLocs = int( m_HuntLocs.size() );
1093  m_bag = 0;
1094  m_myShots = 0;
1095  m_huntingdays = 0;
1096  m_baglimit = 999999999; // p_data->m_baglimit;
1097  m_huntlimit = p_data->m_huntingdayslimit;
1099  m_efficiency = p_data->m_efficiency;
1100  m_OurFarmers = p_data->m_farms;
1101  m_weekend = p_data->m_weekend;
1102  m_myname = p_data->m_ref;
1103  m_clock = 0;
1104  m_lasthuntday = 0;
1106  //m_AnnualHuntingAttempts = 0;
1107 }
1108 
1110 {
1115  if ((m_bag >= m_baglimit) || (m_huntingdays >= m_huntlimit)) return tohts_Resting;
1119  int day = m_OurLandscape->SupplyDayInYear();
1120  if (!InSeason( day )) return tohts_Resting;
1121  // is it a weekday?
1129  if (IsTodayAPreferredHuntDay(day)) {
1130  if (IsTodayAChosenHuntDay( day )) {
1131  return tohts_OutHunting;
1132  }
1133  }
1134  return tohts_Resting; // This is important that it returns resting and not hunting - resting stops the hunter doing anything until the next day.
1135 }
1136 
1137 inline bool Hunter::IsTodayAPreferredHuntDay( int a_today ) {
1145  if (m_weekend == 0) // 0 means only hunt at weekend
1146  {
1147  // 5 & 6 are assumed to be weekends
1148  if (a_today % 7 > 4) return true; else return false;
1149  }
1150  if (m_weekend == 2) // 2 means leave cfg_hunterrefractionperiod days between hunts
1151  {
1152 
1153  if (m_OurLandscape->SupplyGlobalDate() - m_lasthuntday >= cfg_hunterrefractionperiod.value()) return true; else return false;
1154  }
1155  return true;
1156 }
1157 
1158 inline bool Hunter::IsTodayAChosenHuntDay( int a_today ) {
1170  double seasonleft = double( GetSeasonLengthLeft( a_today ) );
1171  if (m_weekend == 0) seasonleft *= 2.0 / 7.0;
1172  double prob = cfg_hunterhuntdayprobscaler.value()*(m_huntlimit - m_huntingdays) / seasonleft;
1173  if (g_rand_uni() < prob) return true;
1174  return false;
1175 }
1176 
1178 {
1182  return tohts_foobar;
1183 }
1184 
1186 {
1190  return tohts_Resting;
1191 }
1192 
1193 //*******************************************************************************************************************/
1194 // Class Goose Hunter
1195 //*******************************************************************************************************************/
1196 
1198 {
1199  m_preyPopulationManger = dynamic_cast<Goose_Population_Manager*>(p_data->m_preyPM);
1200  m_OurFarmers = p_data->m_farms;
1201  m_leader = false;
1204  Init();
1205 }
1206 
1208 {
1209  if (m_huntfields != NULL) delete m_huntfields;
1210 }
1211 
1213 {
1219  m_huntfields = new polylist;
1220  for (int i = 0; i < m_NoHuntLocs; i++)
1221  {
1222  polylist* pl = m_OurFarmers[i]->ListOpenFields((int)cfg_goose_MinForageOpenness.value());
1223  m_huntfields->insert(m_huntfields->begin(), pl->begin(), pl->end()); // add the new one to the main polylist
1224  delete pl;
1225  }
1226  ResetClock();
1227  ResetSeasonData();
1228 }
1229 
1230 
1240  int sz = int(m_huntfields->size());
1241  if (g_rand_uni() >= m_goosecountchance) {
1242  int thepolyref = (*m_huntfields)[int(g_rand_uni()*sz)]; // returns 0 to sz-1;
1243  return thepolyref;
1244  }
1245  else {
1246  // We are checking today, so check out hunting fields
1247  int polyref = -1;
1248  int maxgeese = 0;
1249  for (int hfield = 0; hfield < sz; hfield++) {
1250  int geese = m_OurLandscape->GetQuarryNumbers((*m_huntfields)[hfield]);
1251  if (geese > maxgeese) {
1252  maxgeese = geese;
1253  polyref = (*m_huntfields)[hfield];
1254  }
1255  }
1256  return polyref;
1257  }
1258 }
1259 
1262  if (end == 365){
1263  m_OurLandscape->Warn("GooseHunter::IsSeasonEnd()", "Hunting season end at day 365. First day of the year is 0 hence last day of year is 364");
1264  exit(1);
1265  }
1266  if (day == 1 + end) return true;
1267  if (day == 0 && end == 364) return true; // if the hunting season ends at the end of the year, then day 0 is after it.
1268  return false;
1269 }
1270 
1271 bool GooseHunter::InSeason(int day) {
1278  if (m_OurPopulationManager->GetSeasonNumber() == 0) {
1279 
1280  return false; // We don't want them to start in January in the first year of the sim.
1281  }
1282  if (start > end) {
1283  if ((day < start) && (day > end)) return false;
1284  else {
1285  return true; // must be in the first year after the start of season
1286  }
1287  }
1288  else {
1289  // Season all in one year
1290  if (day < start || day > end) return false;
1291  else {
1292  return true;
1293  }
1294  }
1295 }
1297  if (m_OurPopulationManager->GetSeasonNumber() == 0) return 0; // We don't want them to start in January in the first year of the sim.
1298  int left;
1302  if (start > end) {
1303  // We have a year boundary issue, if the day is in the autumn then we have til the end of year + next year, otherwise we must be in next year already.
1304  if (day >= start) left = (365 - day) + end;
1305  else left = end - day;
1306  }
1307  else {
1308  left = end - day;
1309  }
1310  // We don't want to return a negative number of days, so rather want to say no days left, i.e. 0
1311  if (left < 0) return 0;
1312  return left;
1313 }
1314 
1316 {
1324  else
1325  {
1326  return(Hunter::st_ShouldGoHunting());
1327  }
1328 
1329 }
1330 
1331 
1333 {
1341  m_clock += 10; // this is not strictly necessary, but makes useful debug info (only leader cares)
1342  if (!m_dugin) {
1344  if (m_huntfield_polyref == -1) return tohts_Resting;
1345  else {
1346  m_huntingdays++;
1347  m_dugin = true;
1349  m_lasthuntday = m_OurLandscape->SupplyGlobalDate();
1350  return tohts_OutHunting;
1351  }
1352  }
1353  if (m_leader) {
1354  // Only the leader assesses this
1355  if (m_clock > cfg_huntlength.value())
1356  {
1357  m_dugin = false;
1359  m_huntfield_polyref = -1;
1360  return tohts_Resting; // Come home
1361  }
1377  double fieldsize = m_OurLandscape->SupplyPolygonArea( m_huntfield_polyref );
1378  double shootingchance = 1.0;
1379  if (fieldsize > cfg_largefieldgooseproximitysizecutoff.value()) {
1380  shootingchance = cfg_largefieldgooseproximity.value();
1381  }
1382  /*double pct = 0.0;*/
1384 
1385  if ((birds > 0) && (g_rand_uni() < shootingchance) /* && (pct<cfg_huntermaxprotectedpct.value())*/ ) {
1393  int numbershot = 0;
1394  for (int i = 0; i < m_myMagazine; ++i) {
1395  if ((birds > i) || (numbershot == 0))
1396  {
1397  if (g_rand_uni() < m_efficiency) numbershot++;
1398  m_myShots++;
1399  }
1400  }
1401  if (numbershot > 0) {
1403  }
1405  // All shots are fired then make some sound
1406  // Must scare any birds off that are near here and get them to remember the event
1408  }
1409  }
1410  return tohts_OutHunting;
1411 }
1412 
1413 void GooseHunter::OnShotABird(int a_birdtype, int a_poly) {
1414  m_bag++;
1415  m_goosebag[a_birdtype]++;
1417 }
1418 
1426  int numbershot = 0;
1427  m_myShots++;
1428  if (g_rand_uni() < m_efficiency) numbershot++;
1429  if (birds > 1){
1430  if (g_rand_uni() < m_efficiency) numbershot++;
1431  m_myShots++;
1432  }
1433  if (numbershot > 0) {
1435  }
1436 }
1437 
1439  m_dugin = false; // End of the hunt, so no longer dugin
1440  m_leader = false; // Hunt is over, so nothing to lead.
1441  m_huntfield_polyref = -1; // This has to be reset. We find a new one next time we go hunting.
1442  m_CurrentHState = tohts_Resting; // Come home
1443 }
1444 
1445 
1446 void GooseHunter::Step( void )
1447 {
1448  if (m_StepDone || m_CurrentStateNo == -1) return;
1449  switch (m_CurrentHState)
1450  {
1451  case tohts_InitialState: // Initial state always starts by setting the behaviour to tohts_Hunting
1453  break;
1454  case tohts_Hunting:
1456  break;
1457  case tohts_OutHunting:
1459  break;
1460  case tohts_Resting:
1462  break;
1463  default:
1464  m_OurLandscape->Warn("GooseHunter::Step()","unknown state - default");
1465  exit(1);
1466  }
1467 }
1468 
1469 void GooseHunter::SaveMyData( ofstream* a_ofile ) {
1470  (*a_ofile) << m_myname << '\t' << GetHuntingDays() << '\t' << GetBag() << '\t' << GetShots();
1471  for (int i = 0; i < gst_foobar; i++) {
1472  (*a_ofile) << '\t' << m_goosebag[ i ];
1473  }
1474  (*a_ofile) << endl;
1475 
1476 }
1477 
1478 bool Hunter_Population_Manager::AddHunterHunting( int a_polyref, Hunter* a_hunter ) {
1483  for (unsigned i = 0; i < m_ActiveHuntingLocationsPolyrefs.size(); i++) {
1484  if (m_ActiveHuntingLocationsPolyrefs[ i ] == a_polyref) {
1485  m_ActiveHuntingLocationsHunters[ i ]->push_back( a_hunter );
1487  return false;
1488  }
1489  }
1491  HunterList* p_newhunterlist = new HunterList;
1492  p_newhunterlist->push_back( a_hunter );
1493  m_ActiveHuntingLocationsHunters.push_back( p_newhunterlist );
1494  m_ActiveHuntingLocationsPolyrefs.push_back( a_polyref );
1495  return true;
1496 }
1497 
1502  int start2 = cfg_goose_greylagopenseasonstart.value();
1504  /*Both start and end in the same year*/
1505  if (end1 > start1 && end2 > start2) {
1506  m_HuntingSeasonEnd = end1;
1507  if (m_HuntingSeasonEnd < end2)
1508  {
1509  m_HuntingSeasonEnd = end2;
1510  }
1511  }
1512  /*1 end in the second year*/
1513  if (start1 > end1 && start2 < end2)
1514  {
1515  m_HuntingSeasonEnd = end1;
1516  }
1517  /*2 end in the second year*/
1518  if (start1 < end1 && start2 > end2)
1519  {
1520  m_HuntingSeasonEnd = end2;
1521  }
1522  /*Both end in the second year*/
1523  if (start1 > end1 && start2 > end2)
1524  {
1525  m_HuntingSeasonEnd = end1;
1526  if (m_HuntingSeasonEnd < end2)
1527  {
1528  m_HuntingSeasonEnd = end2;
1529  }
1530  }
1531  if (start1 > start2)
1532  {
1533  m_HuntingSeasonStart = start2;
1534  }
1535  else m_HuntingSeasonStart = start1;
1536  if (m_HuntingSeasonStart < 0)
1537  {
1538  g_msg->Warn("Goose_Population_Manager::SetHuntingSeason() Start of hunting season:", m_HuntingSeasonStart);
1539  exit(1);
1540  }
1541  if (m_HuntingSeasonEnd < 0)
1542  {
1543  g_msg->Warn("Goose_Population_Manager::SetHuntingSeason() End of hunting season:", m_HuntingSeasonEnd);
1544  exit(1);
1545  }
1546 }
GooseHunter::m_pinkfootbaglimit
int m_pinkfootbaglimit
Bag limit for pinkfoot.
Definition: Hunters_all.h:281
farminfo::m_farmref
int m_farmref
Definition: farm.h:494
g_rand_uni2
boost::variate_generator< base_generator_type &, boost::uniform_int<> > g_rand_uni2
struct_Hunter::m_weekend
int m_weekend
Definition: Hunters_all.h:91
farminfo::m_farmarable
int m_farmarable
Definition: farm.h:497
cfg_Hunters_NonresidentPct
static CfgInt cfg_Hunters_NonresidentPct("HUNTERS_NONRESIDENTPCT", CFG_CUSTOM, 30)
Number of hunters living out of area as a percentage of local hunters.
Goose_Population_Manager::BangAtPoly
void BangAtPoly(int a_polyref)
Passes a 'Bang' message to birds near to the location specified by the polygon reference.
Definition: Goose_Population_Manager.cpp:1947
struct_Hunter::m_huntingdayslimit
int m_huntingdayslimit
Definition: Hunters_all.h:90
FarmManager::GetFarmNoOpenFields
int GetFarmNoOpenFields(int a_farmref, int a_openness)
Returns the number of fields with openness more than a_openness.
Definition: farm.h:1754
Hunter_Population_Manager::GetNoHuntLocs
unsigned GetNoHuntLocs()
Calculates the number of hunting locations based on a distribution.
Definition: Hunters_all.cpp:186
GooseHunter::m_preyPopulationManger
Goose_Population_Manager * m_preyPopulationManger
Pointer to our game population, the geese.
Definition: Hunters_all.h:273
FarmManager::GetFarmValidCoords
APoint GetFarmValidCoords(int a_farmref)
Returns the number of fields owned by a from the farm ref num.
Definition: farm.h:1748
Hunter::IsOutHunting
bool IsOutHunting()
A debug function, but may be useful in other contexts. Returns true of currently out hunting.
Definition: Hunters_all.h:223
polylist
vector< unsigned > polylist
Definition: farm.h:207
Calendar::GetHour
int GetHour(void)
Definition: calendar.h:71
g_PopulationManagerList
PopulationManagerList g_PopulationManagerList
FarmManager::GetFarmTotalSize
int GetFarmTotalSize(int a_farmref)
Returns the total farm area from the farm ref num.
Definition: farm.h:1728
Hunter_Population_Manager::SetHuntingSeason
void SetHuntingSeason()
This returns the number of geese which are legal quarry on the polygon the day before.
Definition: Hunters_all.cpp:1498
cfg_gooseopenseasonend
static CfgInt cfg_gooseopenseasonend("GOOSE_OPENSEASON_END", CFG_CUSTOM, 364)
The end of the goose open season. Legal values are 0 to 364.
GooseHunter::OnShoot
virtual void OnShoot()
On shoot message handler.
Definition: Hunters_all.cpp:1419
GooseHunter::Init
virtual void Init()
Initiation of a specific goose hunter here.
Definition: Hunters_all.cpp:1212
GooseHunter::m_leader
bool m_leader
When hunting this indicates whether the hunter is a team leader.
Definition: Hunters_all.h:285
Hunter::m_baglimit
int m_baglimit
Annual self-imposed limit on number shot - unused at present.
Definition: Hunters_all.h:143
FarmManager::FindClosestFarmOpennessProbSmallIsBest
int FindClosestFarmOpennessProbSmallIsBest(HunterInfo a_hinfo, vector< int > *a_farmlist, int a_openness, vector< int > *a_farmsizelist)
Finds the closest farm to this co-ordinate with openness more than a value but uses a probability dis...
Definition: farm.cpp:3233
Hunter_Population_Manager::m_HuntingSeasonStart
int m_HuntingSeasonStart
Start of the overall hunting season.
Definition: Hunters_all.h:390
Hunter::m_weekend
int m_weekend
Code for weekly hunting activity.
Definition: Hunters_all.h:151
Hunter_Population_Manager
The class to handle all predator population related matters.
Definition: Hunters_all.h:334
FarmManager::FindClosestFarmOpenness
int FindClosestFarmOpenness(HunterInfo a_hinfo, vector< int > *a_farmlist, int a_openness)
Finds the closest farm to this co-ordinate but uses a probability distribtution for acceptance.
Definition: farm.cpp:3155
FarmManager::AddToIllegalList
void AddToIllegalList(int a_farm_ref, vector< int > *a_farmlist)
Add to a list if a farm is not already among the illegal list of references.
Definition: farm.cpp:3099
Hunter::IsTodayAPreferredHuntDay
bool IsTodayAPreferredHuntDay(int a_today)
Checks for the hunting day preference (weekday or any day)
Definition: Hunters_all.cpp:1137
Hunter::m_huntfield_polyref
int m_huntfield_polyref
The polygon reference number to our current hunting field (which is at a hunting location)
Definition: Hunters_all.h:157
Hunter::IsSeasonEnd
virtual bool IsSeasonEnd(int)
Is it the end of the hunting season? - MUST be overridden in descendent class.
Definition: Hunters_all.h:246
Hunter_Population_Manager::DistributeHunters
void DistributeHunters(void)
Distributes hunters to hunting locations (farms).
Definition: Hunters_all.cpp:151
GooseHunter::GooseHunter
GooseHunter(struct_Hunter *p_data, Hunter_Population_Manager *p_PPM)
GooseHunter constructor.
Definition: Hunters_all.cpp:1197
cfg_Hunters_MaxDensity
static CfgFloat cfg_Hunters_MaxDensity("HUNTERS_MAXDENSITY", CFG_CUSTOM, 0.1)
Maximum hunter density per ha.
struct_Hunter::m_ref
int m_ref
Definition: Hunters_all.h:82
g_rand_uni
boost::variate_generator< base_generator_type &, boost::uniform_real<> > g_rand_uni
cfg_largefieldgooseproximitysizecutoff
static CfgInt cfg_largefieldgooseproximitysizecutoff("HUNTER_LARGEFIELDGOOSEPROXIMITYCHANCESIZECUTOFF", CFG_CUSTOM, 20000)
The size of the field which will trigger the use of cfg_largefieldgooseproximity.
GooseHunter::IsLeader
bool IsLeader()
Returns the leader flag.
Definition: Hunters_all.h:325
struct_Hunter::m_farms
vector< Farm * > m_farms
Definition: Hunters_all.h:89
farminfo::m_farmsize
int m_farmsize
Definition: farm.h:496
struct_Hunter::m_preyPM
Population_Manager * m_preyPM
Definition: Hunters_all.h:95
start
Definition: treatment.h:32
struct_Hunter::m_huntlocrefs
vector< int > m_huntlocrefs
Definition: Hunters_all.h:85
FarmManager::GetFarmAreaOpenFields
int GetFarmAreaOpenFields(int a_farmref, int a_openness)
Returns the area of fields with openness more than a_openness.
Definition: farm.h:1760
Hunter::st_OutHunting
TypeOfHunterState st_OutHunting(void)
The basic hunting behaviour.
Definition: Hunters_all.cpp:1177
GooseHunter::IsSeasonEnd
virtual bool IsSeasonEnd(int day)
Is it the end of the goose hunting season? - MUST be overridden in descendent class.
Definition: Hunters_all.cpp:1260
Hunter_Population_Manager::HunterLeaderMessage
void HunterLeaderMessage(TypeOfHunterLeaderMessage a_signal, int a_polyref)
A message system to rely messages from the leader hunter to others in his team.
Definition: Hunters_all.cpp:1027
Hunter::m_huntingdays
int m_huntingdays
The numbers of days used for hunting this year.
Definition: Hunters_all.h:139
Hunter::GetShots
int GetShots()
Gets the number of shots this season to-date.
Definition: Hunters_all.h:197
cfg_Hunters_Distribute
static CfgBool cfg_Hunters_Distribute("HUNTERS_DISTRIBUTE", CFG_CUSTOM, false)
Should we enter hunter distribution mode?
cfg_Hunters_MaxDensityPower
static CfgFloat cfg_Hunters_MaxDensityPower("HUNTERS_MAXDENSITYPOWER", CFG_CUSTOM, 0.741)
Maximum hunter density per ha - power parameter.
Hunter::m_lasthuntday
int m_lasthuntday
The date for the last hunt day.
Definition: Hunters_all.h:141
GooseHunter::m_dugin
bool m_dugin
Flag to show whether a hunting location has been found.
Definition: Hunters_all.h:277
Hunter::m_huntlimit
int m_huntlimit
Annual self-imposed limit on number of days spent hunting.
Definition: Hunters_all.h:145
Hunter::GetBag
int GetBag()
Gets the annual hunting bag.
Definition: Hunters_all.h:193
cfg_goose_greylagopenseasonstart
CfgInt cfg_goose_greylagopenseasonstart
The start of the greylag hunting season.
FarmManager::FindFarmWithRandom
int FindFarmWithRandom(vector< int > *a_farmlist)
Finds a farm openness more than a value not on the list.
Definition: farm.cpp:3353
TypeOfHunterState
TypeOfHunterState
Hunters like other ALMaSS animals work using a state/transition concept. These are the hunter behavio...
Definition: Hunters_all.h:55
Hunter::st_ShouldGoHunting
virtual TypeOfHunterState st_ShouldGoHunting(void)
Decide whether to go out hunting on a specific day.
Definition: Hunters_all.cpp:1109
Hunter::m_OurFarmers
vector< Farm * > m_OurFarmers
List of pointers to the farmers whose land the hunter hunts
Definition: Hunters_all.h:153
FarmManager::FindFarmWithOpenness
int FindFarmWithOpenness(vector< int > *a_farmlist, int a_openness)
Finds a farm openness more than a value not on the list.
Definition: farm.cpp:3370
cfg_Hunters_RecordBag
static CfgBool cfg_Hunters_RecordBag("HUNTERS_RECORDBAG", CFG_CUSTOM, false)
Should we record the birds shot?
Hunter::m_NoHuntLocs
int m_NoHuntLocs
Definition: Hunters_all.h:159
TypeOfHunterLeaderMessage
TypeOfHunterLeaderMessage
Types of message a hunter leader can pass on to team members.
Definition: Hunters_all.h:68
cfg_hunter_pinkfootbaglimit
static CfgInt cfg_hunter_pinkfootbaglimit("HUNTER_PINKFOOTBAGLIMIT", CFG_CUSTOM, 9999)
The pinkfoot hunting bag limit.
Hunter::Hunter
Hunter(struct_Hunter *p_data, Hunter_Population_Manager *p_PPM)
The constructor for the Hunter class.
Definition: Hunters_all.cpp:1075
GooseHunter::CheckForGame
virtual int CheckForGame(void)
If the hunter checks for game at their hunting locations then this is done here. Must be overridden.
Definition: Hunters_all.cpp:1231
FarmManager::GetFarmPtrIndex
Farm * GetFarmPtrIndex(int a_index)
Returns the pointer to a farm with a specific index.
Definition: farm.h:1777
cfg_huntlength
static CfgInt cfg_huntlength("GOOSE_HUNTER_HUNT_LENGTH", CFG_CUSTOM, 180)
The default length of hunting.
Landscape
The landscape class containing all environmental and topographical data.
Definition: landscape.h:112
farminfo
Used during saving farm/hunter information.
Definition: farm.h:493
Hunter_Population_Manager::GetHunterHuntLoc
APoint GetHunterHuntLoc(int a_index, int a_list, unsigned a_ref)
Returns the hunter hunting location location.
Definition: Hunters_all.cpp:1021
Hunter::~Hunter
virtual ~Hunter()
The destructor for the Hunter class.
Definition: Hunters_all.cpp:1081
GooseHunter::SaveMyData
virtual void SaveMyData(ofstream *a_ofile)
Each hunter needs to save different kinds of data, so we use a polymorphic method for this.
Definition: Hunters_all.cpp:1469
hlm_shoot
Definition: Hunters_all.h:70
Farm::GetFarmNumber
int GetFarmNumber(void)
Definition: farm.h:782
Hunter_Population_Manager::~Hunter_Population_Manager
virtual ~Hunter_Population_Manager(void)
Hunter population manager destructor.
Definition: Hunters_all.cpp:141
Hunter_Population_Manager::CreateObjects
void CreateObjects(int ob_type, TAnimal *, struct_Hunter *data, int number)
Creates hunter objects and assigns them to the population manager lists.
Definition: Hunters_all.cpp:925
Hunter_Population_Manager::IsPolyrefOnActiveList
bool IsPolyrefOnActiveList(int a_polyref)
Debugging check method.
Definition: Hunters_all.cpp:1059
cfg_goose_MinForageOpenness
CfgFloat cfg_goose_MinForageOpenness
The minimum openness score that a goose will tolerate for foraging.
cfg_hunterlocTWO
static CfgFloat cfg_hunterlocTWO("HUNTERS_HUNTERLOCPROB_TWO", CFG_CUSTOM, 0.616)
The cumulative probability of hunters having up to 2 hunter locations.
toh_GooseHunter
Definition: Hunters_all.h:47
GooseHunter::st_OutHunting
TypeOfHunterState st_OutHunting(void)
The basic hunting behaviour.
Definition: Hunters_all.cpp:1332
struct_Hunter::m_HType
int m_HType
Definition: Hunters_all.h:83
CfgBool
Bool configurator entry class.
Definition: configurator.h:127
GooseHunter::GetSeasonLengthLeft
virtual int GetSeasonLengthLeft(int day)
Returns the length of the hunting season in days - MUST be overridden in descendent class.
Definition: Hunters_all.cpp:1296
cfg_gooseopenseasonstart
static CfgInt cfg_gooseopenseasonstart("GOOSE_OPENSEASON_START", CFG_CUSTOM, 243)
The start of the goose open season.
Hunter::m_OurPopulationManager
Hunter_Population_Manager * m_OurPopulationManager
Pointer to the population manager.
Definition: Hunters_all.h:129
TAnimal
Hunter::m_HuntLocs
vector< APoint > m_HuntLocs
Definition: Hunters_all.h:163
cfg_hunterhuntdayprobscaler
static CfgFloat cfg_hunterhuntdayprobscaler("HUNTER_HUNTDAYPROBSCALER", CFG_CUSTOM, 2.0)
Hedging bets scaler to the probability of going hunting on a particular day.
GooseHunter::st_ShouldGoHunting
virtual TypeOfHunterState st_ShouldGoHunting(void)
Behavior involved in deciding whether to go hunting.
Definition: Hunters_all.cpp:1315
FarmOccupcancyData::m_FarmRef
int m_FarmRef
Definition: Hunters_all.h:104
FarmManager::GetFarmArableSize
int GetFarmArableSize(int a_farmref)
Returns the arable area from the farm ref num.
Definition: farm.h:1733
cfg_hunterlocTHREE
static CfgFloat cfg_hunterlocTHREE("HUNTERS_HUNTERLOCPROB_THREE", CFG_CUSTOM, 0.806)
The cumulative probability of hunters having up to 3 hunter locations.
Hunter_Population_Manager::Init
void Init(void)
Create the initial hunter population and initializes any output options.
Definition: Hunters_all.cpp:837
GooseHunter::m_huntfields
polylist * m_huntfields
Our list of possible hunting fields as polygon reference numbers as supplied by Landscape::SupplyPoly...
Definition: Hunters_all.h:275
Hunter::m_myMagazine
int m_myMagazine
The number of shells in the magazine.
Definition: Hunters_all.h:137
struct_Hunter::m_efficiency
double m_efficiency
Definition: Hunters_all.h:92
FarmManager::GetNoFarms
int GetNoFarms()
Definition: farm.h:1900
Hunter_Population_Manager::m_ActiveHuntingLocationsPolyrefs
vector< int > m_ActiveHuntingLocationsPolyrefs
Lists of polygon reference numbers for all active hunting locations (updated daily)
Definition: Hunters_all.h:373
Hunter::GetClock
int GetClock()
Supplies the clock time.
Definition: Hunters_all.h:210
Hunter::GetHuntField
int GetHuntField()
Get the polygon reference number to our current hunting field (which is at a hunting location)
Definition: Hunters_all.h:234
MapErrorMsg::Warn
void Warn(MapErrorState a_level, std::string a_msg1, std::string a_msg2)
Definition: maperrormsg.cpp:59
Hunter::GetHuntingDays
int GetHuntingDays()
Gets the annual hunting attempts count.
Definition: Hunters_all.h:189
Hunter_Population_Manager::SaveDistributedHunters
void SaveDistributedHunters(vector< HunterInfo > *a_hunterlist, int a_no_hunters)
Saves the results of the hunter distribution to an output file.
Definition: Hunters_all.cpp:198
Population_Manager
gst_PinkfootNonBreeder
Definition: Goose_Base.h:61
Hunter::m_myname
int m_myname
A reference number unique to this hunter.
Definition: Hunters_all.h:125
FarmManager::FindClosestFarm
int FindClosestFarm(HunterInfo a_hinfo, vector< int > *a_farmlist)
Finds the closest farm to this co-ordinate.
Definition: farm.cpp:3126
Hunter_Population_Manager::SaveFarmHunters
void SaveFarmHunters(vector< HunterInfo > *a_hunterlist, int a_no_hunters)
Saves the results of the hunter distribution to an output file by farm.
Definition: Hunters_all.cpp:233
struct_Hunter::m_home
APoint m_home
Definition: Hunters_all.h:84
gst_foobar
Definition: Goose_Base.h:66
Goose_Population_Manager::BirdsShot
void BirdsShot(int a_polyref, int a_numbershot, GooseHunter *a_Hunter)
Passes the message to shoot a number of birds at a forage location.
Definition: Goose_Population_Manager.cpp:1862
farminfo::m_NoHunters
int m_NoHunters
Definition: farm.h:503
FarmManager::FindClosestFarmOpennessProbNearRoostIsBest
int FindClosestFarmOpennessProbNearRoostIsBest(HunterInfo a_hinfo, vector< int > *a_farmlist, int a_openness, vector< APoint > *a_farmsizelist)
Finds the closest farm to this co-ordinate with openness more than a value but uses a probability dis...
Definition: farm.cpp:3289
Hunter::m_goosecountchance
double m_goosecountchance
Probability of checking for geese in hunting area.
Definition: Hunters_all.h:149
cfg_hunterlocFOUR
static CfgFloat cfg_hunterlocFOUR("HUNTERS_HUNTERLOCPROB_FOUR", CFG_CUSTOM, 0.854)
The cumulative probability of hunters having up to 4 hunter locations.
Hunter
The base class for hunters encompsassing all their general behaviours.
Definition: Hunters_all.h:120
GooseHunter::~GooseHunter
virtual ~GooseHunter()
GooseHunter destructor.
Definition: Hunters_all.cpp:1207
Hunter_Population_Manager::DoFirst
virtual void DoFirst()
Does general daily tasks e.g. reset time of day, reset bag lists if start of year etc....
Definition: Hunters_all.cpp:947
cfg_goose_greylagopenseasonend
CfgInt cfg_goose_greylagopenseasonend
The end of the greylag hunting season.
Hunter::OnMorning
void OnMorning()
Optimism in the morning, perhaps we should hunt?
Definition: Hunters_all.h:228
Hunter::GetSeasonLengthLeft
virtual int GetSeasonLengthLeft(int)
Returns the length of the hunting season in days - MUST be overridden in descendent class.
Definition: Hunters_all.h:250
CfgFloat::value
double value(void)
Definition: configurator.h:118
cfg_hunter_magazinecapacity
static CfgInt cfg_hunter_magazinecapacity("HUNTER_MAGAZINECAPACITY", CFG_CUSTOM, 2)
The number of shots a hunter can take per shooting event.
struct_Hunter::m_L
Landscape * m_L
Definition: Hunters_all.h:94
GooseHunter::m_goosebag
int m_goosebag[gst_foobar]
A special bag data structure so the hunter knows what kind of geese he shot.
Definition: Hunters_all.h:279
Hunter::m_myShots
int m_myShots
The numbers of shots to-date this year.
Definition: Hunters_all.h:135
struct_Hunter::m_huntlocs
vector< APoint > m_huntlocs
Definition: Hunters_all.h:86
GooseHunter::m_greylagbaglimit
int m_greylagbaglimit
Bag limit for greylag.
Definition: Hunters_all.h:283
GooseHunter::Step
virtual void Step()
GooseHunter Step code.
Definition: Hunters_all.cpp:1446
tohts_foobar
Definition: Hunters_all.h:61
FarmOccupcancyData
Definition: Hunters_all.h:102
HunterList
vector< Hunter * > HunterList
Definition: Hunters_all.h:111
GooseHunter::OnGoHome
virtual void OnGoHome()
On gohome message handler.
Definition: Hunters_all.cpp:1438
Hunter::m_HuntLocRefs
vector< int > m_HuntLocRefs
Definition: Hunters_all.h:161
CFG_CUSTOM
Definition: configurator.h:60
farminfo::m_farmtype
int m_farmtype
Definition: farm.h:495
hlm_gohome
Definition: Hunters_all.h:71
tohts_Resting
Definition: Hunters_all.h:60
FarmManager::FindOpennessFarm
int FindOpennessFarm(int a_openness)
Finds a random farm with at least one field with openness above a_openness.
Definition: farm.cpp:3387
farminfo::m_farmcentroid
APoint m_farmcentroid
Definition: farm.h:501
Hunter_Population_Manager::m_daytime
unsigned m_daytime
Used to follow the time of day in 10 minute steps.
Definition: Hunters_all.h:386
FarmManager::IsDuplicateRef
bool IsDuplicateRef(int a_ref, HunterInfo *a_hinfo)
Checks if we already have this ref.
Definition: farm.cpp:3116
FarmOccupcancyData::m_no_hunters
int m_no_hunters
Definition: Hunters_all.h:105
Hunter::m_CurrentHState
TypeOfHunterState m_CurrentHState
The current hunter behavioural state.
Definition: Hunters_all.h:127
Hunter_Population_Manager::RecordHuntingSuccess
void RecordHuntingSuccess(int poly, int birds, int a_hunter)
Hunting bag output.
Definition: Hunters_all.cpp:1002
FarmManager::GetFarmType
TTypesOfFarm GetFarmType(int a_farmref)
Returns the farm type from the farm ref num.
Definition: farm.h:1738
Hunter_Population_Manager::GetHuntingSeasonEnd
int GetHuntingSeasonEnd()
Get the end of the overall hunting season.
Definition: Hunters_all.h:381
Hunter_Population_Manager::GetHuntingSeasonStart
int GetHuntingSeasonStart()
Get the start of the overall hunting season.
Definition: Hunters_all.h:379
FarmManager::FindClosestFarmOpennessProb
int FindClosestFarmOpennessProb(HunterInfo a_hinfo, vector< int > *a_farmlist, int a_openness)
Finds the closest farm to this co-ordinate with openness more than a value but uses a probability dis...
Definition: farm.cpp:3182
cfg_goose_pinkfootopenseasonend
CfgInt cfg_goose_pinkfootopenseasonend
The end of the pinkfoot hunting season.
gst_PinkfootFamilyGroup
Definition: Goose_Base.h:60
CfgInt
Integer configurator entry class.
Definition: configurator.h:87
struct_Hunter
Used for creation of a new hunter object.
Definition: Hunters_all.h:79
farminfo::m_openfields
int m_openfields
Definition: farm.h:499
farminfo::m_farmvalid
APoint m_farmvalid
Definition: farm.h:502
Hunter::IsTodayAChosenHuntDay
bool IsTodayAChosenHuntDay(int a_today)
Uses a probability test to determine whether to go hunting today.
Definition: Hunters_all.cpp:1158
cfg_hunterlocONE
static CfgFloat cfg_hunterlocONE("HUNTERS_HUNTERLOCPROB_ONE", CFG_CUSTOM, 0.297)
The probability of hunters having one hunter location.
Farm
The base class for all farm types.
Definition: farm.h:767
Hunter_Population_Manager::m_HuntingBagRecord
ofstream * m_HuntingBagRecord
Output file for hunting bag record.
Definition: Hunters_all.h:388
g_msg
MapErrorMsg * g_msg
This pointer provides access the to the internal ALMaSS error message system.
Definition: maperrormsg.cpp:41
tohts_Hunting
Definition: Hunters_all.h:58
cfg_huntermaxprotectedpct
static CfgFloat cfg_huntermaxprotectedpct("HUNTER_MAXPROTECTECTEDPCT", CFG_CUSTOM, 0.1)
The proportion of protected species in a flock above which there is no shooting
CfgFloat
Double configurator entry class.
Definition: configurator.h:106
tohts_OutHunting
Definition: Hunters_all.h:59
Hunter_Population_Manager::GetHunterHome
APoint GetHunterHome(int a_index, int a_list)
Returns the hunter home location.
Definition: Hunters_all.cpp:1016
Hunter_Population_Manager::RuleSet10Based
void RuleSet10Based(int a_no_hunters, vector< int > *a_farmsizes, vector< HunterInfo > *a_hunterlist, vector< APoint > *a_roostlocs, int a_ruleset)
Used to implement rule sets based on rule set 10.
Definition: Hunters_all.cpp:800
FarmManager::GetFarmCentroid
APoint GetFarmCentroid(int a_farmref)
Gets the farm centroid as an APoint.
Definition: farm.h:1809
CfgInt::value
int value(void)
Definition: configurator.h:98
cfg_hunterrefractionperiod
static CfgInt cfg_hunterrefractionperiod("HUNTER_REFRACTIONPERIOD", CFG_CUSTOM, 7)
The number of days rest between going hunting.
FarmManager::GetRandomFarmRefnum
int GetRandomFarmRefnum()
Returns a random farm reference number.
Definition: farm.h:1781
struct_Hunter::m_goosecountchance
double m_goosecountchance
Definition: Hunters_all.h:93
cfg_Hunters_Distribute_Ruleset
static CfgInt cfg_Hunters_Distribute_Ruleset("HUNTERS_DISTRIBUTE_RULESET", CFG_CUSTOM, 0)
The rule set to use for distributing hunters.
Hunter::ResetSeasonData
void ResetSeasonData()
Sets the bag and hunting counters to zero.
Definition: Hunters_all.h:218
farminfo::m_nofields
int m_nofields
Definition: farm.h:498
Hunter_Population_Manager::Hunter_Population_Manager
Hunter_Population_Manager(Landscape *p_L)
Hunter population manager constructor.
Definition: Hunters_all.cpp:119
tohts_InitialState
Definition: Hunters_all.h:57
FarmManager::GetFarmNoFields
int GetFarmNoFields(int a_farmref)
Returns the number of fields owned by a from the farm ref num.
Definition: farm.h:1743
g_date
class Calendar * g_date
Definition: calendar.cpp:38
cfg_hunter_greylagbaglimit
static CfgInt cfg_hunter_greylagbaglimit("HUNTER_GREYLAGBAGLIMIT", CFG_CUSTOM, 9999)
The greylag hunting bag limit.
cfg_Hunters_Distribute_NonResRuleset
static CfgInt cfg_Hunters_Distribute_NonResRuleset("HUNTERS_DISTRIBUTE_NONRESRULESET", CFG_CUSTOM, 0)
The rule set to use for distributing non-resident hunters.
Hunter_Population_Manager::CheckDensity
bool CheckDensity(int a_ref, vector< int > *a_illegalfarms, vector< FarmOccupcancyData > *a_FarmOccupancy)
helper method to reduce code size in hunter rules - checks density rules
Definition: Hunters_all.cpp:300
Hunter_Population_Manager::m_HuntingSeasonEnd
int m_HuntingSeasonEnd
End of the overall hunting season.
Definition: Hunters_all.h:392
Hunter_Population_Manager::m_ActiveHuntingLocationsHunters
vector< HunterList * > m_ActiveHuntingLocationsHunters
Lists of hunters at all active hunting locations (updated daily)
Definition: Hunters_all.h:371
Hunter::ResetClock
void ResetClock()
Sets the clock back to zero.
Definition: Hunters_all.h:214
cfg_largefieldgooseproximity
static CfgFloat cfg_largefieldgooseproximity("HUNTER_LARGEFIELDGOOSEPROXIMITYCHANCE", CFG_CUSTOM, 0.5)
The likelihood that geese are close enough to shoot on large fields
Hunter::m_clock
int m_clock
Records the time spent hunting per day.
Definition: Hunters_all.h:131
FarmManager::CalcCentroids
void CalcCentroids()
calculate all farm centroids
Definition: farm.h:1783
Goose_Population_Manager::BirdsToShootAtPoly
int BirdsToShootAtPoly(int a_poly)
Returns the number of birds at a forage location - given by a poly ref.
Definition: Goose_Population_Manager.cpp:1833
Hunter::m_bag
int m_bag
The numbers of game items shot todate this year.
Definition: Hunters_all.h:133
Hunter::st_Resting
TypeOfHunterState st_Resting(void)
Finished hunting and waiting for the next opportunity.
Definition: Hunters_all.cpp:1185
farminfo::m_areaopenfields
int m_areaopenfields
Definition: farm.h:500
FarmManager
The Farm Manager class.
Definition: farm.h:1706
CfgBool::value
bool value(void)
Definition: configurator.h:135
Hunter::m_efficiency
double m_efficiency
Probability of 'hitting' a game item.
Definition: Hunters_all.h:147
Hunter::SaveMyData
virtual void SaveMyData(ofstream *)
Each hunter needs to save different kinds of data, so we use a polymorphic method for this.
Definition: Hunters_all.h:254
GooseHunter
The class for goose hunters encompsassing all their specific behaviours.
Definition: Hunters_all.h:268
Hunter_Population_Manager::AddHunterHunting
bool AddHunterHunting(int a_polyref, Hunter *a_hunter)
Adds a hunter hunting, returns true if that hunter is the leader otherwise false.
Definition: Hunters_all.cpp:1478
GooseHunter::InSeason
virtual bool InSeason(int day)
Is it goose hunting season? - MUST be overridden in descendent class.
Definition: Hunters_all.cpp:1271
GooseHunter::OnShotABird
void OnShotABird(int a_birdtype, int a_poly)
Message received when a goose is successully shot.
Definition: Hunters_all.cpp:1413
Hunter::m_Home
APoint m_Home
Definition: Hunters_all.h:155
Hunter::Init
virtual void Init(struct_Hunter *p_data)
Initiation of a basic hunter here.
Definition: Hunters_all.cpp:1086
Hunter_Population_Manager::DistributeHuntersByRules
void DistributeHuntersByRules(vector< HunterInfo > *a_hunterlist, int a_no_hunters, int a_ruleset)
Implements the rule sets to distributes hunters to hunting locations (farms).
Definition: Hunters_all.cpp:346
cfg_goose_pinkfootopenseasonstart
CfgInt cfg_goose_pinkfootopenseasonstart
The start of the pinkfoot hunting season.
Hunter::InSeason
virtual bool InSeason(int)
Is it hunting season? - MUST be overridden in descendent class.
Definition: Hunters_all.h:242
Calendar::GetMinute
int GetMinute(void)
Definition: calendar.h:70