Game と Player の 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
プレーヤーとゲームを初期化するコード:
p1 = Player.new('player_1')
p2 = Player.new('player_2')
game = Game.new(p1, p2)
プレーヤーが番号を選択するたびに (例: p1.play(game) を使用)、その番号がプレーヤーの選択範囲に保存され、ゲーム内の番号が「x」/「o」で更新されるようにプレーヤーをセットアップします。 。
上記の手順が完了したら、Game の :player_1 と :player_2 を次のように更新します。
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"
これで、a を介して「hello」を参照できるようになります。
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 ───────┘
<< ” world” を呼び出すと、オブジェクトが変更されます。つまり、次のようになります。
variable object
a ───────┐
"hello world"
b ───────┘
その後 a と b を検査すると、その変更が示されるだけです。
その必要はありません。コードでは、p1 と game.player_1 はすでに同じオブジェクト、つまり Player のインスタンスを参照しています。したがって、プレーヤー インスタンスを更新するだけで済みます。
game.player_1 = p1 の設定は、game.player_1 がすでに p1 を参照しているため、実際には不要です。まったく同じオブジェクトを再割り当てしているだけです。