/
Megafauna_Hunting_Pressure-V1.1.nlogo
3631 lines (3505 loc) · 108 KB
/
Megafauna_Hunting_Pressure-V1.1.nlogo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
extensions [csv]
; modified from the patch choice model from optimal foraging theory
; (Michael Barton, Arizona State University)
; by Isaac Ullah and Miriam Coleman-Kopels, San Diego State University
breed [foragers forager]
breed [animals animal]
breed [kills kill]
foragers-own [energy diet-breadth]
animals-own [energy age species payoff rank time-since-repro]
patches-own [stimer gtimer desert]
kills-own [ktimer]
globals [prey-list long-prey-list diversity _recording-save-file-name birth-count death-count num-foragers num-animals males-killed females-killed ppfem-killed seasonal wet-season dry-season]
to Setup
clear-all
Setup_Animals
Setup_Foragers
Setup_Patches
set males-killed 0
set females-killed 0
set ppfem-killed 0
set num-foragers count foragers
set num-animals count animals
if not empty? Output-csv-file [
file-open Output-csv-file
file-print csv:to-row [ "Males Taken" "Females Taken" "Post Partum Femals Taken" "Forager Energy" "Number Males" "Number Females" "Buffalo Energy" "Buffalo Births" "Buffalo Deaths" "Proportion Ungrazed" ]
]
reset-ticks
end
to Go
if init-foragers != 0 [
if not any? foragers [stop]
]
if not any? animals [stop]
if ( stop-at-max-ticks = true ) and ticks >= max-ticks [stop]
ask foragers [
set energy energy - foragers-movement-cost
ifelse food-storage = true
[ if energy < 100 [ Move Forage ] ]
[ Move Forage]
Calculate-Diversity
if imortal-foragers = false [
Check-Death
]
]
ask animals [
set age age + 1 ; animals get older
Move-animals
set energy energy - animals-movement-cost
eat-grass
if [species] of self = 2 [ ; am I female?
set time-since-repro time-since-repro + 1 ; advance the reproduction clock
]
ifelse stop-at-max-herd-size = false [ ; check to see if mating is allowed currently, mate if so
mate
]
[
if count animals < max-herd-size [
mate ]
]
if energy >= 100 [ set energy 100 ] ;; make sure that energy does not go above maximum
Check-Animal-Death
if [species] of self = 2 and [time-since-repro] of self = birth-spacing [
wean
set size 4
set color pink
]
]
ask kills [
set ktimer ktimer - 1
if ktimer <= 0 [die]
]
if grass-growth = true [ ask patches [ grow-grass ] ]
Do_Plots
if not empty? Output-csv-file [
output-data
]
tick
end
to Setup_Patches
ifelse seasonality = 1.0 [set seasonal false] [set seasonal true] ;check if we are doing seasonal or continual regrowth
ask patches [ set pcolor green ]
if grass-growth = true [ ask up-to-n-of ( ( count patches ) * (1 - grass-proportion ) ) patches [ set pcolor brown ] ] ; if variable grass, set patches up
ifelse seasonal = true [
set wet-season round(ticks-per-year * seasonality)
set dry-season ticks-per-year - wet-season
ask patches [
set stimer ticks-per-year
ifelse pcolor = green
[ set gtimer 0]
[ set gtimer random regrowth-time ] ; initialize grass regrowth clocks randomly for brown patches
]
]
[
ask patches [
set gtimer random regrowth-time ; set the intital regrowth timer for all patches
]
]
if keep-initial-grass-pattern = true [
ask patches [ if pcolor = brown [ set desert true ] ] ; if keep-initial is on, inital brown patches will stay brown
]
end
to Setup_Foragers
create-foragers init-foragers
[
set shape "hunter2"
set size 5
set color 38
set energy 100 ;; ENHANCEMENT: make this a slider
set prey-list [] ; rolling list of prey species taken
set long-prey-list [] ; a longer list for all kills
]
ask foragers [setxy random-xcor random-ycor] ; place the foragers randomly in the world
end
to Setup_Animals
; Create 2 animal species with different processing costs, food values, birth rates, and initial population densities
let number-of-males round (init-prey * 0.5)
let number-of-females round (init-prey * 0.5)
set birth-count 0
set death-count 0
create-animals number-of-males [ ; These are Males
setxy 0.5 * max-pxcor 0.5 * max-pycor
set species 1
set energy 100
set age random age-of-senescence
set shape "cow"
set size 6
set color cyan
set payoff ( food-value-males - processing-cost-males ) ; find payoff of food value minus processing costs
ifelse payoff >= ( food-value-females - processing-cost-females ) ; set rank of prey
[ set rank 1 ]
[ set rank 2 ]
]
create-animals number-of-females [ ; These are Females
setxy 0.5 * max-pxcor 0.5 * max-pycor
set species 2
set energy 100
set age random age-of-senescence
set time-since-repro 0 ; only females get this
set shape "cow"
set size 4
set color pink
set payoff ( food-value-females - processing-cost-females ) ; find payoff of food value minus processing costs
ifelse payoff >= ( food-value-males - processing-cost-males ) ; set rank of prey
[ set rank 1 ]
[ set rank 2 ]
]
ask animals [ ; initial setup to minimize "burn in" time of model runs
fd (random (0.25 * max-pxcor)) ; move the animals into a loose cluster
set heading mean-heading [ heading ] of animals in-radius (0.25 * max-pxcor) ; get them facing the same way as neighbors
]
end
to mate
let mates one-of animals-on neighbors ; pick a random nearby animal
if mates != nobody [ ; did we get someone?
if ([species] of mates = 1) and ([species] of self = 2) and ([time-since-repro] of self >= birth-spacing) [ ; am I female? Did I meet a male? and has it been long enough?
if random 100 <= energy [ ; reproduction is probabalistic and linked to energy status
set birth-count birth-count + 1
set time-since-repro 0
set size 6
]
]
]
end
to wean
hatch 1 [
ifelse random 100 <= 50 [
set species 1 ; spawn a male and give it some male attributes
set shape "cow"
set size 6
set color cyan
set payoff ( food-value-males - processing-cost-males ) ; find payoff of food value minus processing costs
ifelse payoff >= ( food-value-females - processing-cost-females ) ; set rank of prey
[ set rank 1 ]
[ set rank 2 ]
set energy 100
set age 0
]
[ set species 2 ; spawn a female and give it some female attributes
set shape "cow"
set size 4
set color pink
set payoff ( food-value-females - processing-cost-females ) ; find payoff of food value minus processing costs
ifelse payoff >= ( food-value-males - processing-cost-males ) ; set rank of prey
[ set rank 1 ]
[ set rank 2 ]
set energy 100
set age 0
set time-since-repro 0 ; only females get this
]
]
end
to Move
let target min-one-of (animals in-radius foraging-radius) with [rank = 1] [distance myself] ; closest high-rank prey in radius
let alt-target min-one-of (animals in-radius foraging-radius) with [species = 2 and time-since-repro <= birth-spacing] [distance myself] ; closest post partum female
ifelse target != nobody and alt-target != nobody [ ;are there both kinds of prey?
ifelse [payoff] of alt-target + food-value-calf > [payoff] of target [ ;pp female value is higher
face alt-target
fd 1 ] [
face target
fd 1
]
] [
ifelse target != nobody [
face target
fd 1
] [
rt random 45
lt random 45 ; otherwise do a random walk
fd 1
] ]
end
to Move-animals
let target-patch min-one-of (patches in-radius 3 with [pcolor = green]) [distance myself] ; First, look for nearby grass...
ifelse target-patch != nobody [
face target-patch ; if so, then move towards it...
fd 1
] [
let target-anims (animals in-radius 5)
; ...if not, then look for any nearby buffalo...
ifelse target-anims != nobody [
set heading mean-heading [ heading ] of target-anims ; ... if so, then face the average way your herd neighbors are facing...
fd 1
] [ set heading random 360 fd 1 ] ; ...if not, then do a random walk.
]
end
to Forage
let last-count count animals
let prey one-of animals-here ;; encounter a random nearby animal
let other-prey animals with [rank = 1] in-radius foraging-radius ;; give forager knowledge ofhigh-ranked animals within set distance
let alternative-payoff 0
if count other-prey != 0 [
set alternative-payoff (mean [payoff] of other-prey) - ( (count patches in-radius foraging-radius / count other-prey ) * foragers-movement-cost)
]
if prey != nobody [ ;; did we get one? If so,
let current-payoff 0 ;; current payoff of encountered animal
ifelse [species] of prey = 2 and [time-since-repro] of prey <= birth-spacing
[ set current-payoff [payoff] of prey + food-value-calf ] ;; if prey is female and recently calved, add food value for calf with mother
[ set current-payoff [payoff] of prey ];; males and other femals get assigned payoff
if (current-payoff >= alternative-payoff) or ;; only pursue prey with payoff greater than continued search,
(energy <= alternative-payoff) ; forager is starving and pursues whatever prey is encountered
[ set energy energy + current-payoff ;; get energy from eating animal
set prey-list fput ([species] of prey) prey-list ; add prey-species to running list of prey taken
set long-prey-list fput ([species] of prey) long-prey-list ; add prey-species to running list of prey taken
if [species] of prey = 1 [set males-killed males-killed + 1]
if [species] of prey = 2 [set females-killed females-killed + 1]
if [species] of prey = 2 and [time-since-repro] of prey <= birth-spacing [
set ppfem-killed ppfem-killed + 1 ; if a post partum female was killed, update that count.
]
]
ask prey [ die ] ; kill it, and...
hatch-kills 1 [
set shape "cow"
set size 7
set color black
set ktimer round(ticks-per-year / 12) ]
hatch-kills 1 [
set shape "x"
set size 5
set color red
set ktimer round(ticks-per-year / 12) ]
]
while [length prey-list > ticks-per-year] [set prey-list remove-item ticks-per-year prey-list] ; manage running list of prey taken
if food-storage = false [
if energy > 100 [ set energy 100 ] ;; make sure that energy does not go above maximum
]
let this-count count animals
set death-count (death-count + (last-count - this-count))
end
to eat-grass ; buffalo procedure
ifelse grass-growth = true [
; buffalo eat grass and turn the patch brown
if pcolor = green [
set pcolor brown
set gtimer regrowth-time
set energy energy + animals-gain-from-food ; buffalo maintain energy by eating
]
]
[
; buffalo graze, but grass stays green
if pcolor = green [
set energy energy + animals-gain-from-food ; buffalo maintain energy by eating
]
]
end
to grow-grass ; patch procedure
ifelse seasonal = true [
; seasonal timer
set stimer stimer - 1
set gtimer gtimer - 1
if stimer > dry-season [ ; if we are in the wet-season, regrow grass continually. When in dry season, no regrowth will happen
if pcolor = brown and gtimer <= 0
[ set pcolor green ]
if desert = true
[ set pcolor brown ]; if desertification is on, then the initial brown patches stay brown
]
if stimer <= 0
[set stimer ticks-per-year] ; start a new year
]
[
; continual reset timer
set gtimer gtimer - 1
if pcolor = brown [
ifelse gtimer <= 0
[ set pcolor green
set gtimer regrowth-time ]
[ set gtimer gtimer - 1 ]
if desert = true [
set pcolor brown ; if desertification is on, then the initial brown patches stay brown
]
]
]
end
to-report grass
ifelse grass-growth = true [
report patches with [pcolor = green]
]
[ report 0 ]
end
to Calculate-Diversity
set diversity 0
if member? 1 prey-list [set diversity diversity + 1]
if member? 2 prey-list [set diversity diversity + 1]
end
to-report mean-heading [ headings ]
let mean-x mean map sin headings
let mean-y mean map cos headings
report atan mean-x mean-y
end
to Do_Plots
set-current-plot "Prey Taken"
set-current-plot-pen "Male"
plot males-killed
set-current-plot-pen "Female"
plot females-killed
set-current-plot-pen "PP-Female"
plot ppfem-killed
set-current-plot "Average Energy"
set-current-plot-pen "Foragers"
ifelse count foragers != 0
[plot (mean [energy] of foragers)]
[plot 0]
set-current-plot-pen "Animals"
ifelse count animals != 0
[plot (mean [energy] of animals)]
[plot 0]
set-current-plot "Population"
set-current-plot-pen "Male"
plot count animals with [species = 1]
set-current-plot-pen "Female"
plot count animals with [species = 2]
set-current-plot-pen "Foragers"
plot num-foragers
set-current-plot "Proportion of Grazed to Ungrazed Grass"
set-current-plot-pen "pgraze"
plot ( ( count patches with [ pcolor = green ] ) / ( count patches ) ) * 100
end
to output-data
file-print csv:to-row ( list
( num-foragers )
( sum [energy] of foragers )
( males-killed )
( females-killed )
( ppfem-killed )
( birth-count )
( death-count )
( count animals with [species = 1] )
( count animals with [species = 2] )
( count animals )
( sum [energy] of animals with [species = 1] )
( sum [energy] of animals with [species = 2] )
( sum [energy] of animals )
( ( ( count patches with [ pcolor = green ] ) / ( count patches ) ) * 100 )
)
file-flush
end
to Check-Death
ask foragers [if energy <= 0 [die]]
set num-foragers count foragers
end
to Check-Animal-Death
; Animals in hunger stress or that have lived longer than senescence have an increased chance of dying.
; Totally spent animals, and animals past maximum lifespan will always die.
; apply a mortality curve for external predation and accidental death
let last-count count animals
ask animals with [energy <= 0] [die]
ask up-to-n-of (last-count * (internal-mortality)) animals with [energy <= animals-starvation-threshold] [die]
ask animals with [age > maximum-lifespan] [die]
ask up-to-n-of (last-count * (internal-mortality)) animals with [age >= age-of-senescence] [die]
ask up-to-n-of (last-count * (external-mortality)) animals [die]
let this-count count animals
set death-count (death-count + (last-count - this-count))
set num-animals count animals
end
@#$#@#$#@
GRAPHICS-WINDOW
575
150
1099
675
-1
-1
2.45
1
10
1
1
1
0
1
1
1
0
210
0
210
1
1
1
ticks
40.0
BUTTON
234
148
300
181
setup
Setup
NIL
1
T
OBSERVER
NIL
NIL
NIL
NIL
1
BUTTON
304
148
367
181
run
Go
T
1
T
OBSERVER
NIL
NIL
NIL
NIL
1
SLIDER
13
28
223
61
init-foragers
init-foragers
0
100
0.0
1
1
NIL
HORIZONTAL
SLIDER
192
196
371
229
processing-cost-males
processing-cost-males
0
20
3.0
1
1
NIL
HORIZONTAL
SLIDER
193
234
372
267
food-value-males
food-value-males
5
100
30.0
1
1
NIL
HORIZONTAL
BUTTON
374
148
437
181
step
go
NIL
1
T
OBSERVER
NIL
NIL
NIL
NIL
1
SLIDER
10
345
222
378
maximum-lifespan
maximum-lifespan
0
12000
10220.0
1
1
NIL
HORIZONTAL
SLIDER
375
196
567
229
processing-cost-females
processing-cost-females
0
20
3.0
1
1
NIL
HORIZONTAL
SLIDER
375
233
568
266
food-value-females
food-value-females
5
100
27.0
1
1
NIL
HORIZONTAL
TEXTBOX
17
173
155
203
Animal Parameters
12
0.0
1
SLIDER
10
196
189
229
init-prey
init-prey
0
1000
250.0
1
1
NIL
HORIZONTAL
PLOT
10
433
561
558
Prey Taken
NIL
NIL
0.0
10.0
0.0
10.0
true
true
"" ""
PENS
"Male" 1.0 0 -11221820 true "" ""
"Female" 1.0 0 -3508570 true "" ""
"PP-Female" 1.0 0 -8630108 true "" ""
MONITOR
474
367
543
412
Males
length (filter [ ?1 -> ?1 = 1 ] prey-list)
0
1
11
MONITOR
473
317
542
362
Females
length (filter [ ?1 -> ?1 = 2 ] prey-list)
0
1
11
TEXTBOX
475
282
549
309
# taken over last year
10
0.0
1
PLOT
10
685
560
805
Average Energy
NIL
NIL
0.0
10.0
0.0
10.0
true
true
"" ""
PENS
"Foragers" 1.0 0 -16777216 true "" ""
"Animals" 1.0 0 -7500403 true "" ""
SLIDER
12
382
222
415
internal-mortality
internal-mortality
0
.2
0.025
0.0001
1
NIL
HORIZONTAL
SLIDER
10
308
222
341
age-of-senescence
age-of-senescence
0
10000
7300.0
1
1
NIL
HORIZONTAL
PLOT
574
685
1099
805
Population
NIL
Number
0.0
10.0
0.0
10.0
true
true
"" ""
PENS
"Male" 1.0 0 -11221820 true "" ""
"Female" 1.0 0 -3508570 true "" ""
"Foragers" 1.0 0 -16777216 true "" ""
SLIDER
740
35
905
68
ticks-per-year
ticks-per-year
0
720
365.0
1
1
NIL
HORIZONTAL
SLIDER
232
309
437
342
animals-gain-from-food
animals-gain-from-food
0
10
1.5
0.01
1
NIL
HORIZONTAL
SLIDER
233
347
436
380
animals-starvation-threshold
animals-starvation-threshold
0
100
25.0
1
1
NIL
HORIZONTAL
SLIDER
232
271
436
304
animals-movement-cost
animals-movement-cost
0
10
1.0
0.01
1
NIL
HORIZONTAL
SLIDER
14
65
224
98
foragers-movement-cost
foragers-movement-cost
0
10
1.0
.01
1
NIL
HORIZONTAL
PLOT
10
561
560
681
Proportion of Grazed to Ungrazed Grass
NIL
NIL
0.0
10.0
0.0
100.0
true
false
"" ""
PENS
"pgraze" 1.0 0 -14439633 true "" ""
INPUTBOX
420
20
540
80
Output-csv-file
NIL
1
0
String
INPUTBOX
1009
85
1098
145
max-herd-size
500.0
1
0
Number
INPUTBOX
913
85
1006
145
max-ticks
73000.0
1
0
Number
SWITCH
914
10
1097
43
stop-at-max-ticks
stop-at-max-ticks
0
1
-1000
SWITCH
914
48
1098
81
stop-at-max-herd-size
stop-at-max-herd-size
1
1
-1000
SWITCH
575
75
710
108
grass-growth
grass-growth
0
1
-1000
SLIDER
715
75
905
108
grass-proportion
grass-proportion
0
1
0.9
.01
1
NIL
HORIZONTAL
SWITCH
575
115
785
148
keep-initial-grass-pattern
keep-initial-grass-pattern
0
1
-1000
SLIDER
232
384
437
417
external-mortality
external-mortality
0
.2
0.0025
0.0001
1
NIL
HORIZONTAL
MONITOR
460
99
552
144
Birth count
birth-count
0
1
11
SLIDER
11
272
222
305
birth-spacing
birth-spacing
0
1000
730.0
1
1
NIL
HORIZONTAL
SLIDER
14
101
224
134
foraging-radius
foraging-radius
1
100
6.0
1
1
NIL
HORIZONTAL
TEXTBOX
19
10
169
28
Forager Parameters
12
0.0
1
SLIDER
10
233
190
266
food-value-calf
food-value-calf
0
20
3.0