Reputation: 35
I'm trying to program the AI for a Mastermind game in ruby using Donal Knuth's 5 guess algorithm. The game consists of a codemaker, who uses 8 different colored pegs to create a set of 4, and a codebreaker, who guesses at the code and receives feedback (a red square for a peg which is both the right color and in the right spot, and a white square for a peg which is the right color but in the wrong spot).
I've created a set for all possible codes. My goal is to compare feedback from the guess to feedback from all codes in the set, then delete the ones that don't match. It seems to delete the entire set though.
class ComputerPlayer < Player
def initialize(game)
super(game)
@all_possible_codes = create_codes
@turn = 1
end
def get_code
Array.new(4){rand(1..6)}
end
def get_guess
puts @all_possible_codes.length
if @turn == 0
@turn += 1
cull_set([1, 1, 2, 2])
@all_possible_codes.delete("1122")
return [1, 1, 2, 2]
else
random_sample = @all_possible_codes.to_a.sample.split('').map{|str| str.to_i}
@all_possible_codes.delete(random_sample.join(''))
cull_set(random_sample)
random_sample
end
end
def cull_set(guess)
feedback = @game.feedback_on_guess(guess)
puts feedback
@all_possible_codes.delete_if { |str| @game.feedback_on_guess(str.split.map{|num| num.to_i}) != feedback }
end
def create_codes
set = Set.new
(1..8).each do |i|
(1..8).each do |j|
(1..8).each do |k|
(1..8).each do |l|
set << [i, j, k, l].join('')
end
end
end
end
set
end
end
#this is the feedback_on_guess method used by the above class
def feedback_on_guess(code_guess)
code_duplicate = @code
feedback = []
code_duplicate.map.with_index do |entry, i|
if entry == code_guess[i]
feedback.push('r')
code_guess[i] = -1
-2
else
entry
end
end.each do |entry|
found_index = code_guess.find_index(entry)
if found_index
feedback.push('g')
code_guess[found_index] = -1
end
end
puts feedback
feedback
end
Upvotes: 0
Views: 53
Reputation: 8646
Try
copy = something.dup
because after just
copy = something
copy
and something
are pointing to the same object. You can confirm this by checking the object_id
of the object referenced by the variable. If it is the same, then it is the same object.
When you dup
an object, you will cretae a copy. Depending on what you want to dup
you might need to implement/override the logic to create a copy. For built in Classes like String
, Hash
and so on it will work out of the box.
Be aware that nested constructs (eq. Hash containing other Hashes) are not duplicated.
h1 = {"a" => {"b" => 2}}
h2 = h1.dup
puts h1.object_id # 70199597610060
puts h2.object_id # 70199597627020
puts h1["a"].object_id # 70199597610080
puts h2["a"].object_id # 70199597610080
Upvotes: 1