Parcours
/
R
R
/
Exercices
/
Blackjack
Blackjack

Blackjack

Exercice d'apprentissage

Introduction

La fonction switch() peut remplacer de façon concise une longue série de tests if ... else if. La variable sur laquelle on fait un switch est le plus souvent une string, et dans ce cas les guillemets peuvent être omis dans le sélecteur.

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"

Note que les options ne passent à la suivante que si la valeur est laissée vide, comme avec M dans l'exemple ci-dessus. Il n'est pas nécessaire d'inclure des instructions break, contrairement à certains autres langages.

Quand on fait un switch sur des types character, la dernière valeur est une valeur par défaut, comme ici. Avec les types entiers, aucune valeur par défaut ne peut être donnée.

Les fonctions dans dplyr

Le switch de R de base est assez limité : il ne fait qu'une correspondance exacte avec une seule entrée. Cela semblait raisonnable lors de la première version de R en 1993, mais mérite des améliorations pour un usage moderne.

Note

Comme mentionné dans le concept Conditionals, l'ensemble de paquets tidyverse est conçu pour compléter (et parfois remplacer) les fonctionnalités de R de base sans nuire à la rétrocompatibilité.

Pour mettre le paquet dplyr dans la portée, il suffit d'ajouter soit library(dplyr) (pour le paquet seul) soit library(tidyverse) (pour l'ensemble de la collection) en haut de ton code.

La bibliothèque dplyr fournit deux fonctions supplémentaires liées à switch.

Les fonctions recode_values et replace_values

Ces deux fonctions apparentées permettent une correspondance vectorisée, proche du switch, entre d'anciennes valeurs et de nouvelles valeurs.

La principale différence entre elles est que recode_values() crée un vecteur entièrement nouveau, tandis que replace_values() permet des mises à jour partielles d'un vecteur existant.

La correspondance reste exacte, mais :

  • Les options à gauche peuvent être des vecteurs, et l'entrée correspond si un élément correspond.
  • Les options à gauche et les résultats à droite sont reliés par un tilde ~ au lieu de =.
  • Une valeur par défaut peut être spécifiée dans tous les cas.
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 fonction case_when

case_when pousse la syntaxe de case_match encore plus loin, en autorisant n'importe quelle expression logique à gauche du ~.

Le vecteur d'entrée (x dans l'exemple ci-dessous) n'est pas fourni comme argument, il doit simplement être déjà défini.

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?"

La fonction between() fait aussi partie de dplyr.

Instructions

Dans cet exercice, on va simuler le premier tour d'une partie de Blackjack.

Tu vas recevoir deux cartes et tu pourras voir la carte visible du croupier. Toutes les cartes sont représentées par une string telle que « ace », « king », « three », « two », etc. Voici la valeur de chaque carte :

carte valeur carte valeur
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 other 0

Remarque : les as peuvent généralement valoir 1 ou 11, mais par souci de simplicité, on considérera qu'ils ne peuvent valoir que 11.

Selon tes deux cartes et la carte du croupier, il existe une stratégie pour le premier tour de la partie, avec les options suivantes :

  • Rester (S)
  • Tirer (H)
  • Séparer (P)
  • Gagner automatiquement (W)

Bien qu'elle ne soit pas encore optimale, tu vas suivre la stratégie que ton ami Alex a mise au point, qui est la suivante :

  • Si tu as une paire d'as, tu dois toujours les séparer.
  • Si tu as un Blackjack (deux cartes dont la somme vaut 21) et que le croupier n'a ni as, ni figure, ni dix, tu gagnes automatiquement. Si le croupier a l'une de ces cartes, tu devras rester et attendre que l'autre carte soit révélée.
  • Si la somme de tes cartes se situe dans l'intervalle [17, 20], tu dois toujours rester.
  • Si la somme de tes cartes se situe dans l'intervalle [12, 16], tu dois toujours rester, sauf si le croupier a un 7 ou plus, auquel cas tu dois toujours tirer.
  • Si la somme de tes cartes est inférieure ou égale à 11, tu dois toujours tirer.

1. Calcule la valeur de n'importe quelle carte.

Implémente une fonction parse_card qui calcule la valeur numérique d'une carte :

parse_card("ace")
# => 11

2. Implémente la logique de décision pour le premier tour.

Écris une fonction first_turn qui implémente la logique de décision décrite plus haut :

first_turn(card1, card2, dealer_card)

Voici quelques exemples de résultats attendus :

first_turn("ace", "ace", "jack") == "P"
first_turn("ace", "king", "ace") == "S"
first_turn("five", "queen", "ace") == "H"
Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet
R Exercism

Prêt à commencer Blackjack ?

Inscris-toi sur Exercism pour apprendre et maîtriser R avec 21 concepts111 exercices, et un vrai mentorat humain, le tout gratuitement.