Skip to content

Instantly share code, notes, and snippets.

@jason
Forked from nramadas/ w1d4
Created January 11, 2013 21:19
Show Gist options
  • Save jason/4514048 to your computer and use it in GitHub Desktop.
Save jason/4514048 to your computer and use it in GitHub Desktop.
Hangman and Mastermind
# require 'debugger'
class Hangman
#choice to choose word or have computer choose word
#method that gets human evaluation
attr_accessor :used_letters
def initialize
@used_letters = []
@game_board = []
end
def play_loop
# if choose_game_mode
word_length = choose_length
create_board(word_length)
computer_player = Computer.new(word_length)
i = 0 # i'm not sure what this 'i' does. you increment
# it in the while loop, but it's not used for anything?
while true
#show the game board with numbers underneath (or something)
comp_guess = computer_player.make_guess(@used_letters)
@used_letters << comp_guess
evaluate(comp_guess, computer_player)
p @game_board
p @used_letters
if win?
puts "The word is #{@game_board.join}!"
puts "Computer wins!"
return
end
i += 1
end
end
def choose_length
print "How long is your word: "
length = gets.chomp.to_i
#checks if length is int by converting to string and back
#if non-num, will equal 0
if length.to_s.to_i != length # you can use is_a? here to
# test for type. like:
# unless length.is_a?(Fixnum) ...
puts "Try a real number this time."
choose_length
end
length
end
def create_board(number)
number.times do
@game_board << "_"
end
end
def evaluate(guess, computer_name)
# debugger
puts "Is the letter '#{guess}' in your word?"
print "Enter y/n: "
response = gets.chomp.downcase
if response == "n"
computer_name.refine_dictionary!(guess, "n")
return false
elsif response == "y"
set_index(guess)
computer_name.refine_dictionary!(guess, "y")
else
puts "Invalid entry, please try again"
evaluate(guess)
end
end
def set_index(correct_letter)
puts "how many times does your letter occur?"
print "> "
occurrence = gets.chomp.to_i
occurrence.times do
puts "In which position does the letter occur (one position at a time)"
print "> "
word_index = gets.chomp.to_i - 1
@game_board[word_index] = correct_letter
end
end
def win?
win_condition = 0
@game_board.each do |letter|
if letter == "_"
else
win_condition += 1
end
end
if win_condition == @game_board.length
return true
else
return false
end
# you could replace this entire bit with:
# !@game_board.include?('_')
# :)
end
end
class Computer
attr_accessor :dictionary_array
def initialize(word_length)
@word_length = word_length
dictionary_init
end
def dictionary_init
@dictionary_array = []
File.foreach("test_dictionary.txt") do |line|
if line.chomp.length == @word_length
@dictionary_array << line.chomp
end
end
# puts @dictionary_array
end
#updates dictionary
def refine_dictionary!(guessed_letter, wrong_or_right, letter_index = [])
new_dictionary = []
@dictionary_array.each do |word|
if wrong_or_right == "y"
if word.include?(guessed_letter)
new_dictionary << word
end
else
if !word.include?(guessed_letter)
new_dictionary << word
end
end
end # you could use the map! function to modify your
# dictionary_array instead of the above
#@dictionary_array
@dictionary_array = @dictionary_array & new_dictionary
p @dictionary_array
end
def make_guess(used_letters)
# debugger
unused_letters = prevent_repeats(used_letters)
highest_freq_letter(unused_letters)
end
def prevent_repeats(used_letters)
letters_to_delete = []
letter_array = @dictionary_array.join.split(//)
letter_array.each do |letter|
if used_letters.include?(letter)
letters_to_delete << letter
end
end
# p "this is the letter array #{letter_array}"
letter_array = letter_array - letters_to_delete
letter_array
end
def highest_freq_letter(letter_array)
frequency = letter_array.inject(Hash.new(0)) do |hash, element|
hash[element] += 1
hash
end
most_freq_letter = frequency.max_by { |letter, occurrence| occurrence }
# p frequency
most_freq_letter[0]
end
end
class Human
def evaluate_computer_guess
end
def make_guess
end
end
def test
computer = Computer.new(5)
computer.refine_dictionary!("a")
p computer.dictionary_array
end
def test_loop
hangman = Hangman.new
hangman.play_loop
end
test_loop
class MasterMind
attr_accessor :answer_hint
def initialize
@valid_pegs = [:R, :G, :B, :Y, :O, :P]
@answer = []
@guess = []
@guess_history = []
@answer_hint = []
end
def get_input
user_guess = gets.chomp
formatted_guess = user_guess.upcase.split(//).map! { |item| item.to_sym }
if !valid_guess?(formatted_guess)
print "Please input properly, motherfucker: "
get_input
else
@guess = formatted_guess.dup # why do you dup here?
# also, it's not clear why get input should make
# changes to the Instance Variable. Since it returns
# a value, it would be better for the returned
# value to be used elsewhere to update @guess. right
# now, this behavior is a bit unexpected
formatted_guess
end
end
def valid_guess?(user_guess)
if user_guess.length != 4
return false
end
user_guess.each do |peg|
if !@valid_pegs.include?(peg) # instead of 'if !',
# you could use unless. So, this line of code
# would read:
# unless @valid_pegs.include?(peg)
return false
end
end
true
end
def add_guess_to_history(guess_array) # instead of
# updating @guess in get_input, you could
# do it here. imo, it would fit better here
# than in the get_input method
@guess_history << guess_array
end
def run_loop
generate_answer
i = 0
#explain format & rules...
while i < 11
@answer_hint = []
print "Enter a four letter combination of R, G, B, Y, O, or P: "
add_guess_to_history(get_input)
return if win?
check_guess(check_black)
#shuffle hints to change order
@guess_history[i] << @answer_hint.shuffle
display_history
i += 1
end
puts "Too many guesses. You lose. :'("
end
#formats and displays history of guesses
def display_history
@guess_history.each_with_index do |guess, index|
puts "#{index + 1}: Guess: #{guess[0..3]} | Hint: #{guess[4]}"
end
end
#correct guess in correct place
def check_black
checked_answer = @answer.dup
@guess.each_with_index do |peg, index|
if peg == @answer[index]
@answer_hint << "black"
@guess[index] = "guessed"
checked_answer[index] = "removed guess"
end
end
checked_answer
end
#correct guess in incorrect place & runs check_black
def check_guess(checked_answer)
@guess.each do |peg|
if checked_answer.include?(peg)
@answer_hint << "white"
checked_answer[checked_answer.index(peg)] = "removed guess"
elsif peg != "guessed"
@answer_hint << "no match"
end
end
end
def generate_answer
4.times do
@answer << @valid_pegs[rand(5)]
end
end
def win?
if @guess == @answer
puts "You guessed #{@answer}.\nYou win!"
return true
end
end
end
#type start in irb after loading to start playing
def start
game = MasterMind.new
game.run_loop
end
start
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment