module AlexCodebreaker class Game include AlexCodebreaker::Modules::ArgumentsValidation attr_reader :secret_code, :session, :win_status def initialize @secret_code = AlexCodebreaker::SecretCodeGenerator.new.secret_code @secret_code_for_hint = @secret_code.clone.uniq @session = Session.new end def hint return unless @session.check_hints hint_processing end def guess(user_input) return unless guess_validation(user_input) && @session.check_attempts comparator(user_input) end private def hint_processing return @secret_code_for_hint.first if @secret_code_for_hint.one? @secret_code_for_hint.delete(@secret_code_for_hint.sample) end def comparator(user_input) user_input = user_input.chars.map!(&:to_i) secret_code_for_comparison = @secret_code.clone user_input = matching_numbers_and_indexes(user_input, secret_code_for_comparison).compact user_input = matching_only_numbers(user_input, secret_code_for_comparison).compact matching_absent(user_input) end def matching_numbers_and_indexes(user_input, secret_code_for_comparison) user_input.map.with_index do |value, index| if value == secret_code_for_comparison[index] secret_code_for_comparison[index] = nil AlexCodebreaker::Modules::Settings::MATCHING[:place] else value end end end def matching_only_numbers(user_input, secret_code_for_comparison) user_input.map do |value| if secret_code_for_comparison.include?(value) secret_code_for_comparison.delete_at(secret_code_for_comparison.index(value)) AlexCodebreaker::Modules::Settings::MATCHING[:presence] elsif value == AlexCodebreaker::Modules::Settings::MATCHING[:place] value end end end def matching_absent(user_input) AlexCodebreaker::Modules::Settings::MATCHING[:place] * user_input.count(AlexCodebreaker::Modules::Settings::MATCHING[:place]) + AlexCodebreaker::Modules::Settings::MATCHING[:presence] * user_input.count(AlexCodebreaker::Modules::Settings::MATCHING[:presence]) + AlexCodebreaker::Modules::Settings::MATCHING[:absent] * (AlexCodebreaker::Modules::Settings::CODE_LENGTH - user_input.length) end end end