# frozen_string_literal: true require_relative 'config' module CodebreakerDiz class Game attr_reader :summary, :tries_count, :hints_count def initialize set_default_difficulty end def difficulty(value) raise ArgumentError unless DIFFICULTIES.include? value.to_sym @difficulty = value.to_sym @difficulty_data = DIFFICULTIES[value.to_sym] end def prepare_data @hints = (0...CODE_LENGTH).to_a @code = Array.new(CODE_LENGTH) { rand(MIN..MAX) } @tries_count = @difficulty_data[:tries] @hints_count = @difficulty_data[:hints] create_summary_container end def jsonify @summary.to_json end def check_guess(input) input = to_array(input) return update_summary(:guess_result, 'no tries left') if lose? return update_summary(:guess_result, 'wrong format') unless valid? input make_results calculate_matches(input) end def generate_hint return update_summary(:hint, 'no hints left') if @hints_count.zero? index = @hints.sample hint = @code[index] @hints.delete index @hints_count -= 1 update_summary :hints_used, :increase update_summary :hint, hint end def win? @summary[:guess_result] == Array.new(CODE_LENGTH, '+').join end def lose? @tries_count.zero? end private def update_summary(key, value) return ArgumentError unless @summary.include? key case value when :increase @summary[key] += 1 else @summary[key] = value end end def set_default_difficulty @difficulty = :kid @difficulty_data = DIFFICULTIES[@difficulty] end def calculate_matches(user_code) delta = [] result = [] (0...CODE_LENGTH).each do |i| if @code[i] == user_code[i] then result << '+' elsif (@code - delta).include? user_code[i] then result << '-' end delta << user_code[i] end result.sort!.join end def make_results(guess_result) @tries_count -= 1 update_summary :tries_used, :increase update_summary :guess_result, guess_result end def to_array(input) input.to_i.digits.reverse end def create_summary_container @summary = { secret: @code, difficulty: DIFFICULTIES.keys.index(@difficulty), tries_total: @tries_count, hints_total: @hints_count, tries_used: 0, hints_used: 0, guess_result: nil, hint: nil } end def valid?(input) input != 0 && input.size == CODE_LENGTH && input.all? do |number| number.between? MIN, MAX end end end end