Skip to content

Instantly share code, notes, and snippets.

@asterite
Created January 20, 2021 12:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save asterite/9c912a4ef651cd02aad16aec36678699 to your computer and use it in GitHub Desktop.
Save asterite/9c912a4ef651cd02aad16aec36678699 to your computer and use it in GitHub Desktop.
Plays "Secret Code" from Clubhouse Games 51 (Spanish only)
require "colorize"
enum Color
Red
Green
Blue
Yellow
Pink
Gray
def texts
case self
in Red then {"Red", "Rojo"}
in Green then {"Green", "Verde"}
in Blue then {"Blue", "Azul"}
in Yellow then {"Yellow", "Amarillo"}
in Pink then {"Pink", "Rosa"}
in Gray then {"Gray", "Gris"}
end
end
def colorize(text)
case self
in Red then text.colorize.red
in Green then text.colorize.green
in Blue then text.colorize.blue
in Yellow then text.colorize.yellow
in Pink then text.colorize.magenta
in Gray then text.colorize.light_gray
end
end
def to_s
colorize texts[1].downcase
end
end
record Guess, colors : Array(Color), hits : Int32, misses : Int32 do
def matches?(other_colors : Array(Color))
hits = 0
misses = 0
other_colors.each_with_index do |other_color, index|
if other_color == colors[index]
hits += 1
elsif colors.includes?(other_color)
misses += 1
end
end
hits == self.hits && misses == self.misses
end
def to_s(io)
colors.join(io, ", ") { |color| io << color }
io << ": "
io << hits << " aciertos, "
io << misses << " pifias"
end
end
class SecretCode
def initialize
@guesses = [] of Guess
end
def run
while true
unless @guesses.empty?
puts "Jugadas existentes:"
@guesses.each do |guess|
print " - "
puts guess
end
puts
end
puts "#{possibilities.count { true }} posibilidades"
puts
puts "Elegí una opción:"
puts "1. Adivinar"
puts "2. Agregar una jugada"
case gets_number
when 1
guess
when 2
break unless add_existing
else
error "opción incorrecta."
end
end
end
def guess
colors = guess_colors
puts colors.join(", ")
hits, misses = ask_hits_and_misses
@guesses << Guess.new(colors, hits, misses)
end
def guess_colors
possibilities.sample
end
def possibilities
Color.values.each_permutation(4).select do |guess|
@guesses.all? &.matches?(guess)
end
end
def add_existing
@guesses << ask_guess
end
def ask_guess
colors = [] of Color
{"Primer", "Segudo", "Tercer", "Cuarto"}.each do |text|
color = nil
until color
value = ask_color(text)
if colors.includes?(value)
error "ese color ya apareció"
else
color = value
end
end
colors << color
end
hits, misses = ask_hits_and_misses
Guess.new(colors, hits, misses)
end
def ask_color(number)
while true
puts "#{number} color (#{Color.values.map(&.to_s).join(", ")}):"
value = gets.downcase
colors = Color.values.select &.texts.any? &.downcase.starts_with?(value)
case colors
when .empty?
error "no conozco ese color"
when .one?
return colors.first
else
error "demasiadas coincidencias (#{colors.map(&.to_s).join(", ")})"
end
end
end
def ask_hits_and_misses
hits = nil
until hits
puts "Cuántos aciertos? (0-3)"
value = gets_number
if value && 0 <= value <= 3
hits = value
else
error "los aciertos tienen que ser entre 0 y 3"
end
end
min_misses = {2 - hits, 0}.max
max_misses = {4 - hits, min_misses}.max
misses = nil
until misses
puts "Cuántas pifias? (#{min_misses}-#{max_misses})"
value = gets_number
if value && min_misses <= value <= max_misses
misses = value
else
error "las pifias tienen que ser entre #{min_misses} y #{max_misses}"
end
end
{hits, misses}
end
def gets_number
gets.to_i?
end
def error(message)
print "Error: ".colorize.red
puts message
end
def gets
line = ::gets
if line
line
else
puts "Chau!"
exit
end
end
end
SecretCode.new.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment