# 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 = generate_code end def to_s @secret_digit_arr.join end def code_check(user_digits_arr) check_array_code_format(user_digits_arr) { in_positions: check_in_positions(user_digits_arr), out_of_positions: check_out_positions(user_digits_arr), not_guessed: check_not_guessed(user_digits_arr) } end def random_digit(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 generate_code 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 check_miss_indexes(user_arr) GAME_NUMBERS[:count].times.reject { |user_index| user_arr[user_index] == @secret_digit_arr[user_index] } end def check_in_positions(user_arr) GAME_NUMBERS[:count] - check_miss_indexes(user_arr).length end def check_out_positions(user_arr) miss_indexes = check_miss_indexes(user_arr) system_digits = @secret_digit_arr.select.with_index { |_, system_index| miss_indexes.include? system_index } miss_indexes.collect do |miss_index| found = system_digits.find_index { |system_num| user_arr[miss_index] == system_num } found.nil? ? nil : system_digits.delete_at(found) end.compact.length end def check_not_guessed(user_arr) GAME_NUMBERS[:count] - check_in_positions(user_arr) - check_out_positions(user_arr) end end end