当前位置:网站首页>Make a small game with R language and only basic package

Make a small game with R language and only basic package

2022-06-11 06:14:00 Infinity343

The rules of the game

  • Any number of players can join ( contain 1), Multiple pairs of interlinked cards are randomly arranged in a grid , Face down . Each player chooses two cards in turn , And put it face up , This is considered a move . If the faces are equal , The player wins the pair of cards , Do it again . If two cards are different , Then face down again , It's the next player's turn . When the last pair is picked up , Game over . The player with the most pairs wins . It is possible to be tied for the first place .

In fact, this is the memory card game we used to play more or less , Logically speaking, it is not complicated , We can only use R Language and basic package , That would be a little difficult

Problem analysis

We can split the rules of the game , Separate different logical parts into functions , Call them in the body of the main function , This can reduce the amount of code and increase the readability of the code .
This game obviously contains the following logic :

  • Number of players 、 The size of the venue directly determines the direction of the game
  • Who starts first is random , The next turn is random , Then you must avoid using for loop , Because we can't cycle through all the possible matches in sequence
  • Winning or losing includes a draw , But there are also cases of absolute victory , such as 8 " , The player 1 Already obtained 5 branch , Or is it 4:3 when , There is only a pair of cards left in the venue , The player 1 Victory is still inevitable . Then there is no need to write complicated rules of victory , Score directly
  • Don't assume that players are rational , In other words, he may enter the wrong logo or the card with repeated scores , To avoid program crash, it is necessary to detect each input , That means we need to use while loop
  • It is necessary to display and record the scores of players
  • Remove the cards that have scored
  • Give clear game tips

Write game logic ( With 2 Players ,16 Take cards for example )

  • load package
library(stats, graphics, grDevices) 
library(utils)
library(datasets, methods, base)
options(repr.plot.width = 5, repr.plot.height = 5)  # Set the drawing square 
op <- par(bg = "white") # The background is white 
  • Limit player input specifications
    Limit the horizontal and vertical coordinates to (1,4) Inside
check <- function(cells_possible) {
    
  cell_valid <- FALSE
  while (!cell_valid) {
    
    cell <- scan(what = integer(0) , nmax = 1, quiet = TRUE)
    # Check validity of input
    if (!(cell %in% cells_possible)) {
    
      cat("Cell not valid. Again:")
    } else{
    
      cell_valid <- TRUE
    }
  }
  return(cell)
}
  • Restrict players from entering cards that have scored
check_rep <- function(v, df){
    
  while (FALSE %in% is.na(df[which(df$first==v[1] & df$second==v[2]), ][1,])){
    
    print('Card not valid, Again')
    v = scan(what=integer(0), nmax=2, quiet = TRUE)
    return(v)
  }
  return(v)
}
  • Write body functions
    n_row and n_col Determines the size of the playing field ,pch For the design and color of the card , col For the color of the card ,n_player For player data . Are customized by players
memory <- function(n_row = 1, n_col = 3, 
                   pch=1:13, col = 1:8, 
                   n_player = 2){
    }
  • Draw the site
    Once the main function is called, the game begins , So first draw the playing field
  x = 0.5:4.5 # Drawing board x coordinate 
  y = 0.5:4.5 # Drawing board y coordinate 
  plot(x,y, type='n', xlab="", ylab="", main="Memory",
       xlim = c(0.5, 4.3), ylim = c(0.5, 4.3), xaxt = "n", yaxt = "n") # Draw the playing field 
  grid(4, 4, lwd = 2) #  At the same time x,y Add direction to grid 
  axis(1, 1:4, las=0, tck=0) # Change the representation of the coordinate axis (x)
  axis(2, 1:4, las=0, tck=0) # Change the representation of the coordinate axis (y)

 Insert picture description here

With 4*4 For example , Decor default 13 Kind of , Color default 8 Kind of
  • Preloading and rules
    Make some global rules in advance , In case the program breaks down in the middle
if (n%%2==1){
    
    stop("n_row * n_col must be an even number.\n")
  }
  if (length(pch) * length(col) < n/2){
    
    stop("Not enough different \
         possible cared(combinations of pch and col\
         )were specified for the given 
         size of the playing field.")
  }
  
  p = length(pch) # Number of decors 
  c = length(col) # The number of colors 
  set.seed(1234)
  rows <- sample((1:(p*c)), size=n/2, replace=FALSE) # From all combinations (p*c) Mid extraction n/2 Zhang card The abscissa of 
  set.seed(1234)
  copy_rows <- sample(1:8, size=8, replace=FALSE) # in addition n/2 individual card The abscissa of ,  It is equivalent to disrupting rows Result 
  coor <- data.frame(xc=rep(c(1:4), each=4), yc=rep(c(1:4), each=1)) # extract card In the field x,y coordinate 
  cards <- data.frame(face=rep(c(1:p), c), color=rep(c(1:c), each=p))  # Generate card The decors and colors of 
  cards_n <- cards[rows, ] # according to rows The results of n/2 Zhang card
  copy <- cards_n[copy_rows,] # according to copy_rows The results of the other n/2 Zhang card
  cards_n <- rbind(cards_n, copy) # Put two parts card Merge into n Cards 
  rownames(cards_n) <- 1:nrow(cards_n) # Because it is randomly selected ,  So reset the index 
  cards_n$xc <- coor$xc # take x Add the coordinates to the card deck 
  cards_n$yc <- coor$yc # take y Add the coordinates to the card deck 
  
  cex = 1.5 # Null card image size 
  pair = n_row * n_col / 2 # The logarithm of the card 
  score1 = 0 #1 Player No. scored 
  score2 = 0 #2 Player No. scored 
  x_scan1 <- c(1:2) # Generate an initial coordinate , It will be overwritten when the player enters 
  x_scan2 <- c(1:2) # ditto 
  df = data.frame(first=0, second=0) # An empty data frame , Used to store cards that have scored 

Because every time who loses and who wins is random , Obviously not for+ if The cycle of , Because there are too many cases of scoring and not scoring each time , The code volume has exploded . The solution is to define variables pair To determine how many pairs of non scoring cards are left to choose from . p a i r < 1 \rm{pair}<1 pair<1 It means that all the card groups have scored , Obviously this is a while loop . Now? , The general idea of the game is : Establish a site → \to Make rules → \to Scan player input and start cycle → \to Logical judgment of win / loss and some auxiliary outputs → \to At the end of the game, judge the winner → \to initialization . On the whole , The framework of the code is

while (pair) >1{
    
	if (no==1){
    } # The player 1 If you start first, execute 
	else{
    }  # The player 2 If you start first, execute 
if (score1 > score2){
    } #1 win victory 
if (score1 == score2){
    } # It ends in a draw 
if (score1 < score2){
    } #2 win victory 
}

When the player selected at random is 1 when , Get into if body ,2 When entering else body , Each circulates its own , Mutual interference

  • The game goes on
    Because now there are only two players , So the player number is either one or two , So write directly if and else Contents of Li
if (no==1){
    
    # The first 1 Player number 1 card 
    cat(paste('Player', no, 'choose your first card (1: row, 2: colunm)!')) # Prompt players to choose cards 
    
    x_scan1[1] <- check(c(1:4))
    x_scan1[2] <- check(c(1:4))# Players choose cards ( Two at most ) Coordinates of  [1]: Abscissa  [2]: Ordinate   Determine whether the input is correct 
    x_scan1 <- check_rep(x_scan1, df) # Check if this card scores 
    
    face1_1 = cards_n[which(cards_n$xc==x_scan1[1] & cards_n$yc==x_scan1[2]), 'face'] # Query the corresponding designs and colors according to the coordinate conditions 
    color1_1 = cards_n[which(cards_n$xc==x_scan1[1] & cards_n$yc==x_scan1[2]), 'color']# Query the corresponding color according to the coordinate conditions 
    
    points(x_scan1[1], x_scan1[2], pch=face1_1, col=color1_1, cex=cex) # Draw the cards turned out by the player 
    
    # The first 1 Player number 2 card 
    cat(paste('Player', no, 'choose your second card (1: row, 2: colunm)!')) # Prompt players to choose cards 
    x_scan2[1] <- check(c(1:4))
    x_scan2[2] <- check(c(1:4))  #scan Method get Players choose cards ( Two at most ) Coordinates of  [1]: Abscissa  [2]: Ordinate 
    x_scan2 <- check_rep(x_scan2, df)
    
    face1_2 = cards_n[which(cards_n$xc==x_scan2[1] & cards_n$yc==x_scan2[2]), 'face'] # Query the corresponding designs and colors according to the coordinate conditions 
    color1_2 = cards_n[which(cards_n$xc==x_scan2[1] & cards_n$yc==x_scan2[2]), 'color']# Query the corresponding color according to the coordinate conditions 
    
    points(x_scan2[1], x_scan2[2], pch=face1_2, col=color1_2, cex=cex) # Draw the cards turned out by the player 
    
    if (face1_1 ==  face1_2 & color1_1 == color1_2){
      # Judge whether the two cards are the same 
      while (face1_1 == face1_2 & color1_1 == color1_2 & pair > 1) {
      # If it is the same, draw cards until it is different 
        pair = pair - 1 # obviously while The body is full of scoring cards , So logarithms have to be -1
        score1 = score1 + 1 # The same score should be +1
        df <- rbind(df, x_scan1, x_scan2) # The scored cards should be added to the waste pile for double checking 
        cat(paste('Correct Player', no, 'plays again! Current leaderboard:\n'))  # Tell the player to win ,  Continue to flop 
        no2 = 2 # This is player number two 
        cat(paste(' Player', no,     ' Player', no2, '\n'))
        cat(paste(' ', score1, ' ', score2, '\n'))
        cat(paste('Press [y] when you are ready to move on!'))  # Print their score 
        yes_no = scan(what = 'character', nmax = 1, quiet = TRUE)
        
        points(x_scan1[1], x_scan1[2], pch=face1_1, col='white', cex=cex) # The cards that have scored will become the serial number of the player, so that it can identify who scored in what position 
        points(x_scan2[1], x_scan2[2], pch=face1_2, col='white', cex=cex)
        text(x_scan1[1], x_scan1[2], label=no, cex=2)# The cards that have scored will become the serial number of the player, so that it can identify who scored in what position 
        text(x_scan2[1], x_scan2[2], label=no, cex=2)
        
        if (yes_no == 'y'){
      # We want to give players time to remember and think , Wait for the player to input y Then continue to execute 
          cat(paste('Player', no, 'choose your first card (1: row, 2: colunm)!')) # Prompt players to choose cards 
          x_scan1[1] <- check(c(1:4))
          x_scan1[2] <- check(c(1:4))  #scan Method get Players choose cards ( Two at most ) Coordinates of  [1]: Abscissa  [2]: Ordinate 
          x_scan1 <- check_rep(x_scan1, df)
          
          face1_1 = cards_n[which(cards_n$xc==x_scan1[1] & cards_n$yc==x_scan1[2]), 'face'] # Query the corresponding designs and colors according to the coordinate conditions 
          color1_1 = cards_n[which(cards_n$xc==x_scan1[1] & cards_n$yc==x_scan1[2]), 'color']# Query the corresponding color according to the coordinate conditions 
          points(x_scan1[1], x_scan1[2], pch=face1_1, col=color1_1, cex=cex) # Draw the cards turned out by the player 
         
           cat(paste('Player', no, 'choose your second card (1: row, 2: colunm)!')) # Prompt players to choose cards 
          x_scan2[1] <- check(c(1:4))
          x_scan2[2] <- check(c(1:4))  #scan Method get Players choose cards ( Two at most ) Coordinates of  [1]: Abscissa  [2]: Ordinate 
          x_scan2 <- check_rep(x_scan2, df)
          
          face1_2 = cards_n[which(cards_n$xc==x_scan2[1] & cards_n$yc==x_scan2[2]), 'face'] # Query the corresponding designs and colors according to the coordinate conditions 
          color1_2 = cards_n[which(cards_n$xc==x_scan2[1] & cards_n$yc==x_scan2[2]), 'color']# Query the corresponding color according to the coordinate conditions 
          points(x_scan2[1], x_scan2[2], pch=face1_2, col=color1_2, cex=cex) # Draw the cards turned out by the player 


        }
      }
    }
     no = 2 # This means that you have jumped out while 了 , Indicates that either the player 1 Win all , To the player 1 At least one failure ,  that 2 No. 1 player becomes the new 1 Player number one 
    if (pair==1){
    next} 
    else{
      # Because the cards selected by the player do not match , Both sides need to be given time to remember and think 
    cat(paste('Wrong, Player', no, 'plays! Press [y], when you are ready to move on!\n'))
    yes_no = scan(what = 'character', nmax = 1, quiet = TRUE)}
    if (yes_no == 'y'){
    
      points(x_scan1[1], x_scan1[2], pch=face1_1, col='white', cex=cex) # Hide the cards again 
      points(x_scan2[1], x_scan2[2], pch=face1_2, col='white', cex=cex) # Hide the cards again 
      next
      }
    }

  • The other person's logic is basically the same
   else{
    
    # The first 2 Player number 1 card 
    cat(paste('Player', no, 'choose your first card (1: row, 2: colunm)!')) # Prompt players to choose cards 
    x_scan1[1] <- check(c(1:4))
    x_scan1[2] <- check(c(1:4))  #scan Method get Players choose cards ( Two at most ) Coordinates of  [1]: Abscissa  [2]: Ordinate 
    x_scan1 <- check_rep(x_scan1, df)
    face1_1 = cards_n[which(cards_n$xc==x_scan1[1] & cards_n$yc==x_scan1[2]),'face'] # Query the corresponding designs and colors according to the coordinate conditions 
    color1_1 = cards_n[which(cards_n$xc==x_scan1[1] & cards_n$yc==x_scan1[2]),'color']# Query the corresponding color according to the coordinate conditions 
    points(x_scan1[1], x_scan1[2], pch=face1_1, col=color1_1, cex=cex) # Draw the cards turned out by the player 
    # The first 2 Player number 2 card 
    cat(paste('Player', no, 'choose your second card (1: row, 2: colunm)!')) # Prompt players to choose cards 
    x_scan2[1] <- check(c(1:4))
    x_scan2[2] <- check(c(1:4)) #scan Method get Players choose cards ( Two at most ) Coordinates of  [1]: Abscissa  [2]: Ordinate 
    x_scan2 <- check_rep(x_scan2, df)
    
    face1_2 = cards_n[which(cards_n$xc==x_scan2[1] & cards_n$yc==x_scan2[2]),'face'] # Query the corresponding designs and colors according to the coordinate conditions 
    color1_2 = cards_n[which(cards_n$xc==x_scan2[1] & cards_n$yc==x_scan2[2]),'color']# Query the corresponding color according to the coordinate conditions 
    points(x_scan2[1], x_scan2[2], pch=face1_2, col=color1_2, cex=cex) # Draw the cards turned out by the player 
    if (face1_1 ==  face1_2 & color1_1 == color1_2){
      # Judge whether the two cards are the same 
      while (face1_1 == face1_2 & color1_1 == color1_2 & pair > 1) {
    
        pair = pair - 1
        score2 = score2 + 1
        df <- rbind(df, x_scan1, x_scan2)
        cat(paste('Correct Player', no, 'plays again! Current leaderboard:\n'))  # If you win ,  Continue to flop 
        no2 = 1
        cat(paste(' Player', no2,    ' Player', no, '\n'))
        cat(paste(' ', score1, ' ', score2, '\n'))
        cat(paste('Press [y] when you are ready to move on!'))
        yes_no = scan(what = 'character', nmax = 1, quiet = TRUE)
        
        points(x_scan1[1], x_scan1[2], pch=face1_1, col='white', cex=cex)
        points(x_scan2[1], x_scan2[2], pch=face1_2, col='white', cex=cex)
        text(x_scan1[1], x_scan1[2], label=no, cex=2)
        text(x_scan2[1], x_scan2[2], label=no, cex=2)
        
        if (yes_no == 'y'){
     
          cat(paste('Player', no, 'choose your first card (1: row, 2: colunm)!')) # Prompt players to choose cards 
          x_scan1[1] <- check(c(1:4))
          x_scan1[2] <- check(c(1:4))  #scan Method get Players choose cards ( Two at most ) Coordinates of  [1]: Abscissa  [2]: Ordinate 
          x_scan1 <- check_rep(x_scan1, df)
          
          face1_1 = cards_n[which(cards_n$xc==x_scan1[1] & cards_n$yc==x_scan1[2]), 'face'] # Query the corresponding designs and colors according to the coordinate conditions 
          color1_1 = cards_n[which(cards_n$xc==x_scan1[1] & cards_n$yc==x_scan1[2]), 'color']# Query the corresponding color according to the coordinate conditions 
          points(x_scan1[1], x_scan1[2], pch=face1_1, col=color1_1, cex=cex) # Draw the cards turned out by the player 
          
          cat(paste('Player', no, 'choose your second card (1: row, 2: colunm)!')) # Prompt players to choose cards 
          
          x_scan2[1] <- check(c(1:4))
          x_scan2[2] <- check(c(1:4))  #scan Method get Players choose cards ( Two at most ) Coordinates of  [1]: Abscissa  [2]: Ordinate 
          x_scan2 <- check_rep(x_scan2, df)
          face1_2 = cards_n[which(cards_n$xc==x_scan2[1] & cards_n$yc==x_scan2[2]),'face'] # Query the corresponding designs and colors according to the coordinate conditions 
          color1_2 = cards_n[which(cards_n$xc==x_scan2[1] & cards_n$yc==x_scan2[2]),'color']# Query the corresponding color according to the coordinate conditions 
          points(x_scan2[1], x_scan2[2], pch=face1_2, col=color1_2, cex=cex) # Draw the cards turned out by the player 

        }
      }
    }
    no = 1
    if (pair==1){
    next}
    else{
    
    cat(paste('Wrong, Player', no, 'plays! Press [y], when you are ready to move on!\n'))
    yes_no = scan(what = 'character', nmax = 1, quiet = TRUE)}
    if (yes_no == 'y'){
    
      points(x_scan1[1], x_scan1[2], pch=face1_1, col='white', cex=cex)
      points(x_scan2[1], x_scan2[2], pch=face1_2, col='white', cex=cex)
      next
      }
    }
  }

Compare the scores after the game

  if (score1 > score2){
    
    cat(paste('Correct, plays 1 wins! Final leaderboard:\n'))
    cat(paste(' Player 1 Player 2 \n'))
    cat(paste(' ', score1, ' ', score2, '\n'))
  }
  if (score1 == score2){
    
    cat(paste('Correct, plays 1 and Player2 are tied wins! Final leaderboard:\n'))
    cat(paste(' Player 1 Player 2 \n'))
    cat(paste(' ', score1, ' ', score2, '\n'))
  }
  if(score1 < score2){
    
    cat(paste('Correct, plays 2 wins! Final leaderboard:\n'))
    cat(paste(' Player 2 Player 1 \n'))
    cat(paste(' ', score2, ' ', score1, '\n'))
  }

Assemble these modules and test run them

 Insert picture description here

Screenshot of the game in progress

 Insert picture description here

Screenshot of the game in progress

 Insert picture description here

Screenshot after the game

Above we have realized such a simple game , Although the form of the game is simple , But the programming content involved is not simple , Including the requirement of reasonable judgment cycle , The combination of drawing and logical expression , Human computer interaction control program operation, etc .

原网站

版权声明
本文为[Infinity343]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/162/202206110603135669.html