Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Exercice][Novice]Le jeu du plus ou moins

8 juillet 2010 à 20:21:34

Disons que c'est plus un exercice de style. Sinon, le programme ne marche pas chez moi :


# -*- coding: utf-8 -*-
from random import randrange

nombre_mystere = randrange(1, 100)

def plus_ou_moins(nombre_entre, nb_coups, nombre_mystere):
    if nombre_entre == nombre_mystere:
        print "Bravo, réussi en %d coups" %nb_coups
    else:
        return plus_ou_moins(int(input(["=", "<", ">"][cmp(nombre_entre, nombre_mystere)])),
                             nb_coups + 1, nombre_mystere)


plus_ou_moins(input(), 1, nombre_mystere)


candide@~/python/sdz/autres$ python3 plusmoins_maxi.py 
  File "plusmoins_maxi.py", line 8
    print "Bravo, réussi en %d coups" %nb_coups
                                     ^
SyntaxError: invalid syntax
candide@~/python/sdz/autres$
  • Partager sur Facebook
  • Partager sur Twitter
8 juillet 2010 à 20:29:19

C'est-à-dire ? La fonction ne doit pas remettre le nombre à chaque fois...
Si tu veux parler de ma variable nombre_mystere, effectivement, elle ne sert à rien, j'avais prévu un autre plan au départ en fait et j'en avais besoin. D'ailleurs, mon return est inutile aussi. Ce qui donne :
from random import randrange

def plus_ou_moins(nombre_entre, nb_coups, nombre_mystere):
    if nombre_entre == nombre_mystere:
        print "Bravo, réussi en %d coups" % nb_coups
    else:
        plus_ou_moins(int(input(["=", "<", ">"][cmp(nombre_entre, nombre_mystere)])),
                             nb_coups + 1, nombre_mystere)


plus_ou_moins(input(), 1, randrange(1, 100))
  • Partager sur Facebook
  • Partager sur Twitter
8 juillet 2010 à 20:34:12

Non le problème est que, comme mon code console le montre, j'ai exécuté avec Python 3, et il me semblait que c'était cette version que tu utilisais jusqu'à présent ...
  • Partager sur Facebook
  • Partager sur Twitter
8 juillet 2010 à 20:37:33

Mmh, je répondais à fred. Soit l'anti grillé n'a pas marché, soit j'avais pas assez actualisé, mais je n'avais pas vu ton message.

Effectivement, je l'ai écrit sous Python 2.6.
J'utilise un peu les deux en fait, si tu mets des parenthèses ça devrait aller. Enfin c'est vrai que du coup mon input devrait se transformer en raw_input.
Comme ça, je vous laisse choisir quel problème corriger selon la version que vous préférez.
  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
8 juillet 2010 à 20:39:25

Pour moi c'est ok, je n'avais pas remarqué que tu imposais lors de l'execution de ta fonction le nombre de coups, It's good

:)
  • Partager sur Facebook
  • Partager sur Twitter
8 juillet 2010 à 20:41:43

Je n'impose pas le nombre de coups, c'est un compteur que je mets dans les arguments pour le transmettre à la récursion suivante.
  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
8 juillet 2010 à 20:48:29

Citation

Je n'impose pas le nombre de coups



On c'est pas compris, tu n'imposes pas le nombre de coups, tu imposes l'initialisation de nb_coups dans l'execution de ta fonction.

Citation

c'est un compteur que je mets dans les arguments pour le transmettre à la récursion suivante



Oui oui j'avais compris :)
  • Partager sur Facebook
  • Partager sur Twitter
8 juillet 2010 à 23:51:20

voila pour moi version simple :-° :
from random import randrange
nb=int(randrange(101))
print("qu'elle est le nombre mistere?")
mise=-1
tentative=0
quitter=True
while quitter:
	mise=int(input())
	tentative+=1

	if mise==nb:
		print("felicitation vous avez gagnger avec",tentative,"tentatives")
		print("voulez-vous quitter O/N?")
		quitter=input()
		if quitter=="o" or quitter=="O":
			print("bye!")
			quitter=False
		else:
			print("qu'elle est le nombre mistere?")
			nb=int(randrange(101))
			continue
	elif mise<nb:  
        	print("c'est plus grand ")
	elif mise>nb:
        	print("c'est plus petit")
	continue
  • Partager sur Facebook
  • Partager sur Twitter
9 juillet 2010 à 1:34:43

Voici ma version, j'ai juste mis le compteur de coups et le jeu. ( Les autres trucs sont pas dur à faire, je voulais juste faire la base.)
Aussi, c'est Python 3.1.
#-*- coding: Latin-1 -*-

from random import randrange

nombre_cache, nombre_entre, nombre_coups = randrange(100), -1, 0

while nombre_entre != nombre_cache:
    try:
        nombre_entre = int(input('Nombre ? '))
    except ValueError:
        print("Vous n'avez pas entrer un nombre.")
        continue
    nombre_coups += 1

    if nombre_entre == nombre_cache:
        print('Bravo vous avez trouvé en {0} coups'.format(nombre_coups))
    elif nombre_entre < nombre_cache:
        print('Trop petit, désolé...')
    elif nombre_entre > nombre_cache:
        print('Trop grand, désolé...')
  • Partager sur Facebook
  • Partager sur Twitter
9 juillet 2010 à 2:35:55

Citation : Eiji Okuda

Voici ma version,




Pas mal.

Quelques remarques :

*) il n'est pas normal que le jeu s'arrête définitivement parce que mon doigt a rippé et enfoncé la touche 'Z' au lieu de '2' ;) il faut que le programme soit indulgent et me laisse une chance.
*) Il serait bien qu'on ait une version "hard" qui s'interrompe si le joueur ne trouve pas en moins de X coups (X calculable au départ par dichotomie, avec une petite marge pour pas être trop méchant :p ).

J'ajouterais qu'il serait souhaitable, vu l'engouement que suscite ce jeu auprès des débutants, que nous disposions d'un code (voire de plusieurs, à plusieurs niveaux s'entend) que l'on pourrait qualifier de "référence" et auquel on pourrait renvoyer les débutants qui cherchent à avoir une correction-modèle.
  • Partager sur Facebook
  • Partager sur Twitter
9 juillet 2010 à 10:11:25

*) Le code ne s'arrête pas il recommence juste la boucle et j'ai fait en sorte que cela n'ajoute pas un coups (Du moins le code me dit cela :p ).
*) Max coups = 10 pour pas être méchant ?

Pour la version de référence, si quelqu'un veut s'en occuper, il faudrait que le code soit en python 3.1, commenté correctement et lisible surtout ( Parce que cmp le débutant il ne connait pas... Et que les if machin : print('lol') sur une ligne c'est moche.

Je veux bien essayer de le faire à partir de mon code mais il faudrait un truc qui soit toutes fonctionnalités ou simplement le jeu ?

Edit :

Voila un code commenté sans les ajouts (Je sait pas ceux qui sont souhaités pour le programme de référence) écrit en v3.1 et qui respecte je pense la plupart des standards établis par la PEP 8.


#-*- coding: Latin-1 -*-
# Ce fichier est un programme du jeu plus ou moins, exercice pour novices, 
# il a pour but de se rapprocher le plus possible d'un code de référence
# qui serait correctement commenté et facile à comprendre pour un novice.
# Cette version comprend un compteur de coups et la gestion des exceptions.
# De plus elle est codée en version de Python 3.1.


# On importe la fonction randrange pour définir le nombre aléatoire.
from random import randrange

# On initialise les variables qu'on utilisera.
nombre_cache, nombre_entre, nombre_coups = randrange(100), -1, 0

# Boucle qui sera exécutée tant que l'utilisateur ne trouve pas le bon nombre.
while nombre_entre != nombre_cache:
    
	# On vérifie que la donnée que l'utilisateur entre est bien un nombre
	# entier, s'il ne l'est pas, on relance la boucle sans exécuter les 
	# instructions qui suivent.
    try:
        nombre_entre = int(input('Nombre ? '))
    except ValueError:
        print("Vous n'avez pas entrer un nombre.")
        continue
		
	# Comme il a entré un nombre on peut maintenant incrémenter la variable
    nombre_coups += 1

	# Code servant à tester si l'utilisateur à trouvé la solution ou a lui
	# donner des indications.
    if nombre_entre == nombre_cache:
        print('Bravo vous avez trouvé en {0} coups'.format(nombre_coups))
    elif nombre_entre < nombre_cache:
        print('Trop petit, désolé...')
    elif nombre_entre > nombre_cache:
        print('Trop grand, désolé...')


Les commentaires et critiques sont bien sûre les bienvenues.
  • Partager sur Facebook
  • Partager sur Twitter
9 juillet 2010 à 11:36:05

Citation : Eiji Okuda

*) Le code ne s'arrête pas



Le jeu s'arrête en cas d'erreur dans les entrées :


candide@~/python/sdz/autres$ python plusmoins.py
Nombre ? 5
Trop petit, désolé...
Nombre ? a
Traceback (most recent call last):
  File "plusmoins.py", line 9, in <module>
    nombre_entre = int(input('Nombre ? '))
  File "<string>", line 1, in <module>
NameError: name 'a' is not defined
candide@~/python/sdz/autres$




Citation : Eiji Okuda

.
*) Max coups = 10 pour pas être méchant ?



Oui mais à condition que le nombre soit entre 1 et 1000 (2**10 environ 1000).

  • Partager sur Facebook
  • Partager sur Twitter
9 juillet 2010 à 12:31:33

Erreur d'indentation du try au copier coller ;)

Edit : Voilà, ça devrait fonctionner.
  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
9 juillet 2010 à 13:34:45

Toujours pareil

Nombre ? 50
Trop petit, désolé...
Nombre ? A

Traceback (most recent call last):
  File "C:/Users/Fred/Desktop/test.py", line 13, in <module>
    nombre_entre = int(input('Nombre ? '))
  File "<string>", line 1, in <module>
NameError: name 'A' is not defined


Enlève juste ValueError dans ton except

Proposition d'amélioration :

1) Créer un menu
2) Créer différents niveaux
3) Limiter le nombre de coups, car si tu gagnes en 50 coups... ce qui permet de gagner ou de perdre, c'est mieux dans un jeu.

  • Partager sur Facebook
  • Partager sur Twitter
9 juillet 2010 à 14:41:06

Citation : fred1599


Proposition d'amélioration :

1) Créer un menu
2) Créer différents niveaux
3) Limiter le nombre de coups, car si tu gagnes en 50 coups... ce qui permet de gagner ou de perdre, c'est mieux dans un jeu.



Less is more.
  • Partager sur Facebook
  • Partager sur Twitter
21 septembre 2010 à 9:52:26

Je l'ai fait avec toutes les options sauf les différents niveaux de difficulté !
si vous avez des commentaires ou remarques elles sont les bienvenues !

# Jeu du plus ou moins
# Le programme choisit un nombre aléatoire entre 1 et 100
# L'utilisateur est invité a entrer un nombre jusqu'a qu'il trouve le bon !
# Le programme propose de recommencer la partie tant que l'utilisateur tape "O"
# L'utilisateur doit entrer un nombre entier et rien d'autre sinon une exeption est levée

from random import randrange

def nombre():
    flag = 0
    trouv = randrange(1, 101)
    while 1:
        res = int(input("Entrez un nombre entre 1 et 100: "))
        flag = flag + 1
        if res < trouv and res>0:
            print("C'est trop petit !")
        elif res > trouv and res<101:
            print ("C'est trop grand !")
        elif res<1 or res>100:
            print ("Le nombre entré doit se situer entre 1 et 100 !")
        else:
            print("Bravo, vous avez trouvé ! le nombre ",str(trouv), " en ", flag, " coups !")
            break

try:
    nombre()
except ValueError:
    print("Vous devez entrer un nombre entier !")
    while 1:
        rej = input("Tapez <O> pour rejouer ou <Enter> pour quitter ! ")
        if rej=="o" or rej=="O":
            try:
                nombre()
            except ValueError:
                print("Vous devez entrer un nombre entier !")
        else:
            break


Edition du post, j'ai rajouté une exeption si l'utilisateur ne rentre pas un nombre entié !
  • Partager sur Facebook
  • Partager sur Twitter
28 octobre 2010 à 22:46:03

Voici ma première version.

from random import randint

nombre_a_trouver = randint(1,100)

print ("Donner un nombre : ")
nombre = int(input())

while nombre_a_trouver != nombre:
    if nombre < nombre_a_trouver :
        print ("Plus")
        print ("Donner un nombre : ")
        nombre = int(input())

    elif nombre > nombre_a_trouver :
        print ("Moins")
        print ("Donner un nombre : ")
        nombre = int(input())

    else :
        print ("Vous avez gagne !!")


Seul problème dans ce code quand je trouve le nombre la phrase vous avez gagner ne s'affiche pas.
Si quelqu'un pourrait m'expliquer pourquoi.
Merci d'avance.
  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
29 octobre 2010 à 0:18:58

Lorsque tu sors de la boucle, alors tu annonces que tu as gagné, ça me semble beaucoup plus logique, non?

  • Partager sur Facebook
  • Partager sur Twitter
29 octobre 2010 à 0:45:52

Citation : valdeco

Voici ma première version.



Pas testé ton code mais, déjà, il y a de la duplication de code évitable.
  • Partager sur Facebook
  • Partager sur Twitter
29 octobre 2010 à 1:01:09

Citation : fred1599

Lorsque tu sors de la boucle, alors tu annonces que tu as gagné, ça me semble beaucoup plus logique, non?



La logique c'est pas de la magie, il faut savoir l'expliquée ;)

Dans ce cas là valdeco tu peux voir que ton else est dans ta boucle while et il ne s'executera donc que si nombre_a_trouver != nombre , c'est à dire jamais :) .
  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
29 octobre 2010 à 5:41:01

Je n'ai jamais vu que l'on créé une boucle magiquement :)

En gros ton code pourrait comme le dit Candide être beaucoup plus simplifié.

from random import randint

nb_mystere = randint(0, 50)

while True: # boucle infinie
    nb=int(input("Entre un nombre entre 1 et 50 :"))

    if nb == nb_mystere :
        print("Vous avez gagné")
        break # on sort de la boucle

    else :
        if nb < nb_mystere :
            print("Le nombre mystère est plus grand") # on revient à la boucle

        else :
            print("le nombre mystère est plus petit") # on revient à la boucle
  • Partager sur Facebook
  • Partager sur Twitter
29 octobre 2010 à 16:10:14

J'ai simplifié mon code comme vous me l'avez montré et j'ai rajouté la possibilité de rejouer ou de ne pas rejouer.
Je pense (j'en suis sur) que je peux faire plus cours pour rejouer mais je ne trouve pas comment.

Voici mon code :
from random import randint

nombre_a_trouver = randint(1 , 100)

while True :
    print ("Donner un nombre entre 1 et 100 :")
    nombre_joueur = int(input())

    if nombre_joueur == nombre_a_trouver:
        print ("Vous avez gagner !")
        break

    else:
        if nombre_a_trouver > nombre_joueur :
            print ("Plus")

        else :
            print ("Moins")

print ("Veux tu rejouer")
print ("1 : Oui")
print ("2 : Non")
decision = int(input())

if decision == 1 :
    nombre_a_trouver = randint(1 , 100)

    while True :
        print ("Donner un nombre entre 1 et 100 :")
        nombre_joueur = int(input())

        if nombre_joueur == nombre_a_trouver:
            print ("Vous avez gagner !")
            break

        else:
            if nombre_a_trouver > nombre_joueur :
                print ("Plus")

            else :
                print ("Moins")

if decision == 2 :
    quit
  • Partager sur Facebook
  • Partager sur Twitter
29 octobre 2010 à 16:47:03

Citation : fred1599


from random import randint

nb_mystere = randint(0, 50)

while True: # boucle infinie
    nb=int(input("Entre un nombre entre 1 et 50 :"))

    if nb == nb_mystere :
        print("Vous avez gagné")
        break # on sort de la boucle

    else :
        if nb < nb_mystere :
            print("Le nombre mystère est plus grand") # on revient à la boucle

        else :
            print("le nombre mystère est plus petit") # on revient à la boucle


Cela me semble être la meilleure façon de faire [au passage, c'est l'occasion de se poser la question : la boucle infinie est-elle expliquée dans le cours ? car quand on débute, les boucles infinies ça fait très bizarre. Or c'est une notion extrêmement commode et souple ]. Mais pourquoi ce else/if/else au lieu d'un elif/else ?
  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
29 octobre 2010 à 17:27:13

Citation

Mais pourquoi ce else/if/else au lieu d'un elif/else ?



Bonne question, j'ai déliré :p

Citation

la boucle infinie est-elle expliquée dans le cours ?



Ba ça c'est une question pour le PO, cependant je ne suis pas du même avis que toi, je pense que la boucle infinie est très compréhensible, ce n'est que mon avis. Encore une fois le PO pourra mieux juger.

Edit : Code modifié

from random import randint

nb_mystere = randint(0, 50)

while True: # boucle infinie
    nb=int(input("Entre un nombre entre 1 et 50 :"))

    if nb == nb_mystere :
        print("Vous avez gagné")
        break # on sort de la boucle

    elif nb < nb_mystere :
        print("Le nombre mystère est plus grand") # on revient à la boucle

    else :
        print("le nombre mystère est plus petit") # on revient à la boucle
  • Partager sur Facebook
  • Partager sur Twitter
29 octobre 2010 à 17:38:19

Citation : Candide

la boucle infinie est-elle expliquée dans le cours ?



Non pas où j'en suis mais je suis d'accord avec fred1599 la boucle infinie est très compréhensible.

Citation : Candide

Mais pourquoi ce else/if/else au lieu d'un elif/else ?



Eh bien je ne vois pas trop la différence entre les elif et les if.

EDIT : Je voudrais que quand je rejoue l'écran s'efface.
J'ai donc utilisé os_system(clear) mais du coup la fenetre s'éteint.
Si quelqu'un sait comment faire
  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
29 octobre 2010 à 18:04:50

Eh bien je ne vois pas trop la différence entre les elif et les if

doc officielle

Citation

Je voudrais que quand je rejoue l'écran s'efface



berk! Mais si tu insistes cela doit fonctionner

from random import randint
from os import system

nb_mystere = randint(0, 50)

while True: # boucle infinie
    nb=int(input("Entre un nombre entre 1 et 50 :"))

    if nb == nb_mystere :
        print("Vous avez gagné")
        break # on sort de la boucle

    elif nb < nb_mystere :
        system('clear')
        print("Le nombre mystère est plus grand") # on revient à la boucle

    else :
        system('clear')
        print("le nombre mystère est plus petit") # on revient à la boucle


  • Partager sur Facebook
  • Partager sur Twitter
29 octobre 2010 à 18:14:30

Je veux que l'écran s'efface que au moment ou le joueur décide de rejouer une partie.

if decision == 1 :

    system('clear')


Mais je ne comprends pas pourquoi cela ne marche pas.
  • Partager sur Facebook
  • Partager sur Twitter
29 octobre 2010 à 18:36:22

Citation : fred1599


Ba ça c'est une question pour le PO, cependant je ne suis pas du même avis que toi, je pense que la boucle infinie est très compréhensible, ce n'est que mon avis. Encore une fois le PO pourra mieux juger.



La boucle infinie est très compréhensible une fois qu'on la comprise ;) comme dirait Monsieur de la Palice.



Je ne dis pas que la boucle infinie soit incompréhensible, personnellement je la comprends très bien, je dis que dans l'ordre d'apprentissage (la seule chose qui m'intéresse ici), elle a toutes les raisons de paraître mystérieuse au débutant et je pense qu'il faut déjà posséder une certaine maturité en programmation pour l'utiliser à bon escient, cela correspond d'ailleurs à mon expérience d'enseignement de Python à des débutants complets en programmation et à des mojns débutants (la boucle while seule est en fait assez difficile à comprendre et à appliquer à des gens qui n'ont jamais pratiqué de boucles).

En pratique, on demande d'abord de maîtriser les boucles while "normales" avant d'utiliser les boucles infinies ; ensuite, une fois les boucles infinies introduites, la personne va finir par se demander à quoi les boucles while "normales" servent puisqu'on peut les remplacer par des boucles infinies. Enfin, utiliser une boucle infinie nécessite de connaître l'instruction break ce qui n'est pas nécessaire pour utiliser l'instruction while (et donc c'est un truc de plus à apprendre).


Concernant le cours officiel et la boucle infinie, il en parle ICI mais selon moi assez mal. D'abord, c'est une mauvaise pratique pédagogique que d'introduire deux notions nouvelles simultanément. En l'occurrence, l'auteur introduit simultanément l'instruction break et la boucle infinie, ce qui surcharge la compréhension. Or, on peut, bien sûr, parler de la boucle while interrompue par une instruction break sans se limiter aux boucles infinies, je vous laisse le soin de trouver des circonstances où cela s'applique. Par ailleurs, le cours officiel pourrait expliquer que, dans l'exemple choisi, la boucle infinie est de peu d'utilité ici, il est facile de la remplacer par une boucle while usuelle (le cours le suggère mais il aurait dû donner le code complet de substitution). Je signale au passage qu'il est plus pythonnique d'écrire while True que while 1 (style C). De toute façon, l'auteur ne semble pas apprécier particulièrement les boucles infinies. En tous, cas, il a raison de dire qu'en pratique on peut souvent remplacer une boucle infinie par une boucle finie.

Citation : valdeco


Non pas où j'en suis


Ben alors pas bien loin ;)

Citation : valdeco


je suis d'accord avec fred1599 la boucle infinie est très compréhensible.



Hum, qu'est-ce qui te prouve que tu as bien comprise ? Est-tu certain de savoir l'utiliser à bon escient ? Si tu dis ne pas avoir a compris la différence entre if et elif, je suis en droit de me poser la question.


Citation : valdeco

Je voudrais que quand je rejoue l'écran s'efface.
J'ai donc utilisé os_system(clear) mais du coup la fenetre s'éteint.


te perds pas dans ce gendre de détail qui peuvent être assez compliqués à résoudre et qui n'apportent rien à la compréhension de la programmation en Python.

Citation : fred1599

Eh bien je ne vois pas trop la différence entre les elif et les if

doc officielle



Je veux pas dire mais se référer à la doc officielle de Python (particulièrement indigeste lorsqu'on débute) plutôt qu'au cours du sdz laisserait presque penser, si la différence entre if et elif n'est pas faite, ce qui est un problème très classique chez les débutants, que ce cours du sdz est incomplet ou mal fait.

Citation : fred1599

Eh bien je ne vois pas trop la différence entre les elif et les if

doc officielle

Citation

Je voudrais que quand je rejoue l'écran s'efface



berk! Mais si tu insistes cela doit fonctionner

from random import randint
from os import system

nb_mystere = randint(0, 50)

while True: # boucle infinie
    nb=int(input("Entre un nombre entre 1 et 50 :"))

    if nb == nb_mystere :
        print("Vous avez gagné")
        break # on sort de la boucle

    elif nb < nb_mystere :
        system('clear')
        print("Le nombre mystère est plus grand") # on revient à la boucle

    else :
        system('clear')
        print("le nombre mystère est plus petit") # on revient à la boucle





code duplication detected ! Et tu as vérifié que ça marchait sous tous les sytèmes, en particulier avec IDLE ?


Citation : valdeco

Je veux que l'écran s'efface que au moment ou le joueur décide de rejouer une partie.

if decision == 1 :

    system('clear')





Mais je ne comprends pas pourquoi cela ne marche pas.






In code we trust !
  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
29 octobre 2010 à 18:51:33

Citation

code duplication detected



De quoi parles-tu ? Je ne vois pas.

Citation

Et tu as vérifié que ça marchait sous tous les systèmes, en particulier avec IDLE ?



Tu parles du clear ? Si oui, il est évident que cela ne fonctionne que sous Linux et je ne travaille que sous Linux

Le fait de m'avoir indiqué 'clear' dans son code... D'ailleurs j'y pense, il n'a pas donné de message d'erreur. Je crois que le PO a déjà d'autres problèmes à résoudre.
  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
29 octobre 2010 à 19:01:45

En faite, le problème avec IDLE, c'est que cela ne fonctionnera pas et sous windôb$ avec 'cls' ça ouvrira en plus une console pour rien. ;)
  • Partager sur Facebook
  • Partager sur Twitter