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

时间:2015-01-21 20:39:20

标签: ruby translate

不久前我做了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 Collumn (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

1 个答案:

答案 0 :(得分:2)

正如评论者指出的那样,您当前的问题是您使用的是一维数组作为您的电路板。这意味着,如果您致电board[guess_row][guess_col],您将获得nil

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

您应该首先更改定义board的方式,以便它实际上是一个多维数组,或者使'row'字符串具有您期望的字符数。

由于您要求提供进一步的提示,因此需要考虑以下事项:

Fencepost错误: Ruby中的数组(和字符串)是零索引的。假设您的电路板是十元素阵列,则行为board[0]board[9]。代码中有很多地方可以将它们称为board[1]board[10],这会让你感到沮丧。例如,当您选择“Battleship”所在的随机值时,您使用rand(1..10),当您可能需要的是rand(10)时,它会返回一个随机整数(稍微违反直觉)0到9在具有十个元素(索引为0到9)的数组上调用a[10]不会产生异常,它只是(你猜对了)nil

对象参考:您可能会像这样定义电路板:Array.new(10, Array.new(10,'O'))。如果你这样做,你会遇到一个有趣的问题......将一个元素设置为'X'也会设置该列中的每个元素。 Ruby首先定义'内部'数组,然后将板的每个元素设置为相同的数组。我几乎没有提到这一点,因为这是一次宝贵的学习经历,但我想我会决定如何避免这种情况作为读者的练习。

最后,一些随机的风格提示:Rubyists通常使用.each而不是for。如果您的提示使用print而不是puts,则不会插入换行符。 Ruby不需要显式return语句 - 它将返回方法最后一行的值。尝试将整个程序设为方法,可以命名为play