R语言 如何通过“错误:参数长度为零”

brgchamk  于 2022-12-20  发布在  其他
关注(0)|答案(2)|浏览(1506)

请原谅我的胡言乱语。我最近开始学习R,并一直致力于使井字游戏项目,以提高我的编码技能。
目前,我正在尝试使功能的球员占领一个空的位置,同时确保他们不会覆盖已经占领的位置。
但是,从if语句中,我一直在得到该行下面的错误。
"如果(播放器标记!=" X "&播放器标记!=" O "){:参数长度为零"
下面是井字游戏的完整代码

# This is the board.
environment <- data.frame(c(1, 2, 3), c(4, 5, 6), c(7, 8, 9))
colnames(environment) <- c("[1]", "[2]", "[3]")
row.names(environment) <- c("[1]", "[2]", "[3]")

# This are the victory conditions
win.condition <- list(
  (environment[1, 1] & environment[1, 2] & environment[1, 3]) |
    (environment[2, 1] & environment[2, 2] & environment[2, 3]) |
    (environment[3, 1] & environment[3, 2] & environment[3, 3]) |
    (environment[1, 1] & environment[2, 2] & environment[3, 3]) |
    (environment[3, 1] & environment[2, 2] & environment[1, 3])
)

# This will evaluate if the victory condition is met
check_victor <- function() {
  winner <- NULL
  if (player_shape %in% win.condition) {
    winner <- player
    cat("You won!")
    break
  } else if (computer_shape %in% win.condition) {
    winner <- computer
    cat("You lost!")
    break
  } else {
    winner <- NULL
  }
}

# This is the player's movement
player_movement <- function() {
  # Acquiring where the player wants to move.
  player_select_row <- readline("Choose the row: ")
  player_select_col <- readline("choose the column: ")
  player_mark <- environment[substr(player_select_row, 1, 1), substr(player_select_col, 1, 1)]

  # Checking if the next spot is already marked by player or computer
  if (player_mark != "X" & player_mark != "O") {
    # If the spot isn't taken yet, replace the spot
    environment[player_select_row, player_select_col] <<- player_shape

    # Display the change and let computer make movement
    print(environment)
    check_victor()
    computer_movement()
  } else {
    cat("Illegal movement!")
    player_movement()
  }
}

# This is computer's movement
computer_movement <- function() {
  # This will used later to ensure the computer doesn't make multiple movement at once.
  computer_movement_count <- 0
  # Generate random number to find a spot where to make a movement.
  while (computer_movement_count == 0) {
    computer_row_mark <- sample(1:3, 1)
    computer_col_mark <- sample(1:3, 1)
    computer_mark <- c(computer_row_mark, computer_col_mark)
    # Check if the next mark for computer isn't already occupied yet.
    if (environment[computer_mark] != "X" & environment[computer_mark] != "O") {
      environment[computer_mark] <<- computer_shape
      computer_movement_count <- computer_movement_count + 1
      print(environment)
      check_victor()
      player_movement()
    }
  }
}

# This will change the player's shape depending on who's going first.
firstorsecond <- function() {
  Answer <- readline("Would you like to go first or second? \nType 1 if you like to go first or type 2 if you prefer to go second.")
  if (substr(Answer, 1, 1) == "1") {
    player_shape <<- "X"
    computer_shape <<- "O"
    cat("You're going first")
    cat("\n")
    print(environment)
    player_movement()
  } else if (substr(Answer, 1, 1) == "2") {
    player_shape <<- "O"
    computer_shape <<- "X"
    cat("You're going second")
    cat("\n")
    print(environment)
    computer_movement()
  } else {
    NULL
    cat("Do it again")
    firstorsecond()
  }
}

# Start the game
if (interactive()) firstorsecond()

我在网上搜索了解决方案,发现添加"istrue(x)"可能是这个问题的解决方案。
这是我做的改动。

# This is the player's movement
player_movement <- function() {
  # Acquiring where the player wants to move.
  player_select_row <- readline("Choose the row: ")
  player_select_col <- readline("choose the column: ")
  player_mark <- environment[substr(player_select_row, 1, 1), substr(player_select_col, 1, 1)]

  # Checking if the next spot is already marked by player or computer
  if (is.integer(player_mark) && player_mark != "X" & player_mark != "O" && is.integer(player_mark)) {
    # If the spot isn't taken yet, replace the spot
    environment[player_select_row, player_select_col] <<- player_shape

    # Display the change and let computer make movement
    print(environment)
    check_victor()
    computer_movement()
  } else {
    cat("Illegal movement!")
    player_movement()
  }
}

现在的问题是,无论我在控制台中输入的行号和列号是多少,"player_movement"函数总是将输入值传递给else语句。

Would you like to go first or second? 
Type 1 if you like to go first or type 2 if you prefer to go second.1
You're going first
    [1] [2] [3]
[1]   1   4   7
[2]   2   5   8
[3]   3   6   9
Choose the row: 1
choose the column: 3
Illegal movement!
xjreopfe

xjreopfe1#

readline()返回一个字符串,所以在第一个版本中你尝试使用字符串而不是整数来索引数组,结果是NULL,因此出现了关于零长度参数的错误。
在第二个版本中,if条件在is.integer()处失败,因为is.integer(NULL)FALSE

py49o6xq

py49o6xq2#

我非常肯定有更好的方法来实现它,但是我使用“as.integer”将子字符串转换为整数来解决这个问题。

# This is the player's movement
player_movement <- function() {
  # Acquiring where the player wants to move.
  player_select_row <- readline("Choose the row: ")
  player_select_row_int <- as.integer(substr(player_select_row, 1, 1))
  player_select_col <- readline("choose the column: ")
  player_select_col_int <- as.integer(substr(player_select_col, 1, 1))
  player_mark <- environment[player_select_row_int, player_select_col_int]

  # Checking if the next spot is already marked by player or computer
  if (player_mark != "X" & player_mark != "O") {
    # If the spot isn't taken yet, replace the spot
    environment[player_select_row_int, player_select_col_int] <<- player_shape

    # Display the change and let computer make movement
    print(environment)
    check_victor()
    computer_movement()
  } else {
    cat("Illegal movement!")
    player_movement()
  }
}

相关问题