我有 2 个类:游戏类和玩家类。这是一款井字棋游戏。
class Game
attr_accessor :player_1, :player_2, :numbers, :board
def initialize(player_1, player_2)
@player_1 = player_1
@player_2 = player_2
@numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
end
end
class Player
attr_reader :name
attr_accessor :selection
def initialize(name)
@name = name
@selection = []
end
def play(game)
print "#{name}, please pick a number: "
number = gets.chomp.to_i
print "#{name} selected #{number}"
puts
selection << number
index = game.numbers.find_index(number)
if (name == 'player_1')
game.numbers[index] = 'X'
else
game.numbers[index] = 'O'
end
end
end
初始化代码
Player
和Game
:
p1 = Player.new('player_1')
p2 = Player.new('player_2')
game = Game.new(p1, p2)
我设置播放器的方式是,每当玩家选择一个数字(例如:使用
p1.play(game)
)时,该数字将存储在 selection
的 Player
中,并且 numbers
中的 Game
将更新为“ x”/“o”。
完成上述步骤后,我将
:player_1
中的 :player_2
和 Game
更新为:
game.player_1 = p1
& game.player_2 = p2
打印出
game.player_1.selection
,结果就是预期的。然而,我错误地跳过了一次game.player_1 = p1
和game.player_2 = p2
并再次打印了game.player_1.selection
。令我惊讶的是,无论我执行 game.player_1 = p1
& game.player_2 = p2
,两种方式的结果都是相同的。
作为 OOP 世界的新手,我想得到澄清;对于我的情况,更新
player_1
/ player_2
的正确方法是什么?谢谢。
变量用于引用对象。您可以通过
=
将对象分配给变量来设置对象,例如:
a = "hello"
您现在可以通过
"hello"
参考 a
,例如
a << " world"
a #=> "hello world"
由于这种用法,您可能会认为您修改了
a
。但这并不完全正确。您实际上修改了a
所指的对象,即字符串"hello"
,然后变成了"hello world"
。
当您将一个对象分配给多个变量时,这种区别很重要,例如:
a = "hello"
b = a
a << " world"
a #=> "hello world"
b #=> "hello world"
b = a
将使 b
引用与 a
所引用的同一个对象。我认为它是:
variable object
a ───────┐
"hello"
b ───────┘
当调用
a << "hello"
时,对象被修改,即:
variable object
a ───────┐
"hello world"
b ───────┘
事后检查
a
和 b
仅显示该修改。
对于我的情况,更新
/player_1
的正确方法是什么?player_2
你不必这样做。在您的代码中,
p1
和 game.player_1
已经引用同一个对象,即 Player
的实例。因此,您只需更新该播放器实例即可。
设置
game.player_1 = p1
实际上是多余的,因为game.player_1
已经引用了p1
。您只是重新分配了同一个对象。