module Codebreaker include Validation class Game include Constants attr_reader :name, :difficult, :secret, :attempts, :hints def initialize(name, difficult) @name = name @difficult = difficult @attempts = get_attempts(difficult) @hints = get_hints(difficult) generate_secret @secret_chars = @secret.chars.shuffle end def decrement_attempts return false if @attempts.zero? @attempts -= 1 end def use_hint return false if @hints.zero? @hints -= 1 @secret_chars.pop end def win?(matches) matches == WIN_RESULT end def used_attempts get_attempts(@difficult) - @attempts end def used_hints get_hints(@difficult) - @hints end def check_number(guess, secret_code = @secret) secret = secret_code.chars input = guess.chars grouped = group_arrays(secret, input) plus = grouped[true].size return result(plus) if plus == 4 minus = get_minuses_count(grouped) result(plus, minus) end private def result(plus, minus = 0) PLUS * plus << MINUS * minus end def get_minuses_count(grouped) secret, input = grouped[false].transpose (secret & input).inject(0) do |count, number| count + [secret.count(number), input.count(number)].min end end def group_arrays(secret, input) grouped = secret .zip(input) .group_by { |values| values.first == values.last } grouped.default = [] grouped end def generate_secret @secret = (1..4).map { rand(1..6) }.join end def get_attempts(level) DIFFICULTS[level.to_sym][:attempts] end def get_hints(level) DIFFICULTS[level.to_sym][:hints] end end end