# frozen_string_literal: true # Main Gem module module CodeBrkrGameTraining # Class class for storage and operations with secret code class Code include Validator GAME_NUMBERS = { from: 1, to: 6, count: 4 }.freeze def initialize @secret_digit_arr = code_generator end def to_s @secret_digit_arr.join end def code_check(user_digits_arr) check_array_code_format(user_digits_arr) alg_result = code_check_algorithm(@secret_digit_arr.clone, user_digits_arr) result = { in_position: GAME_NUMBERS[:count] - alg_result[:miss_indexes].length, out_of_position: alg_result[:out_of_positions].length } result[:not_guessed] = GAME_NUMBERS[:count] - result[:in_position] - result[:out_of_position] result end def random_secret_digit_according_indexes(exclude_indexes) rand_index = @secret_digit_arr.each_index.reject { |index| exclude_indexes.include? index }.sample { index: rand_index, digit: @secret_digit_arr[rand_index] } end private def code_generator Array.new(GAME_NUMBERS[:count]) { rand(GAME_NUMBERS[:from]..GAME_NUMBERS[:to]) } end def check_array_code_format(code_arr) check_type(code_arr, Array) raise GameError, 'incorrect_code_format' unless code_arr.size == GAME_NUMBERS[:count] digits_range_arr = (GAME_NUMBERS[:from]..GAME_NUMBERS[:to]).to_a code_arr.each { |digit| raise GameError, 'incorrect_code_format' unless digits_range_arr.member? digit } end def code_check_algorithm(system_arr, user_arr) miss_indexes_arr = user_arr.each_index.reject { |user_index| user_arr[user_index] == system_arr[user_index] } system_arr.select!.with_index { |_, sys_index| miss_indexes_arr.include? sys_index } out_of_positions = miss_indexes_arr.collect do |miss_index| found = system_arr.find_index { |sys_num| user_arr[miss_index] == sys_num } found.nil? ? nil : system_arr.delete_at(found) end { miss_indexes: miss_indexes_arr, out_of_positions: out_of_positions.compact } end end end