class Codebreaker::Game

Constants

HINTS
LENGTH
MAX
MIN
TRIES

Attributes

hints_left[R]
tries_left[R]

Public Class Methods

new(writer = GameWriter.new, player_class = Player) click to toggle source
# File lib/ep-codebreaker/game.rb, line 19
def initialize(writer = GameWriter.new, player_class = Player)
  @writer       = writer
  @player_class = player_class
end

Public Instance Methods

answer() click to toggle source
# File lib/ep-codebreaker/game.rb, line 53
def answer
  @code if finished?
end
as_json() click to toggle source
# File lib/ep-codebreaker/game.rb, line 65
def as_json
  {
    result: nil,
    hint: nil,
    tries_left: @tries_left,
    hints_left: @hints_left,
    finished: finished?,
    won: won?,
    answer: answer
  }
end
check_guess(input) click to toggle source
# File lib/ep-codebreaker/game.rb, line 32
def check_guess(input)
  verify input
  @tries_left -= 1
  @result = check_input(@code.chars, input.chars)
end
finished?() click to toggle source
# File lib/ep-codebreaker/game.rb, line 45
def finished?
  @tries_left.zero? || won?
end
high_scores() click to toggle source
# File lib/ep-codebreaker/game.rb, line 61
def high_scores
  @writer.load_scores
end
hint() click to toggle source
# File lib/ep-codebreaker/game.rb, line 38
def hint
  return false if @hints_left.zero?
  @tries_left -= 1
  @hints_left -= 1
  generate_hint
end
save_score(name) click to toggle source
# File lib/ep-codebreaker/game.rb, line 57
def save_score(name)
  @writer.write @player_class.new(name, @tries_left, @hints_left)
end
start() click to toggle source
# File lib/ep-codebreaker/game.rb, line 24
def start
  @code             = Array.new(LENGTH) { rand(MIN..MAX) }.join
  @result           = ''
  @tries_left       = TRIES
  @hints_left       = HINTS
  @indexes_for_hint = (0...LENGTH).to_a
end
to_json(*options) click to toggle source
# File lib/ep-codebreaker/game.rb, line 77
def to_json(*options)
  as_json.to_json(*options)
end
won?() click to toggle source
# File lib/ep-codebreaker/game.rb, line 49
def won?
  @result == ('+' * LENGTH)
end

Private Instance Methods

check_input(code_chars, input_chars) click to toggle source
# File lib/ep-codebreaker/game.rb, line 83
def check_input(code_chars, input_chars)
  num_of_pluses = LENGTH.times.count { |i| code_chars[i] == input_chars[i] }

  input_chars.each do |char|
    next unless code_chars.include? char
    code_chars.delete_at(code_chars.index(char))
  end

  num_of_minuses = LENGTH - num_of_pluses - code_chars.size

  ('+' * num_of_pluses) + ('-' * num_of_minuses)
end
generate_hint() click to toggle source
# File lib/ep-codebreaker/game.rb, line 96
def generate_hint
  index = @indexes_for_hint.delete(@indexes_for_hint.sample)
  ('_' * LENGTH).tap { |hint| hint[index] = @code[index] }
end
verify(input) click to toggle source
# File lib/ep-codebreaker/game.rb, line 101
def verify(input)
  regexp = /\A[#{MIN}-#{MAX}]{#{LENGTH}}\z/
  msg    = "Guesses must consist of #{LENGTH} digits from #{MIN} to #{MAX}"

  raise(ArgumentError, msg) if !input.is_a?(String) || !input.match?(regexp)
end