Skip to content

Instantly share code, notes, and snippets.

@benneuman
Created February 14, 2014 03:47
Show Gist options
  • Save benneuman/8995432 to your computer and use it in GitHub Desktop.
Save benneuman/8995432 to your computer and use it in GitHub Desktop.
def assert(actual, expected)
if actual == expected
puts "#{actual.inspect} equals #{expected.inspect}"
else
raise "Expected #{actual.inspect} to equal #{expected.inspect}"
end
end
def check_repeating_digits(code)
code.each_char { |char| return true if code.count(char) > 1 }
false
end
def generate_code
string = ""
until string.length == 4
num = rand(1..6).to_s
string << num unless string.include? num
end
string
end
class Game
attr_reader :guesser
def initialize(guesser)
@guesser = guesser
end
def guess(guess)
guesser.guess(guess)
guesser.last_guess_result
end
def won?
@won ||= (guesser.last_guess == guesser.code)
end
def over?
won? || guesser.maxed?
end
def max_guesses=(max_guesses)
guesser.max_guesses = max_guesses
end
end
class Guesser
attr_reader :last_guess, :code
attr_accessor :max_guesses
def initialize(code, max_guesses=7)
@max_guesses = 7
@guess_count = 0
@last_guess = nil
@code = code
end
def maxed?
@guess_count >= @max_guesses
end
def guess(guess)
@last_guess = guess
@guess_count += 1
end
def last_guess_result
check_guess(@last_guess)
end
def check_guess(guess)
return "++++" if guess == @code
result_string = ""
guess.each_char.with_index do |char, index|
if char == @code[index]
result_string << "+"
elsif @code.include? char
result_string << '-'
end
end
result_string.chars.sort.join
end
end
def play_game
game = Game.new(Guesser.new(generate_code))
game.max_guesses = 5
until game.over?
puts "Enter a guess: "
guess = gets.chomp
until guess =~ /[1-6]{4}/
puts "Guess must be four digits 1-6; no repeating digits"
guess = gets.chomp
end
result = game.guess(guess)
puts result
end
if game.won?
puts "You won!"
else
puts "You lost."
end
end
#Making another guess after you win should not change won? status
game = Game.new(Guesser.new('1234'))
game.guess('1234')
assert(game.won?, true)
game.guess('3241')
assert(game.won?, true)
#generate_code never generates code with repeating digits
codes = []
10000.times { codes << generate_code }
assert(codes.none? { |code| check_repeating_digits(code) }, true)
#check_repeating_digits returns true if digits repeat in code
code = "1231"
assert(check_repeating_digits(code), true)
#check_repeaing_digits returns false if digits don't repeat in code
code = "1234"
assert(check_repeating_digits(code), false)
#Game should be over after specified number of guesses if no right guess given
game = Game.new(Guesser.new('1234'))
game.max_guesses = 5
5.times { game.guess('5555') }
assert(game.over?, true)
#Game should be over after correct guess
game = Game.new(Guesser.new('1234'))
game.guess('1234')
assert(game.over?, true)
#Game should not be over on startup
game = Game.new(Guesser.new('1234'))
game.max_guesses = 5
assert(game.over?, false)
#Game should not be won on startup
game = Game.new(Guesser.new('1234'))
assert((game.won? == true), false)
#An incorrect guess should not win the game
game = Game.new(Guesser.new('1234'))
game.guess('2234')
assert(game.won?, false)
#A correct guess should win the game
game = Game.new(Guesser.new('1234'))
game.guess('1234')
assert(game.won?, true)
#generate_code generates a 4-length string
code = generate_code
assert(code.length, 4)
#generate_code generates a different code each time
code1 = generate_code
code2 = generate_code
assert((code1 == code2), false)
#generate_code generate a 4-length string - each character is digit 1-6
code = generate_code
assert(code.split('').all? { |char| char =~ /[1-6]/ }, true)
#A guess that has no matches will return an empty string
guesser = Guesser.new("1234")
guess = "5555"
assert(guesser.check_guess(guess), "")
#A guess that is an exact match will return ++++
guess = "1234"
assert(guesser.check_guess(guess), "++++")
#A guess that has one exact match will return one +
guess = "1555"
assert(guesser.check_guess(guess), "+")
#A guess that has two exact matches will return ++
guess = "1255"
assert(guesser.check_guess(guess), "++")
#A guess that has one inexact match wil return -
guess = "5155"
assert(guesser.check_guess(guess), '-')
#A guess that has four inexact match will return ----
guess = "2143"
assert(guesser.check_guess(guess), '----')
#A guess that has two exact match and two inexact will return ++--
guess = "1432"
assert(guesser.check_guess(guess), '++--')
play_game
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment