# frozen_string_literal: true require 'yaml' require 'i18n' require 'pry' require './lib/modules/check_module.rb' require './lib/classes/difficulty.rb' require './lib/classes/user.rb' require './lib/classes/statistic.rb' require './lib/classes/file_worker.rb' require './lib/config.rb' require './lib/codebreakergem/version.rb' module Codebreakergem class Game include Checker DIGIT_NUMBER = 4 DIFFICULTIES = [Difficulty.new(name: 'Easy', attempts: 15, hints: 2, order: 3), Difficulty.new(name: 'Medium', attempts: 10, hints: 1, order: 2), Difficulty.new(name: 'Hell', attempts: 5, hints: 1, order: 1)].freeze COMMANDS = %w[hint exit].freeze GUESS_PLACE = '+' GUESS_PRESENCE = '-' FILE = 'lib\data\data.yml' attr_reader :secret_code, :user attr_accessor :difficulty, :statistics def initialize(user) @user = user @secret_code = generate_code end def show_hint if difficulty.hints.positive? difficulty.hints -= 1 secret_code[difficulty.hints] else I18n.t(:no_hints) end end def try_guess(guess) return I18n.t(:out_of_attempts) unless difficulty.attempts.positive? if guess == secret_code save difficulty.attempts = 0 return I18n.t(:victory_message) end difficulty.attempts -= 1 make_guess(guess) end def validate_guess(guess) return false if guess.empty? guess.match?(/\D/) ? COMMANDS.include?(guess) : true end def save source_difficulty = DIFFICULTIES.find { |item| item.name == difficulty.name } statistic = Statistic.new(name: user.name, difficulty: difficulty, attempts_total: source_difficulty.attempts, hints_total: source_difficulty.hints) File.file?(FILE) ? FileWorker.add_to_file(FILE, statistic) : FileWorker.write_to_file(FILE, statistic) end class << self def rules I18n.t(:rules) end def stats index = 1 result = I18n.t(:stats_header) data = FileWorker.read_from_file(FILE) return unless data if data.is_a?(Array) sorted_data = data.select { |item| item.is_a? Statistic }.sort_by { |item| [item.difficulty.order, item.attempts_used, item.hints_used] } sorted_data.each do |item| result += "#{index}\t #{item.name}\t #{item.difficulty.name}\t #{item.attempts_total}\t #{item.attempts_used}\t #{item.hints_total}\t #{item.hints_used}\n" index += 1 end else result += "1\t #{data.name}\t #{data.difficulty.name}\t #{data.attempts_total}\t #{data.attempts_used}\t #{data.hints_total}\t #{data.hints_used}\n" end result end end private def generate_code DIGIT_NUMBER.times.map { rand(1..6) }.join end def find_place(guess, code) result = '' (0...guess.length).each do |index| next unless guess[index] == code[index] result += GUESS_PLACE code[index] = ' ' guess[index] = '_' end result end def find_presence(guess, code) result = '' (0...guess.length).each do |index| position = code.index(guess[index]) if position result += GUESS_PRESENCE code[position] = ' ' end end result end def make_guess(guess) result = '' code_copy = secret_code.dup result += find_place(guess, code_copy) result + find_presence(guess, code_copy) end end end