<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/rdew-valley-optimizing-farming-with-r/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://blog.schochastics.net/post/rdew-valley-optimizing-farming-with-r/"> schochastics</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>I recently picked up a copy of my favorite game <a rel="nofollow" href="https://stardewvalley.net/" target="_blank">Stardew Valley</a> again.<br>
If you don’t know the game, I can highly recommend it! You inherit a pixel farm and<br>
you are in charge of everything. Crops, animals, fishing, mining and never forget to socialize.<br>
My plan was to shut off work for at least a few hours while playing. But at one point<br>
you inevitably start optimizing your farm. In most cases, the layout of crops.<br>
Aaaaaaaand that’s how you turn a farming game into an optimization problem you try to solve with R.</p>
<p><img src="https://i0.wp.com/stardewvalley.net/presskit/Stardew%20Valley/images/SDV_logo_3x.png?w=456" data-recalc-dims="1"></p>
<pre><code>library(tidyverse)</code></pre>
<div>
<h1>Your farm</h1>
<p>If you start a standard farm, this is what you can work with.</p>
<p><img src="https://i2.wp.com/blog.schochastics.net/img/stardewplanner.png?w=456" data-recalc-dims="1"></p>
<p>The first step is to get the layout into R. Luckily, I found a<br>
<a rel="nofollow" href="https://www.reddit.com/r/StardewValley/comments/8kcxlz/regular_farm_map_in_excel/" target="_blank">reddit post</a>,<br>
where someone posted the layout as an excel file. I converted the file into a matrix and<br>
a long data frame. The data frame is for plotting and the matrix for the actual optimization.</p>
<pre><code>farm_blank &lt;- readRDS(&quot;farm_blank.RDS&quot;)
map &lt;- read_csv(&quot;fun_projects/stardew/map.csv&quot;)</code></pre>
<pre><code>dim(farm_blank)</code></pre>
<pre><code>## [1] 78 61</code></pre>
<pre><code>ggplot(map)+geom_tile(aes(x,y,fill=val))+
    scale_fill_manual(values=c(&quot;c&quot;=&quot;#458B00&quot;, &quot;w&quot;=&quot;#1874CD&quot;,
                               &quot;h&quot;=&quot;#8B0000&quot;,&quot;b&quot;=&quot;#B0B0B0&quot;,&quot;e&quot;=&quot;#CD2626&quot;,
                               &quot;x&quot;=&quot;black&quot;))+
  ggraph::theme_graph()+
  theme(legend.position = &quot;none&quot;)+
  coord_fixed()</code></pre>
<p><img src="https://i2.wp.com/blog.schochastics.net/post/2018-11-13-rdew-valley-optimizing-farming-with-r_files/figure-html/plot_blank-1.png?w=450" data-recalc-dims="1"></p>
<p>The green tiles are the ones we can use for farming. In theory, we could plant<br>
3414 crops there. <strong>But</strong> the tiles are totally unprotected against the nasty<br>
crows that would eat all your precious crops. We need scarecrows to protect them.</p>
</div>
<div>
<h1>Scarecrows</h1>
<p>When you plant your crops, you should make sure that your crops fall into the range of<br>
a placed scarecrow. No crow will ever touch anything there.</p>
<p><img src="https://i0.wp.com/stardewvalleywiki.com/mediawiki/images/thumb/f/f9/Scarecrow_Range.png/800px-Scarecrow_Range.png?w=456&ssl=1" data-recalc-dims="1"></p>
<p>A single scarecrow can protect 248 tiles. And now we have our first optimization problem:<br>
Where should we place scarecrows on<br>
the farm to maximize the protected area?</p>
</div>
<div>
<h1>Optimizing scarecrow placement</h1>
<p>Now of course we could just blindly put them on the map until everything is covered.<br>
But this would a) reduce the number of tiles we can use for growing crops and b)<br>
result in a lot of unnecessary overlap between scarecrow ranges. So the goal is to maximize the<br>
covered area and minimize the overlap of scarecrows. This is not an easy task though.<br>
If you want to place one crow somewhere on the farm, you have 3414 possibilities<br>
to do so. For two crows 5,825,991 and for three 6,626,093,764. So it is definitely not a viable option to try out all<br>
possible placements, especially when the number of crows increases. We will not be able<br>
to get the optimal solution, but we can try to come as close as possible.</p>
<div>
<h2>Simulated annealing</h2>
<p>There are certainly several <a rel="nofollow" href="https://en.wikipedia.org/wiki/Heuristic" target="_blank">heuristics</a> we could use<br>
but I decided to apply <a rel="nofollow" href="https://en.wikipedia.org/wiki/Simulated_annealing" target="_blank">simulated annealing</a>.<br>
The general idea is very simple. In each iteration, try out a new solution. If it is<br>
better then the old one, keep it. If it is worse, accept it with a certain probability.<br>
This second step is very important, since it allows us to get out of local maxima.<br>
The probability to accept worse solution decreases over time, since we assume that we<br>
come closer to the “true” maximum. New solutions are of course not chosen randomly, but constructed from<br>
previous solutions. In our case, I decided to implement four potential alterations of the current solution:</p>
<ul>
<li>add a scarecrow on a random unoccupied tile</li>
<li>delete a random scarecrow</li>
<li>teleport a scarecrow to a random unoccupied tile</li>
<li>move a scarecrow to random neighboring tile</li>
</ul>
<p>This is the theory, now to the code.</p>
</div>
<div>
<h2>R code</h2>
<p>The code of the helper functions (add/delete/move/teleport scarecrows) can be found at the end of this post.</p>
<p>We can use the <code>init_farm()</code> function to get an initial scarecrow layout</p>
<pre><code>farm &lt;- farm_max &lt;- init_farm(farm_blank,no = 10)
opt_val &lt;- opt_val_max &lt;- opt_func(farm)</code></pre>
<p>This initial solution covers 820 tiles. Now onto the optimization.</p>
<pre><code>#initialize variables
temp &lt;- 100
max_crow &lt;- 35
min_crow &lt;- 3
steps &lt;- c(&quot;a&quot;,&quot;d&quot;,&quot;m&quot;)

#annealing
while(temp>=0.1){
  for(i in 1:1000){
    ncrow &lt;- nrow(locate_crows(farm,farm_blank))
    farm_old &lt;- farm
    t &lt;- sample(steps,1)
    if(t==&quot;a&quot;){
      if(ncrow&lt;max_crow){
        farm &lt;- add_crow(farm)
      } else{
        farm &lt;- del_crow(farm,farm_blank)
      }  
    } else if(t==&quot;d&quot;){
      if(ncrow>min_crow){
        farm &lt;- del_crow(farm,farm_blank)
      } else{
        farm &lt;- add_crow(farm)
      }
    } else if(t==&quot;m&quot;){
      p &lt;- exp(temp-100)
      if(runif(1)&lt;=p){
        farm &lt;- teleport_crow(farm,farm_blank)
      } else{
        farm &lt;- move_crow(farm,farm_blank)
      }
    }
    #evaluate
    farm_val &lt;- opt_func(farm)
    if(farm_val>opt_val){
      opt_val &lt;- farm_val
      if(opt_val>opt_val_max){
        opt_val_max &lt;- opt_val
        farm_max &lt;- farm
        print(c(temp,opt_val_max))
      }
    } else{
      p  &lt;-  exp((farm_val-opt_val)/temp)
      if(runif(1)&lt;=p){
        opt_val &lt;- farm_val
      } else{
        farm &lt;- farm_old
      }
    }
  }
  temp &lt;- temp*0.99
}</code></pre>
<p>Note that this will run for a while (R and loops, you know). If you want to optimize the runtime,<br>
implementing it in C++ with <code>Rcpp</code> might do the trick.</p>
<p>Below is the best layout found during the optimization.</p>
<pre><code>crows &lt;- as_tibble(locate_crows(farm_max,farm_blank))
idx &lt;- which(farm_max>=1,arr.ind = T)
crow_area &lt;- tibble(x=idx[,1],y=idx[,2],val=farm_max[which(farm_max>=1)])
ggplot(map)+geom_tile(aes(x,y,fill=val))+
  scale_fill_manual(values=c(&quot;c&quot;=&quot;#458B00&quot;, &quot;w&quot;=&quot;#1874CD&quot;,&quot;h&quot;=&quot;#8B0000&quot;,&quot;b&quot;=&quot;#B0B0B0&quot;,&quot;e&quot;=&quot;#CD2626&quot;,&quot;x&quot;=&quot;black&quot;))+
  geom_tile(aes(x=x,y=y),fill=c(&quot;#104E8B&quot;),alpha=0.25,data=crow_area[crow_area$val==1,])+
  geom_tile(aes(x=x,y=y),fill=c(&quot;#104E8B&quot;),alpha=0.35,data=crow_area[crow_area$val>1,])+
  geom_point(aes(x=row,y=col),data=crows,col=&quot;#CD9B1D&quot;)+
  theme(legend.position = &quot;none&quot;,
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        axis.title = element_blank(),
        axis.line = element_blank(),
        panel.background = element_blank(),
        panel.grid = element_blank())</code></pre>
<p><img src="https://i0.wp.com/blog.schochastics.net/post/2018-11-13-rdew-valley-optimizing-farming-with-r_files/figure-html/crow_sol-1.png?w=450" data-recalc-dims="1"></p>
<p>The number of placed scarecrows is 18. 3119 tiles<br>
are uniquely protected and 88 are protected by more than one scarecrow.<br>
That leaves 207 tiles outside of the crow ranges.<br>
So we can now safely plant 3207 crops without crows attacking them.<br>
But wait, there is more! We also need to water them…</p>
</div>
</div>
<div>
<h1>Optimizing sprinkler placement</h1>
<p>I am sure nobody wants to water those crops manually, so we need to place <a rel="nofollow" href="https://stardewvalleywiki.com/Sprinkler" target="_blank">sprinkler</a>.<br>
To optimize their placement, we do exactly the same as for scarecrows. Our optimization<br>
goal is to maximize the number of protected <strong>and</strong> watered tiles.</p>
<pre><code>farm &lt;- list(A=farm_blank,sprinklers=matrix(0,0,3))
farm$A[is.na(farm_max) &amp; !is.na(farm_blank)] &lt;- NA
farm_layout &lt;- farm$A
for(i in 1:50){
  farm &lt;- add_sprinkler(farm)
}

temp &lt;- 100
max_sprink &lt;- 400
min_sprink &lt;- 3
steps &lt;- c(&quot;a&quot;,&quot;d&quot;,&quot;m&quot;)
farm_opt &lt;- farm 

while(temp>=0.1){
  for(i in 1:1000){
    if(nrow(farm$sprinklers)==3){
      stop()
    }
    farm_old &lt;- farm
    t &lt;- sample(steps,1,prob =c(0.4,0.4,0.2))
    if(t==&quot;a&quot;){
      if(nrow(farm$sprinklers)&lt;max_sprink){
        farm &lt;- add_sprinkler(farm)
      } else{
        farm &lt;- del_sprinkler(farm,farm_layout)
      }  
    } else if(t==&quot;d&quot;){
      if(nrow(farm$sprinklers)>min_sprink){
        farm &lt;- del_sprinkler(farm,farm_layout)
      } else{
        farm &lt;- add_sprinkler(farm)
      }
    } else if(t==&quot;m&quot;){
      p &lt;- exp(temp-100)
      if(runif(1)&lt;=p){
        farm &lt;- teleport_sprinkler(farm,farm_layout)
      } else{
        farm &lt;- move_sprinkler(farm,farm_layout)
      }
    }
    #evaluate
    farm_val &lt;- opt_func1(farm,farm_max)
    if(farm_val>opt_val){
      opt_val &lt;- farm_val
      if(opt_val>opt_val_max){
        opt_val_max &lt;- opt_val
        farm_opt &lt;- farm
        print(c(temp,opt_val_max))
      }
    } else{
      p  &lt;-  exp((farm_val-opt_val)/temp)
      if(runif(1)&lt;=p){
        opt_val &lt;- farm_val
      } else{
        farm &lt;- farm_old
      }
    }
  }
  temp &lt;- temp*0.99
}</code></pre>
<p>This is the final layout. The dark blue tiles are the ones that are watered and protected by a scarecrow.<br>
light blue tiles are only watered, dark green tiles only protected and light green ones are neither.</p>
<pre><code>sprinklers &lt;- as_tibble(farm_opt$sprinklers)
idx &lt;- which(farm_opt$A>=1,arr.ind = T)
sprinkler_area &lt;- tibble(x=idx[,1],y=idx[,2],val=farm_opt$A[which(farm_opt$A>=1)])

ggplot(map)+
  geom_tile(aes(x,y,fill=val))+
  scale_fill_manual(values=c(&quot;c&quot;=&quot;#458B00&quot;, &quot;w&quot;=&quot;#1874CD&quot;,&quot;h&quot;=&quot;#8B0000&quot;,&quot;b&quot;=&quot;#B0B0B0&quot;,&quot;e&quot;=&quot;#CD2626&quot;,&quot;x&quot;=&quot;black&quot;))+
  geom_tile(aes(x=x,y=y),fill=c(&quot;#104E8B&quot;),alpha=1,data=sprinkler_area[sprinkler_area$val>=1,])+
  geom_tile(aes(x=x,y=y),fill=&quot;black&quot;,alpha=0.1,data=crow_area[crow_area$val>=1,])+
  geom_point(aes(x=row,y=col),data=crows,col=&quot;#CD9B1D&quot;)+
  geom_point(aes(x=V1,y=V2,col=factor(V3)),data=sprinklers,size=2,shape=10)+
  scale_color_manual(values=c(&quot;#C1CDCD&quot;, &quot;#8B4726&quot;, &quot;#CD00CD&quot;))+
  theme(legend.position = &quot;none&quot;,
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        axis.title = element_blank(),
        axis.line = element_blank(),
        panel.background = element_blank(),
        panel.grid = element_blank())</code></pre>
<p><img src="https://i2.wp.com/blog.schochastics.net/post/2018-11-13-rdew-valley-optimizing-farming-with-r_files/figure-html/unnamed-chunk-2-1.png?w=450" data-recalc-dims="1"></p>
<p>This layout gives us 3144 watered tiles with 180 sprinkler and<br>
2998 of those are protected by a scarecrow.</p>
</div>
<div>
<h1>Notes</h1>
<p>If you run this code by yourself, you will notice that you might get different (even better!)<br>
results. Simulated annealing is not deterministic, hence it produces different nearly<br>
optimal solutions in each run.</p>
</div>
<div>
<h1>helper functions for scarecrow placement</h1>
<pre><code>#place a crow on given coordinates
init_crow &lt;- function(x,y){
  A &lt;- matrix(0,78,61)
  
  idx &lt;-(x-4):(x+4) 
  idy &lt;- (y-8):(y+8)
  A[idx[idx&lt;=78 &amp; idx>=1],idy[idy&lt;=61 &amp; idy>=1]] &lt;- 1
  idx &lt;-(x-8):(x+8) 
  idy &lt;- (y-4):(y+4)
  A[idx[idx&lt;=78 &amp; idx >=1],idy[idy&lt;=61 &amp; idy>=1]] &lt;- 1

  idx &lt;- (x-7):(x+7)
  k &lt;- 5
  while(y+k&lt;=61 &amp; k&lt;=8){
    A[idx[idx&lt;=78 &amp; idx>=1],y+k] &lt;- 1
    k &lt;- k+1
    idx &lt;- idx[-c(1,length(idx))]
  }
  idx &lt;- (x-7):(x+7)
  k &lt;- 5
  while(y-k>=1 &amp; k&lt;=8){
    A[idx[idx&lt;=78 &amp; idx>=1],y-k] &lt;- 1
    k &lt;- k+1
    idx &lt;- idx[-c(1,length(idx))]
  }
  A[x,y] &lt;- NA
  A
}

# find the crows on the map
locate_crows &lt;- function(farm,farm_blank){
  which(is.na(farm) &amp; farm_blank==0,arr.ind = T)
}

# add a scarecrow on a random empty tile
add_crow &lt;- function(farm){
  pos &lt;- which(!is.na(farm),arr.ind=T)
  xy &lt;- pos[sample(1:nrow(pos),1),]
  A &lt;- init_crow(xy[1],xy[2])
  farm+A
}

# delete a random scarecrow
del_crow &lt;- function(farm,farm_blank){
  pos &lt;- locate_crows(farm,farm_blank)
  del &lt;- sample(1:nrow(pos),1)
  pos &lt;- pos[-del,]
  farm &lt;- farm_blank
  for(i in 1:nrow(pos)){
    farm &lt;- farm+init_crow(pos[i,1],pos[i,2])
  }
  farm
}

# helper function to find overlapping rows in two matrices
overlap &lt;- function(m1,m2){
  outer(seq_len(nrow(m1)), seq_len(nrow(m2)), Vectorize(
    function(i, j) all(m1[i,]==m2[j,])
  ))
}

# teleport a scarecrow
teleport_crow &lt;- function(farm,farm_blank){
  farm &lt;- del_crow(farm,farm_blank)
  farm &lt;- add_crow(farm)
  farm
}

# move a scarecrow on a neighboring tile
move_crow &lt;- function(farm,farm_blank){
  cur_crow &lt;- locate_crows(farm,farm_blank)
  farm &lt;- del_crow(farm,farm_blank)
  new_crow &lt;- locate_crows(farm,farm_blank)
  deleted &lt;- which(apply(!overlap(cur_crow,new_crow),1,function(x) all(x)))
  xy &lt;- cur_crow[deleted,]
  xnew &lt;- xy[1]+sample(c(-1,0,1),1)
  ynew &lt;- xy[2]+sample(c(-1,0,1),1)
  while((xnew==xy[1] &amp; ynew==xy[2]) | xnew&lt;1 | xnew>78 | ynew&lt;1 | ynew>61){
    xnew &lt;- xy[1]+sample(c(-1,0,1),1)
    ynew &lt;- xy[2]+sample(c(-1,0,1),1)
  }
  if(!is.na(farm[xnew,ynew])){
    A &lt;- init_crow(xnew,ynew)
    farm &lt;- farm+A
  } else{
    A &lt;- init_crow(xy[1],xy[2])
    farm &lt;- farm+A
  }
  farm
}

# initialize a first solution
init_farm &lt;- function(farm,no=3){
  for(i in 1:no){
    x &lt;- sample(1:78,1)
    y &lt;- sample(1:61,1)
    while(is.na(farm[x,y])){
      x &lt;- sample(1:78,1)
      y &lt;- sample(1:61,1)
    }
    A &lt;- init_crow(x,y)
    farm &lt;- farm+A
  }
  farm
}

#optimization function
opt_func &lt;- function(A){
  sum(A==1,na.rm = T)
}</code></pre>
</div>
<div>
<h1>helper functions for sprinkler placement</h1>
<pre><code>add_sprinkler &lt;- function(farm){
  A &lt;- matrix(0,78,61)
  types &lt;- c(&quot;n&quot;,&quot;q&quot;,&quot;i&quot;)
  x &lt;- sample(1:78,1)
  y &lt;- sample(1:61,1)
  while(is.na(farm$A[x,y])){
    x &lt;- sample(1:78,1)
    y &lt;- sample(1:61,1)
  }
  t &lt;- sample(types,1)
  if(t==&quot;n&quot;){
    idx &lt;- (x-1):(x+1)
    A[idx[idx>=1 &amp; idx&lt;=78],y] &lt;- 1
    idy &lt;- (y-1):(y+1)
    A[x,idy[idy>=1 &amp; idy&lt;=61]] &lt;- 1
    A[x,y] &lt;- NA
    farm$sprinklers &lt;- rbind(farm$sprinklers,c(x,y,1))
  } else if(t==&quot;q&quot;){
    idx &lt;- (x-1):(x+1)
    idy &lt;- (y-1):(y+1)
    A[idx[idx>=1 &amp; idx&lt;=78],idy[idy>=1 &amp; idy&lt;=61]] &lt;- 1
    A[x,y] &lt;- NA    
    farm$sprinklers &lt;- rbind(farm$sprinklers,c(x,y,2))
  } else if(t==&quot;i&quot;){
    idx &lt;- (x-2):(x+2)
    idy &lt;- (y-2):(y+2)
    A[idx[idx>=1 &amp; idx&lt;=78],idy[idy>=1 &amp; idy&lt;=61]] &lt;- 1
    A[x,y] &lt;- NA    
    farm$sprinklers &lt;- rbind(farm$sprinklers,c(x,y,3))
  }
  farm$A &lt;- farm$A+A
  farm
}

del_sprinkler &lt;- function(farm,farm_layout){
  del &lt;- sample(1:nrow(farm$sprinklers),1)
  farm$sprinklers &lt;- farm$sprinklers[-del,]
  farm$A &lt;- farm_layout
  for(i in 1:nrow(farm$sprinklers)){
    farm$A &lt;- farm$A + init_sprinkler(farm$sprinklers[i,1],farm$sprinklers[i,2],farm$sprinklers[i,3])
  }
  farm
}

move_sprinkler &lt;- function(farm,farm_layout){
  cur_spr &lt;- farm$sprinklers
  farm &lt;- del_sprinkler(farm,farm_layout)
  new_spr &lt;- farm$sprinklers
  deleted &lt;- which(apply(!overlap(cur_spr,new_spr),1,function(x) all(x)))
  xy &lt;- cur_spr[deleted,]
  xnew &lt;- xy[1]+sample(c(-1,0,1),1)
  ynew &lt;- xy[2]+sample(c(-1,0,1),1)
  while((xnew==xy[1] &amp; ynew==xy[2]) | xnew&lt;1 | xnew>78 | ynew&lt;1 | ynew>61){
    xnew &lt;- xy[1]+sample(c(-1,0,1),1)
    ynew &lt;- xy[2]+sample(c(-1,0,1),1)
  }
  if(!is.na(farm$A[xnew,ynew])){
    A &lt;- init_sprinkler(xnew,ynew,xy[3])
    farm$A &lt;- farm$A+A
    farm$sprinklers &lt;- rbind(new_spr,c(xnew,ynew,xy[3]))
  } else{
    A &lt;- init_sprinkler(xy[1],xy[2],xy[3])
    farm$A &lt;- farm$A+A
    farm$sprinklers &lt;- rbind(new_spr,c(xy[1],xy[2],xy[3]))
  }
  farm
}

teleport_sprinkler &lt;- function(farm,farm_layout){
  cur_spr &lt;- farm$sprinklers
  farm &lt;- del_sprinkler(farm,farm_layout)
  new_spr &lt;- farm$sprinklers
  deleted &lt;- which(apply(!overlap(cur_spr,new_spr),1,function(x) all(x)))
  t &lt;- c(&quot;n&quot;,&quot;q&quot;,&quot;i&quot;)[cur_spr[deleted,3]]
  x &lt;- sample(1:78,1)
  y &lt;- sample(1:61,1)
  while(is.na(farm$A[x,y])){
    x &lt;- sample(1:78,1)
    y &lt;- sample(1:61,1)
  }
  A &lt;- matrix(0,78,61)
  if(t==&quot;n&quot;){
    idx &lt;- (x-1):(x+1)
    A[idx[idx>=1 &amp; idx&lt;=78],y] &lt;- 1
    idy &lt;- (y-1):(y+1)
    A[x,idy[idy>=1 &amp; idy&lt;=61]] &lt;- 1
    A[x,y] &lt;- NA
    farm$sprinklers &lt;- rbind(farm$sprinklers,c(x,y,1))
  } else if(t==&quot;q&quot;){
    idx &lt;- (x-1):(x+1)
    idy &lt;- (y-1):(y+1)
    A[idx[idx>=1 &amp; idx&lt;=78],idy[idy>=1 &amp; idy&lt;=61]] &lt;- 1
    A[x,y] &lt;- NA    
    farm$sprinklers &lt;- rbind(farm$sprinklers,c(x,y,2))
  } else if(t==&quot;i&quot;){
    idx &lt;- (x-2):(x+2)
    idy &lt;- (y-2):(y+2)
    A[idx[idx>=1 &amp; idx&lt;=78],idy[idy>=1 &amp; idy&lt;=61]] &lt;- 1
    A[x,y] &lt;- NA    
    farm$sprinklers &lt;- rbind(farm$sprinklers,c(x,y,3))
  }
  farm$A &lt;- farm$A+A
  farm
}

init_sprinkler &lt;- function(x,y,type){
  t &lt;- c(&quot;n&quot;,&quot;q&quot;,&quot;i&quot;)[type]
  A &lt;- matrix(0,78,61)
  if(t==&quot;n&quot;){
    idx &lt;- (x-1):(x+1)
    A[idx[idx>=1 &amp; idx&lt;=78],y] &lt;- 1
    idy &lt;- (y-1):(y+1)
    A[x,idy[idy>=1 &amp; idy&lt;=61]] &lt;- 1
    A[x,y] &lt;- NA
  } else if(t==&quot;q&quot;){
    idx &lt;- (x-1):(x+1)
    idy &lt;- (y-1):(y+1)
    A[idx[idx>=1 &amp; idx&lt;=78],idy[idy>=1 &amp; idy&lt;=61]] &lt;- 1
    A[x,y] &lt;- NA    
  } else if(t==&quot;i&quot;){
    idx &lt;- (x-2):(x+2)
    idy &lt;- (y-2):(y+2)
    A[idx[idx>=1 &amp; idx&lt;=78],idy[idy>=1 &amp; idy&lt;=61]] &lt;- 1
    A[x,y] &lt;- NA    
  }
  A
}

opt_func1 &lt;- function(farm,farm_max){
  sum(farm$A==1 &amp; farm_max>0,na.rm=T)
}</code></pre>
</div>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://blog.schochastics.net/post/rdew-valley-optimizing-farming-with-r/"> schochastics</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/vfO_R93ulFY" height="1"></a></div>