Partage
  • Partager sur Facebook
  • Partager sur Twitter

Théorème, ruine du joueur, Prolog

Sujet résolu
7 décembre 2016 à 12:39:41

Bonjour à toute l'équipe. J'ai un sujet de TP sur Prolog concernant le théorème de la ruine du joueur ( Si un joueur a une fortune initiale finie, il n'existe pas de stratégie pour gagner à coup sûr. À l'inverse, s'il joue sans limite de temps, il finira ruine) et ayant déjà des difficultés dans cette langue de programmation, je me permets de vous demander des conseils.


Mon problème :
- Je pense savoir comment l'exprimer en français, mais j'éprouve des difficultés pour le retranscrire en Prolog et par la suite pour le faire boucler.

- Pouvoir stocker la variable mise_ini.

Mon Sujet :
Le joueur dispose de 134 €. La mise effective sera de 60 Euros €. Si le joueur n’a plus d’argent, le jeu s’arrête, il est ruiné.
Il est demandé de réaliser un programme qui sera appelé par le prédicat jeu/3 définit comme suit :


Prédicat jeu(Mise_init,Strategie,Valeur) */ /* ROLE prédicat d'appel global qui permet de savoir en combien de parties un joueur qui a une mise initiale donnée met à être ruine en suivant une stratégie donnée.

Argument Mise_init(entier, +) : somme disponible en début de partie.

Stratégie (entier, +) : type de stratégie (fixe=2,variable=1).

Valeur (entier, +) : pourcentage de la mise disponible ou somme fixe.



Mes idées :
Pour moi en français, cela donne :

Temps que le joueur à de l'argent, je boucle. Suivant la stratégie au début, je génère un nombre aléatoire (0=gagner, 1=perdu), suivant le résultat de ce nombre aléatoire, je déduis ou ajoute la somme à la mise initiale. Je regarde si la mise initiale est bien > à 0 (condition d’arrêt) et je boucle.

Condition d’arrêt : si le joueur n'a plus d'argent, il a perdus (Mise_ini<0).en Prolog pour moi cela donne 
jeu(x):- mise_ini(y)y>0.     mais je ne sais pas si c'est bon )


Voici ce que j'ai commencé à faire, mais une fois que j'ai testé avec l'arbre de résolution, je me rends compte que la récursivité ne fonctionne pas comme je le souhaitais

mise_ini(_).
strategie(_).
pari(_).
lancement(gagner,mise_ini + pari).
lancement(perdu,mise_ini - pari).
gen_random(N).
gen_random(1,gagner).
gen_random(0,perdu).

/* X joue si y est la mise et Y superieur a 0(condition d'arret)*/
jeu( X,_,_):- mise_ini(X),X>0.
jeu(X,Y,Z):-strategie(Y),mise_ini(X),pari(Z),gen_random(N,W),lancement(W,_),jeu(_,_,_).


Je vous remercie par avance pour vos conseils 
Respectueusement 

  • Partager sur Facebook
  • Partager sur Twitter
8 décembre 2016 à 9:52:12

Effectivement, il y a pas mal de problèmes Prolog.

mise_init(_). ne fait rien du tout.

Lorsque tu écris mise_init(50) tu declares un fait : une mise initiale de 50. Avec le _ on n'a pas de fait declaré, donc ça ne sert à rien.

lancement(gagner,mise_ini + pari). En Prolog les arguments ne sont pas évalués, donc il faut écrire expressement

lancement(gagne, Mise, Pari, Resultat) :-
	Resultat is Mise + Pari.


Tel que j'ai compris ton problème, je te donnes un début de solution, tout n'est pas fait, à toi de terminer le code :

lancement(gagne, Mise, Pari, Resultat) :-
	Resultat is Mise + Pari.

lancement(perdu, Mise, Pari, Resultat) :-
	Resultat is Mise - Pari.

gen_resultat(Resultat) :-
	N is random(2),
	(   N = 0
	->  Resultat = perdu
	;   Resultat = gagne).

jeu(Mise_init,Strategie, Valeur):- 
	% calcul du montant du pari
	(   Strategie = 1
	->  Pari is Mise_init * Valeur / 100
	;   Pari = Valeur),
	% obtention du resultat du pari (gagne/perdu)
	gen_resultat(Resultat),
	% 
	lancement(Resultat, Mise_init, Pari, Nouvelle_Mise),
	jeu(Nouvelle_Mise, Strategie, Valeur).



  • Partager sur Facebook
  • Partager sur Twitter

Le crayon la gomme et le papier sont les meilleurs outils du programmeur !

8 décembre 2016 à 17:55:02

Bonjour

Tout d'abord je tiens à vous remercier pour votre aide. J'aurais deux questions à vous poser.

1°/ Pour le nom des variable que vous avais utiliser.

ligne 1 et 2

lancement(gagne, MisePariResultat) :-
Resultat is Mise Pari.

et ligne 22:

lancement(ResultatMise_initPariNouvelle_Mise),

Lorsque Prolog va entrer dans le prédicat "lancement" ligne 22, les variables "Mise_ini" et "Nouvelle_Mise " ne porte pas le même nom que celui ligne 1 et 2("Mise" et Résultat") ce n'est pas un problème ? Ce que je veux dire, c'est que "Résultat" est déjà égal à "gagner" ou "perdu" cela ne va pas faire (lancement("gagner"Mise,Pari,gagner")) ?. Je me pose la même question pour la récursivité dans le prédicat ligne 22 :

jeu(Nouvelle_MiseStrategieValeur).

avec "Nouvelle_Mise" et "Mise_init". (ligne 13)

jeu(Mise_init,StrategieValeur):-

2°/  J'ai voulu déclarer une variable avec un nombre précis dans les faits,(pour le compteur de partie gagner/perdu demander dans mon sujet) mais je ne pense pas que cela fonction de plus après avoir fait l'arbre de résolution, je me rends compte que je dois aussi appliquer une récursivité si je ne me trompe pas. Pourriez-vous m'indiquer ou me conseiller afin que je puisse corriger l'erreur ?

    - Pour le compteur total j'ai l'impression qu'il ne prend pas en compte les deux variables "comp_gagner"et"comp_perdu"

    - J'ai essayé de reformuler la condition d’arrêt aussi.      jeu(Nouvelle_mise,_,_):- Nouvelle_mise > 0.

Nouvelle_Mise sera testé à chaque fois afin que le programme s'arrête si elle est inférieur à zéro, j'ai placé ",_," car pour ces deux variables, on n'en a pas vraiment besoin, je pense.


Voici ce que j'ai continué à faire en me basant sur votre code.

/*------------------Faits---------------------*/
comp(0).
/*------------------Régles--------------------*/
compteur_total(Comp_total):- Comp_total is Comp_perdu + Comp_gagner.
compteur(Gagne,Comp,Comp_gagner):- Comp_gagner is Comp + 1.
compteur(Perdu,Comp,Comp_perdu):- Comp_perdu is Comp + 1.
lancement(Gagne,Mise,Pari,Resultat):- Resultat is Mise+Pari.
lancement(Perdu, Mise, Pari, Resultat) :- Resultat is Mise - Pari.
gen_resultat(Resultat) :- N is random(2),
    (   N = 0
    ->  Resultat = perdu
    ;   Resultat = gagne).

/*Je teste si la Nouvelle_mise est superieur a 0 pour ma condition d'arret*/
jeu(Nouvelle_mise,_,_):- Nouvelle_mise > 0.
jeu(Mise_init,Strategie, Valeur):-
	
/*calcul du montant du pari*/
( Strategie = 1 ->  Pari is Mise_init * Valeur / 100 ;Pari = Valeur),
        write(mise_initiale_=_),
        write(Mise_init),
        write(strategie_a_mise_variable),
	write(Strategie),
	
/*obtention du resultat du pari (gagne/perdu) */
gen_resultat(Resultat),
	
	/*Compteur pour le nombre de partie gagner/perdu*/
	/*Je prend le faits"compt" auquelle j'ajoute +1 a chaque fois que j'ai gagner/perdu*/
compteur(Resultat,Comp,_),
	write(parties_),
        write(Resultat),
	write(_=_),
        write(Comp),
	
lancement(Resultat, Mise_init, Pari, Nouvelle_Mise),
	
jeu(Nouvelle_Mise, Strategie, Valeur).

/*********************************************/
/******* Strategie = 2 ***********************/
/*********************************************/

jeu(Mise_init,Strategie, Valeur):-

/*calcul du montant du pari*/
( Strategie = 2 -> Pari = Valeur),
	write(mise_initial_=_),
	write(Mise_init),
	write(startegie_a_mise_fixe),
	write(Strategie),
/*obtention du resultat du pari (gagne/perdu) */
gen_resultat(Resultat),
	/*Compteur*/
	compteur(Resultat,Comp,_),
	write(parties_),
	write(Resultat),
	write(_=_),
	write(Comp),
lancement(Resultat, Mise_init, Pari, Nouvelle_Mise),jeu(Nouvelle_Mise, Strategie, Valeur).


Respectueusement 


  • Partager sur Facebook
  • Partager sur Twitter
9 décembre 2016 à 18:25:02

J'ai enfin réussi à rentrer dans la récursivité "jeu" en ajoutant   comp(Comp) après le "gen_résultat" pour le compteur,

gen_resultat(Resultat),comp(Comp)

mais j'ai l'impression qu'il ne fait qu’augmenter la Mise_init à l'infini même en passant par "partie perdue" jusqu’à m'afficher un message d'erreur comme quoi la variable "Mise_init" déborde.

  • Partager sur Facebook
  • Partager sur Twitter
11 décembre 2016 à 5:55:42

Serait-il possible d'avoir un petit coup de pouce s'il vous plaît ? ^^  Car honnêtement, je sèche en ce moment .
  • Partager sur Facebook
  • Partager sur Twitter
12 décembre 2016 à 8:59:11

Ceci fonctionne très bien :

jeu(Mise_init,Strategie, Valeur):-
	(   Mise_init =< 0
	->  writeln('You loose !')
	;   % calcul du montant du pari
	    writeln('Avoir ': Mise_init),
	    (   Strategie = 1
	    ->  Pari is Mise_init * Valeur / 100
	    ;   Pari = Valeur),
            % obtention du resultat du pari (gagne/perdu)
	    gen_resultat(Resultat),
	    lancement(Resultat, Mise_init, Pari, Nouvelle_Mise),
	    jeu(Nouvelle_Mise, Strategie, Valeur)).


Par exemple:

 ?- jeu(134, 2, 60).
Avoir :134
Avoir :194
Avoir :134
Avoir :74
Avoir :14
Avoir :74
Avoir :14
You loose !
true.

  • Partager sur Facebook
  • Partager sur Twitter

Le crayon la gomme et le papier sont les meilleurs outils du programmeur !

12 décembre 2016 à 9:48:52

Oui, votre programme fonctionne très bien, je l'avais déjà lancé pour me donner des idées au début.

 Mon seul problème résulte de la récursivité dans mon compteur, car je lui fais toujours prendre la variable "comp(0)" et il m'affiche donc toujours 0 pour les parties gagner ou perdus.

Je ne sais pas comment lui dire :

" Si c'est gagner tu ajout 1 au "comp" gagner et tu le garde en mémoire pour la prochaine partie gagné ou perdu. Une fois fini, tu me calcules le nombre de partie total".

Pour cette dernière étape, je pense que j'aurais juste à récupérer par la suite les deux variables contenant le nombre de parties gagné et perdu.

  • Partager sur Facebook
  • Partager sur Twitter
12 décembre 2016 à 20:20:26

Renseignes toi sur les prédicats dynamic, sur assert/retract qui permettent de mémoriser dans la bdd prolog des résultats entre des appels.

-
Edité par joel76 12 décembre 2016 à 23:22:35

  • Partager sur Facebook
  • Partager sur Twitter

Le crayon la gomme et le papier sont les meilleurs outils du programmeur !

12 décembre 2016 à 23:26:12

Donc si j'ai bien compris, retract supprime un fait ou une clause de la BD et assert au contraire en ajoute une qui est toujours vrais. Je ne suis pas sûr d'avoir tout compris, mais voici ce que j'ai fais :

compG(0).
compP(0).
compteur(Gagne,CompGagner,CompG):-
%Le compteur gagner = 0 + 1
	CompGagner is CompG + 1,
%Je modifie la variable compG(0) par le nouveau résultat que je vient de trouver compG(1)
	assert(compG(CompGagner)).

compteur(Perdu,CompPerdu,CompP):-
	CompPerdu is CompP + 1,
	assert(compP(CompPerdu)).


%début du lancement du predicat "jeu"
        gen_resultat(Resultat),
%j'appelle la variable compP et compG
        compG(Comp),compP(Comp),
%compteur(gagner/perdu,(Le resultat de mon compteur),0)
        compteur(Resultat,Compteur, Comp),
	


Et pour le compteur total:

%fait
compteur(CompG,CompP,Total):- Total is CompG+CompP.

%Dans le prédicat "jeu" juste après la condition d’arrêt
 compteur(CompG,CompP,Resultat),
    write(Resultat);



  • Partager sur Facebook
  • Partager sur Twitter
13 décembre 2016 à 10:05:45

Je voyais plutôt ceci :

:-dynamic compteur/2.

% compteur(Joue, Gagne).
compteur(0,0).


lancement(gagne, Mise, Pari, Resultat) :-
	Resultat is Mise + Pari.

lancement(perdu, Mise, Pari, Resultat) :-
	Resultat is Mise - Pari.

gen_resultat(Resultat) :-
	N is random(2),
	(   N = 0
	->  Resultat = perdu
	;   Resultat = gagne).





jeu(Mise_init,Strategie, Valeur):-
	(   Mise_init =< 0
	->  writeln('You loose !'),
	    compteur(Joue, Gagne),
	    format('Parties Jouees ~w, gagnees ~w~n', [Joue, Gagne])
	;   % calcul du montant du pari
	    writeln('Avoir ': Mise_init),
	    (   Strategie = 1
	    ->  Pari is Mise_init * Valeur / 100
	    ;   Pari = Valeur),
            % obtention du resultat du pari (gagne/perdu)
	    gen_resultat(Resultat),
	    retract(compteur(J, G)),
	    J1 is J+1,
	    (	Resultat = gagne
	    ->	G1 is G+1
	    ;	G1 = G),
	    assert(compteur(J1, G1)),
	    lancement(Resultat, Mise_init, Pari, Nouvelle_Mise),
	    jeu(Nouvelle_Mise, Strategie, Valeur)).

Avec comme resultat :


 ?- jeu(134, 2, 60).
Avoir :134
Avoir :74
Avoir :14
Avoir :74
Avoir :134
Avoir :74
Avoir :14
You loose !
Parties Jouees 7, gagnees 2
true.

  • Partager sur Facebook
  • Partager sur Twitter

Le crayon la gomme et le papier sont les meilleurs outils du programmeur !

13 décembre 2016 à 12:02:25

En effet, c'était loin de ce que j'imaginé. Cela m'a permis de finir le compteur avec la partie perdu

Fait:

teste(Perdu):-compteur(X,Y), Perdu is X - Y.

Prédicat jeu :

 compteur(Joue, Gagne),
        format('Parties Jouees ~w, gagnees ~w~n', [Joue, Gagne]),
        teste(Perdu),
        write('Partie perdu : '),write(Perdu)


Je tiens à vous remercier pour l'attention portée sur mon sujet et l'aide que vous m'avais apporté.

Respectueusement.

  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
8 mai 2021 à 1:17:11

Bonsoir, j'aimerai savoir comment faire pour afficher la mise initiale qu'on  mit au debut car ça m'affiche toujours la dernière mise que le joueur a pu mettre.
  • Partager sur Facebook
  • Partager sur Twitter
8 mai 2021 à 2:36:42

@TafsouthSaighi Bonsoir, merci de ne pas déterrer d'ancien sujet résolu.

Déterrage

Citation des règles générales du forum :

Avant de poster un message, vérifiez la date du sujet dans lequel vous comptiez intervenir.

Si le dernier message sur le sujet date de plus de deux mois, mieux vaut ne pas répondre.
En effet, le déterrage d'un sujet nuit au bon fonctionnement du forum, et l'informatique pouvant grandement changer en quelques mois il n'est donc que rarement pertinent de déterrer un vieux sujet.

Au lieu de déterrer un sujet il est préférable :

  • soit de contacter directement le membre voulu par messagerie privée en cliquant sur son pseudonyme pour accéder à sa page profil, puis sur le lien "Ecrire un message"
  • soit de créer un nouveau sujet décrivant votre propre contexte
  • ne pas répondre à un déterrage et le signaler à la modération

Je ferme ce sujet. En cas de désaccord, me contacter par MP.

  • Partager sur Facebook
  • Partager sur Twitter