Settlers of Catan

The objective of this code is to simulate different strategies in the game Settlers of Catan. The best way Catan can be described is as a “game of resources”. An individual begins with two settlements on the board and obtains resources if the number associated with the resource is rolled on any turn. To win, a player must obtain 10 points before any other player.

There are several methods to obtain the most points. I aim to determine which strategy may obtain the 10 points the quickest. Each player essentially starts off with 2 settlements/2points, so really, each player only needs to obtain 8 more points.

How to get points: -1 settlement = 1 point (can only have 5 settlements maximum) -1 city = 2 points (can only make a city if there is an existing settlement in place, can only have 4 cities maximum) -Longest Road = 2 points (need 6 consecutive roads and most roads to obtain this card, can only have 15 roads maximum) -Largest Army = 2 points (need 3 or more knights from development cards) -Victory points = 1 point (from development cards)

Rolling Dice

This function simulates two dice rolls. Every player rolls two dice every turn.

library(ggplot2)
## Warning: package 'ggplot2' was built under R version 3.5.2
roll_dice <- function(k){
  all_rolls <- sample(c(1:6),k, replace=TRUE)
final_answer <- sum(all_rolls)
return(final_answer)
}

roll_dice(2)
## [1] 2
rolls <- replicate(100, roll_dice(2))
table(rolls)
## rolls
##  2  3  4  5  6  7  8  9 10 11 12 
##  3  6  9 11 11 22 11  6 14  3  4

Different Combinations of Places to Put Settlements

In the game, each settlment is placed on the corner of a hexagon. Each hexagon has an associated number and resource which are randomly generated. If any player rolls a number and an individual has a settlement on it, the individual collects the resource the settlement is on.

For example, if I have a settlement on a corner that has a 5 on wood and a 5 is rolled, I would collect 1 wood. If I have a city there, I would collect 2 woods.

Every number from 3 to 11 is on the board twice (except for 7), and 2 and 12 are listed once. We will not be playing with 7’s because there is a special rule with 7’s. We will not be implementing that rule into our simulation as it levels an added level of complexity.

resource <- as.factor(c(rep("wood",4),rep("wheat",4),rep("sheep",4),rep("brick",3),rep("ore",3)))
numbs <- c(2,rep(3:6,2),rep(8:11,2),12)

combos <- expand.grid(resource, numbs)

names(combos)[names(combos) == "Var1"] <- "resource"
names(combos)[names(combos) == "Var2"] <- "numbers"

head(combos)
##   resource numbers
## 1     wood       2
## 2     wood       2
## 3     wood       2
## 4     wood       2
## 5    wheat       2
## 6    wheat       2

Players Starting Point

This will be the first two settlements we put on the board. So, any time a 9 is rolled, we will obtain a wheat and any time an 8 is rolled, we will obtain a sheep.

set.seed(123456)
p1 <- sample(nrow(combos), 2)
combos2 <- combos[-p1, ]

#Player 1 Starting Point
p1 <- combos[p1, ] 
p1
##     resource numbers
## 259    wheat       9
## 244    sheep       8

Other Players

set.seed(123)
p2 <- sample(nrow(combos2), 2)
combos3 <- combos2[-p2, ]

#Player 2 Starting Point
p2 <- combos2[p2, ] 
p2
##     resource numbers
## 93      wood       3
## 255     wood       9

Bank + 2 good spots, vs Port Trade (3:1) + 1 good spot + 1 okay spot

Player 1 is on two very good spots (8 and 6) and will trade with the bank for a 4:1 trade.

Player 2 is on 1 very good spot (8), 1 okay spot (3), and a 3:1 port.

settlement <- c("wheat","sheep","wood","brick")

s1 <- function(){
points.p1 <- 2
points.p2 <- 2
resources.p1 <- c()
resources.p2 <- c()
p1win <- 0
p2win <- 0
while(points.p1 < 10 & points.p2 < 10){

#Check Dice Rolls and Give Resources
dice <- roll_dice(2)
if (dice == '8'){
(resources.p1 = c(resources.p1,"wheat"))}
if (dice == '8'){
(resources.p2 = c(resources.p2,"wood"))}
if (dice == '6'){
resources.p1 = c(resources.p1,"sheep")}
if (dice == '4'){
resources.p2 = c(resources.p1,"sheep")}

#print(resources.p1)
#print(resources.p2)

#If you have all the resources to buy a settlement, do it!
if (all(settlement %in% resources.p1)){ 
points.p1 <- points.p1 +1
resources.p1 <- resources.p1[-which(!duplicated(resources.p1))]
}
if (all(settlement %in% resources.p2)){ 
points.p2 <- points.p2 +1
resources.p2 <- resources.p2[-which(!duplicated(resources.p2))]
}

#If you don't have all the resources, we should trade with the bank or with the port
if (length(resources.p1) != 0) {
#Bank Trading
if (sum(resources.p1=="wheat") >= 4){
if(sum(resources.p1 == "wood") < 1) {
resources.p1 <- c(resources.p1[-which(resources.p1 == "wheat")[1:4]], "wood") }

else if(sum(resources.p1 == "brick") < 1) {
resources.p1 <- c(resources.p1[-which(resources.p1 == "wheat")[1:4]], "brick") }
}

if (sum(resources.p1=="sheep") >= 4) { #If no sheep, trade sheep 
if(sum(resources.p1 == "wood") < 1) {
resources.p1 <- c(resources.p1[-which(resources.p1 == "sheep")[1:4]], "wood")}

else if(sum(resources.p1 == "brick") < 1) {
resources.p1 <- c(resources.p1[-which(resources.p1 == "sheep")[1:4]], "brick")}
}
}

#Port Trading
if (length(resources.p2) != 0) {
if (sum(resources.p2=="wood") >= 3) {
if(sum(resources.p2 == "sheep") < 1) {
resources.p2 <- c(resources.p2[-which(resources.p2 == "wood")[1:3]], "sheep") }

else if(sum(resources.p2 == "brick") < 1) {
resources.p2 <- c(resources.p2[-which(resources.p2 == "wood")[1:3]], "brick") }

else if(sum(resources.p2 == "wheat") < 1) {
resources.p2 <- c(resources.p2[-which(resources.p2 == "wood")[1:3]], "wheat") }
}
}
#print(points.p1)
#print(points.p2)
}
if (points.p1 > points.p2) {
p1win <- p1win + 1
}else{
p2win <- p2win + 1
}
ratio <-(p1win/(p2win+p1win))
ratio
}

s1()
## [1] 1
mean(replicate(1000,s1()))
## [1] 0.741
odds <- replicate(1000,s1())
odds <-as.data.frame(odds)
s1plot <- ggplot(odds, aes(x = factor(odds))) +
    geom_bar() + ggtitle("S1 vs S2") +
  xlab("Odds of Player 1 Winning = 1, Losing = 0") + ylab("Frequency")

Bank + 2 good spots, vs Port Trade (2:1) + 1 good spot + 1 okay spot

Player 1 is on two very good spots (8 and 6) and will trade with the bank for a 4:1 trade.

Player 2 is on 1 very good spot (8), 1 okay spot (3), and a 2:1 port.

settlement <- c("wheat","sheep","wood","brick")

s2 <- function(){
points.p1 <- 2
points.p2 <- 2
resources.p1 <- c()
resources.p2 <- c()
p1win <- 0
p2win <- 0
while(points.p1 < 10 & points.p2 < 10){

#Check Dice Rolls and Give Resources
dice <- roll_dice(2)
if (dice == '8'){
(resources.p1 = c(resources.p1,"wheat"))}
if (dice == '8'){
(resources.p2 = c(resources.p2,"wood"))}
if (dice == '6'){
resources.p1 = c(resources.p1,"sheep")}
if (dice == '4'){
resources.p2 = c(resources.p1,"sheep")}

#print(resources.p1)
#print(resources.p2)

#If you have all the resources to buy a settlement, do it!
if (all(settlement %in% resources.p1)){ 
points.p1 <- points.p1 +1
resources.p1 <- resources.p1[-which(!duplicated(resources.p1))]
}
if (all(settlement %in% resources.p2)){ 
points.p2 <- points.p2 +1
resources.p2 <- resources.p2[-which(!duplicated(resources.p2))]
}

#If you don't have all the resources, we should trade with the bank or with the port
if (length(resources.p1) != 0) {
#Bank Trading
if (sum(resources.p1=="wheat") >= 4){
if(sum(resources.p1 == "wood") < 1) {
resources.p1 <- c(resources.p1[-which(resources.p1 == "wheat")[1:4]], "wood") }

else if(sum(resources.p1 == "brick") < 1) {
resources.p1 <- c(resources.p1[-which(resources.p1 == "wheat")[1:4]], "brick") }
}

if (sum(resources.p1=="sheep") >= 4) { #If no sheep, trade sheep 
if(sum(resources.p1 == "wood") < 1) {
resources.p1 <- c(resources.p1[-which(resources.p1 == "sheep")[1:4]], "wood")}

else if(sum(resources.p1 == "brick") < 1) {
resources.p1 <- c(resources.p1[-which(resources.p1 == "sheep")[1:4]], "brick")}
}
}

#Port Trading
if (length(resources.p2) != 0) {
if (sum(resources.p2=="wood") >= 3) {
if(sum(resources.p2 == "sheep") < 1) {
resources.p2 <- c(resources.p2[-which(resources.p2 == "wood")[1:2]], "sheep") }

else if(sum(resources.p2 == "brick") < 1) {
resources.p2 <- c(resources.p2[-which(resources.p2 == "wood")[1:2]], "brick") }

else if(sum(resources.p2 == "wheat") < 1) {
resources.p2 <- c(resources.p2[-which(resources.p2 == "wood")[1:2]], "wheat") }
}
}
#print(points.p1)
#print(points.p2)
}
if (points.p1 > points.p2) {
p1win <- p1win + 1
}else{
p2win <- p2win + 1
}
ratio <-(p1win/(p2win+p1win))
ratio
}

s2()
## [1] 1
mean(replicate(1000,s2()))
## [1] 0.28
odds2 <- replicate(1000,s2())
odds2 <-as.data.frame(odds2)
s2plot <- ggplot(odds2, aes(x = factor(odds2))) +
    geom_bar() + ggtitle("S1 vs S3") +
  xlab("Odds of Player 1 Winning = 1, Losing = 0") + ylab("Frequency")

Bank + 2 good spots, vs Port Trade (2:1) + 2 okay spots

Player 1 is on two very good spots (8 and 6) and will trade with the bank for a 4:1 trade.

Player 2 is on 2 okay spots (10 and 4), and a 2:1 port.

settlement <- c("wheat","sheep","wood","brick")

s3 <- function(){
points.p1 <- 2
points.p2 <- 2
resources.p1 <- c()
resources.p2 <- c()
p1win <- 0
p2win <- 0
while(points.p1 < 10 & points.p2 < 10){

#Check Dice Rolls and Give Resources
dice <- roll_dice(2)
if (dice == '8'){
(resources.p1 = c(resources.p1,"wheat"))}
if (dice == '10'){
(resources.p2 = c(resources.p2,"wood"))}
if (dice == '6'){
resources.p1 = c(resources.p1,"sheep")}
if (dice == '4'){
resources.p2 = c(resources.p1,"sheep")}

#print(resources.p1)
#print(resources.p2)

#If you have all the resources to buy a settlement, do it!
if (all(settlement %in% resources.p1)){ 
points.p1 <- points.p1 +1
resources.p1 <- resources.p1[-which(!duplicated(resources.p1))]
}
if (all(settlement %in% resources.p2)){ 
points.p2 <- points.p2 +1
resources.p2 <- resources.p2[-which(!duplicated(resources.p2))]
}

#If you don't have all the resources, we should trade with the bank or with the port
if (length(resources.p1) != 0) {
#Bank Trading
if (sum(resources.p1=="wheat") >= 4){
if(sum(resources.p1 == "wood") < 1) {
resources.p1 <- c(resources.p1[-which(resources.p1 == "wheat")[1:4]], "wood") }

else if(sum(resources.p1 == "brick") < 1) {
resources.p1 <- c(resources.p1[-which(resources.p1 == "wheat")[1:4]], "brick") }
}

if (sum(resources.p1=="sheep") >= 4) { #If no sheep, trade sheep 
if(sum(resources.p1 == "wood") < 1) {
resources.p1 <- c(resources.p1[-which(resources.p1 == "sheep")[1:4]], "wood")}

else if(sum(resources.p1 == "brick") < 1) {
resources.p1 <- c(resources.p1[-which(resources.p1 == "sheep")[1:4]], "brick")}
}
}

#Port Trading
if (length(resources.p2) != 0) {
if (sum(resources.p2=="wood") >= 3) {
if(sum(resources.p2 == "sheep") < 1) {
resources.p2 <- c(resources.p2[-which(resources.p2 == "wood")[1:2]], "sheep") }

else if(sum(resources.p2 == "brick") < 1) {
resources.p2 <- c(resources.p2[-which(resources.p2 == "wood")[1:2]], "brick") }

else if(sum(resources.p2 == "wheat") < 1) {
resources.p2 <- c(resources.p2[-which(resources.p2 == "wood")[1:2]], "wheat") }
}
}
#print(points.p1)
#print(points.p2)
}
if (points.p1 > points.p2) {
p1win <- p1win + 1
}else{
p2win <- p2win + 1
}
ratio <-(p1win/(p2win+p1win))
ratio
}

s3()
## [1] 1
mean(replicate(1000,s3()))
## [1] 0.793
odds3 <- replicate(1000,s3())
odds3 <-as.data.frame(odds3)
s3plot <- ggplot(odds3, aes(x = factor(odds3))) +
    geom_bar() + ggtitle("S1 vs S4") +
  xlab("Odds of Player 1 Winning = 1, Losing = 0") + ylab("Frequency")

Bank + 2 good spots, vs Port Trade (3:1) + 2 okay spots

Player 1 is on two very good spots (8 and 6) and will trade with the bank for a 4:1 trade.

Player 2 is on 2 okay spots (10 and 4), and a 3:1 port.

settlement <- c("wheat","sheep","wood","brick")

s4 <- function(){
points.p1 <- 2
points.p2 <- 2
resources.p1 <- c()
resources.p2 <- c()
p1win <- 0
p2win <- 0
while(points.p1 < 10 & points.p2 < 10){

#Check Dice Rolls and Give Resources
dice <- roll_dice(2)
if (dice == '8'){
(resources.p1 = c(resources.p1,"wheat"))}
if (dice == '10'){
(resources.p2 = c(resources.p2,"wood"))}
if (dice == '6'){
resources.p1 = c(resources.p1,"sheep")}
if (dice == '4'){
resources.p2 = c(resources.p1,"sheep")}

#print(resources.p1)
#print(resources.p2)

#If you have all the resources to buy a settlement, do it!
if (all(settlement %in% resources.p1)){ 
points.p1 <- points.p1 +1
resources.p1 <- resources.p1[-which(!duplicated(resources.p1))]
}
if (all(settlement %in% resources.p2)){ 
points.p2 <- points.p2 +1
resources.p2 <- resources.p2[-which(!duplicated(resources.p2))]
}

#If you don't have all the resources, we should trade with the bank or with the port
if (length(resources.p1) != 0) {
#Bank Trading
if (sum(resources.p1=="wheat") >= 4){
if(sum(resources.p1 == "wood") < 1) {
resources.p1 <- c(resources.p1[-which(resources.p1 == "wheat")[1:4]], "wood") }

else if(sum(resources.p1 == "brick") < 1) {
resources.p1 <- c(resources.p1[-which(resources.p1 == "wheat")[1:4]], "brick") }
}

if (sum(resources.p1=="sheep") >= 4) { #If no sheep, trade sheep 
if(sum(resources.p1 == "wood") < 1) {
resources.p1 <- c(resources.p1[-which(resources.p1 == "sheep")[1:4]], "wood")}

else if(sum(resources.p1 == "brick") < 1) {
resources.p1 <- c(resources.p1[-which(resources.p1 == "sheep")[1:4]], "brick")}
}
}

#Port Trading
if (length(resources.p2) != 0) {
if (sum(resources.p2=="wood") >= 3) {
if(sum(resources.p2 == "sheep") < 1) {
resources.p2 <- c(resources.p2[-which(resources.p2 == "wood")[1:3]], "sheep") }

else if(sum(resources.p2 == "brick") < 1) {
resources.p2 <- c(resources.p2[-which(resources.p2 == "wood")[1:3]], "brick") }

else if(sum(resources.p2 == "wheat") < 1) {
resources.p2 <- c(resources.p2[-which(resources.p2 == "wood")[1:3]], "wheat") }
}
}
#print(points.p1)
#print(points.p2)
}
if (points.p1 > points.p2) {
p1win <- p1win + 1
}else{
p2win <- p2win + 1
}
ratio <-(p1win/(p2win+p1win))
ratio
}

s4()
## [1] 1
mean(replicate(1000,s4()))
## [1] 0.913
odds4 <- replicate(1000,s4())
odds4 <-as.data.frame(odds4)
s4plot <- ggplot(odds4, aes(x = factor(odds4))) +
    geom_bar() + ggtitle("S1 vs S5") +
  xlab("Odds of Player 1 Winning = 1, Losing = 0") + ylab("Frequency")
s1plot

s2plot

s3plot

s4plot

library(ggpubr)
## Warning: package 'ggpubr' was built under R version 3.5.2
## Loading required package: magrittr
ggarrange(s1plot, s2plot, s3plot, s4plot , 
       ncol = 2, nrow = 2)