不久前,我做了 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
正如评论者所指出的,您当前的问题是您使用一维数组作为您的棋盘。这意味着如果您拨打
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
。