Netlogo : change patch color of one patch if orthogonal neighbors have the same color - patch

I'm new to netlogo and I need some help.
I am trying to grow a continuous patch of one color (green on a black background). However, I will sometimes have a black patch that is completely surrounded by green patches. I would like to change the color of those black patches to green.
I tried :
ask patches [
if neighbors4 with [pcolor = 55]
[set pcolor 55]
]
but it gives me an error, as does
ask patches [
if any? neighbors4 [pcolor = 55]
[set pcolor 55]
]
Here is the code that works that will sometimes leave black patches surrounded by green patches :
to setup
clear-all
set-patch-size 4
resize-world -50 50 -50 50
ask patches[set pcolor black]
grow-cell
reset-ticks
end
to grow-cell
ask patch 0 0 [
set pcolor 55
ask neighbors [
set pcolor 55
]
]
repeat 45
[ ask patches with [pcolor = black]
[ set pcolor [pcolor] of one-of neighbors4 ] ]
end

Here is an ugly/barely clever hack.
Ask patches[
if mean [pcolor] of neighbors4 = green[set pcolor green]
]
Or alternately:
Ask patches with [ count neighbors4 with [pcolor = green] = 4 ]
[set pcolor green]

Related

iterate over two lists in NetLogo: Big picture context :R extension. Assign patch values to specific patches from R

I need to pass some data to R from NetLogo using the R-extension, do some computations and then assign the R output to specific patches.
I have tried every combination of map and foreach in NetLogo that I can imagine. I have been trying to change colors based on a patch id because it is visible. Setting all of the patches blue works.
observer> foreach [1 2 3] [ x -> ask patches with [id = x] [ set pcolor blue ] ]
When I add the second list nothing I have tried works. I also tried assigning values to the patches to no avail. This turned patches 4, 5, and 6 red...
observer> foreach [4 5 6] [ x -> ask patches with [id = x] [ set pcolor [blue red green] ]]
The next approach did not work.
observer> set list-a (list blue red green)
observer> set list-b (list 7 8 9)
observer> ask patches with [id = list-b] [ set pcolor list-a]
Attempting a foreach with two lists like this:
observer> foreach list-b list-b ask patches with [id = list-b] [set pcolor list-a]
observer> show map list-b list-b ask patches with [id = list-b] [set pcolor list-a]
redefining list-a and then trying the original approach again sets those patches blue.
observer> set list-a r:get "df1[[1]]"
observer> show list-a
observer: [1 5 8]
observer> foreach list-a [ x -> ask patches with [id = x] [ set pcolor blue ] ]
If I could just understand how to work through two lists I would be set.
for example
list-a [1 2 3]
list-b [blue green red]
; effectively do the following
ask patch with [id = 1] [set pcolor blue]
ask patch with [id = 2] [set pcolor green]
ask patch with [id = 3] [set pcolor red]
The actual problem is I have activity variables (all the patches below are planting corn).
> a
id a_corn a_crp a_soy
1 1 0 1 0
2 2 0 1 0
3 3 0 1 0
4 4 0 1 0
5 5 0 1 0
6 6 0 1 0
7 7 0 1 0
8 8 0 1 0
9 9 0 1 0
10 10 0 1 0
>
I know with the r extension dataframes come into netlogo as unnamed nested lists. So if I avoid the nesting by:
set list-id r:get "a$id"
set list-a r:get "a$a_corn"
; then netlogo iterates through the lists:
ask patch with [id = 1] [set a_corn 0]
ask patch with [id = 2] [set a_corn 0]
; and so on
I am open to suggestions for better ways. But the ids need to match, may not be sequential, and the a dataframe above will vary in size and contents.
UPDATE:
As I continue working the problem I am documenting the steps here so I can find them later.
I have found anonymous-commands.
observer> set procedure [[x y] -> ask patches with [id = x] [set pcolor y]]
observer> show is-anonymous-command? procedure
observer: true
observer> set list-a (list blue red green)
observer> set list-b (list 7 8 9)
observer> (foreach list-b list-a procedure) ; does nothing
I cleared all, set up again and the following worked:
observer> ask patches with [id = 7] [set pcolor red]
observer> set procedure [[x y] -> ask patches with [id = x] [set pcolor y]]
observer> set list-b (list 7 8 9)
observer> set list-a (list blue red green)
observer> (foreach list-b list-a procedure)
Now for the application portion of the problem:
observer> set procedure [[x y] -> ask patches with [id = x] [set a_corn y]]
observer> set list-a (list 1 1 1)
observer> (foreach list-b list-a procedure)
and it works!

Netlogo Get a pushing force from all neighbours within a distance

For each turtle, I got an agentset called visible-neighbors which are the turtles within a distance.
I wanna get a pulling force on this turtle from each of visible-neighbors. And then sum the forces. For each single pulling force from one neighbor is following the equation force = 1 / distance ^ 2. My idea is to decompose the force to x and y components and then sum the forces on x and y, finally compose the force again.
Here is the code I have at the moment. It's runnable, but for some reasons it doesn't work.
to get-direction-naive
set visible-neighbors (other turtles) in-radius 75 with [ distance myself > 0 ]
ifelse any? visible-neighbors
[let distance-list [distance myself] of visible-neighbors
let x-cors [xcor] of visible-neighbors
let x-diff map [? -> ? - xcor] x-cors
let x-forces (map [ [a b] -> a / (b ^ 3) ] x-diff distance-list)
let x-sum sum x-forces
let y-cors [ycor] of visible-neighbors
let y-diff map [? -> ? - ycor] y-cors
let y-forces (map [ [a b] -> a / (b ^ 3) ] y-diff distance-list)
let y-sum sum y-forces
ifelse y-sum = 0
[ifelse x-sum > 0
[set heading 0]
[set heading 180] ]
[set heading atan x-sum y-sum]
]
[right random 360]
end
Any advices would be appreciated.
What are you finding that isn't working? You want the turtles to be pulled towards each other, is that correct? This seems to set turtles' headings as needed- I think you can drop the two nested ifelse statements, though. Check out this toy version:
to setup
ca
crt 20 [
setxy random-xcor random-ycor
pd
]
reset-ticks
end
to force-pull
ask turtles [
let visible-neighbors other turtles in-radius 10
ifelse any? visible-neighbors [
let distance-list [distance myself] of visible-neighbors
let x-cors [xcor] of visible-neighbors
let x-diff map [ ? -> ? - xcor] x-cors
let x-forces force-calc x-diff distance-list
let x-sum sum x-forces
let y-cors [ycor] of visible-neighbors
let y-diff map [? -> ? - ycor] y-cors
let y-forces force-calc y-diff distance-list
let y-sum sum y-forces
set heading atan x-sum y-sum
let hyp sqrt ( ( x-sum ^ 2 ) + ( y-sum ^ 2 ) )
fd e ^ ( -0.5 * hyp )
] [
right random 360
]
]
tick
end
to-report force-calc [ dif-list dist-list ]
report ( map [ [ a b ] -> a / ( b ^ 3 ) ] dif-list dist-list )
end
It seems to me that the turtles face the calculated heading properly and get drawn together.

Netlogo Flocking Model Code Explanation

I'm investigating the flocking model of netlogo. It has the following code that is strange. What does this code do mathematically?
If I would see this in mathematical notations I would understand this. I suppose this is how trigonometry gets implemented in netlogo ?
to heading
turn-towards average-heading max-align-turn
end
to-report average-heading
let x-component sum [dx] of flock
let y-component sum [dy] of flock
ifelse x-component = 0 and y-component = 0
[ report heading ]
[ report atan x-component y-component ]
end
to turn-towards [new-heading max-turn]
turn-at-most (subtract-headings new-heading heading) max-turn
end
to turn-at-most [turn max-turn]
ifelse abs turn > max-turn
[ ifelse turn > 0
[ rt max-turn ]
[ lt max-turn ] ]
[ rt turn ]
end
to-report average-heading
let x-component sum [dx] of flock
let y-component sum [dy] of flock
ifelse x-component = 0 and y-component = 0
[ report heading ]
[ report atan x-component y-component ]
end
dy and dy are the sine and cosine of the turtles headings so what we are looking at is
The procedure reports
The arctangent of the sum of the sines of the turtle-headings , sum of the cosines of the turtle-headings.
it is so the mean heading of the set of angles obviously if we just up the headings and divide by the number of turtles we end up with a lot of problems.

Get the coordinates of a matrix from its flatten index

How can we get the coordinates of a n dimensions matrix from its shape and its flatten index?
I mean, if for example I have the following (2,3) matrix of 2 dimensions:
[ [ 0, 1 ],
[ 2, 3 ],
[ *4*, 5 ] ]
...and I want to find the value of the index in bold from the coordinates [0,2], how can I do?
Or if I have this (2,2,5) matrix of 3 dimensions:
[ [ [ nil, nil ],
[ nil, nil ] ],
[ [ nil, nil ],
[ nil, nil ] ],
[ [ nil, *9* ],
[ nil, nil ] ],
[ [ nil, nil ],
[ nil, nil ] ],
[ [ nil, nil ],
[ nil, nil ] ] ]
...and I know the coordinates that I want have a flatten index value of 9, how can I find the relative coordinates are: [1,0,2]?
If possible, I would like to know a general and simple method, which work on matrix of any shape.
Many thanks for your help.
You can use this simple algorithm:
Let's say you have the matrix A[a][b][c][d] (where a,b,c,d are the dimensions) and the index X.
To get the first coordinate of the index X you simply divide X by b*c*d.
Let it be this next matrix, having the sizes [2][5] and the index X=7
0 1 2 3 4
5 6 7 8 9
You first divide X by the last dimension to find the first coordinate. X/5=1 . Then, from there you move forward and give X the value X%=5 . So you'll have X = 7%5 =2. Now you have to search the coordinates for the remaining dimensions using the same algorithm. If you reach the last dimension , the coordinate will be the remaining X, in this case 2. So the coordinates for X=7 are [1][2] , which is actually the answear.
Again, for the general case, where you have a,b,c,d dimensions.
I'll note with (yd) the y'th dimension.
X=index
(1d)=X/b*c*d
X gets value X % b*c*d
(2d)=X/c*d
X gets value X % c*d
(3d)=X/d
X gets value X % d
(4d)=X
If you had the dimensions [2][2][5] you would get:
X=9;
(1d) = 9/2*5 = 0
X = 9%10 = 9
(2d) = 9/5 = 1
X = 9%5 = 4
(3d) = 4
Result: [0][1][4] is the 9th element.
To get from [0][1][4] to the index 9 , you do the reverse algorithm by multiplying:
X=(1d)*b*c + (2d)*c + 3d = 0 + 1*5 +4 =9

Generating a quiz in Common Lisp?

I want to teach myself Spanish and Lisp. I've got several word lists like
the data show below. How can I generate a quiz from the data that looks like this?
amarillo? [ ] blue [ ] yellow [ ] gray [ ] pink
azul? [ ] red [ ] blue [ ] green [ ] orange
.
.
.
verde? [ ] purple [ ] gold [ ] green [ ] black
The idea is to randomly include the answer with 3 randomly chosen
incorrect answers. Ideally, the incorrect answers would not be too
repetitive.
amarillo|yellow
azul|blue
blanco|white
dorado|golden
gris|gray
marrón|brown
naranja|orange
negro|black
oro|gold
púrpura|purple
rojo|red
rosa|pink
verde|green
Using LispWorks, with support for Unicode.
The color translations.
(defparameter *word-data*
"amarillo|yellow
azul|blue
blanco|white
dorado|golden
gris|gray
marrón|brown
naranja|orange
negro|black
oro|gold
púrpura|purple
rojo|red
rosa|pink
verde|green")
a few top-level variables: a translation table and two lists with color names
(defvar *translation* (make-hash-table :test #'equalp))
(defvar *all-english-colors* nil)
(defvar *all-spanish-colors* nil)
Parsing the translation data and filling the table and the lists:
(defun parse-word-data (&optional (data *word-data*))
(with-input-from-string (stream data)
(loop for line = (read-line stream nil nil)
while line
do (let ((pos (position #\| line)))
(setf (gethash (subseq line 0 pos) *translation*)
(subseq line (1+ pos)))
(pushnew (subseq line 0 pos) *all-spanish-colors*
:test #'equalp)
(pushnew (subseq line (1+ pos)) *all-english-colors*
:test #'equalp)))))
Find the translation for a spanish word:
(defun translate-s->e (word)
(gethash word *translation*))
Choose n random elements from a list:
(defun random-elements (list &optional (n 1))
(let ((elements nil)
(all-elements list))
(loop repeat n
for r = (random (length all-elements))
for e = (elt all-elements r)
do (push e elements)
do (setf all-elements (remove e all-elements :test #'equal)))
elements))
Choose three random english colors:
(defun random-english-colors (answer &optional (n 3))
(random-elements (remove answer *all-english-colors* :test #'equal) n))
Compute the choices -
(defun compute-choices (answer answers &optional (n 3))
(let ((pos (random (1+ n))))
(append (subseq answers 0 pos)
(list answer)
(subseq answers pos))))
The test:
(defun test ()
(loop for sc in *all-spanish-colors*
for ec = (translate-s->e sc)
do (apply #'format
t
"~%~a~1,16#T[ ] ~a~1,16#T[ ] ~a~1,16#T[ ] ~a~1,16#T[ ] ~a"
sc
(compute-choices ec (random-english-colors ec))))
(terpri))
Compute the data:
(parse-word-data)
The test:
CL-USER 212 > (test)
verde [ ] green [ ] yellow [ ] orange [ ] brown
rosa [ ] yellow [ ] orange [ ] pink [ ] golden
rojo [ ] gold [ ] golden [ ] brown [ ] red
púrpura [ ] gold [ ] red [ ] orange [ ] purple
oro [ ] orange [ ] gold [ ] red [ ] white
negro [ ] gold [ ] black [ ] golden [ ] purple
naranja [ ] red [ ] gray [ ] orange [ ] gold
marrón [ ] orange [ ] pink [ ] brown [ ] red
gris [ ] brown [ ] green [ ] gray [ ] orange
dorado [ ] golden [ ] pink [ ] blue [ ] gray
blanco [ ] blue [ ] red [ ] white [ ] gold
azul [ ] brown [ ] blue [ ] green [ ] purple
amarillo [ ] red [ ] yellow [ ] brown [ ] black

Resources