我有一些ConnectFour
类,我有一个方法:
def apply_move!(column_number, symbol, row_number = 0)
# Some gravity logic
@board[row_number][column_number] = symbol
end
在适当的地方修改类。
我试着在它周围写一个包装器,返回一个板,不改变原来的,所以函数编程技术可以使用。
我的尝试是:
def apply_move(column_number, symbol)
dummy = ConnectFour.new(@board)
dummy.apply_move!(column_number, symbol)
dummy
end
但是问题是修改dummy
也修改了原来的类本身!如何只修改dummy
和dummy
?
更多代码和上下文
你可能感兴趣的是:
class CpuWinIfPossible < Player
def decide_move(board)
(0...6).find do |move|
board.apply_move(move, self.symbol).is_won?(self.symbol)
end || (0...6).to_a.sample
end
end
在这里,我循环并执行apply_move
到我的棋盘,正如你可以从上面的定义中看到的,apply_move
不应该改变棋盘,但棋盘显示7(+ 1)移动后,这段代码运行:它看起来像这样:
Player X: Where would you like to play (Number from 1 to 7) ?
2
O O
OXOOOO
The winner is O
构造函数
class ConnectFour
attr_accessor :board
def initialize(board)
@board = board
end
我认为这与@board的当前状态有关,如果您将ConnectFour#initialize
更改为以下样子,我认为它应该是工作
def initialize(board)
@board = board.dup
end
如果你正在使用rails,你可以使用deep_dup
def initialize(board)
@board = board.deep_dup
end
解决这个问题的方法是:
def initialize(board)
@board = board.map(&:dup)
end
但是正如@JörgWMittag所指出的,我真的应该让我的代码更加面向对象,以适应Ruby风格,这样就不再需要这种变通方法了。
你可以深拷贝这个类:
new_class = Marshal.load(Marshal.dump(ConnectFour))
,并从那里(dummy = new_class.new(@board)
等)。