Rutas
/
Ruby
Ruby
/
Ejercicios
/
BlackJack
BlackJack

BlackJack

Ejercicio de aprendizaje

Introducción

Case (que en otros lenguajes se suele llamar switch) es una forma de expresión de control, igual que if-else. Case permite encadenar varias instrucciones if-else-if y puede resultar más legible sin dejar de ofrecer control de flujo.

Un case se define mediante la palabra clave case seguida de una expresión opcional. Después, para cada caso se usa la palabra clave when seguida de una expresión que se compara con la expresión del case. La palabra clave when no debe llevar sangría respecto a la palabra clave case. Tras la palabra clave when va el código que debe ejecutarse si la expresión del case coincide con la expresión del when. Case admite una instrucción else opcional que se ejecuta si no coincide ningún otro caso.

La expresión del case se evalúa y luego se compara con cada expresión del when. La comparación se hace con el operador de igualdad de case (===).

value = 1
case value
when 1
  "One"
when 2
  "Two"
else
  "Other"
end

# This is the same as:
value = 1
if 1 === value
  "One"
elsif 2 === value
  "Two"
else
  "Other"
end

Operador de igualdad de case (===)

El operador de igualdad de case (===) es un poco distinto del operador de igualdad (==). Comprueba si el lado derecho es un miembro del conjunto descrito por el lado izquierdo. Esto significa que sí importa dónde se coloca cada operando. Cómo funciona depende del tipo del lado izquierdo; por ejemplo, un Range comprobaría si el lado derecho está dentro del rango, y un Object comprobaría si el lado derecho es una instancia de Object.

(1..3) == 1  # => false
(1..3) === 1 # => true

String == "foo"  # => false
String === "foo" # => true

Case con varias expresiones

Los case permiten hacer coincidir varias expresiones en un mismo caso, separando cada valor posible con una coma. Se ejecutará el código si coincide alguna de las expresiones. Esto puede resultar útil cuando quieres que un mismo caso tenga varios valores posibles.

case var
when 1, 2
  "One or two"
else
  "Other"
end

Case con rangos

Los case también pueden comprobar si un valor está dentro de un rango. Para ello se usa un rango como expresión del when.

case var
when 1..3
  puts "One to three"
else
  puts "Other"
end

Case sin expresión de case

Cuando no se necesita una expresión de case, es posible omitirla. Al hacerlo, cada expresión se evalúa según su veracidad, y se comportan como instrucciones if-else-if.

case
when 1 == 1
  "One is equal to one"
when 1 > 2
  "One is greater than two"
else
  "Other"
end

When en una sola línea

Ruby permite instrucciones case de una sola línea. Esto puede usarse cuando tienes una instrucción simple de una sola línea. La instrucción when de una sola línea se escribe como when <expression> then <statement>. Y cuando se usa en la instrucción else, se escribe como else <statement>.

case var
when 1 then "One"
when 2 then "Two"
else "Other"
end

Case con tipos

Case permite hacer coincidir con tipos. Esto resulta útil cuando quieres un comportamiento distinto según el tipo de una variable.

case var
when Integer
  "Integer"
when String
  "String"
else
  "Other"
end

Instrucciones

En este ejercicio vamos a simular el primer turno de una partida de Blackjack.

1. Calcula el valor de cualquier carta.

Recibirás dos cartas y podrás ver la carta descubierta del crupier. Todas las cartas se representan con un string como "ace", "king", "three", "two", etc. Los valores de cada carta son:

carta valor carta valor
ace 11 eight 8
two 2 nine 9
three 3 ten 10
four 4 jack 10
five 5 queen 10
six 6 king 10
seven 7 otra 0
Note

Normalmente, los aces pueden tomar el valor de 1 o 11, pero por simplicidad asumiremos que solo pueden tomar el valor de 11.

Implementa el método Blackjack.parse_card, que recibe una carta como string como argumento. El método debe devolver el valor de la carta como número entero.

Blackjack.parse_card("ace")
# => 11

2. Nombra rangos de valores.

La puntuación del jugador debe clasificarse en rangos de valores. La puntuación del jugador se calcula sumando los valores de las dos cartas del jugador. Los rangos que se utilizan son:

rango valor
low [4, 11]
mid [12, 16]
high [17, 20]
blackjack [21]

Implementa el método Blackjack.card_range, que recibe dos cartas como strings como argumentos. El método debe devolver el nombre del rango de valores en el que se encuentran las dos cartas.

Blackjack.card_range("ten", "king")
# => "high"

3. Implementa la lógica de decisión para el primer turno.

En función de tus dos cartas y de la carta del crupier, hay una estrategia para el primer turno de la partida, en la que tienes las siguientes opciones:

  • Plantarse (S)
  • Pedir (H)
  • Dividir (P)
  • Ganar automáticamente (W)

Aunque todavía no es óptima, seguirás la estrategia que tu amigo Alex ha ido desarrollando, que es la siguiente:

  • Si tienes una pareja de aces, siempre debes dividirlos.
  • Si tienes un Blackjack (dos cartas que suman un valor de 21) y el crupier no tiene un ace, una figura o un ten, ganas automáticamente. Si el crupier tiene alguna de esas cartas, tendrás que plantearte y esperar a que se revele la otra carta.
  • Si tus cartas suman un valor dentro del rango [17, 20], siempre debes plantearte.
  • Si tus cartas suman un valor dentro del rango [12, 16], siempre debes plantearte a menos que el crupier tenga un 7 o más, en cuyo caso siempre debes pedir.
  • Si tus cartas suman 11 o menos, siempre debes pedir.

Implementa el método Blackjack.first_turn, que recibe tres cartas como strings como argumentos. El método debe devolver la decisión que debes tomar como string.

Blackjack.first_turn("ace", "ace", "two")
# => "P"
Editar en GitHub El enlace se abre en una ventana o pestaña nueva
Ruby Exercism

¿Listo para empezar BlackJack?

Regístrate en Exercism para aprender y dominar Ruby con 21 conceptos121 ejercicios y mentoría humana real, todo gratis.