Skip to content

Instantly share code, notes, and snippets.

@dreamr
Last active December 26, 2015 17:29
Show Gist options
  • Save dreamr/7187332 to your computer and use it in GitHub Desktop.
Save dreamr/7187332 to your computer and use it in GitHub Desktop.
hangman in ruby lambdas!
require 'io/console'
# Some vars to give us data
dict = %W(ruby lambda functional)
game_word = dict[rand(dict.size)]
guesses = {
correct: [],
incorrect: []
}
max_guesses = 7
# Lambda madness
has_turns_left = ->(guesses, game_word) { (guesses[:incorrect].size||0) < max_guesses }
turns_left = ->(guesses, game_word) { max_guesses-guesses[:incorrect].size }
valid_input_only = ->(stdin) {
input = stdin.getch
return input if input =~ /[a-zA-Z]/
exit if input == "\e"
valid_input_only.(stdin)
}
query_player = -> { puts "Guess a letter!"; valid_input_only.(STDIN) }
validate_answer = ->(guess) {
list = game_word.include?(guess) ? :correct : :incorrect
[guess, list]
}
sort_answer = ->(guess) { guesses[guess[1]] << guess[0] }
is_solved = ->(guesses, game_word) { guesses[:correct].sort == game_word.chars.uniq.sort }
already_guessed = ->(guesses, guess) {
previously_guessed = (guesses[:correct] + guesses[:incorrect]).include?(guess)
puts "Umm, you already guessed #{guess}" if previously_guessed
previously_guessed
}
display_ascii = ->(t) {
puts <<-EOS
_____
| #{t<7 ? '|':' '}
| #{t<6 ? 'O':' '}
| #{t<4 ? '/':' '}#{t<5 ? '|':' '}#{t<3 ? '\\':' '}
| #{t<2 ? '/':' '} #{t<1 ? '\\':' '}
|
===========
EOS
}
display_letter_board = ->(guesses, game_word) {
letter_board = game_word.chars.map do |c|
(guesses[:correct].include?(c) ? c : '_')
end.join(" ").upcase
puts [" ",letter_board].join
}
display_misses_left = ->(turns_left) {
puts "You have #{turns_left} #{turns_left > 1 ? "misses" : "miss"} left."
}
take_turn = -> {
player_guess = query_player.()
return if already_guessed.(guesses, player_guess)
sort_answer.(validate_answer.(player_guess))
}
clear_screen = ->{
non_osx=`which cls`
osx=`which clear`
system [non_osx,osx].reject {|i| i == ""}[0].split("/")[-1]
}
# Imperative shell
message = while true
clear_screen.()
player_turns_left = turns_left.(guesses, game_word)
break "AWESOME!\nYou guessed the word!" if is_solved.(guesses, game_word)
unless has_turns_left.(guesses, game_word)
display_ascii.(player_turns_left)
break "Sorry, but you were hanged!\nThe word was: #{game_word}"
end
display_ascii.(player_turns_left)
display_letter_board.(guesses, game_word) && puts
display_misses_left.(player_turns_left) && puts
take_turn.()
end
puts message
@dreamr
Copy link
Author

dreamr commented Oct 31, 2013

Note: You should not write code that looks like this, except when pushing boundaries and playing with a language. There are no tests, there is at least 1 bug (that never really matters to the user) and it is in short, a toy.

We should be building more toys and tools to go along our projects, but mostly, toys. Toy making teaches you interesting things when you aren't bound to the rigorous standards and conventions you use to keep your ass out of trouble at your day job.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment