Compare two variables from two breeds - netlogo

I still haven't learned how to compare two attributes from two different breeds.
In my example, I want to ask the breeds (healthy shops and unhealthy shops) to compare their revenues. The type of shop with the least revenues will close and the other type of shop will open in his place. The command to "compare-revenue" is the one that doesn't work. I know I shouldn't use breed, but I don't know how to formulate it differently without getting the "tick" error.
Thanks!
breed[healthy-shops healthy-shop]
breed[unhealthy-shops unhealthy-shop]
healthy-shops-own[
total-earnings-h
]
unhealthy-shops-own[
total-earnings-nh
]
to setup
create-healthy-shops 50
create-unhealthy-shops 50
ask healthy-shop [set total-earnings-n 2000 + random 2000]
ask unhealthy-shop [set total-earnings-nn 2000 + random 2000]
end
to go
compare-revenue
end
;;;;;;;;;
to compare-revenue
let minhealth one-of healthy-shops with-min [total-earnings-h]
let minunhealth one-of unhealthy-shops with-min [total-earnings-nh]
ask breed [ifelse (total-earnings-nh < total-earnings-h
[ask minunhealth [die hatch-healthy-shops 1]]
[ask minhealth [die hatch-unhealthy-shops 1]]]
end
Another version using the let command (not sure if it is right)
to compare-revenue
let minhealth one-of healthy-shops with-min [total-earnings-h]
let minunhealth one-of unhealthy-shops with-min [total-earnings-nh]
if minhealth > minunhealth [ask minunhealth [die hatch-healthy-shops 1]]
if minhealth < minunhealth [ask minhealth [die hatch-unhealthy-shops 1]]
end

When you correct the typos: ask healthy-shops [set total-earnings-h 2000 + random 2000] and ask unhealthy-shops [set total-earnings-nh 2000 + random 2000] I get an error "You can't use go in an observer context, because go is turtle/link-only".
That is because of the usage of minhealth/minunhealth without giving the respective shop. You can correct that by writing:
([total-earnings-nh] of minunhealth < [total-earnings-h] of minhealth)
This will make the code run until there are no healty or unhealty shops left and then crash.
You can change that by using
if any? unhealthy-shops and any? healthy-shops
[compare-revenue]
Also, you have to change the order of die and hatch. Right now, no new shops are created, because the shop, it should hatch from is already deleted.
This would be the full code:
breed[healthy-shops healthy-shop]
breed[unhealthy-shops unhealthy-shop]
healthy-shops-own[
total-earnings-h
]
unhealthy-shops-own[
total-earnings-nh
]
to setup
create-healthy-shops 50
[
setxy random-xcor random-ycor
set total-earnings-h 2000 + random 2000
]
create-unhealthy-shops 50
[
setxy random-xcor random-ycor
set total-earnings-nh 2000 + random 2000
]
end
to go
if any? unhealthy-shops and any? healthy-shops
[compare-revenue]
end
to compare-revenue
let minhealth one-of healthy-shops with-min [total-earnings-h]
let minunhealth one-of unhealthy-shops with-min [total-earnings-nh]
ifelse ([total-earnings-nh] of minunhealth < [total-earnings-h] of minhealth)
[ask minunhealth [hatch-healthy-shops 1 die]]
[ask minhealth [hatch-unhealthy-shops 1 die]]
end

Related

Creating conditional links between two breeds

I am writing a NetLogo model of a housing market and its political ramifications. There are two breeds in the model: households and houses. An early step in my development with which I am having difficulty is having households match to houses via one of two types of links, own or rent, defined by nested conditional statements. This has resulted in two difficulties I haven't been able to overcome as of yet.
Within the command setup-market command, I'm trying to define a set of possible houses to purchase for each household which, if they meet a set of conditions, the household then buys (and creates a link). If it cannot afford to buy, then it will try to rent. If it cannot afford to rent the household will die.
My code continually results in the following error:
IFELSE expected input to be a TRUE/FALSE but got the turtle (house XXX) instead.
There is a further issue I'm having as well later in the code (in the two lines commented out with ";") where I attempt to set the variables owner-occupied and renter to 1 based on the presence of the appropriate link (they should remain 0 and the household should die if it remains unlinked).
The full code is below. The line with ";; This is the line giving me trouble" denotes where the error seems to be occurring.
UPDATE:
Code has been updated with JenB's solution. Resulting error is now:
CREATE-LINK-WITH expected input to be a turtle but got NOBODY instead. which occurs at the line: create-link-with one-of potentialHomes [ set color red
undirected-link-breed [own-links own-link]
undirected-link-breed [rent-links rent-link]
breed [city-centers city-center]
breed [households household]
households-own
[
age
money
income
monthly-income
consumption
monthly-consumption
hh-size race
preference
net-income
net-monthly-income
myHouse
]
breed [houses house]
houses-own
[
cost
down-payment
mortgage-payment
rent
rent-premium
rooms
onMarket
owner-occupied
rental
onMarket?
]
patches-own [
seed? ;;district seed
district ;;district number
full? ;;is the district at capacity?
quadrant
]
to setup
clear-all
reset-ticks
setup-patches
set-default-shape households "person"
create-households num-households [ setxy random-xcor random-ycor ]
set-default-shape houses "house"
create-houses num-houses [ setxy random-xcor random-ycor ]
setup-households
setup-houses
setup-market
generate-cities
end
to generate-cities
let center-x random-xcor / 1.5 ;;keep cities away from edges
let center-y random-ycor / 1.5
end
to setup-patches
ask patches with [pxcor > 0 and pycor > 0] [set quadrant 1 set pcolor 19 ]
ask patches with [pxcor > 0 and pycor < 0] [set quadrant 2 set pcolor 49 ]
ask patches with [pxcor < 0 and pycor < 0] [set quadrant 3 set pcolor 139 ]
ask patches with [pxcor < 0 and pycor > 0] [set quadrant 4 set pcolor 89 ]
end
to setup-households
ask households
[ set age random-poisson 38
set money random-exponential 30600
set income random-exponential 64324
set monthly-income income / 12
set consumption .5 * income
set monthly-consumption consumption / 12
set hh-size random 6 + 1
set net-income income - consumption
set net-monthly-income monthly-income - monthly-consumption
]
end
to setup-houses
ask houses
[ set cost random-normal 300000 50000
set down-payment cost * down-payment-rate
set mortgage-payment (cost - down-payment) / 360
set rooms random-exponential 3
set onMarket 1
set rent mortgage-payment + mortgage-payment * .25
set owner-occupied 0
set rental 0
]
end
to setup-market
ask houses
[ set onMarket? TRUE ]
ask households
[ ifelse any? houses with [ [money] of myself > down-payment and [net-monthly-income] of myself > mortgage-payment ]
[ let potentialHomes houses with [[money] of myself > cost and onMarket? ]
create-link-with one-of potentialHomes [
set color red
]
]
[
ifelse any? houses with [ [net-monthly-income] of myself > rent]
[ let potentialRentals houses with [ [net-monthly-income] of myself > rent and onMarket? ]
create-link-with one-of potentialRentals [ set color blue ]
]
[ die ]
]
]
ask houses
[ if any? link-neighbors [set onMarket FALSE ]
;if any? link-neighbors and color red [ set owner-occupied 1 ]
;if any? link-neighbors and color blue [ set rental 1 ]
]
end
to go
move-households
tick
end
to move-households
ask households [
move-to myHouse
]
end
You don't need to "suspect" where the problem is, NetLogo points to the problem line. Running your code, the problem is actually ifelse one-of houses with [ [net-monthly-income] of myself > rent]. Looking at that line, you pull out a randomly selected house from the pool with rent less than income. But you don't have a condition for the ifelse to test.
In previous constructions you have had != nobody at the end but you forgot that in this line. That will fix the error, but your code would be much less error prone if you used any? instead. You seem to be using one-of .... != nobody to test whether there are any turtles that satisfy the condition. That's what any? is for.
So instead of:
ifelse one-of houses with [ [net-monthly-income] of myself > rent] != nobody
[ let potentialRentals houses with [[money] of myself > rent and onMarket = 1 ]
create-link-with one-of potentialRentals [ set color blue ]
]
[ die ]
you can have:
ifelse any? houses with [ [net-monthly-income] of myself > rent]
[ let potentialRentals houses with [[money] of myself > rent and onMarket = 1 ]
create-link-with one-of potentialRentals [ set color blue ]
]
[ die ]
I should add that there is a potential logic problem here. Say there are houses with rent lower than income, the code goes to the first (true) actions. But there's no guarantee that there are any houses that satisfy the new conditions, which are different.
Also, NetLogo has the concept of true and false so you don't need to use 1 and 0. By convention (but not required), boolean variable names end with a question mark. So you could have set onMarket? true instead of set onMarket 1. Why would you do this? It makes logical operators cleaner and easier to read (which reduces bugs). Your line:
let potentialRentals houses with [[money] of myself > rent and onMarket = 1 ]
would look like:
let potentialRentals houses with [[money] of myself > rent and onMarket? ]
And you can do things like if not onMarket? instead of if onMarket? = false or if onMarket = 0

Catch nobody for target patch

I want to check if target patches fulfil a condition. If a patch is found that fulfils the condition,
then the turtles should move there. If 'nobody' fulfils this condition, then an error message should be printed.
The condition is that a patch should have in radius 10 2 turtles of the same breed.
I try to achieve this with ifelse and nobody. However, at the moment I always get the error message, even though the
target variable is not empty (you can check this with the if loop).
breed [ breed1s breed1 ]
breed [ breed2s breed2 ]
globals [target1 target2]
to setup
ca
create-breed1s 1000 [
setxy random-xcor random-ycor
]
create-breed1s 1000 [
setxy random-xcor random-ycor
]
end
to go
ask turtles [
set target1 ( count turtles in-radius 10 with [breed = breed1s] ) >= 2
set target2 ( count turtles in-radius 10 with [breed = breed2s] ) >= 2
new-position
]
end
to new-position
ifelse target1 != nobody
[ if (breed = breed1s) [ move-to one-of patches with [ target1 ] ] ]
[ print "Not enough agents in the neighborhood" ]
ifelse target2 != nobody
[ if (breed = breed2s) [ move-to one-of patches with [ target2 ] ] ]
[ print "Not enough agents in the neighborhood" ]
; if (breed = breed1s)
; [ move-to one-of patches with [ target1 ] ]
end
A remark to the efficiency of the model: as I want to add turtles later in every tick, target has to be reevaluated
in every tick (therefore it is in "go" and not in "setup").
Another question: is there a possibility to do something like [ breed = myself ] instead of [ breed = breed1s ], so
I don't have to type the breed for every breed?
Edit:
the turtles that move to the target patch should have the same breed that is also addressed in the target patch.
The problem is actually how you are creating target1, not the check as to whether it is nobody. You have:
set target1 ( count turtles in-radius 10 with [breed = breed1s] ) >= 2
This line first identifies all the nearby turtles with the appropriate breed and counts them. If the count is 2 or higher, then the variable target1 is set to true and to false if the count is 0 or 1. So you are comparing a boolean true or false to nobody (a special type of agent). That will always be a mismatch and therefore print the error.
Just a note on debugging - when you get this sort of problem, it's always useful to have a print statement for each side of the check just before doing the check. You would have immediately spotted that target1 wasn't what you thought it was.
Since you are asking to move to one-of the patches, you probably really want to store the available patches that are within 10 distance (I think) and have enough of the right type of turtles. So, you need something like:
to go
ask turtles [
set target1 patches in-radius 10 with [count breed1s-here >= 2]
set target2 patches in-radius 10 with [count breed2s-here >= 2]
new-position
]
end
Then your emptiness test is any?
to new-position
ifelse any? target1
[ move-to one-of target1 ]
[ print "Not enough agents in the neighborhood" ]
ifelse any? target2
[ move-to one-of target2 ]
[ print "Not enough agents in the neighborhood" ]
end
Assuming I have correctly interpreted that you want patches within 10 of the asking turtle (as compared to any patch with sufficient turtles within a distance of 10) and all you care about is the number of turtles of its own breed, then:
to go
ask turtles [
let target-breed [breed] of myself
set targets patches in-radius 10 with [count turtles-here with [breed = target-breed] >= 2]
new-position
]
end
to new-position
ifelse any? targets
[ move-to one-of targets ]
[ print "Not enough agents in the neighborhood" ]
end
On the efficiency, it depends on how many turtles you have. If you have quite a lot of turtles, then asking each to count its own neighbourhood will be expensive. Instead, you could have patchsets for each breed. That is, set up target1 as patches with [count breed1s-here >= 2] at the beginning of the go procedures. Then you can just do:
to go
let targets1 patches with [count breed1s-here >= 2]
let targets2 patches with [count breed2s-here >= 2]
ask turtles
[ set targets targets1 in-radius 10
new-position
]
end
However, you can no longer use the breed of the turtle and the myself trick to pick the correct patchset. There are ways to get around this (for example, using a list with two items, breed at first position and the patchset as second position) but that's getting well off track for this answer.
to new-position
ifelse any? targets
[ move-to one-of targets ]
[ print "Not enough agents in the neighborhood" ]
end

Netlogo, how to delete link between turtles based on value they own

I am writing simulation where i am trying to simlate recruiting process for terrorost organization. In this model turtles have groups of friends i.e other turtles they are connected to with links. The model includes the forming of new bonds(links) with turtles they meet if their world view is similar and is supposed to have a mechanism for disconectiong from friends with world view most different from them among their friends.
Tried to solve the issue with following block of code which does not seem to work properly, often get the error message
"OF expected input to be a turtle agentset or turtle but got NOBODY instead."
related to value of friend_dif
ask turtles with [(connections > 0) and (color = blue)][
let friends_inverse ( 1 / connections )
if friends_inverse > random-float 1[
let friend_dif abs([world_view] of self - [world_view] of one-of other link-neighbors)
ask max-one-of links [friend_dif][
die
]
]
set connections count link-neighbors
]
Below is the whole code for the mentioned simulation. The aim is to comparetwo strategies one where recriters focus on turtles with most radical world view, the second where they first targets the most central turtles in the net.
turtles-own [connections world_view]
to setup
ca
crt potential_recruits [setxy random-xcor random-ycor set color blue]
ask turtles with [color = blue][
let przypisania random max_start_recruits_connections
;; 0-0.4 non interested, 0.4-0.7 moderate, 0.7-0.9 symphatizing, >0.9 radical - can be recrouted
set world_view random-float 1
if count my-links < 10 [
repeat przypisania [
create-link-with one-of other turtles with [(count link-neighbors < 10) and (color = blue)]
]
]
show link-neighbors
set connections count link-neighbors
]
crt recruiters [setxy random-xcor random-ycor set color orange]
ask turtles with [color = orange][
set world_view 1
if strategy = "world view"[
recruit_view
]
if strategy = "most central"[
recruit_central
]
]
;;show count links
reset-ticks
setup-plots
update-plots
end
to go
;;creating new links with turtles they meet and movement which is random
ask turtles [
rt random-float 360
fd 1
if any? other turtles-here[
let world_view1 [world_view] of one-of turtles-here
let world_view2 [world_view] of one-of other turtles-here
let connection_chance abs(world_view1 - world_view2)
if connection_chance <= 0.2 [
;;show connection_chance
create-links-with other turtles-here
]
]
;;show link-neighbors
set connections count link-neighbors
]
;;how recruiting works in this model
ask turtles with [world_view > 0.9][
if count in-link-neighbors with [color = orange] > 0[
set color orange
set world_view 1
]
]
;; friend's influence on turtles
ask turtles with [(count link-neighbors > 0) and (color = blue)][
let friends_view (sum [world_view] of link-neighbors / count link-neighbors)
let view_dev (friends_view - world_view)
;;show world_view show view_dev
set world_view world_view + (view_dev / 2)
]
;; removing turtles from with most different opinion from our colleagues
ask turtles with [(connections > 0) and (color = blue)][
let friends_inverse ( 1 / connections )
if friends_inverse > random-float 1[
let friend_dif abs([world_view] of self - [world_view] of one-of other link-neighbors)
ask max-one-of links [friend_dif][
die
]
]
set connections count link-neighbors
]
;show count links
tick
update-plots
end
to recruit_view
ask max-n-of start_recruiters_connections turtles with [ color = blue][world_view][
repeat start_recruiters_connections[
create-link-with one-of other turtles with [ color = orange]
]
]
ask turtles with [color = orange][
set connections count link-neighbors
]
end
to recruit_central
ask max-n-of start_recruiters_connections turtles with [ color = blue][count my-links][
repeat start_recruiters_connections[
create-link-with one-of other turtles with [ color = orange]
]
]
ask turtles with [color = orange][
set connections count link-neighbors
]
end
to batch
repeat 50 [
go
]
end
Your problem is that you aren't switching contexts (that is, whether the code is 'currently' in the perspective of a turtle or a link) correctly.
You start with ask turtles - pretend you are now the first turtle being asked. First a value is calculated and then compared to a random number - assume that the if is satisfied. The code is still in the turtle context, so the code inside the [] is applied to this first turtle.
The code creates a variable called friend_dif and assigns its value as the difference in worldviews between itself and one randomly selected network neighbours. In your code, you then have max-one-of links [friend_dif]. However, that only selects the link with the maximum value of friend_dif if (1) friend_dif is a links-own attribute and (2) the value of friend_dif has been set for all links. Neither is true. Furthermore, by asking for max-one-of links [friend_dif], you are asking for the link with the highest value from all links in the model, not just the ones with the turtle of interest at one end.
So you need to get your turtle to calculate the difference for all its link-neighbors and then switch contexts to the link that connects the two turtles, before asking that link to die.
This is not tested. What it is supposed to do is identify the network neighbour that returns the biggest difference in worldview values and then use the name of the link (which is given by the two ends) to ask it to die.
ask turtles with [ count my-links > 0 and color = blue]
[ if random-float 1 < 1 / count my-links
[ let bigdif max-one-of link-neighbours [abs ([worldview] - [worldview] of myself)
ask link self bigdif [die]
]
]
Alternatively (and easier to read), you can create a link attribute that stores the value of the differences in worldviews (called dif below), then do something like:
ask links [ set dif abs ([worldview] of end1 - [worldview] of end2) ]
ask turtles with [ count my-links > 0 and color = blue]
[ if random-float 1 < 1 / count my-links
[ ask max-one-of my-links [dif] [die]
]
]

Subtract. SET variableX-variableY only once

I'm trying to set a resource variable. It will be time and will function like sugar in sugarscape. Its setup is: ask agentes [set time random-in-range 1 6].
The thing is... I want the agentesto participate in activities linking like we said here. But, with each participation, it should subtract a unity of agentes's time. I imagine it must be with foreachbut I seem to be unable to grasp how this works.
ask n-of n-to-link agentes with [n-t-activity = [n-t-activity] of myself] in-radius sight-radius [
while [time >= 2] [
create-participation-with myself [ set color [color] of myself ] ]
foreach (command I don't know)[
set time time - count participations]]
Essentially, I want the agentes to look if they have time to participate. If they do, they create the link and subtract 1 to their time. Only ONE per participation. If they have 3 time, they'll have 2 participations and 1 time. If they have 1 time, they won't have links at all.
EDIT
You're right. I don't need while. About foreach, every place I looked said the same thing but I can't think of other way. About colors, they're only for show purpose.
The relationship between time and participation counts is as follows: the agentes have time they can spend in activities. They participate if time>=2. But every participation (link with activity) consumes 1 time when the link is active (I didn't write the decay code yet; they'll regain their time when it is off).
EDIT V2
Nothing, it keeps subtracting even with the []. Maybe the best choice is if I give you the code so you can try it. You'll have to set 5 sliders: prob-female (53%), initial-people (around 200), num-activity (around 20), n-capacity (around 25) and sight-radius (around 7). And two buttons, setup and go. I also set a patch size of 10 with 30 max-pxcor and max-pycor. Here is the code. Sorry if I'm not clear enough!
undirected-link-breed [participations participation]
turtles-own [
n-t-activity
]
breed [activities activity]
activities-own [
t-culture-tags
shared-culture
]
breed [agentes agente]
agentes-own [
gender
time
culture-tags
shared-culture
]
to setup
clear-all
setup-world
setup-people-quotes
setup-activities
reset-ticks
END
to setup-world
ask patches [set pcolor white]
END
to setup-people-quotes
let quote (prob-female / 100 * initial-people)
create-agentes initial-people
[ while [any? other turtles-here ]
[ setxy random-xcor random-ycor ]
set gender "male" set color black
]
ask n-of quote agentes
[ set gender "female" set color blue
]
ask agentes [
set culture-tags n-values 11 [random 2]
set shared-culture (filter [ i -> i = 0 ] culture-tags)
]
ask agentes [
set time random-in-range 1 6
]
ask agentes [
assign-n-t-activity
]
END
to setup-activities
create-activities num-activity [
set shape "box"
set size 2
set xcor random-xcor
set ycor random-ycor
ask activities [
set t-culture-tags n-values 11 [random 2]
set shared-culture (filter [i -> i = 0] t-culture-tags)
]
ask activities [
assign-n-t-activity]
]
END
to assign-n-t-activity
if length shared-culture <= 4 [
set n-t-activity ["red"]
set color red
]
if length shared-culture = 5 [
set n-t-activity ["green"]
set color green
]
if length shared-culture = 6 [
set n-t-activity ["green"]
set color green
]
if length shared-culture >= 7 [
set n-t-activity ["black"]
set color black
]
END
to go
move-agentes
participate
tick
end
to move-agentes
ask agentes [
if time >= 2 [
rt random 40
lt random 40
fd 0.3
]
]
end
to participate
ask activities [
if count my-links < n-capacity [
let n-to-link ( n-capacity - count my-links)
let n-agentes-in-radius count (
agentes with [
n-t-activity = [n-t-activity] of myself ] in-radius sight-radius)
if n-agentes-in-radius < n-to-link [
set n-to-link n-agentes-in-radius
]
ask n-of n-to-link agentes with [
n-t-activity = [n-t-activity] of myself] in-radius sight-radius [
if time >= 2 [
create-participation-with myself [
set color [color] of myself ]
ask agentes [set time time - count my-participations] ]
]
ask activities [
if not any? agentes in-radius sight-radius [
ask participations [die]
]
]
]
]
end
to-report random-in-range [low high]
report low + random (high - low + 1)
END
EDIT V3
I asked Bill Rand to help me and he solved the problem. The issue was in this line: let candidates agentes with [ n-t-activity = [n-t-activity] of myself ] in-radius sight-radius. He solved the problem this way: let candidates agentes with [ n-t-activity = [n-t-activity] of myself and not participation-neighbor? myself ] in-radius sight-radius. Being this and not participation-neighbor? myself the condition to make sure that the agente is not already a part of that activity.
You almost never need foreach in NetLogo. If you find yourself thinking you need foreach, your immediate reaction should be that you need ask. In particular, if you are iterating through a group of agents, this is what ask does and you should only be using foreach when you need to iterate through a list (and that list should be something other than agents). Looking at your code, you probably don't want the while loop either.
UPDATED FOR COMMENTS and code - you definitely do not need while or foreach.
Your problem is the following code. You ask agentes that satisfy your conditions to create the links, but then you ask ALL AGENTES to change their time (line I have marked), not just the agentes that are creating participation links.
ask n-of n-to-link agentes with [
n-t-activity = [n-t-activity] of myself] in-radius sight-radius [
if time >= 2 [
create-participation-with myself [
set color [color] of myself ]
ask agentes [set time time - count my-participations] ] ; THIS LINE
]
The following code fixes this problem. I have also done something else to simplify reading and also make the code more efficient - I created an agentset (called candidates) of the agentes that satisfy the conditions. In this code, the candidates set is only created once (for each activity) instead of twice (for each activity) because you are creating it to count it and then creating it again to use for participation link generation.
to participate
ask activities
[ if count my-links < n-capacity
[ let candidates agentes with [
n-t-activity = [n-t-activity] of myself ] in-radius sight-radius
let n-to-link min (list (n-capacity - count my-links) (count candidates ) )
ask n-of n-to-link candidates
[ if time >= 2
[ create-participation-with myself [ set color [color] of myself ]
set time time - count my-participations ] ; REPLACED WITH THIS LINE
]
ask activities [
if not any? agentes in-radius sight-radius [
ask participations [die]
]
]
]
]
end

NetLogo releasing isolated patches from patch-set

I am growing animal territories. Animal territories may cleave parts of other animal territories during the process of expand. So instead of being one contiguous territory, the territory may include more than one cluster (i.e., unattached clusters). This is what happens in the model below. I'd like to have the territory recognize this and release whichever cluster of cells (or a single unattached cell) is smallest so that the territory remains one contiguous cluster. I'm not sure where to start with this. Any help would be great.
breed [animals animal]
breed [homeranges homerange]
animals-own
[
Name
orig
territory
food
status
]
patches-own
[
owner
prey
]
to setup
clear-all
random-seed 2234
ask patches
[
set owner nobody
set prey 2
set pcolor scale-color (black) prey 1 4
]
let $colors [brown orange violet sky lime]
let $Name ["t6" "t7" "t8" "t9" "t10"]
let $status [0 0 0 0 5]
ask n-of 5 patches
[
sprout-animals 1
[
set shape "circle"
set orig patch-here
set territory patch-set orig
set status item who $status
set size 0.3 + 0.1 * status
set color item who $colors
set pcolor color
set Name item who $Name
set owner self
]
]
reset-ticks
end
to go
if all? animals [food >= 350] [ stop ]
if ticks = 70 [ stop ]
expand
tick
end
to expand ; animals procedure
repeat 10
[
ask animals
[
let vacant no-patches
let subord no-patches
let target nobody
let new-patches no-patches
let status-of-calling-tiger status ;
let calling-tiger self ;
; If territory not yet good enough:
if food < 500
[
ask territory
[
; Add unoccupied neighbor patches as potential targets:
set vacant (patch-set vacant neighbors with [owner = nobody])
; Add occupied neighbor patches as potential targets if their tiger has a lower status than me:
set subord (patch-set subord neighbors with [owner != nobody and [status] of owner < status-of-calling-tiger])
]
ask subord [ set pcolor red ]
; Set of all potential targets:
set new-patches (patch-set new-patches vacant subord)
; Choose as target the one potential target with highest prey:
if any? new-patches
[
ask new-patches
[ifelse any? vacant
[ifelse any? subord
[ifelse [prey] of max-one-of vacant [prey] = [prey] of max-one-of subord [prey]
[set target max-one-of vacant [prey]]
[set target max-one-of new-patches [prey]]
]
[set target max-one-of vacant [prey]]
]
[set target max-one-of subord [prey]]
]
move-to target
if-else member? target subord
[ set shape "triangle" ] ; so you can see that the target patch was from "subord"
[ set shape "circle" ] ; or from "vacant"
]
;ifelse any? target with [owner != nobody]
if target != nobody
[
; Add target patch to territory of the current animal:
set territory (patch-set territory target) ; this is the territory of the calling tiger
let old-owner [owner] of target; this needs to be memorized
; Tell target patch that is has new owner:
ask target [ set owner calling-tiger ]
; Tell the original owner of the target patch to remove the target patch from its territory:
if old-owner != nobody ;
[
ask old-owner
[
set territory territory with [ owner != calling-tiger ]
]
]
]
set food sum [prey] of territory
]
]
]
ask animals
[
ask territory
[
set pcolor [color] of myself
set plabel (word [status] of owner [status] of myself)
]
if food < 10 [die]
]
end
Patch Clusters Example, in the Code Examples section of NetLogo's Models Library, has code for identifying a contiguous cluster of patches. The core code is as follows:
patches-own [cluster]
to setup
...
ask patches [ set cluster nobody ]
...
end
to grow-cluster ;; patch procedure
ask neighbors4 with [(cluster = nobody) and
(pcolor = [pcolor] of myself)]
[ set cluster [cluster] of myself
grow-cluster ]
end
But see the rest of the example as well.
In your use case, instead of placing the "seeds" randomly for growing the clusters, you'll start growing the clusters in the patches where the animals are standing.