#' @title A classic chessborad game.
#'
#' @description Play with your friend or play with computer.
#' Players first choose their color (black or white),
#' then choose a position to locate their stones alternatively, with
#' black going first.
#' Player who first has five stones in row (horizontally,
#' vertically or diagonally) wins the game.
#'
#' @param n numbers of rows and columns in the chessboard. The default value
#' is 19, which is the standard size of a gomoku chessboard.
#'
#' @note (1)Do not roll the mouse scroll after the graphic device pops out, or the
#' plots will be messed up.
#' (2)Better not close the graphic device during the game. Close it only after
#' clicking the quit option.
#' (3)The value of n should be larger than 5 so the board can accomadate at
#' least five stones.
#' (4)The value of code{n} should be an odd number.
#'
#' @return If you keep playing the game, nothing will be returned; If you close
#' the game by clicking "quit", a table containing all the results will be displayed;
#' if there are no results, a character string "Game Closed, No Record" will return.
#'
#' @author Yimo Zhang
#'
#' @references \url{https://github.com/yihui/fun/blob/master/R/gomoku.R}, where
#' the basic idea of this function came from.
#' \url{http://www.sohu.com/a/156507478_466874}, where the idea of ploting taiji.png
#' is borrowd.
#' @examples
#' gomoku(n = 21)
#'
#' @export
gomoku = function(n = 19)
{
if (!interactive()) return() #check if R is running interactively; if not, quit the game
if(n < 5) stop("Hmm, n is too small for the game to play!")
if(n %% 2 < 1) stop("Sorry, n must be a odd number!")
result_table = tibble("Date"= as.character(Sys.Date()), "Time" = as.character(format(Sys.time(), "%X")), "Game" = "None", "Result" = "None")
#Choose to play with your friend or computer
first_choose = function(){
repeat{
options(locatorBell = FALSE)
l = locator(1)
x = l$x
y = l$y
if(x>37 & x<63 & y>23 & y<31){return(1)}
if(x>30 & x<70 & y>8 & y<16){return(2)}
}
}
#Choose the difficulty of the game
second_choose = function(){
repeat{
options(locatorBell = FALSE)
l = locator(1)
x = l$x
y = l$y
if(x>42 & x<58 & y>23 & y<31){return(3)}
if(x>40 & x<60 & y>8 & y<16){return(4)}
}
}
#Choose the color you want to play
third_choose = function(){
repeat{
options(locatorBell = FALSE)
l = locator(1)
x = l$x
y = l$y
if(x>40 & x<61 & y>23 & y<31){return(5)}
if(x>39 & x<61 & y>8 & y<16){return(6)}
}
}
########################Backstage functions###############################
#Check if there are five stones of the same color in row
judge_five = function(x, location){
#line1 is a y=x kind of line, the point x is the middle of the five points
x1 = c((x[1]-2):(x[1]+2))
x1 = as.double(x1)
y1 = c((x[2]-2):(x[2]+2))
y1 = as.double(y1)
line1 = make_line(x1, y1)
#line2 is a y=-x kind of line, the point x is the middle of the five points
x2 = x1
y2 = rev(y1)
line2 = make_line(x2, y2)
#line3 is a horizontal line, the point x is the middle of the five points
x3 = rep(x[1], 5)
y3 = y1
line3 = make_line(x3, y3)
#line4 is a vertical line, the point x is the middle of the five points
x4 = x1
y4 = rep(x[2], 5)
line4 = make_line(x4, y4)
#save the lines in a list
line = list(line1, line2, line3, line4)
#check if there are five continuous points in the set
for(i in 1:4){
judge = sum(is.element(line[[i]], location))
if (judge == 5)
return(1)
if(i == 4)
return(0)
}
}
#check if somebody wins
if_win = function(set){
win = sapply(set, judge_five, set)#check if there are five continuous points in black chessmen set
return(is.element(1, win))
}
#player plays
player_play = function(playlist, n){
repeat {
options(locatorBell = FALSE)
l = locator(1)
l$x <- min(n, max(1, round(l$x))) #modify the x-location to where nearest point
l$y <- min(n, max(1, round(l$y))) #modify the y-location to where nearest point
xy <- paste(l, collapse = ":") #record the step
if (!is.element(xy, playlist)) #break when the point had chessman on it
break
}
return(l)
}
#computer plays
computer_play = function(player, computer, playlist, n){
get_4 = get_function(4, player, computer, n)
#If there are available spots to block 4 continuous stones
if(!is.list(get_4)){get_3 = get_function(3, player, computer, n)} else{return(get_4)}
#If there are available spots to block 3 continuous stones
if(!is.list(get_3)){get_2 = get_function(2, player, computer, n)} else{return(get_3)}
#If there are available spots to block 2 continuous stones
if(!is.list(get_2)){get_1 = get_function(1, player, computer, n)} else{return(get_2)}
#If there are available spots to around 1 stone
if(!is.list(get_1)){
repeat{
#randomly choose an available spot
new = list(c(sample(1:n,1),sample(1:n,1)))
xy <- paste(new, collapse = ":") #record the step
if (!is.element(xy, playlist)) #break when the point had chessman on it
break
} }else{return(get_1)}
return(new)
}
#Get the avalible spot; if not available , return 0
get_function = function(num, set1, set2 = NULL, n = NULL){
get_num = lapply(set1, judge, num, set1, set2, n)
temp = sapply(get_num, is.list)
if(is.element(1, temp)){
equal_to_one = which(temp == 1)
get_one = sample(1:length(equal_to_one),1)
get_list = get_num[[equal_to_one[get_one]]]
} else {return (0)}
return(get_list)
}
#Check if there are num continuous points
judge = function(x, num, set1, set2 = NULL, n = NULL){
#line1 is a y=x kind of line, the point x is the middle of the five points
x1 = c(x[1]:(x[1]+num-1))
y1 = c(x[2]:(x[2]+num-1))
x1 = as.double(x1)
y1 = as.double(y1)
line1 = make_line(x1, y1)
#line2 is a y=-x kind of line, the point x is the middle of the five points
x2 = x1
y2 = c(x[2]:(x[2]-num+1))
line2 = make_line(x2, y2)
#line3 is a horizontal line, the point x is the middle of the five points
x3 = rep(x[1], num)
y3 = y1
line3 = make_line(x3, y3)
#line4 is a vertical line, the point x is the middle of the five points
x4 = x1
y4 = rep(x[2], num)
line4 = make_line(x4, y4)
#save the lines in a list
line = list(line1, line2, line3, line4)
#check if there are five continuous points in the set
for(i in 1:4){
judge = sum(is.element(line[[i]], set1))
temp = check_blank(num, i, x, set2, set1, n)
if(judge == num & is.list(temp))
return(temp)
if(i==4)
return(0)
}
}
#Generate five points based on their x-value and y-value
make_line = function(x,y){
a = list()
for(i in 1:length(x)){
a[[i]] = c(x[i],y[i])
}
return(a)
}
#Check if the neareast points are filled
check_blank = function(num_point, index, point, location, location2, n){
i = num_point
x = point
if(index == 1)
{
left = list(c(x[1]-1, x[2]-1))
right = list(c(x[1]+i, x[2]+i))
}
if(index == 2)
{
left = list(c(x[1]-1, x[2]+1))
right = list(c(x[1]+i, x[2]-i))
}
if(index == 3)
{
left = list(c(x[1], x[2]-1))
right = list(c(x[1], x[2]+i))
}
if(index == 4){
left = list(c(x[1]-1, x[2]))
right = list(c(x[1]+i, x[2]))
}
left = list(as.double(unlist(left)))
right = list(as.double(unlist(right)))
if_left = sum(is.element(left, location),!within_boundary(left, n),is.element(left, location2))
if_right = sum(is.element(right, location),!within_boundary(right, n), is.element(right,location2))
if(if_left == 0){return(left)}
if(if_right == 0){return(right)}
return(0)
}
#Check if the point is located inside the chessboard
within_boundary = function(x, n){
x = unlist(x)
judge_l = x<1
judge_r = x>n
if(sum(judge_l)>0 || sum(judge_r)>0){return(0)}
else{return(1)}
}
#check if a spot is available
check_blank_hard = function(num_point, index, point, player, computer, n){
i = num_point
x = point
if(index == 1)
{
left = list(c(x[1]-1, x[2]-1))
right = list(c(x[1]+i, x[2]+i))
}
if(index == 2)
{
left = list(c(x[1]-1, x[2]+1))
right = list(c(x[1]+i, x[2]-i))
}
if(index == 3)
{
left = list(c(x[1], x[2]-1))
right = list(c(x[1], x[2]+i))
}
if(index == 4)
{
left = list(c(x[1]-1, x[2]))
right = list(c(x[1]+i, x[2]))
}
left = list(as.double(unlist(left)))
right = list(as.double(unlist(right)))
if_left = sum(is.element(left, player),!within_boundary(left, n),is.element(left, computer))
if_right = sum(is.element(right, player),!within_boundary(right, n), is.element(right,computer))
if(if_left + if_right == 0){return(list(left, right, 2))}
if(if_left == 0){return(list(left, 1))}
if(if_right == 0){(return(list(right, 1)))}
return(0)
}
#Get the avalible spot; if not available , return 0 (hard version)
get_function_hard = function(num, player, computer, n = NULL){
get_num = lapply(player, judge_hard, num, player, computer, n)
temp = sapply(get_num, length)
two_ava = which(temp == 3)
one_ava = which(temp == 2)
if(length(two_ava) > 0){
get_one = sample(1:length(two_ava),1)
get_list = get_num[[two_ava[get_one]]]
random = sample(1:2, 1)
final = get_list[[random]]
return(final)
}
if(length(one_ava) > 0){
get_one = sample(1:length(one_ava),1)
get_list = get_num[[one_ava[get_one]]]
final = get_list[[1]]
return(final)
}
else {return (0)}
}
#computer play (hard version)
computer_play_hard = function(player, computer, playlist, n){
m = n+1
i = 0
get_4 = get_function_hard(4, player, computer, n)
if(!is.list(get_4)){get_3 = get_function_hard(3, player, computer, n)} else{return(get_4)}
if(!is.list(get_3)){get_2 = get_function_hard(2, player, computer, n)} else{return(get_3)}
if(!is.list(get_2)){
repeat{
#From center to margin, choose an available spot
spot = vector()
left = m/2 - i
right = m/2 +i
x = rep(left:right,2*i+1)
y = rep(left:right, each = 2*i+1)
for(j in 1:length(x)){
spot[[j]] = paste(list(x[j],y[j]), collapse = ":")
}
i = i+1
index = is.element(spot, playlist)
temp = which(index == 0)
if (length(temp)>0) #break when the point had chessman on it
break
} }else{return(get_2)}
random = sample(temp,1)
return(list(c(x[random],y[random])))
}
#Check if there are num continuous points (hard version)
judge_hard = function(x, num, player, computer, n = NULL){
#line1 is a y=x kind of line, the point x is the middle of the five points
x1 = c(x[1]:(x[1]+num-1))
x1 = as.double(x1)
y1 = c(x[2]:(x[2]+num-1))
y1 = as.double(y1)
line1 = make_line(x1, y1)
#line2 is a y=-x kind of line, the point x is the middle of the five points
x2 = x1
y2 = c(x[2]:(x[2]-num+1))
line2 = make_line(x2, y2)
#line3 is a horizontal line, the point x is the middle of the five points
x3 = rep(x[1], num)
y3 = y1
line3 = make_line(x3, y3)
#line4 is a vertical line, the point x is the middle of the five points
x4 = x1
y4 = rep(x[2], num)
line4 = make_line(x4, y4)
#save the lines in a list
line = list(line1, line2, line3, line4)
#check if there are five continuous points in the set
get_num = list()
for(i in 1:4){
if_line = sum(is.element(line[[i]], player))
if(if_line == num)
get_num[[i]] = check_blank_hard(num, i, x, player, computer, n)
else {get_num[[i]] = 0}
}
temp = sapply(get_num, length)
two_ava = which(temp == 3)
one_ava = which(temp == 2)
if(length(two_ava) > 0){
get_one = sample(1:length(two_ava),1)
get_list = get_num[[two_ava[get_one]]]
return(get_list)
}
if(length(one_ava) > 0){
get_one = sample(1:length(one_ava),1)
get_list = get_num[[one_ava[get_one]]]
return(get_list)
}
return(0)
}
#######################Backstage function end###########################
#######################plot function####################################
#plot the start menu (choose opponent)
stage0 = function(){
n = 100
x=c(1:n)
y=c(1:n)
taiji = readPNG(system.file("img","taiji.png",package = "LittleGames"))
windowsFonts(JP1 = windowsFont("Pristina"))
bg = readJPEG(system.file("img","wood.jpg",package = "LittleGames"))
colfunc <- colorRampPalette(c("white","goldenrod3", "white","goldenrod3","white"))
par(mar = rep(0, 4)) #No blank space for the main plot and the margin of plot
plot(1:n, type = "n", xlim = c(1, n), axes = FALSE, xlab = "",
ylab = "", bty = "o", lab = c(n, n, 1))
rasterImage(bg,0,0,1+n,1+n)
text(x = seq(32,68, length.out = 6), y=rep(8*n/9,6), col = colfunc(6),
cex = 3.5, label = unlist(strsplit("GOMOKU", NULL)), family = "JP1", lwd = 2.5)
text(x = 50, y = 28, col = "black", label = "BATTLE", family = "JP1", cex =2.5, lwd = 2.5)
text(x = 50, y = 13, col = "white", family = "JP1", cex = 2.5, label = "COMPUTER", lwd = 2.5)
rasterImage(taiji,30, 35, 70, 75)
}
#Plot the level choose menu
stage1 = function(){
taiji = readPNG(system.file("img","taiji.png",package = "LittleGames"))
windowsFonts(JP1 = windowsFont("Pristina"))
bg = readJPEG(system.file("img","wood.jpg",package = "LittleGames"))
colfunc <- colorRampPalette(c("white","goldenrod3", "white","goldenrod3","white"))
colfunc1 = colorRampPalette(c("black","gray90"))
n = 100
x=c(1:n)
y=c(1:n)
par(mar = rep(0, 4)) #No blank space for the main plot and the margin of plot
plot(1:n, type = "n", xlim = c(1, n), axes = FALSE, xlab = "",
ylab = "", bty = "o", lab = c(n, n, 1))
rasterImage(bg,0,0,1+n,1+n)
text(x = seq(25,75, length.out = 10), y=rep(8*n/9,10), col = colfunc(10),
cex = 3.5, label = unlist(strsplit("DIFFICULTY", NULL)), family = "JP1", lwd = 2.5)
text(x = 50, y = 28, label = "EASY", col = "black", family = "JP1", cex = 2.5, lwd = 2.5)
text(x = 50, y = 13, label = "HARD", col = "white", cex=2.5, family = "JP1", lwd = 2.5)
rasterImage(taiji,30, 35, 70, 75)
}
#Plot the color choose menu
stage2 = function(){
taiji = readPNG(system.file("img","taiji.png",package = "LittleGames"))
windowsFonts(JP1 = windowsFont("Pristina"))
bg = readJPEG(system.file("img","wood.jpg",package = "LittleGames"))
colfunc <- colorRampPalette(c("white","goldenrod3", "white","goldenrod3","white"))
colfunc1 = colorRampPalette(c("black","gray90"))
n = 100
x=c(1:n)
y=c(1:n)
par(mar = rep(0, 4)) #No blank space for the main plot and the margin of plot
plot(1:n, type = "n", xlim = c(1, n), axes = FALSE, xlab = "",
ylab = "", bty = "o", lab = c(n, n, 1))
rasterImage(bg,0,0,1+n,1+n)
text(x = seq(25,75, length.out = 8), y=rep(8*n/9,8), col = colfunc(8),
cex = 3.5, label = unlist(strsplit("COMPUTER", NULL)), family = "JP1", lwd = 2.5)
text(x = 50, y = 28, label = "BLACK", col = "black", family = "JP1", cex = 2.5, lwd = 2.5)
text(x = 50, y = 13, label = "WHITE", col = "white", cex=2.5, family = "JP1", lwd = 2.5)
rasterImage(taiji,30, 35, 70, 75)
}
#Plot the game over menu (to play again or to quit)
gameover = function(result, img){
colfunc <- colorRampPalette(c("white","goldenrod3", "white","goldenrod3","white"))
colfunc1 = colorRampPalette(c("black","gray90"))
windowsFonts(JP1 = windowsFont("Pristina"))
bg = readJPEG(system.file("img","wood.jpg",package = "LittleGames"))
n = 100
x=c(1:n)
y=c(1:n)
par(mar = rep(0, 4)) #No blank space for the main plot and the margin of plot
plot(1:n, type = "n", xlim = c(1, n), axes = FALSE, xlab = "",
ylab = "", bty = "o", lab = c(n, n, 1))#add points to the plot where the lines should be located
rasterImage(bg,0,0,1+n,1+n)
text(x = 50, y = 28, label = "PLAY AGAIN", col = "black", family = "JP1", cex = 2.5, lwd = 2.5)
text(x = 50, y = 13, label = "QUIT", col = "white", cex = 2.5, family = "JP1", lwd = 2.5)
rasterImage(img, 30, 35, 70, 75)
if(result == "White Wins!"){text(x = 50, y = 8*n/9, label = toupper(result), cex = 3.5, col = "white", family = "JP1")
}
if(result == "Black Wins!"){text(x = 50, y = 8*n/9, label = toupper(result), cex = 3.5, col = "black", family = "JP1")
}
if(result == "You Win!"){
result = toupper(result)
len = str_count(result)
text(x = seq(25,75, length.out = len), y = rep(8*n/9,len), label = unlist(strsplit(result, NULL)), cex = 3.5, col = colfunc(len), family = "JP1", lwd = 5)
}
if(result == "You Lose!"){
result = toupper(result)
len = str_count(result)
text(x = seq(25,75, length.out = len), y = rep(8*n/9,len), label = unlist(strsplit(result, NULL)), cex = 3.5, col = colfunc1(len), family = "JP1", lwd = 2.5)
}
}
#Plot chessboard
chess_board = function(n){
#Setting of the game
img = readJPEG(system.file("img","wood.jpg",package = "LittleGames"))
par(mar = rep(0, 4)) #No blank space for the main plot and the margin of plot
plot(1:n, type = "n", xlim = c(1, n), axes = FALSE, xlab = "",
ylab = "", bty = "o", lab = c(n, n, 1))#add points to the plot where the lines should be located
rasterImage(img,0,0,1+n,1+n)
segments(1, 1:n, n, 1:n)#draw horizontal lines
segments(1:n, 1, 1:n, n)#draw vertical lines
temp = c(round((n+1)/5),(n+1)/2, round(4*(n+1)/5),round(4*(n+1)/5))
points(rep(temp, 3), rep(temp, each = 3),
pch = 19, cex = 6/sqrt(n))#draw the black point with the shape of solid circle
box() #draw the outline of the plot
}
#############################Plot functions over########################################
############################Begin functions###########################################
#Play with your friend
gomoku_self <- function(n = 19) {
#draw chessboard
chess_board(n)
#Playing the game
playedlist <- NULL #record the points have been stepped on
i <- 1 #rounds that will have be played
black = list() #record the black chessman
white = list() #record the while chessman
repeat {
for (j in 1:2) {
repeat {
options(locatorBell = FALSE)
l = locator(1)
l$x <- min(n, max(1, round(l$x))) #modify the x-location to where nearest point
l$y <- min(n, max(1, round(l$y))) #modify the y-location to where nearest point
xy <- paste(l, collapse = ":") #record the step
if (!is.element(xy, playedlist)) #break when the point had chessman on it
break
}
playedlist <- c(playedlist, xy) #add the step to the playlist if it is successfully played
points(l, cex = 3*19/n, pch = c(19, 21)[j], bg = c("black", "white")[j]) #draw the step (black first)
#black as solid circle, while as filled circle
#check the black chessmen
if(j == 1){
black[[i]] = c(l$x, l$y)#update the black chessmen set
if(if_win(black)){
return("Black Wins!")
}
}
#check the white chessman
if(j == 2){
white[[i]] = c(l$x, l$y)#update the white chessmen set
if(if_win(white)==1){
return("White Wins!")
}
}
if (2*(i) >= n^2) break #break when the chessboard has been filled
}
i = i+1 #enter the next round
if (2*(i-1) >= n^2) break #bread when the chessboard has been filled
}
}
#Play with computer (easy version)
gomoku_computer <- function(n = 19, choose = 1, level) {
#Draw chessboard
chess_board(n)
#Playing the game
l = list()
playedlist <- c("0:0") #record the points have been stepped on
i <- 1 #rounds that will have be played
black = list() #record the black chessman
white = list() #record the while chessman
chess_color = c("black", "white")
player = get(chess_color[choose])
computer = get(chess_color[3-choose])
repeat {
for (j in 1:2) {
if(choose == 1){
#player play
l = player_play(playedlist, n)
xy <- paste(l, collapse = ":")
playedlist <- c(playedlist, xy) #add the step to the playlist if it is successfully played
points(l, cex = 3*19/n, pch = c(19, 21)[choose], bg = c("black", "white")[choose]) #draw the step (black first)
#black as solid circle, while as filled circle
#check if player wins
player[[i]] = c(l$x, l$y)
if(if_win(player)){
return("You Win!")
}
#computer play
if(level == "easy"){new = computer_play(player, computer, playedlist, n)}
if(level == "hard"){new = computer_play_hard(player, computer, playedlist, n)}
new = unlist(new)
l$x = new[1]
l$y = new[2]
xy <- paste(l, collapse = ":")
playedlist <- c(playedlist, xy)
points(l, cex = 3*19/n, pch = c(19, 21)[3-choose], bg = c("black", "white")[3-choose]) #draw the step (black first)
#black as solid circle, while as filled circle
#check if computer wins
computer[[i]] = c(l$x, l$y)#update the black chessmen set
if(if_win(computer)){
return("You Lose!")
}
j = j+2
}
if(choose == 2){
#computer play
if(level == "easy"){new = computer_play(player, computer, playedlist, n)}
if(level == "hard"){new = computer_play_hard(player, computer, playedlist, n)}
new = unlist(new)
l$x = new[1]
l$y = new[2]
xy <- paste(l, collapse = ":")
playedlist <- c(playedlist, xy)
points(l, cex = 3*19/n, pch = c(19, 21)[3-choose], bg = c("black", "white")[3-choose]) #draw the step (black first)
#black as solid circle, while as filled circle
#check if computer wins
computer[[i]] = c(l$x, l$y)#update the black chessmen set
if(if_win(computer)){
return("You Lose!")
}
#player play
l = player_play(playedlist, n)
xy <- paste(l, collapse = ":")
playedlist <- c(playedlist, xy) #add the step to the playlist if it is successfully played
points(l, cex = 3*19/n, pch = c(19, 21)[choose], bg = c("black", "white")[choose]) #draw the step (black first)
#black as solid circle, while as filled circle
#check if player wins
player[[i]] = c(l$x, l$y)
if(if_win(player)){
return("You Win!")
}
j = j+2
}
if (2*(i) >= n^2) break #break when the chessboard has been filled
i = i+1 #enter the next round
if (2*(i-1) >= n^2) break #bread when the chessboard has been filled
}
}
}
###############################Begin functions over#####################################3
gomoku_begin = function(n, r_table){
x11() #open the graphics
click = 0
result = ""
#Choose whom to play wit
stage0()
click = first_choose()
if(click == 1){result = gomoku_self(n)}
if(click == 2){
#Choose color
stage1()
click = second_choose()
if(click == 3){
stage2()
click = third_choose()
if(click == 5){result = gomoku_computer(n, choose = 1, level = "easy")}
if(click == 6){result = gomoku_computer(n, choose = 2, level = "easy")}
}
if(click == 4){
stage2()
click = third_choose()
if(click == 5){result = gomoku_computer(n, choose = 1, level = "hard")}
if(click == 6){result = gomoku_computer(n, choose = 2, level = "hard")}
}
}
if(result == "White Wins!"){
img = readPNG(system.file("img","white_wins.png", package="LittleGames"))
game = "Battle"
}
if(result == "Black Wins!"){
img = readPNG(system.file("img","black_wins.png",package = "LittleGames"))
game = "Battle"
}
if(result == "You Win!"){
img = readPNG(system.file("img","happy_face.png", package = "LittleGames"))
game = "Computer"
}
if(result == "You Lose!"){
img = readPNG(system.file("img","sad_face.png",package = "LittleGames"))
game = "Computer"
}
result_table <<- result_table%>%
rbind(c(as.character(Sys.Date()), as.character(format(Sys.time(), "%X")), game, result))
gameover(result = result, img = img)
repeat{
options(locatorBell = FALSE)
l=locator(1)
x = l$x
y = l$y
if(x>40 & x<60 & y>8 & y<16){return(result_table)}
if(x>32 & x<69 & y>23 & y<31){
dev.off()
return(gomoku_begin(n, result_table))}
}
}
#############################gomoku begin#############################
r_table = gomoku_begin(n, result_table)
if(nrow(r_table) == 1){return("Game Closed, No Record")}
else{
r_table = r_table%>%
filter(Game != "None")
return(r_table)
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.