Well, you could, certainly, a good way to do it is a Fisher-Yates/Knuth shuffle
So, you would create an array of length 12 * 4 = 48
cards and then shuffle it (you can find this shuffle code in this page) and then use Array.to_list
if you want to keep a list of cards and not an array.
[EDIT]
I took the liberty of rewriting your types :
type palo = Espada | Basto | Oro | Copa
type valor = Uno | Dos | Tres | Quatro | Cinco | Seis | Siete |
Ocho | Nueve | Diez | Once | Doce
type carta = palo * valor
You don't need to say that carta
is a Carta of palo * valor
since you have only one constructor ;-) carta
will be an alias for the couple palo * valor
.
But, actually, an easiest way to do would be to have the types :
type palo = Espada | Basto | Oro | Copa
type valor = int
type carta = palo * valor
and to ensure that your valor can't be greater than 12, for example. It would make the card creation much easier. (For example, doing so :
let cards = Array.init 48 (fun i ->
let palo =
if i < 12 then Espada
else if i < 24 then Basto
else if i < 36 then Oro
else Copa
in palo, i mod 12 + 1
)
)
[SECOND EDIT]
If you really want to have your valor types, this is one way to do :
type palo = Espada | Basto | Oro | Copa
type valor = Uno | Dos | Tres | Quatro | Cinco | Seis | Siete |
Ocho | Nueve | Diez | Once | Doce
type carta = palo * valor
let lv = [Uno; Dos; Tres; Quatro; Cinco; Seis; Siete;
Ocho; Nueve; Diez; Once; Doce]
let cards =
let new_list p = List.map (fun v -> p, v) lv in
let l1 = new_list Espada in
let l2 = new_list Basto in
let l3 = new_list Oro in
let l4 = new_list Copa in
List.rev_append l1 (List.rev_append l2 (List.rev_append l3 l4))
As you can see, I created a list of valors and for each palo
I add the palo
to each element of this list (since lists are persistent data structures, it gives me a new list, it does not modify the previous one) and then I concatenate the four lists.
And an even better way to do :
let lp = [Espada; Basto; Oro; Copa]
let cardsb =
let new_list p = List.map (fun v -> p, v) lv in
List.fold_left (fun acc p ->
List.rev_append (new_list p) acc) [] lp
Which uses iterators which is beautiful, so wow, so charming !
The problem os these last methods is that you can't be sure that you put all your constructors in the list and the typing system won't warn you about it. :-(