Pierre
Pierre

Reputation: 387

How to randomly remove block side in a grid?

Following on from How to control square size in a grid from square area?, I would like to randomly remove block side in a grid. Here my idea:

%% In a first time, I randomly select a white patch in the grid (figure below):

let random-patch one-of patches with [pcolor = white]

%% Then, I draw red patches to identify intersections between white roads (figure below):

ask patches with [ (pxcor mod (side + 1) = 0 ) and (pycor mod (side + 1) = 0 ) ] [set pcolor red]

%% Finally, I color in brown all white patches that are situated between two red patches and on the same side than the random patch. To identify these white patches, have I to calculate distance between the random patch and the nearest red patches and to color all white patches situated along these distances ?

Thanks in advance for your help.

enter image description here

Upvotes: 1

Views: 130

Answers (2)

Seth Tisue
Seth Tisue

Reputation: 30453

Since you're making a uniform grid, you might consider just doing math on pxcor and pycor instead of taking the Patch Clusters Example approach. That approach is best suited to dealing with irregular shapes.

To set up your grid, you can just do:

ask patches [
  set pcolor brown
  let horizontal-street? pycor mod (side + 1) = 0
  let vertical-street? pxcor mod (side + 1) = 0
  if horizontal-street? or vertical-street?
    [ set pcolor white ]
  if horizontal-street? and vertical-street?
    [ set pcolor red ]
]

Upvotes: 0

Nicolas Payette
Nicolas Payette

Reputation: 14972

An alternative way to think about your problem is in terms of finding clusters of white patches: you're picking a white patch at random, and you want to turn all the contiguous white patches to brown.

You can look at the "Patch Clusters Example" in the Code Examples section of NetLogo's model library to see one way to do this.

Here is how I would do it. Let's start by defining a grow-cluster reporter:

to-report grow-cluster [ current-cluster new-patch ]
  let patches-to-add [
    neighbors4 with [
      pcolor = [ pcolor ] of myself and
      not member? self current-cluster
    ]
  ] of new-patch
  let new-cluster (patch-set current-cluster new-patch)
  report ifelse-value any? patches-to-add
    [ reduce grow-cluster fput new-cluster sort patches-to-add ]
    [ new-cluster ]
end

The code may be hard to understand if you're not used to functional programming because it uses recursion within a call to reduce. Still, in a nutshell, it:

  • takes an existing patch cluster and a new patch to add to this cluster
  • looks for neighbors of that new patch that should also be added to the cluster, i.e., those that are the same color but not already part of the cluster
  • calls itself for these new patches to add so that their neighbors can be added to the cluster (and those neighbors' neighbors, etc.) until no new patches are found.

Once you have grow-cluster, you can use it to accomplish exactly what you want by seeding it with an empty cluster and the random patch that you selected:

to remove-random-side
  let random-patch one-of patches with [pcolor = white]
  let side grow-cluster no-patches random-patch
  ask side [ set pcolor brown ]
end

Caveat: for this to work, world wrapping has to be disabled in your model settings.

Upvotes: 1

Related Questions