Pages : 1
#1 Le 25/11/2007, à 16:39
- Alix007
caml jeu de poker
Bonjour je dois faire cet exo. J'ai réussi à faire les deux premières questions mais après je n'y arrive plus. Je vous mets ce que j'ai fait. Si vous pouvez m'aider pour la suite ça serait sympa. Merci beaucoup
On considère un jeu de 54 cartes et on définit le type carte de la façon suivante :
type carte = Joker | Pique of int | Coeur of int | Carreau of int | Trefle of int;;
Les cartes sont codées par leur valeur faciale, avec pour convention pour les «figures» les
correspondances suivantes :
A tout Valet on fait correspondre la valeur 11
A toute Dame on fait correspondre la valeur 12
A tout Roi on fait correspondre la valeur 13
Exemple : Dame de Coeur est représentée par Coeur 12
.
1. à‰crire une fonction joker de profil carte list -> int qui compte le nombre de cartes joker
présentes dans la liste de cartes.
2. à‰crire une fonction separe de profil
carte list -> carte list * carte list * carte list * carte list qui sépare
une liste de cartes en la liste des cartes à coeur, pique, carreau, et trèfle respectivement.
3. à‰crire une fonction valide de profil carte list -> bool qui détermine si la liste de cartes
donnée en entrée correspond à un paquet de 54 cartes complet.
4. Donner une fonction suite de profil carte list -> bool testant si la liste de cartes donnée en
argument est une longue suite (5 cartes de même «couleur» et de valeur successives). On supposera
pour simplifier que si la liste de cartes donnée en argument est une telle suite, alors elle est donnée
par ordre croissant de valeur faciale. Techniquement au poker on appelle cette combinaison une
«quinte flush».
Donner un exemple d’une telle suite en Ocaml.
5. à‰crire une fonction distribue de profil
carte list -> int -> carte list list * carte list qui distribue 5 cartes, une par
une, à chaque joueur dans l’ordre o๠elles apparaissent dans le tas de cartes donné en argument (et
retourne aussi le tas de cartes restantes). Par exemple distribue paquet 2 enlève les 10 premières
cartes du tas de cartes paquet , construit deux listes de 5 cartes contenant les cartes de chacun des
deux joueurs, et retourne un couple constitué de la liste de ces deux donnes de 5 cartes et de la liste
des cartes restantes.
1)# let rec joker l = match l with
[]->0
| t::q -> if (t=Joker)then 1 + (joker q) else (joker q);;
val joker : carte list -> int = <fun>
2) # let rec separe l = match l with
[]->([],[],[],[])
|t::q -> let(pi,ca,co,tr)= separe q in
match t with
Joker ->(pi,ca,co,tr)
|Pique v -> (t::pi,co,ca,tr)
|Coeur v -> (pi,t::co,ca,tr)
|Carreau v -> (pi,co,t::ca,tr)
|Trefle v-> (pi,co,ca,t::tr);;
val separe : carte list -> carte list * carte list * carte list * carte list =
<fun>
3)#let rec compte_occur x l = match l with
[]->0
|t::q-> if t=x then 1 + compte_occur x q else compte_occur x q;;
val compte_occur : 'a -> 'a list -> int = <fun>
#let get_val c = match c with
Joker ->0
|Pique v->v
|Coeur v->v
|Carreau v->v
|Trefle v->v;;
val get_val : carte -> int = <fun>
#2 Le 25/11/2007, à 21:36
- Alix000
Re : caml jeu de poker
S'il vous plait
#3 Le 26/11/2007, à 18:28
- alix007
Re : caml jeu de poker
#4 Le 28/11/2007, à 10:46
- alix007
Re : caml jeu de poker
Question 3 ok il me reste plus que la 4 et la 5 que je n'arrive pas à faire. Si vous pouvez m'aider. Merci d'avance
#5 Le 28/11/2007, à 19:30
- Yannick_LM
Re : caml jeu de poker
Ah, le Caml, que c'est beau.
Ca doit faie au moins 3 ans que je n'en ai pas fait, mais on en revoit de temps en temps sur ce forum. (prépas infos en général)...
Bon, mais tu m'as l'air très bien parti, là !
Après, je veux bien t'aider mais pas faire l'exo à ta place. (D'ailleurs, je ne sais même pas si j'en suis capable).
Sur quoi tu bloques ?
Pour la question 4, je pense qu'on peut résoudre le problème en ne parcourant la liste qu'une fois, avec un tampon.
Tu mets la première carte que tu rencontes dans le tampon.
Tu lis la valeur de la suivante.
Si elle est de la même couleur et de valeur +1, tu la rajoutes à la suite de la précédente dans le tampon.
Sinon, tu vides le tampon, et tu n'y mets que la nouvelle carte.
Tu continues tant que la taille du tampon n'est pas plus grande que 5.
Si tu arrives à la fin de la liste : y a pas de quinte Flush.
Pour la 5, je ne vois pas o๠tu coinces. Ca ne m'a pas l'air plu dur que les 3 premières questions.
Qu'est-ce qui ne va pas ?
Trucs et astuces pour Vim
Ma web page avec des trucs dessus ...
Hors ligne
#6 Le 29/11/2007, à 20:31
- best_friend_fr
Re : caml jeu de poker
Pour la 4, pense juste a faire en 2 etapes.
Trate la premiere carte, qui te permet de connaitre la couleur et la valeur de la premiere carte, puis parcourt le reste des 5 cartes en verifiant que c'est la bonne couleur et la bonne valeur.
sudo apt-get replace langage_sms by grammaire orthographe ponctuation
La documentation est avant tout faite pour ceux qui posent les questions, et non ceux qui y répondent
Best_friend_fr
Hors ligne
#7 Le 29/11/2007, à 23:08
- Yannick_LM
Re : caml jeu de poker
@best friend : ça marche mais c'est moins bon en terme de complexité.
Avec ma méthode, tu ne traite chaque carte qu'une seule fois.
EDIT : (Ou comment occuper ses nuits)
J'ai la solution à la question 4, si tu veux.
let rec length = function
| [] -> 0 ;
| a::q -> 1 + (length q);;
let rec suite(a,b) =
match (a,b) with
| (Coeur(i),Coeur(j)) when i = j+1 -> true
| (Trefle(i),Trefle(j)) when i = j+1-> true
| (Carreau(i),Carreau(j)) when i = j+1-> true
| (Pique(i),Pique(j)) when i = j+1-> true
| (_,_) -> false ;;
let check l =
let rec aux (liste,tampon) =
| ([], _) -> false
| (_,t) when (length t) = 5 -> true
| (a::q,[]) -> aux(q,[a])
| (a::q, b::r) ->
if (suite (a,b)) then
true && aux(q,a::b::r)
else
false || aux(q,[a]);
in
aux(l,[]) ;;
Je trouve ça vraiment joli, perso.
PS : comme l'a dit un certain Knuth : faites attention, je n'ai pas testé ce programme, j'ai seulement prouvé qu'il était correct.
Bon, je l'ai quand même testé, mais pas intensivement. (a priori, déjà , pas d'erreurs de syntaxe)
Le traitement du cas du Joker est laissé en exercice au lecteur.
Quant à moi, je vais me coucher ...--
Edit 2 : on peut améliorer l'algo en se souvenant de la taille du tampon à chaque étape plutà´t que de la calculer à chaque fois. (ce qui est mauvais, car on reparcourt le tampon). C'est pas difficle, je te laisse chercher.
Dernière modification par Yannick_LM (Le 30/11/2007, à 04:31)
Trucs et astuces pour Vim
Ma web page avec des trucs dessus ...
Hors ligne
#8 Le 30/11/2007, à 09:21
- best_friend_fr
Re : caml jeu de poker
juste en remarque, moi aussi je ne passe qu'une fois...
pas besoin de faire une passe pour regarder juste la premiere carte.
genre un truc
let carte_to_couple = function
Coeur a = (0,a)
|Carreau a = (1,a)
|Pique a = (2,a)
|Trefle a = (3,a);;
let is_suite = function
[] -> false
| carte::suite -> let (a,b) = carte_to_couple carte in
is_suite_aux a b suite;;
let rec is_suite_aux a b = function
[] -> true
| carte::suite -> let (a2,b2) = carte_to_couple carte in
if a2 = b and b2 = b+1 then is_suite_aux a (b+1) suite else false;;
Je precise que ca fait trop de temps que je n'ai pas fait de caml pour certifier ce code sans test...
sudo apt-get replace langage_sms by grammaire orthographe ponctuation
La documentation est avant tout faite pour ceux qui posent les questions, et non ceux qui y répondent
Best_friend_fr
Hors ligne
#9 Le 01/12/2007, à 00:49
- Yannick_LM
Re : caml jeu de poker
@best_friend :
Ah d'accord. On répond pas à la même question, en fait.
Le code que j'ai donné reconnaà®t une quinte flush dans n'importe qu'elle suite de cartes. (en clair, il peut y avoir des quartes qui ne font pas partie de la suite avant et après, du genre :
T3 P4 P5 P6 P7 P8 C1 )
Alors que le tien reconnaà®t une quinte flush dans une suite de 5 cartes.
D'ailleurs, à la relecture, c'est bien ce que tu disais : "le reste des cinq quartes"
J'avais pas bien lu, désolé.
@alix:
A toi de voir lequel tu prends ...
Trucs et astuces pour Vim
Ma web page avec des trucs dessus ...
Hors ligne
#10 Le 01/12/2007, à 01:29
- BookeldOr
Re : caml jeu de poker
Tsss, se faire faire ses exos c'est mal !
Enfin puisque la réponse t'a déjà été donnée, je propose de vraiment utiliser les facilités offertes par caml :
let quinte l =
match List.sort compare l with
| [ Coeur i ; _ ; _ ; _ ; Coeur j ]
| [ Trefle i ; _ ; _ ; _ ; Trefle j ]
| [ Pique i ; _ ; _ ; _ ; Pique j ]
| [ Carreau i; _ ; _ ; _ ; Carreau j] -> j - i = 4
| _ -> false
Dernière modification par BookeldOr (Le 01/12/2007, à 01:30)
Ubuntu is an ancient african word meaning : "I can't configure Debian".
Hors ligne
#11 Le 01/12/2007, à 15:26
- Yannick_LM
Re : caml jeu de poker
@Bookeldor :
Je suis vexé comme un pou !
Cela dit, je veux bien plus de détails.
Il me semble (mais je peux me tromper), que ce n'est pas du Caml Light. (cela dit, pourquoi pas ?)
Tu peux détailler un peu plus ?
Trucs et astuces pour Vim
Ma web page avec des trucs dessus ...
Hors ligne
#12 Le 01/12/2007, à 16:09
- BookeldOr
Re : caml jeu de poker
Bon, je ne sais pas si c'est dans caml light, mais je pense que oui.
à€ la rigueur, il faut peut être remplacer [ Coeur i ; _ ; _ ; _ ; Coeur j ] par (Coeur i) :: _ :: _ :: _ :: (Coeur j) :: [].
Sinon, en gros, en ocaml on peut associer un traitement à plusieurs motifs, du moment que ceux-ci capturent le même ensemble de variables avec les mêmes types (ici ils ont tous i et j, les deux de type int).
Ensuite, on peut faire des filtres de profondeur arbitraire, donc on peut vérifier directement que la liste a bien 5 élements en faisant un motif ayant 5 éléments...
On se fout des éléments au milieu puisque la liste est triée, donc on capture les valeurs des élements extrèmes et comme la liste est triée, il ne pourra pas y avoir de couleur différente au milieu (1), ni de carte en dehors de l'intervalle [i,j] (2).
Avec (1) et (2), on a forcément une quinte si la différence entre i et j est de 4 (en assumant qu'il n'y a pas de carte en double).
Ubuntu is an ancient african word meaning : "I can't configure Debian".
Hors ligne
#13 Le 01/12/2007, à 23:11
- Yannick_LM
Re : caml jeu de poker
match List.sort compare l with
En fait, c'est sur ceci que je me posais des questions...
(Mais bien vu pour ne tester que la première et la dernière carte)
Dernière modification par Yannick_LM (Le 01/12/2007, à 23:11)
Trucs et astuces pour Vim
Ma web page avec des trucs dessus ...
Hors ligne
#14 Le 07/12/2007, à 00:34
- BookeldOr
Re : caml jeu de poker
Ah ok, je vais donc te donner quelques informations sur sort et compare et désolé pour le temps de réponse.
Donc List.sort prend une fonction qui compare deux éléments, ce qui permet de définir l'ordre total approprié sur le type des valeurs à trier.
Quelques rappels mathématiques :
Une relation d'ordre est une relation (fonction de type 'a -> 'a -> bool) qui est transitive, réflexive et antisymétrique.
Par exemple, "est un préfixe de" est une relation d'ordre :
* transitive : "ab est un préfixe de abc" et "abc est un préfixe de abcd" => "ab est un préfixe de abcd"
* réflexive : "x est un préfixe de x"
* antisymétrique : "x est un préfixe de y" et "y est un préfixe de x" =>"x = y"
Une relation d'ordre total est définie pour tout couple d'éléments de l'ensemble.
C'est à dire que pour la relation R, on a obligatoirement pour tout couple (x,y) xRy ou yRx.
Par exemple, "est un préfixe de" n'est pas total alors que "est inférieur ou égal à " sur les entiers définit un ordre total.
En assumant qu'une fonction ayant ces propriétés est donnée, alors la fonction List.sort va renvoyer une liste contenant les mêmes éléments que la liste passée en argument, et telle que si un élément x est placé avant un élément y dans la liste, alors on a x <= y.
Techniquement, la fonction de comparaison renvoit non pas un bool mais un entier tel que :
f a b < 0 => a < b, f a b > 0 => a > b, f a b = 0 => a = b
Maintenant qu'on a vu comment fonctionne sort, on peut définir sa propre fonction de comparaison, ici on voudrait que tous les Coeur apparaissent avant tous les trèfles, etc. et qu'à l'intérieur d'un groupe les valeurs des cartes soient triées selon l'ordre usuel sur les entiers.
Du genre :
let compare_cartes a b =
match a,b with
| Coeur i, Coeur j
| Trefle i, Trefle j
| Pique i, Pique j
| Carreau i, Carreau j -> i - j
| Coeur _, _ -> -1
| Trefle _, Coeur _ -> 1
| Trefle _, _ -> -1
| Pique _, Trefle _ -> 1
| Pique _, Coeur _ -> 1
| Pique _, Carreau _ -> -1
| Carreau _, _ -> 1
Tu te convaincras par toi-même que la relation est bien une relation d'ordre, comme ocaml ne nous dit pas qu'il manque des cas dans le filtrage, on a bien une fonction totale.
Bien, comme ça ça marche, on peut faire (List.sort compare_cartes l), et comme notre relation nous dit que tous les coeurs sont avant les autres, tous les trèfles sont avant les piques et les carreaux, etc... notre filtrage de seulement le premier et le dernier élément est suffisant
Alors maintenant quest-ce que c'est que ce "compare" :
OCaml définit une opération de comparaison pour tout couple de valeurs du même type, qui correspond à l'ordre lexicographique de la représentation mémoire de la valeur.
Donc, il faut savoir qu'en ocaml, il y a seulement deux types de données : les entiers et les blocs.
Sur les entiers, il fait la comparaison avec l'ordre usuel.
Sur les blocs, il fait l'ordre lexicographique :
D'abord, un bloc plus petit qu'un autre en taille est plus petit.
Ensuite, il compare les deux premiers éléments, si ils sont différents, il retourne cette différence, sinon il continue avec le second élément.
Et aussi, un entier est toujours plus petit qu'un bloc.
Bien, maintenant il faut voir que les constructeurs de cartes sont en fait des blocs à deux éléments (c'est pas exactement ça mais on peut faire comme) dont le premier est la couleur et le second est la valeur.
Au final, ce qu'on obtient est donc exactement l'ordre que j'ai écrit à la main plus haut.
De manière générale, la plupart du temps on peut se débrouiller pour définir le type de sorte que la comparaison de valeurs d'OCaml va donner l'ordre que l'on veut
Par exemple, si on définit :
type positif = Un | UnPlus of positif ;;
Avec l'interprétation évidente :
# let rec int_of_positif = function
| Un -> 1
| UnPlus plus -> 1 + int_of_positif plus;;
val int_of_positif : positif -> int = <fun>
# int_of_positif (Un);;
- : int = 1
# int_of_positif (UnPlus Un);;
- : int = 2
# int_of_positif (UnPlus (UnPlus Un));;
- : int = 3
Un est un entier (constructeur vide) et UnPlus un bloc à un élément.
Donc la comparaison d'OCaml va parcourir la valeur et au final on aura exactement l'ordre sur les entiers :
# Un < UnPlus Un;;
- : bool = true
# UnPlus Un < UnPlus (UnPlus Un);;
- : bool = true
# Un < UnPlus (UnPlus (UnPlus (UnPlus Un)));;
- : bool = true
à‡a va mieux comme ça ?
Dernière modification par BookeldOr (Le 09/12/2007, à 03:18)
Ubuntu is an ancient african word meaning : "I can't configure Debian".
Hors ligne
#15 Le 07/12/2007, à 09:16
- Le Farfadet Spatial
Re : caml jeu de poker
Salut à tous !
De fort belles interventions de la part de BookeldOr, détaillées et complètes. De plus, tu donnes de très bon exemple de programmation CaML. Cependant :
En assumant
La traduction en français de l'expression anglaise « assuming » est « en admettant que. »
Oui, je sais, cette intervention est inutile, mais c'est une récidive : http://www.legos.obs-mip.fr/~lebars/patois
à€ bientà´t.
Le Farfadet Spatial,
qui n'a pas pu se retenir
Dernière modification par Le Farfadet Spatial (Le 07/12/2007, à 09:16)
Hors ligne
#16 Le 07/12/2007, à 13:16
- BookeldOr
Re : caml jeu de poker
Le Farfadet Spatial > Ouaip, désolé pour l'anglicisme j'ai tapé ça un peu vite et un peu tard, et merci pour le lien ;-)
Ubuntu is an ancient african word meaning : "I can't configure Debian".
Hors ligne
#17 Le 07/12/2007, à 19:35
- BookeldOr
Re : caml jeu de poker
Au fait :
CaML
à€ moi de rectifier tes propos maintenant
Tu ne devrais pas mettre ML en majuscules :
Déjà , ce que j'ai donné est du code OCaml pour Objective Caml, dans lequel le O est là pour représenter le paradigme de programmation par objets ajouté à Caml.
ML signifie Meta Language, qui en fait désigne le langage d'implantation (méta langage) de l'assistant de preuves LCF.
Cependant le ml de Caml ne signifie pas "meta language" mais "machine language" (Categorical abstract machine language).
Donc tu peux écrire ocaml, Ocaml, OCaml ou OCAML mais pas OCaML.
Bon ok, c'était petit mais, tout de même, à caractère informatif , et pour plus d'infos, voir http://caml.inria.fr/about/history.en.html .
Ubuntu is an ancient african word meaning : "I can't configure Debian".
Hors ligne
#18 Le 08/12/2007, à 18:36
- Yannick_LM
Re : caml jeu de poker
J'espère qu'Alix suit toujours ce sujet, on y apprend beacoup.
Merci à BookeldOr pour les cours du soir ...
(Et puis, ça me donne envie de réinvestir mes connaissances en Caml "Light" en me lançant dans OCaml, tout ça)
Et puis, puisque tout le monde pinaille :
bookeldOr, tu aurais pu donner le lien en Français... C'est l'INRIA, quand même !
http://caml.inria.fr/about/history.fr.html
Trucs et astuces pour Vim
Ma web page avec des trucs dessus ...
Hors ligne
#19 Le 09/12/2007, à 00:32
- Le Farfadet Spatial
Re : caml jeu de poker
Salut à tous !
Tu ne devrais pas mettre ML en majuscules
Tu as parfaitement raison.
à€ bientà´t.
Le Farfadet Spatial
Hors ligne
Pages : 1