1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| /// Représentation du jeu et de ses différentes cartes possibles
type Card =
| Number of int * Color // Carte numérotée possédant une valeur et une couleur
| DrawTwo of Color // Carte +2 possédant une couleur
| Skip of Color // Carte "passer tour" possédant une couleur
| Reverse of Color // Carte "changement de sens" possédant une couleur
| Wild // Carte Joker sans particularité autre
| WildDrawFour // Carte Joker +4 sans particularité autre
with
/// Surcharge de ToString pour une visualisation plus aisée
override x.ToString () =
// Utilisation du pattern matching (= switch ^ 1000 :D)
// Permet d'identifier la structure du paramètre (ici x ou l'instance active) tout en pouvant lier les constituants de celle-ci à des "variables"
// Exemple si l'instance est la carte 0 Bleue, on matchera le premier pattern en liant à "n" la valeur 0 et Color.Blue à "c"
match x with
| Number (n, c) -> sprintf "%2d %s" n c.Name
| DrawTwo c -> sprintf "+2 %s" c.Name
| Skip c -> sprintf "Sk %s" c.Name
| Reverse c -> sprintf "Rv %s" c.Name
| Wild -> "Wild"
| WildDrawFour -> "Wild +4" // changé depuis le screen avant c'était juste "+4"
/// Création d'un deck source (=neuf) constitué de 108 cartes
/// Pour chaque couleur 1 seul 0, 2 fois les autres chiffres et 2 exemplaires des 3 cartes action ainsi que 4 exemplaires des 2 cartes spéciales
/// val startingDeck: list<Card>
let startingDeck = [
for color in [ Color.Blue; Color.Green; Color.Red; Color.Yellow ] do
yield Number (0, color)
for n in 1 .. 9 do
yield! List.replicate 2 (Number (n, color))
for action in [ DrawTwo; Skip; Reverse ] do
yield! List.replicate 2 (action color)
for special in [ Wild; WildDrawFour ] do
yield! List.replicate 4 special
]
/// Fonction générique retournant une nouvelle collection dont les éléments
/// sont ceux de la collection paramètre mélangés aléatoirement
/// val shuffle: list<'a> -> list<'a>
let shuffle cards =
// Multiplie par 100 pour minimiser la probabilité de 2 éléments avec un même poids
let upperBound = 100 * List.length cards
cards
|> List.map (asPair rnd.Next)
|> List.sortBy (fst >> ((|>) upperBound))
|> List.map snd
/// Fonction générique retournant la collection paramètre, comme un tuple
/// dont le premier élément est le premier élément de la collection (head) ainsi que
/// le reste (tail) comme second élément du tuple
/// val drawOne: list<'a> -> 'a * list<'a>
let drawOne deck = List.head deck, List.tail deck
/// Fonction générique retournant les "count" premiers éléments de la collection d'un côté et les autres de l'autre, comme un tuple de collections
/// val draw: int -> list<'a> -> list<'a> * list<'a>
let draw count cards =
// List.partition sépare une collection en 2, selon, un prédicat
// la syntaxe let a, b = 1, 2 permet d'affecter un identificateur à chacun des élements du résultat
val drawn: list<int * 'a>
val remains: list<int * 'a>
let drawn, remains =
cards
|> List.mapi asPair
|> List.partition (fst >> ((>) count))
// On ne veut que les seconds éléments de chaque tuple des collection
List.map snd drawn, List.map snd remains |
Partager