Created
February 14, 2014 03:47
-
-
Save benneuman/8995432 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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