Попытка отбросить набор, но набор продолжает исчезать - PullRequest
0 голосов
/ 23 июня 2019

Я пытаюсь запрограммировать ИИ для игры Mastermind в рубине, используя алгоритм угадывания Донала Кнута. Игра состоит из создателя кодов, который использует 8 разноцветных колышков для создания набора из 4, и взломщика кодов, который угадывает код и получает обратную связь (красный квадрат для колышка, который является одновременно нужным цветом и в правильном месте). и белый квадрат для колышка правильного цвета, но не в том месте).

Я создал набор для всех возможных кодов. Моя цель - сравнить обратную связь от предположения с обратной связью со всеми кодами в наборе, а затем удалить те, которые не совпадают. Похоже, что удалить весь набор.

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

1 Ответ

0 голосов
/ 24 июня 2019

Попробуйте

copy = something.dup

, потому что только после

copy = something

copy и something указывают на один и тот же объект.Вы можете подтвердить это, проверив object_id объекта, на который ссылается переменная.Если это то же самое, то это тот же объект.

Когда вы dup объект, вы создаете копию.В зависимости от того, что вы хотите dup, вам может потребоваться реализовать / переопределить логику для создания копии.Для встроенных классов, таких как String, Hash и т. Д., Они будут работать «из коробки».

Имейте в виду, что вложенные конструкции (например, хэш, содержащий другие хэши) не дублируются.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...