Last active
December 26, 2015 17:29
-
-
Save dreamr/7187332 to your computer and use it in GitHub Desktop.
hangman in ruby lambdas!
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
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 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.