########################################################## ## 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