Search code examples
netlogomoveneighbours

Move turtle to a patch with some neighbors of same type of turtle and stay there


I tried to move a turtle to a patch where there 2 turtles with the same type (e.g income) as its neighbor and stay there. I did the following code

 to set-move
let target []

 ask turtles with [income = "low"]
 [ let potential-target1 patches with [value < buymiddle and any? turtles-here = false]
   set target potential-target1 with [length remove-duplicates [any? turtles-here with [income = "low"]] of neighbors = 2]
   set target min-one-of potential-target1 [value]
    if target != nobody and any? turtles-on neighbors 
    [ move-to target ask patch-here [set empty false]]]

but it seems did not work. Some turtles still move around after choosing a patch. Some turtles do not choose a patch where there two neighbors of its group. How to specify a patch with two neighbors of certain groups of turtles?

breed [agens agen]

patches-own [value
empty]
turtles-own [income
            myHouses
            ]
to setup
ca


 ;;Check inputs
 let total-prob prob-low + prob-mid + prob-high
 if (total-prob != 100 )
 [
     print (word "Adoption types must sum to 100, but instead sum to " total-prob)
     stop
 ]

   ask patches [set value random-normal 10 3]

   ask patches [ifelse (value < 8)[ set pcolor green  ]
 [ifelse (value < 11)[ set pcolor blue]
[if value < 15[ set pcolor gray]]]]



end

to go
 ask patches [
 if random 100 < 3 [sprout-agens 1 [set color red
     set shape "default"
     set size 1
     set-income
     set-move]]]

 end

 to set-move
let target []

 ask turtles with [income = "low"]
 [ let potential-target1 patches with [value < buymiddle and any? turtles-here = false]
   set target potential-target1 with [length remove-duplicates [any? turtles-here with [income = "low"]] of neighbors = 2]
   set target min-one-of potential-target1 [value]
    if target != nobody and any? turtles-on neighbors 
    [ move-to target ask patch-here [set empty false]]]


ask turtles with [income = "middle"]
 [ let potential-target2 patches with [(value > buymiddle and value < buyhigh) and any? turtles-here = false]
   let target2 potential-target2 with [length remove-duplicates [any? turtles-here with [income = "middle"]] of neighbors = 2]
   set target2 min-one-of potential-target2 [value]
    if target2 != nobody and any? turtles-on neighbors 
    [ move-to target2 ask patch-here [set empty false]]]


ask turtles with [income = "high"]
 [ let potential-target3 patches with [(value > buyhigh) and any? turtles-here = false]
   let target3 potential-target3 with [length remove-duplicates [any? turtles-here with [income = "high"]] of neighbors = 2]
   set target3 min-one-of potential-target3 [value]
    if target3 != nobody and any? turtles-on neighbors 
    [ move-to target ask patch-here [set empty false]]]



end

to set-income
 let kind-prob (random 100)
 let cumulative-prob prob-low
 ifelse (kind-prob < cumulative-prob)[set income "low" set color red]
 [set cumulative-prob cumulative-prob + prob-mid
 ifelse (kind-prob < cumulative-prob)[set income "middle" set color pink ]
    [set cumulative-prob cumulative-prob + prob-high
      if income < cumulative-prob [set income "high" set color blue]
]]
end

Solution

  • Let's look at the first line in the ask block of your first code segment.

    let potential-target1 patches with [value < buymiddle and any? turtles-here = false]
    

    is the same as

    let potential-target1 patches with [value < buymiddle and not any? turtles-here]
    

    so that your potential-target1 patchset will have no turtles. That will make the subsequent lines irrelevant. But lets say that we make that line

    let potential-target1 patches with [value < buymiddle and any? turtles-here]
    

    In next line,

    set target potential-target1 with [length remove-duplicates [any? turtles-here with [income = "low"]] of neighbors = 2]
    

    [any? turtles-here with [income = "low"]] of neighbors yields a list of eight true/false values, true if a neighboring patch has any turtles with income = low, and false if it doesn't. Then you reduce duplicates in that list, and end up with either a single [true] (if all are true), a single [false] (if all are false), or a true and a false [true false] or [false true] if some are true and some false. You then look at the number if entries in that reduced list and compare it to 2. That will occur when at least one neighbor has such turtles and at least one does not. I suspect that is not what you want. If you want exactly two neighboring patches to have at least one turtle with income = low, then something like

    count neighbors with [any? turtles-here with [income = low]] = 2
    

    should do that. If on the other hand you want neighbors with exactly two turtles with income = low, then you would want

    neighbors with [count turtles-here with [income = low] = 2]
    

    It's not clear to me which you are after.

    After seeing the question below, I gather that Dudi is looking for the first interpretation. If so, then finding among all the candidates the patch with the lowest value would be (as they had done in their original code)

    let potential-targets patches with [count neighbors with [any? turtles-here with [income = low]] = 2]
    let target min-one-of potential-targets [value]