用 Ruby 制作一个简单的战舰游戏

问题描述 投票:0回答:1

不久前,我做了 Codecademy - Python 赛道并制作了一个简单的战舰游戏。我现在一直在学习 Ruby,想尝试将游戏从 Python 转换为 Ruby。到目前为止,我的翻译做得很好,但是,我在这一点上陷入困境,试图在玩家已经猜到的棋盘上打印一个“X”。我尝试过不同的方法,但到目前为止还没有达到我的目标。

我在转换时遇到问题的特定行是:

board[guess_row][guess_col] = "X"

这是完整的游戏代码(我知道其他部分仍然需要更改,但已经有条不紊地进行了,到目前为止这是我的停止点,任何进一步的提示也非常感谢!)。

编辑:感谢您提供的信息,在您的帮助下,我能够按照想象的那样启动并运行它!现在我只需要弄清楚如何在其中添加退出方法..

def play_battleship
  
  board = Array.new(10) { Array.new(10, "O") }

  def print_board(board)
    board.each do |r|
      puts r.map { |p| p }.join(" ")
    end
  end


  puts "Let's play Battleship!\n-----\nYou have 10 tries!\n-----"
  print_board(board)
  def random_row(board)
      return rand(10)  
  end

  def random_col(board)
      return rand(10)  
  end

  ship_row = random_row(board)
  ship_col = random_col(board)
  #puts ship_row ##debugging purposes
  #puts ship_col ## ^^^^


  for turn in 1..10
    puts "Turn: #{turn}"
    puts "Guess Row (0-9): "
    guess_row = gets.chomp.to_i  
    puts "Guess Column (0-9): "
    guess_col = gets.chomp.to_i
    if turn == 10
        puts "------\nGame Over!\nThe Battleship coordinates were:#{ship_row},#{ship_col}"
        break
    elsif (guess_row == ship_row) && (guess_col == ship_col)
        puts "Congratulations! You sunk my battleship!"
        break
    else
        if ((guess_row < 0) || (guess_row > 9)) || ((guess_col < 0) || (guess_col > 9))
            puts "Oops, that's not even in the ocean."
        elsif(board[guess_row][guess_col] == "X")
            puts "You guessed that one already."
        else
            puts "You missed my battleship!"
            board[guess_row][guess_col] = "X"
              #if turn == 10
                #  puts "Game Over\nThe Battleship coordinates were:#{ship_row},#{ship_col}"
               #   break
              #end
        end
    end
    print_board(board)
  end
end
play_battleship
ruby translate
1个回答
3
投票

正如评论者所指出的,您当前的问题是您使用一维数组作为您的棋盘。这意味着如果您拨打

board[guess_row][guess_col]
,您将得到
nil

为什么

nil
?因为
board[guess_row]
只是字符串“O”。
'O'[guess_col]
仍然是有效的代码 - 它要求字符串索引
guess_col
处的字符 - 但字符串只有一个字符长,因此任何大于 0 的索引都会得到
nil

您应该首先更改定义

board
的方式,以便它实际上是一个多维数组,或者使“行”字符串具有您期望的字符数。

既然您要求进一步的提示,这里有一些需要考虑的事情:

Fencepost 错误: Ruby 中的数组(和字符串)是零索引的。假设您的棋盘是一个十元素数组,则行为

board[0]
board[9]
。代码中有很多地方您将它们称为
board[1]
board[10]
,这会让您绊倒。例如,当您选择“战舰”所在的随机值时,您可以使用
rand(1..10)
,而您可能想要的是
rand(10)
,它会返回从(有点违反直觉)0 到 9 的随机整数。调用
a[10] 
在具有 10 个元素(索引从 0 到 9)的数组上不会产生异常,它只是(你猜对了)
nil

对象参考:您可能会想像这样定义板:

Array.new(10, Array.new(10,'O'))
。如果这样做,您会遇到一个有趣的问题...将一个元素设置为“X”也会设置该列中的每个元素。 Ruby 首先定义“内部”数组,然后将棋盘的每个元素设置为同一个数组。我几乎没有提到这一点,因为这是一次宝贵的学习经历,但我想我会决定把弄清楚如何避免这种情况作为读者的练习。

最后,一些随机的风格提示:Rubyists 通常使用

.each
而不是
for
。如果您使用
print
而不是
puts
作为提示,则不会插入换行符。 Ruby 不需要显式的
return
语句 - 它会返回方法最后一行的值。尝试将整个程序变成一个方法,也许命名为
play

© www.soinside.com 2019 - 2024. All rights reserved.