复制一个类,这样当我在Ruby中修改新类时,旧类就不会被修改



我有一些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也修改了原来的类本身!如何只修改dummydummy ?

更多代码和上下文

你可能感兴趣的是:

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)等)。

最新更新