我将棋盘游戏编程为Ruby OOP学习练习的一部分。我试图创建一个游戏板,其中包含三排三排的九个空间。以下是当前无效代码的片段:
class Board
def initialize()
#dynamically creates instances of the Space class named @s1 through @s9 with #s 1-9 as the location parameter
9.times do |x|
x += 1
y = "@s" + x.to_s
instance_variable_set( y , x.to_s) = Space.new
end
end
def print_board
#prints a 3X3 grid containing each instance's location parameter
puts "\n\n#{@s1.location}|#{@s2.location}|#{@s3.location}\n-----\n#{@s4.location}|#{@s5.location}|#{@s6.location}\n-----\n#{@s7.location}|#{@s8.location}|#{@s9.location}\n\n\n"
end
end
class Space
attr_accessor :location
def initialize(location)
@location = location
end
end
board = Board.new
board.print_board
所需的输出是:
X|X|X
-----
X|X|X
-----
X|X|X
...但我一直收到与创建Space类实例有关的错误。我尝试了很多不同的事情,我无法记住它们。我知道必须有这样的方法来做到这一点,但我是Ruby的新手,而且让我难过。我知道可以创建9个单独的Space类实例,但这看起来既便宜又脏。
答案 0 :(得分:0)
这是一个稍微重新编写的,更具Ruby风格的版本:
class Board
def initialize
@board = Array.new(9) do
Space.new
end
end
def move(x,y,set)
@board[(x - 1) + (y - 1) * 3].location = set
end
def to_s
@board.each_slice(3).collect do |row|
row.join('|')
end.join("\n------\n") + "\n"
end
end
class Space
attr_accessor :location
def initialize(location = nil)
@location = location || ' '
end
def to_s
@location
end
end
board = Board.new
puts board.to_s
board.move(1,2,'x')
puts board.to_s
值得注意的是一些技巧:
Array.new
会考虑预先填充的条目数。each_slice
抽出一组 N 条目进行处理。collect
将每一行转换为一个简单的字符串。join
将行与水平线组合在一起。to_s
是“show as string”的默认名称,除非另有说法,否则应该使用它。Space
初始化程序nil
initializer
优于initializer()
。通过使用代表单元格的 9个变量,您使用instance_variable_set
进行的方法更难维护并违反Zero, One or Infinity Rule。你需要的是一个理论上无限大小的变量,只有你必要时施加的约束才会受到限制。拥有多个变量会使迭代变得更加困难,使得作为参数传递变得不方便,并且通常会使应该简单的事情变得混乱。