Blackjack

Blackjack

Άσκηση εκμάθησης

Εισαγωγή

Η συνάρτηση switch() μπορεί να αντικαταστήσει με έναν πιο συνοπτικό τρόπο μια μακριά σειρά από ελέγχους if ... else if. Η μεταβλητή στην οποία εφαρμόζεται το switch είναι συνήθως μια συμβολοσειρά, και σε αυτή την περίπτωση τα εισαγωγικά μπορούν να παραλειφθούν από τον επιλογέα.

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"

Σημείωσε ότι οι επιλογές περνούν στην επόμενη μόνο όταν η τιμή μείνει κενή, όπως με το M στο παραπάνω παράδειγμα. Δεν χρειάζεται να συμπεριλάβεις εντολές break, όπως συμβαίνει σε κάποιες άλλες γλώσσες.

Όταν το switch εφαρμόζεται σε τύπους character, η τελευταία τιμή λειτουργεί ως προεπιλογή, όπως εδώ. Με ακέραιους τύπους, δεν μπορεί να δοθεί προεπιλογή.

Συναρτήσεις στο dplyr

Το switch της βασικής R είναι αρκετά περιορισμένο: κάνει μόνο ακριβή αντιστοίχιση με μία μόνο είσοδο. Αυτό φαινόταν λογικό όταν η R κυκλοφόρησε για πρώτη φορά το 1993, αλλά χρειάζεται βελτίωση για τη σύγχρονη χρήση.

Note

Όπως αναφέρθηκε στην έννοια Conditionals, η συλλογή πακέτων tidyverse είναι σχεδιασμένη να συμπληρώνει (και μερικές φορές να αντικαθιστά) τη λειτουργικότητα της βασικής R χωρίς να επηρεάζει τη συμβατότητα προς τα πίσω.

Μπορείς να κάνεις διαθέσιμο το πακέτο dplyr προσθέτοντας είτε library(dplyr) (για το μεμονωμένο πακέτο) είτε library(tidyverse) (για ολόκληρη τη συλλογή) στην αρχή του κώδικά σου.

Η βιβλιοθήκη dplyr παρέχει δύο επιπλέον συναρτήσεις που σχετίζονται με το switch.

Οι συναρτήσεις recode_values και replace_values

Αυτές οι δύο σχετιζόμενες συναρτήσεις επιτρέπουν μια διανυσματοποιημένη αντιστοίχιση παλιών τιμών σε νέες, παρόμοια με το switch.

Η κύρια διαφορά τους είναι ότι η recode_values() δημιουργεί ένα εντελώς νέο διάνυσμα, ενώ η replace_values() επιτρέπει μερικές ενημερώσεις ενός υπάρχοντος διανύσματος.

Η αντιστοίχιση εξακολουθεί να είναι ακριβής, αλλά:

  • Οι επιλογές στα αριστερά μπορούν να είναι διανύσματα, και η είσοδος ταιριάζει αν ταιριάζει οποιοδήποτε στοιχείο.
  • Οι επιλογές στα αριστερά και τα αποτελέσματα στα δεξιά συνδέονται με ένα ~ αντί για =.
  • Μπορεί να οριστεί προεπιλογή σε όλες τις περιπτώσεις.
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

Η συνάρτηση case_when

Η case_when πηγαίνει τη σύνταξη της case_match ένα βήμα παραπέρα, επιτρέποντας οποιαδήποτε λογική έκφραση στα αριστερά του ~.

Το διάνυσμα εισόδου (το x στο παρακάτω παράδειγμα) δεν δίνεται ως όρισμα, απλώς χρειάζεται να έχει ήδη οριστεί.

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

Η συνάρτηση between() είναι επίσης μέρος του dplyr.

Οδηγίες

Σε αυτή την άσκηση θα προσομοιώσουμε τον πρώτο γύρο ενός παιχνιδιού Blackjack.

Θα πάρεις δύο κάρτες και θα μπορείς να δεις την ανοιχτή κάρτα του ντίλερ. Όλες οι κάρτες αναπαρίστανται με μια συμβολοσειρά, όπως "ace", "king", "three", "two" κ.λπ. Οι τιμές κάθε κάρτας είναι:

κάρτα τιμή κάρτα τιμή
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 άλλο 0

Σημείωση: Συνήθως, οι άσσοι μπορούν να πάρουν την τιμή 1 ή 11, αλλά για λόγους απλότητας θα υποθέσουμε ότι μπορούν να πάρουν μόνο την τιμή 11.

Ανάλογα με τις δύο κάρτες σου και την κάρτα του ντίλερ, υπάρχει μια στρατηγική για τον πρώτο γύρο του παιχνιδιού, όπου έχεις τις εξής επιλογές:

  • Να μείνεις (S)
  • Να τραβήξεις χαρτί (H)
  • Να χωρίσεις (P)
  • Να κερδίσεις αυτόματα (W)

Αν και δεν είναι ακόμη βέλτιστη, θα ακολουθήσεις τη στρατηγική που αναπτύσσει ο φίλος σου ο Alex, η οποία είναι η εξής:

  • Αν έχεις ένα ζευγάρι άσσους, πρέπει πάντα να τους χωρίζεις.
  • Αν έχεις Blackjack (δύο κάρτες που αθροίζουν σε τιμή 21) και ο ντίλερ δεν έχει άσσο, φιγούρα ή δεκάρι, τότε κερδίζεις αυτόματα. Αν ο ντίλερ έχει κάποια από αυτές τις κάρτες, τότε θα πρέπει να μείνεις και να περιμένεις να αποκαλυφθεί η άλλη κάρτα.
  • Αν οι κάρτες σου αθροίζουν σε μια τιμή στο διάστημα [17, 20], θα πρέπει πάντα να μένεις.
  • Αν οι κάρτες σου αθροίζουν σε μια τιμή στο διάστημα [12, 16], θα πρέπει πάντα να μένεις, εκτός αν ο ντίλερ έχει 7 ή μεγαλύτερη κάρτα, οπότε θα πρέπει πάντα να τραβάς χαρτί.
  • Αν οι κάρτες σου αθροίζουν σε 11 ή λιγότερο, θα πρέπει πάντα να τραβάς χαρτί.

1. Υπολόγισε την τιμή οποιασδήποτε κάρτας.

Υλοποίησε μια συνάρτηση parse_card που υπολογίζει την αριθμητική τιμή μιας κάρτας:

parse_card("ace")
# => 11

2. Υλοποίησε τη λογική απόφασης για τον πρώτο γύρο.

Γράψε μια συνάρτηση first_turn που υλοποιεί τη λογική απόφασης όπως περιγράφεται παραπάνω:

first_turn(card1, card2, dealer_card)

Ορίστε μερικά παραδείγματα για τα αναμενόμενα αποτελέσματα:

first_turn("ace", "ace", "jack") == "P"
first_turn("ace", "king", "ace") == "S"
first_turn("five", "queen", "ace") == "H"
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα
R Exercism

Έτοιμος να ξεκινήσεις την άσκηση Blackjack;

Γράψου στο Exercism για να μάθεις και να κατακτήσεις R με 21 έννοιες111 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.