Track
/
R
R
/
Esercizi
/
Blackjack
Blackjack

Blackjack

Esercizio di apprendimento

Introduzione

La funzione switch() può essere un sostituto conciso per una lunga serie di controlli if ... else if. La variabile su cui si effettua lo switch è quasi sempre una stringa e, in questo caso, puoi omettere le virgolette dal selettore.

star <- function(type) {
  switch(type,
    M = , # will "fall through" if no value given
    K = "red dwarf",
    G = "Earth-like",
    "bigger star" # only correct for O,B,A,F
  )
}

> star("M")
[1] "red dwarf"

Nota che le opzioni passano a quella successiva solo se il valore viene lasciato vuoto, come per M nell'esempio qui sopra. Non c'è bisogno di includere istruzioni break, come avviene in altri linguaggi.

Quando si effettua lo switch su tipi character, il valore finale è quello predefinito, come qui. Con i tipi integer, invece, non si può indicare alcun valore predefinito.

Le funzioni in dplyr

Lo switch di R base è piuttosto limitato: esegue solo una corrispondenza esatta con un singolo input. Sembrava ragionevole quando R è stato rilasciato per la prima volta nel 1993, ma per l'uso moderno ha bisogno di miglioramenti.

Note

Come accennato nel concetto Conditionals, la raccolta di pacchetti tidyverse è pensata per integrare (e talvolta sostituire) le funzionalità di R base senza compromettere la retrocompatibilità.

Il pacchetto dplyr può essere portato nello scope aggiungendo library(dplyr) (per il singolo pacchetto) oppure library(tidyverse) (per l'intera raccolta) in cima al codice.

La libreria dplyr fornisce due funzioni aggiuntive legate a switch.

Le funzioni recode_values e replace_values

Queste due funzioni correlate consentono una mappatura vettorizzata, simile a uno switch, dai vecchi valori ai nuovi valori.

La differenza principale tra loro è che recode_values() crea un vettore completamente nuovo, mentre replace_values() consente aggiornamenti parziali di un vettore esistente.

La corrispondenza è ancora esatta, ma:

  • Le opzioni a sinistra possono essere vettori e l'input corrisponde se corrisponde uno qualsiasi dei suoi elementi.
  • Le opzioni a sinistra e i risultati a destra si collegano con una tilde ~ invece che con =.
  • In tutti i casi si può specificare un valore predefinito.
library(dplyr)

x <- c("a", "b", "a", "d", "b", NA, "c", "e", "z")
recode_values(
  x,
  "a" ~ 1,
  "b" ~ 2,
  "c" ~ 3,
  c("d", "e") ~ 4, # either "d' or "e" will match
  NA ~ 0,          # matches missing values
  default = 100   # note the different syntax for the default
)
#> [1]   1   2   1   4   2   0   3   4 100

La funzione case_when

case_when porta la sintassi di case_match un passo più avanti, consentendo qualsiasi espressione logica a sinistra della ~.

Il vettore di input (x nell'esempio qui sotto) non viene passato come argomento: deve solo essere già definito.

x <- 1:10
case_when(
  x < 3 ~ "low",
  between(x, 3, 5) ~ "mid",
  between(x, 6, 8) ~ "high",
  .default = "what?"
)
#>  [1] "low"   "low"   "mid"   "mid"   "mid"   "high"  "high"  "high"  "what?" "what?"

Anche la funzione between() fa parte di dplyr.

Istruzioni

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

Riceverai due carte e potrai vedere la carta scoperta del banco. Tutte le carte sono rappresentate da una stringa come "ace", "king", "three", "two", ecc. I valori di ogni 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

Nota: di solito gli assi possono valere 1 o 11, ma per semplicità assumeremo che possano valere solo 11.

A seconda delle tue due carte e della carta del banco, esiste una strategia per il primo turno di gioco, che ti offre le seguenti opzioni:

  • Stare (S)
  • Chiedere carta (H)
  • Dividere (P)
  • Vincere automaticamente (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 sommano a un valore di 21) e il banco non ha un asso, una figura o un dieci, vinci automaticamente. Se invece il banco ha una di quelle carte, devi stare e aspettare che venga rivelata l'altra carta.
  • Se le tue carte sommano a un valore nell'intervallo [17, 20], dovresti sempre stare.
  • Se le tue carte sommano a un valore nell'intervallo [12, 16], dovresti sempre stare a meno che il banco non abbia un 7 o più; in quel caso dovresti sempre chiedere carta.
  • Se le tue carte sommano a 11 o meno, dovresti sempre chiedere carta.

1. Calcola il valore di una carta qualsiasi.

Implementa una funzione parse_card che calcoli il valore numerico di una carta:

parse_card("ace")
# => 11

2. Implementa la logica decisionale per il primo turno.

Scrivi una funzione first_turn che implementi la logica decisionale descritta sopra:

first_turn(card1, card2, dealer_card)

Ecco alcuni esempi dei risultati attesi:

first_turn("ace", "ace", "jack") == "P"
first_turn("ace", "king", "ace") == "S"
first_turn("five", "queen", "ace") == "H"
Modifica tramite GitHub Il link si apre in una nuova finestra o scheda
R Exercism

Vuoi iniziare Blackjack?

Iscriviti a Exercism per imparare e padroneggiare R con 21 concetti111 esercizi e il mentoring di persone reali, tutto gratis.