class Game include ArgumentsValidation attr_reader :session def start @secret_code = Array.new(Settings::CODE_LENGTH) { rand(Settings::CODE_MIN_DIGIT..Settings::CODE_MAX_DIGIT) } @session = Session.new @win_status = false end def add_player_name(given_name) name_validation(given_name) ? @session.player_name = given_name : false end def choose_difficulty(chosen_difficulty) @session.difficulty_manager(chosen_difficulty.to_sym) end def hint return false if @session.hints_used >= @session.hints_total @session.hints_used += 1 @secret_code_for_hint ||= @secret_code.clone.uniq @secret_code_for_hint.delete(@secret_code_for_hint.sample) end def guess(user_input) return false unless guess_validation(user_input) return I18n.t(:no_attempts_left_message) if @session.attempts_used >= @session.attempts_total @session.attempts_used += 1 @win_status = true if user_input.to_i == @secret_code.join.to_i comparator(user_input) end def save_game @session.save_session_statistic if @win_status end def show_secret_code @secret_code.join if @win_status end private 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) user_input = matching_only_numbers(user_input).sort user_input.rotate(user_input.count(Settings::MATCHING[:absent])).join end def matching_numbers_and_indexes(user_input) user_input.map.with_index do |value, index| if value == @secret_code_for_comparison[index] @secret_code_for_comparison[index] = nil Settings::MATCHING[:place] elsif !@secret_code_for_comparison.include?(value) Settings::MATCHING[:absent] else value end end end def matching_only_numbers(user_input) user_input.map do |value| if @secret_code_for_comparison.include?(value) @secret_code_for_comparison.delete_at(@secret_code_for_comparison.index(value)) Settings::MATCHING[:presence] elsif [Settings::MATCHING[:place], Settings::MATCHING[:absent]].include?(value) value else Settings::MATCHING[:absent] end end end end