使用who 数字来索引海龟可能会导致问题 - 在这种情况下,您会遇到无法真正动态更新列表的问题,因为 hous 和 carr 数字仅基于他们的创作顺序。如果可能的话,最好将海龟直接存储在列表中。使用您的设置的修改版本查看此示例:
globals [ route-vector ]
breed [carr car]
breed [hous housess]
breed [spawns spawn]
carr-own [ route route-counter spawn-target target]
to setup
clear-all
create-carros
create-casas
make-routes
reset-ticks
end
to create-carros
create-carr 3 [ set color green ]
ask carr [
set size 1.5
setxy random-xcor random-ycor
; set up a 'route-counter' to act as an index for a car's route
set route-counter 0
set target nobody
set route []
pd
]
; hatch a 'spawn-target' turtle that can be used to return
; the carr back to their starting position
ask carr [
hatch 1 [
set breed spawns
ht
]
set spawn-target one-of other turtles-here with [
xcor = [xcor] of myself
]
]
end
to create-casas
create-hous 5 [ set color red ]
ask hous [
set shape "house"
set size 1.5
setxy random-xcor random-ycor
]
end
现在,不要依赖 who 数字来索引房屋,而是直接在您的 carr 路线中使用房屋列表:
to make-routes
; Just use the car-order
let car-order [ 0 1 2 0 1 ]
; Create a list of hous directly by sorting them
let houses sort hous
; Your same foreach procedure, but in this case the carr
; are storing the house in the list directly to avoid
; indexing problems
ask carr [ ]
(foreach car-order houses
[ [the-car the-house] ->
ask carr with [who = the-car] [ set route lput the-house route ]
]
)
end
然后,carr 可以根据route-counter 的索引值迭代他们的路线以选择一个新目标(他们的spawn-target 有一个小中断)。
to go
ask carr [
; If a car has no target, set the target to the
; item indexed by 'route-counter'
if target = nobody [
set target item route-counter route
]
; Movement chunk
face target
ifelse distance target > 1 [
fd 1
] [
move-to target
; Only advance the route counter if the current target
; was not the original spawn point
if target != spawn-target [
set route-counter route-counter + 1
]
set target nobody
]
; If the route counter would index outside of the
; list boundaries, reset it to 0
if route-counter > length route - 1 [
set route-counter 0
set target spawn-target
]
]
tick
end
这仍然不是超级程序化的,因为您依赖于您的汽车订单长度与您的房屋数量相同,但我不确定您实际上想要做什么,所以它可能会起作用。
编辑
根据your comment- 如果您必须使用who 数字,您仍然可以使用“spawn target”示例让海龟返回它们的起始位置 - 让它发生在产生carr 和hous 之后。同样,这绝对不是理想的,因为如果您不注意生成顺序、carr/house 的数量等,您的模型可能会“崩溃”。
所以,基本的setup 和create-casas 程序如上,这是您的新create-carros 程序:
to create-carros
create-carr 3 [ set color green ]
ask carr [
set size 1.5
setxy random-xcor random-ycor
; set up a 'route-counter' to act as an index for a car's route
set route-counter 0
set target nobody
set route []
pd
]
end
现在,您的make-routes 可以包含spawn 目标海龟(此示例包含您评论中的乱序房屋):
to make-routes
set route-vector [4 7 6 3 5 0 1 2 0 1]
let houses sublist route-vector 0 (length route-vector / 2 )
let carlist sublist route-vector (length route-vector / 2 ) (length route-vector)
(foreach carlist houses
[ [the-car the-house] ->
ask car the-car [
set route lput ( housess the-house ) route
]
]
)
; hatch a 'spawn-target' turtle that can be used to return
; the carr back to their starting position
ask carr [
hatch 1 [
set breed spawns
ht
]
set spawn-target one-of other turtles-here with [
xcor = [xcor] of myself
]
]
end
然后,上面的go 过程应该可以正常工作而无需任何更改。
编辑 2
让您的 carr 停止的一种简单方法是设置一个逻辑标志,以便只有满足特定条件的 carr 才会移动。考虑这个修改后的car-own 和create-carros 设置:
carr-own [ route route-counter spawn-target target route-complete? ]
to create-carros
create-carr 3 [ set color green ]
ask carr [
set size 1.5
setxy random-xcor random-ycor
; set up a 'route-counter' to act as an index for a car's route
set route-counter 0
set target nobody
set route []
set route-complete? false
pd
]
end
在这里,我们现在有一个名为route-complete? 的布尔(逻辑)变量,对于所有新的carr,它都设置为false。现在,您可以在go 过程中添加一行,说明“只有将route-complete? 设置为false 的汽车,执行这些操作。”
to go
; ask carr with route-complete set to false
ask carr with [ not route-complete? ] [
; If a car has no target, set the target to the
; item indexed by 'route-counter'
if target = nobody [
set target item route-counter route
]
face target
ifelse distance target > 1 [
fd 1
] [
move-to target
; Only advance the route counter if the current target
; was not the original spawn point. ADDITIONALLY,
; if the target is the starting target, set route-complete?
; to true for that carr
ifelse target != spawn-target [
set route-counter route-counter + 1
] [
set route-complete? true
]
set target nobody
]
; If the route counter would index outside of the
; list boundaries, reset it to 0
if route-counter > length route - 1 [
set route-counter 0
set target spawn-target
]
]
tick
end
您会注意到move-to 块中有一个修改位,如果carr 移动回其起始位置,它还将其route-complete? 设置为true, so that the next timegois called, thatcarr` won别动。
请注意,如果您希望 carr 在其路线中运行一定次数,您可以将 route-complete? 更改为计数器而不是真/假。