Reputation: 4380
I am trying to program tic-tac-toe in R - here are my two functions for making a move and evaluating all valid moves (the ones are X's, zeros are O's and NA
is not taken yet):
move <- function(board,square,mark)
{
if (square < 1 || square > 9 || !is.na(board[square]))
{
return(NA)
}
else
board[square] <- mark
return(board)
}
valid.moves <- function(board)
{
return(which(is.na(board)))
}
Now setting up a test position, evaluating all valid moves and then make those moves...
test.last <- matrix(c(1,1,NA,0,NA,0,NA,0,1),nrow=3)
moves <- valid.moves(test.last)
move(test.last,moves,1)
...gives a result which I didn't intend:
[,1] [,2] [,3]
[1,] 1 0 1
[2,] 1 1 0
[3,] 1 0 1
I wanted to have three different boards with the respective valid moves (which will then be evaluated with another function whether it is a winning position) and not one board with all valid moves made at once.
I don't want to do this with a loop but the vectorization should not take place all at once 'inside' the move
function but 'outside' of it - so basically I want to do the following without a loop (the eval.pos
function to evaluate the position is of the form eval.pos <- function(board){}
):
for (i in 1:length(moves))
{
after.moves <- move(test.last,moves[i],1)
print(after.moves)
print(eval.pos(after.moves))
}
How can I accomplish this without a loop?
Upvotes: 1
Views: 101
Reputation: 263352
Expanding my suggestion in the comment. How to use matrix indices to generate a list of move options:
valid.moves <- function(board)
{
return(which(is.na(board), arr.ind=TRUE))
}
> moves <- valid.moves(test.last)
> moves
row col
[1,] 3 1
[2,] 2 2
[3,] 1 3
> lapply(1:3, function( mv) {start <- test.last
start[matrix(moves[mv,],ncol=2)] <- 1
start})
[[1]]
[,1] [,2] [,3]
[1,] 1 0 NA
[2,] 1 NA 0
[3,] 1 0 1
[[2]]
[,1] [,2] [,3]
[1,] 1 0 NA
[2,] 1 1 0
[3,] NA 0 1
[[3]]
[,1] [,2] [,3]
[1,] 1 0 1
[2,] 1 NA 0
[3,] NA 0 1
Upvotes: 1
Reputation: 9687
move2 <- function(board, square, mark) {
lapply(square, function(x,i,value) `[<-`(x,i,value), x=board, value=mark)
}
Note that the anonymous function()
is needed because [<-
is primitive.
Upvotes: 1