class Codebreaker::Game

Constants

CODE_DIGITS
CODE_LENGTH
LEVELS
MATCH
PRESENCE
TIME_FORMAT

Attributes

attempts_available[R]
attempts_total[R]
attempts_used[R]
difficulty[R]
errors[R]
hint_keeper[R]
hints[R]
hints_available[R]
hints_total[R]
hints_used[R]
result[R]
secret_code[R]

Public Class Methods

new() click to toggle source
# File lib/codebreaker/game.rb, line 32
def initialize
  @secret_code = Array.new(CODE_LENGTH) { rand(CODE_DIGITS) }
  @errors = []
end

Public Instance Methods

attempts_calculations() click to toggle source
# File lib/codebreaker/game.rb, line 79
def attempts_calculations
  @attempts_total = LEVELS.dig(@difficulty.to_sym, :attempts)
  @attempts_used = LEVELS.dig(@difficulty.to_sym, :attempts) - @attempts
  @attempts_available = @attempts_total - @attempts_used
end
guess(input) click to toggle source
# File lib/codebreaker/game.rb, line 37
def guess(input)
  user_number = input.chars.map(&:to_i)
  validate(user_number)
  @user_number = user_number
end
hint() click to toggle source
# File lib/codebreaker/game.rb, line 61
def hint
  @hint_keeper << tip = @hints.pop
  tip
end
hints_calculations() click to toggle source
# File lib/codebreaker/game.rb, line 85
def hints_calculations
  @hints_total = LEVELS.dig(@difficulty.to_sym, :hints)
  @hints_used = LEVELS.dig(@difficulty.to_sym, :hints) - @hints.size
  @hints_available = @hints_total - @hints_used
end
hints_left?() click to toggle source
# File lib/codebreaker/game.rb, line 66
def hints_left?
  @hints.any?
end
lost?() click to toggle source
# File lib/codebreaker/game.rb, line 57
def lost?
  @attempts.zero?
end
set(input) click to toggle source
# File lib/codebreaker/game.rb, line 70
def set(input)
  return unless LEVELS.key?(input.to_sym)

  @difficulty = LEVELS.dig(input.to_sym, :command)
  @hints = @secret_code.sample(LEVELS.dig(@difficulty.to_sym, :hints))
  @attempts = LEVELS.dig(@difficulty.to_sym, :attempts)
  @hint_keeper = []
end
start() click to toggle source
# File lib/codebreaker/game.rb, line 43
def start
  @code = @secret_code.dup
  @attempts -= 1
  attempts_calculations
  hints_calculations
  matches_result = check_matches
  presence_result = check_presence
  @result = (matches_result + presence_result).join
end
to_h(name) click to toggle source
# File lib/codebreaker/game.rb, line 91
def to_h(name)
  {
    name: name,
    difficulty: @difficulty,
    attempts_total: LEVELS.dig(@difficulty.to_sym, :attempts),
    attempts_used: LEVELS.dig(@difficulty.to_sym, :attempts) - @attempts,
    hints_total: LEVELS.dig(@difficulty.to_sym, :hints),
    hints_used: LEVELS.dig(@difficulty.to_sym, :hints) - @hints.size,
    time: Time.now.strftime(TIME_FORMAT)
  }
end
win?() click to toggle source
# File lib/codebreaker/game.rb, line 53
def win?
  @result == MATCH * CODE_LENGTH
end

Private Instance Methods

check_matches() click to toggle source
# File lib/codebreaker/game.rb, line 105
def check_matches
  output = []
  @code.each_with_index do |num, index|
    next unless num == @user_number[index]

    output << MATCH
    @user_number[index] = nil
    @code[index] = nil
  end
  output
end
check_presence() click to toggle source
# File lib/codebreaker/game.rb, line 117
def check_presence
  output = []
  @code.compact!
  @user_number.compact.each do |num|
    next unless @code.include? num

    output << PRESENCE
    @code[@code.index(num)] = nil
  end
  output
end
validate(number) click to toggle source

rubocop:disable Metrics/LineLength

# File lib/codebreaker/game.rb, line 131
def validate(number)
  @errors = []
  @errors << I18n.t(:GUESS_ERROR, quan: CODE_LENGTH, min: CODE_DIGITS.min, max: CODE_DIGITS.max) unless match_checker(number.size, CODE_LENGTH)

  number.each { |digit| @errors << I18n.t(:GUESS_ERROR, quan: CODE_LENGTH, min: CODE_DIGITS.min, max: CODE_DIGITS.max) unless range_checker(digit, CODE_DIGITS) }
end