## -----------------------------------------------------------------------------
#| label: setup
library(fourinarow)


## ----eval=FALSE---------------------------------------------------------------
# play4inaRow(humanPlayer, randomBot)

## ----echo=FALSE---------------------------------------------------------------
game <- matrix('.', nrow = 6, ncol = 7)
cat(paste0('   ',paste(1:7, collapse='  ')))
cat('\n')
cat(' _______________________\n')
for(i in 1:nrow(game)){
  cat(' | ')
  cat(paste(game[i,], collapse='  '))
  cat(' |\n')
}
cat(' -----------------------\n')
cat('Move: ')


## -----------------------------------------------------------------------------
play4inaRow(easyBot, randomBot)


## -----------------------------------------------------------------------------
myBot <- function(game){
  sample(7, 1)
}


## -----------------------------------------------------------------------------
set.seed(1)
play4inaRow(myBot, randomBot)


## -----------------------------------------------------------------------------
set.seed(2)
play4inaRow(myBot, randomBot)


## ----warning=FALSE------------------------------------------------------------
testBots(myBot, randomBot)


## -----------------------------------------------------------------------------
myBot <- function(game){
  # identify legal moves
  poss <- which(game[1,] == '.')
  
  # if only one legal move
  if(length(poss) == 1){
    return(poss)
  }
  
  # otherwise, select randomly
  return(sample(poss, 1))
}


## -----------------------------------------------------------------------------
testBots(myBot, randomBot)


## -----------------------------------------------------------------------------
sets <- getSetsof4()
head(sets)


## ----eval=FALSE---------------------------------------------------------------
# goodmoves <- apply(sets, 1, function(set){
#   # get symbols from game board ('X','O','.')
#   symbols <- game[set]
#   # index of the (potential) target space
#   index <- 0
# 
#   # look for sets of 3 X's with an open space
#   if(sum(symbols == 'X') == 3 & sum(symbols == '.') == 1){
#     index <- set[which(symbols == '.')]
#   }
#   # look for sets of 3 O's with an open space
#   if(sum(symbols == 'O') == 3 & sum(symbols == '.') == 1){
#     index <- set[which(symbols == '.')]
#   }
# 
#   # if either of the above situations were found,
#   # check whether or not the empty space is reachable on this turn
#   if(index != 0){
#     column <- ((index - 1) %/% 6) + 1
#     row <- ifelse(index %% 6 != 0, index %% 6, 6)
#     if(row == 6 || all(game[(row+1):6, column] %in% c('X','O'))){
#       # found a good move
#       return(column)
#     }
#   }
# 
#   # didn't find a good move, return 0
#   return(0)
# })
# 


## ----eval=FALSE---------------------------------------------------------------
# myBot <- function(game){
#   # identify legal moves
#   poss <- which(game[1,] == '.')
# 
#   # if only one legal move
#   if(length(poss) == 1){
#     return(poss)
#   }
# 
#   # look for good moves (make 4 in a row or block opponent)
#   goodmoves <- apply(sets, 1, function(set){
#     # ...
#   })
# 
#   if(any(goodmoves != 0)){
#     # return the first non-zero value
#     return(goodmoves[which.max(goodmoves != 0)])
#   }
#   # otherwise, select randomly
#   return(sample(poss, 1))
# }


## ----echo=FALSE---------------------------------------------------------------
myBot <- function(game){
  # identify legal moves
  poss <- which(game[1,] == '.')
  
  # if only one legal move
  if(length(poss) == 1){
    return(poss)
  }
  
  # look for good moves (make 4 in a row or block opponent)
  goodmoves <- apply(sets, 1, function(set){
    # get symbols from game board ('X','O','.')
    symbols <- game[set]
    # index of the (potential) target space
    index <- 0
    
    # look for sets of 3 X's with an open space
    if(sum(symbols == 'X') == 3 & sum(symbols == '.') == 1){
      index <- set[which(symbols == '.')]
    }
    # look for sets of 3 O's with an open space
    if(sum(symbols == 'O') == 3 & sum(symbols == '.') == 1){
      index <- set[which(symbols == '.')]
    }
    
    # if either of the above situations were found, 
    # check whether or not the empty space is reachable on this turn
    if(index != 0){
      column <- ((index - 1) %/% 6) + 1
      row <- ifelse(index %% 6 != 0, index %% 6, 6)
      if(row == 6 || all(game[(row+1):6, column] %in% c('X','O'))){
        # found a good move
        return(column)
      }
    }
    
    # didn't find a good move, return 0
    return(0)
  })
  
  if(any(goodmoves != 0)){
    # return the first non-zero value
    return(goodmoves[which.max(goodmoves != 0)])
  }
  # otherwise, select randomly
  return(sample(poss, 1))
}


## -----------------------------------------------------------------------------
testBots(myBot, randomBot)

