error, “Nothing named BEST-AMOUNT has been defined”

28 views
Skip to first unread message

Unruh Lee

unread,
Jun 14, 2022, 8:05:45 PM6/14/22
to netlogo-users
I'm getting this  error, “Nothing named BEST-AMOUNT has been defined”, but I can't figure out why. I've gone over and over this and it seems like it IS defined. 

I'm attempting to build on code that enables turtles to ascertain in which direction to turn, to move one patch ahead and find the "most resources". This original code does NOT have the same problem with the error above. That code is as follows: 

to turn-towards-resource  
  set heading 0
  let best-direction [0] 
  let best-amount resource-ahead ; see "to-report resource-ahead", procedure.
  set heading 90
  if (resource-ahead = best-amount) [set best-direction lput 90 best-direction] 
  if (resource-ahead > best-amount) [set best-direction [90] set best-amount resource-ahead]
  set heading 180
  if (resource-ahead = best-amount) [set best-direction lput 180 best-direction]
  if (resource-ahead > best-amount) [set best-direction [180] set best-amount resource-ahead]
  set heading 270
  if (resource-ahead = best-amount) [set best-direction lput 270 best-direction]
  if (resource-ahead > best-amount) [set best-direction [270] set best-amount resource-ahead]
  ifelse best-amount > (norm-min-resource * max-resource-here) [
    set heading one-of best-direction
  ][
    set heading one-of [0 90 180 270]
  ]
end

What I'm trying to add to the above is just that the turtles will avoid patches with a patches-own boolean variable [cacao-crop =  true]. The re-written procedure, which DOES cause the error, is as follows: 

to turn-towards-resource  
  set heading 0
  ifelse [ cacao-crop = false ] of patch-ahead 1 [ ; if the patch ahead is not an owned cacao farm, let the first direction tested be the "best direction" so far.
    let best-direction [0]
    let best-amount resource-ahead
  ]
  ; On the other hand, if it is an owned cacao farm don't go there...
  [
    let best-amount 0 ; if it's owned cacao farm, consider the resources for non-cacao-growers there to be zero
    let best-direction [0]
  ] ; and the direction of heading can just stay the same, won't matter b/c in the end, if it's heading in a direction of a cacao farm b/c that's all there is then I'll code it to jump to random non-cacao patch.
  set heading 90
  ifelse [ cacao-crop = false ] of patch-ahead 1 [
    if (resource-ahead = best-amount) [set best-direction lput 90 best-direction]
    if (resource-ahead > best-amount) [set best-direction [90] set best-amount resource-ahead]
  ]
  [
    let best-amount 0
    let best-direction [0]
  ]
  set heading 180
  ifelse [ cacao-crop = false ] of patch-ahead 1 [
    if (resource-ahead = best-amount) [set best-direction lput 180 best-direction]
    if (resource-ahead > best-amount) [set best-direction [180] set best-amount resource-ahead]
  ]
  [
    let best-amount 0
    let best-direction [0] ]
  set heading 270
  ifelse [ cacao-crop = false ] of patch-ahead 1 [
    if (resource-ahead = best-amount) [set best-direction lput 270 best-direction]
    if (resource-ahead > best-amount) [set best-direction [270] set best-amount resource-ahead]
  ]
  [
    let best-amount 0 ; if patches in every direction are owned, best-amount = 0 and...
    let best-direction [0] ] ; ...best-direction = 0 ...I think this won't matter that much.
                                  ; the code should help avoid patches with [ cacao-crop = true ], but if they are all owned, a direction will be chosen at random. Then in "to go" I'll address this, making it jump to non-cacao patch.
  ifelse best-amount > (norm-min-resource * max-resource-here) [
    set heading one-of best-direction
  ][
    set heading one-of [0 90 180 270]
  ]
end

I'll attach the entire model's code, in case that is handy. 

resourceharvest_altered_6_14_22_(from_5_3_version).nlogo

Charles Staelin

unread,
Jun 14, 2022, 8:59:08 PM6/14/22
to netlogo-users
Your problem is one of scope.  In the original code, best-amount is defined before going into the various if statements, thus its defined scope is the whole procedure.  In your code, best-amount is first defined (with the "let" statement) inside an if statement.  Variables defined within a block (i.e., between brackets) are defined only for that block, and they lose their definition once the block is exited.  If you put as (say) the first statement in the procedure 

let best-amount 0

and then use "set best-amount ..." through the rest of the code, the definition will hold throughout the procedure.  Scope is tricky, and is an easy mistake to make.  If you need a value only within a block, then defining it within the block is the way to go.  However, if you need to use it across blocks, it's best to define it at the beginning of a procedure.  (Of course,  if there are blocks within blocks, defining it within a block will define it for all the sub-blocks as well.)

Reply all
Reply to author
Forward
0 new messages