Track
/
Crystal
Crystal
/
Esercizi
/
Blackjack
Blackjack

Blackjack

Esercizio di apprendimento

Introduzione

case (spesso chiamato «switch» in altri linguaggi) è una forma di espressione di controllo come if-else. case permette di concatenare più istruzioni if-else-if, può essere più leggibile e consente costrutti potenti.

Un case è definito dalla parola chiave case seguita da un'espressione facoltativa. Poi, per ogni caso, si usa la parola chiave when seguita da un'espressione che viene confrontata con l'espressione del case. La parola chiave when non deve essere indentata rispetto alla parola chiave case. Dopo la parola chiave when c'è il codice che deve essere eseguito se l'espressione del case corrisponde all'espressione del when. Il case consente un'istruzione else facoltativa, che viene eseguita se nessun altro caso corrisponde.

L'espressione del case viene valutata e poi confrontata con ogni espressione dei when. Il confronto avviene usando l'operatore di sussunzione del case (===).

case 1
when 1
  puts "One"
when 2
  puts "Two"
else
  puts "Other"
end
# => One

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

Operatore di sussunzione del case (===)

L'operatore di sussunzione del case (===) è un po' diverso dall'operatore di uguaglianza (==). L'operatore verifica se il lato destro è un membro dell'insieme descritto dal lato sinistro. Questo significa che conta dove viene posizionato ciascun operando. Come funziona dipende dal tipo del lato sinistro: per esempio, un Range verifica se il lato destro è nell'intervallo, mentre un Object verifica se il lato destro è un'istanza di Object.

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

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

Case con più espressioni

I case permettono di far corrispondere più espressioni in un unico case, con ogni valore possibile separato da una virgola. Il codice viene eseguito se una qualsiasi delle espressioni corrisponde. Può essere utile per un singolo case con più valori possibili.

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

Case con gli intervalli

I case possono anche verificare se un valore è in un intervallo. Per farlo, si usa un intervallo come espressione del when.

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

Case senza espressione del case

Quando non serve un'espressione del case, è possibile ometterla. In questo modo, ogni espressione dei when viene valutata in base alla sua veridicità. E li fa comportare come istruzioni if-else-if.

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

When su una sola riga

Crystal consente istruzioni case su una sola riga. Si può usare quando si ha un'istruzione semplice su una sola riga. La forma su una sola riga dell'istruzione si scrive come when <expression> then <statement>. E quando si usa nell'istruzione else, si scrive come else <statement>.

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

Case con i tipi

Il case permette di far corrispondere dei tipi. Il confronto userà l'operatore is_a? per verificare il tipo della variabile. Per esempio, questo permette di avere un ramo per ogni tipo in un tipo unione.

case var
when Int32
  puts "Int32"
when String
  puts "String"
else
  puts "Other"
end

Oggetto implicito

Il case permette l'uso di un oggetto implicito. Questo permette, per esempio, che un'espressione del when sia una chiamata a un metodo sull'espressione del case. A seconda che il metodo restituisca un valore vero o falso, il caso corrisponderà oppure no.

case 1
when .odd?
  puts "Odd"
when .even?
  puts "Even"
end

Istruzioni

In questo esercizio simuleremo il primo turno di una partita a Blackjack.

1. Calcolare il valore di una carta qualsiasi.

Riceverai due carte e potrai vedere la carta scoperta del mazziere. Tutte le carte sono rappresentate usando una stringa come "ace", "king", "three", "two", ecc. I valori di ciascuna carta sono:

carta valore carta valore
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 altre 0
Note

Di solito gli assi possono valere 1 o 11, ma per semplicità supporremo che possano valere solo 11.

Implementa il metodo Blackjack.parse_card, che prende come argomento una carta sotto forma di stringa. Il metodo deve restituire il valore della carta come numero intero.

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

2. Dare un nome agli intervalli di valori.

Il punteggio del giocatore deve essere classificato in intervalli di valori. Il punteggio del giocatore si calcola sommando i valori delle due carte del giocatore. Gli intervalli usati sono:

intervallo valore
low [4, 11]
mid [12, 16]
high [17, 20]
blackjack [21]

Implementa il metodo Blackjack.card_range, che prende come argomenti due carte sotto forma di stringhe. Il metodo deve restituire il nome dell'intervallo di valori in cui ricadono le due carte.

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

3. Implementare la logica decisionale per il primo turno.

A seconda delle tue due carte e della carta del mazziere, esiste una strategia per il primo turno della partita, in cui hai le seguenti opzioni:

  • Stare (S)
  • Chiedere carta (H)
  • Dividere (P)
  • Vincita automatica (W)

Anche se non è ancora ottimale, seguirai la strategia che il tuo amico Alex sta sviluppando, che è la seguente:

  • Se hai una coppia di assi, devi sempre dividerli.
  • Se hai un Blackjack (due carte che sommate danno un valore di 21) e il mazziere non ha un asso, una figura o un dieci, vinci automaticamente. Se invece il mazziere ha una di quelle carte, devi stare e aspettare la rivelazione dell'altra carta.
  • Se le tue carte sommate danno un valore nell'intervallo [17, 20], devi sempre stare.
  • Se le tue carte sommate danno un valore nell'intervallo [12, 16], devi sempre stare, a meno che il mazziere non abbia un 7 o più; in quel caso devi sempre chiedere carta.
  • Se le tue carte sommate danno 11 o meno, devi sempre chiedere carta.

Implementa il metodo Blackjack.first_turn, che prende come argomenti tre carte sotto forma di stringhe. Il metodo deve restituire come stringa la decisione che devi prendere.

Blackjack.first_turn("ace", "ace", "two")
# => "P"
Modifica tramite GitHub Il link si apre in una nuova finestra o scheda
Crystal Exercism

Vuoi iniziare Blackjack?

Iscriviti a Exercism per imparare e padroneggiare Crystal con 26 concetti142 esercizi e il mentoring di persone reali, tutto gratis.