##########################################################
## Battleship function #
## #
## Janina Torbecke & Inga Schwabe #
## 5th TRUG meeting (Object oriented programming in R) #
## #
## Input: Number of rows (nRow) and columns (nCol), #
## number of ships (nShips) #
## #
##########################################################
battleship <- function (nRow, nCol, nShips){
#Create class "ship"
setClass("Ship", representation(posX = "numeric",posY = "numeric",found = "logical"),
prototype(found = FALSE))
#Create board
board <- matrix(0,nRow,nCol)
#For while loop, set to TRUE when all ships are found which will stop the game.
allFound <- FALSE
#Create empty list to store all ship objects
ships <- list()
#Create the first ship
ships[1] <- new("Ship",posX = sample(1:nRow,1),posY = sample(1:nCol, 1))
#Create remaining ships
for(i in 2:nShips) {
foundPos <- FALSE
shipRow <- NA
shipCol <- NA
while(!foundPos){ #Loop continues until position of 1 ship is found
shipRow <- sample(1:nRow,1) #Random row nr
shipCol <- sample(1:nCol,1) #Random col nr
#Check if position is available
for(j in 1:length(ships)) {
foundPos <- !(ships[[j]]@posX == shipRow && ships[[j]]@posY == shipCol)
if(!foundPos) {
break
}
}
}
#Create new ship on available position
ships[i] <- new("Ship", posX = shipRow, posY = shipCol)
}
#Plot output guess:
#Plot grid/board
par(mar = c(0, 0, 0, 0))
plot(1, type = "n", asp = 1, xlab = "", ylab = "",
xlim = c(0.5, nCol + 0.5), ylim = c(0.5, nRow + 0.5), axes = FALSE)
xGrid <- outer(1:nCol, 1:nRow, function(x, y) x)
yGrid <- outer(1:nCol, 1:nRow, function(x, y) y)
symbols(xGrid, yGrid, rectangles = matrix(1, length(xGrid), 2), inches = FALSE,
fg = "lightblue", bg = "white", add = TRUE)
#Plot water
plotWater <- function(shipCol, shipRow, color = "lightblue") {
symbols(shipCol, shipRow, squares = rep(1, length(shipCol)),
inches = FALSE, fg = NULL, bg = color, add = TRUE)
}
#Plot ship
plotShip <- function(shipCol, shipRow) {
symbols(shipCol + 0.075, shipRow + 0.2, rectangles = matrix(rep(c(0.35, 0.2), rep(length(shipCol), 2)), ncol = 2),
inches = FALSE,fg = "red",bg = "red",add = TRUE)
symbols(shipCol, shipRow - 0.25, rectangles = matrix(rep(c(0.8, 0.1), rep(length(shipCol), 2)), ncol = 2),
inches = FALSE, fg = "black", bg = "black", add = TRUE)
segments(shipCol - 0.1, shipRow + 0.3, shipCol - 0.1, shipRow - 0.2)
}
#Play & Output
while(!allFound){
guess <- locator(1)
guess$x <- min(nCol, max(1, round(guess$x)))
guess$y <- min(nRow, max(1, round(guess$y)))
allFound <- TRUE #Stop while loop!
found <- FALSE
plotWater(guess$x, guess$y)
for(i in 1:nShips) {
if (ships[[i]]@found || (guess$x == ships[[i]]@posX && guess$y == ships[[i]]@posY)){
ships[[i]]@found <- TRUE
plotWater(ships[[i]]@posX, ships[[i]]@posY)
plotShip(ships[[i]]@posX, ships[[i]]@posY)
#Good guess:
if (guess$x == ships[[i]]@posX && guess$y == ships[[i]]@posY){
found <- TRUE
}
}else if (!ships[[i]]@found) {
allFound <- FALSE
}
}
if (found) {
print("Congratulations! You sank a battleship")
}else{
print("You missed the battleships")
}
}
}
win.graph() #Open
#quartz() #for mac users
battleship(4,4,6) #Run the function with 4x4 board and 6 ships