12.07.2015 Views

Chapitre 5 Le jeu de Juniper Green - Apprendre en ligne.net

Chapitre 5 Le jeu de Juniper Green - Apprendre en ligne.net

Chapitre 5 Le jeu de Juniper Green - Apprendre en ligne.net

SHOW MORE
SHOW LESS
  • No tags were found...

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Python : objectif <strong>jeu</strong>x <strong>Chapitre</strong> 5<strong>Chapitre</strong> 5<strong>Le</strong> <strong>jeu</strong> <strong>de</strong> <strong>Juniper</strong> <strong>Gre<strong>en</strong></strong>5.1. Nouveaux thèmes abordés dans ce chapitre• objets• classes• métho<strong>de</strong>s• listes• opération sur les listes• les boucles for• tuples5.2. Règles du <strong>jeu</strong><strong>Le</strong> <strong>jeu</strong> a été créé par Richard Porteous, <strong>en</strong>seignant à l'école <strong>de</strong> <strong>Juniper</strong> <strong>Gre<strong>en</strong></strong>, auquel il doit sonnom. Il s'est réellem<strong>en</strong>t fait connaitre grâce à Ian Stewart, qui <strong>en</strong> décrit les règles dans la revue Pour laSci<strong>en</strong>ce, dans le numéro <strong>de</strong> juillet 1997.Ce <strong>jeu</strong> comporte quatre règles :1. <strong>Le</strong> joueur 1 choisit un nombre <strong>en</strong>tre 1 et Nmax.2. À tour <strong>de</strong> rôle, chaque joueur doit choisir un nombre parmi les multiples ou les diviseursdu nombre choisi précé<strong>de</strong>mm<strong>en</strong>t par son adversaire et inférieur à Nmax.3. Un nombre ne peut être joué qu'une seule fois.4. <strong>Le</strong> premier nombre choisi doit être pair.<strong>Le</strong> perdant est le joueur qui ne trouve plus <strong>de</strong> multiples ou <strong>de</strong> diviseurs communs au nombrechoisi par l'adversaire.Exemple <strong>de</strong> partieJouons avec <strong>de</strong>s nombres <strong>en</strong>tre 1 et 20.Je choisis comme nombre <strong>de</strong> départ 2Nombres vali<strong>de</strong>s: [1, 4, 6, 8, 10, 12, 14, 16, 18, 20]Que jouez-vous ? 4Nombres vali<strong>de</strong>s: [1, 8, 12, 16, 20]Je joue 8Nombres vali<strong>de</strong>s: [1, 16]Que jouez-vous ? 16Nombres vali<strong>de</strong>s: [1]Je joue 1Nombres vali<strong>de</strong>s: [3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20]Que jouez-vous ? 11Bravo!Remarque : les nombres <strong>en</strong> gras ont été <strong>en</strong>trés au clavier par le joueur.Didier Müller 5-1 octobre 2012


<strong>Le</strong> <strong>jeu</strong> <strong>de</strong> <strong>Juniper</strong> <strong>Gre<strong>en</strong></strong>5.3. <strong>Le</strong>s objets <strong>en</strong> Python (premier contact)En Python, tout est objet ! On r<strong>en</strong>contre souv<strong>en</strong>t cette phrase dans les livres sur Python et cela <strong>en</strong>dit long sur l'importance <strong>de</strong> ce concept...Qu'est-ce qu'un objet ? Dans un premier temps, nous allons dire que c'est une structure <strong>de</strong>données qui conti<strong>en</strong>t <strong>de</strong>s fonctions permettant <strong>de</strong> la manipuler. On appelle ces fonctions <strong>de</strong>smétho<strong>de</strong>s.Comme l'idée <strong>de</strong> cet ouvrage est <strong>de</strong> partir d'un programme pour découvrir <strong>de</strong> nouveaux concepts,nous allons pr<strong>en</strong>dre comme premier exemple les listes.<strong>Le</strong>s listes form<strong>en</strong>t une classe (la classe 'list'). Un objet est issu d'une classe. Tous les objets <strong>de</strong>cette classe se ressembleront, mais ils auront leur exist<strong>en</strong>ce propre. Par exemple, toutes les listesauront le même aspect (voir § 5.4), mais elles n'auront pas le même cont<strong>en</strong>u.Autre exemple <strong>de</strong> classe v<strong>en</strong>ant <strong>de</strong> la vie courante : une Peugeot 3008 et une Ferrari Testarossasont <strong>de</strong>s objets <strong>de</strong> la classe 'voiture'.5.4. <strong>Le</strong>s listesComme son nom l'indique, une liste est une suite ordonnée <strong>de</strong> valeurs, qui peuv<strong>en</strong>t être <strong>de</strong> typesdiffér<strong>en</strong>ts. <strong>Le</strong>s élém<strong>en</strong>ts sont listés <strong>en</strong>tre <strong>de</strong>ux crochets et séparés par <strong>de</strong>s virgules. On peut aussi voirune liste comme un tableau unidim<strong>en</strong>sionnel où les valeurs sont repérées par un indice. Att<strong>en</strong>tion !Comme dans beaucoup <strong>de</strong> langages, l'indice du premier élém<strong>en</strong>t est 0 et non pas 1.Dans le chapitre 2, nous avions représ<strong>en</strong>té une variable par une boîte cont<strong>en</strong>ant une valeur. Dansle cas d'une liste, la boîte conti<strong>en</strong>t <strong>en</strong> fait une référ<strong>en</strong>ce vers une liste, et non pas la liste elle-même.Cela a une gran<strong>de</strong> importance lorsque l'on veut copier une liste. Si l'on se cont<strong>en</strong>te d'écrirecheese = spamon n'aura pas copié la liste, mais la référ<strong>en</strong>ce vers cette liste, comme indiqué sur le schéma ci<strong>de</strong>ssous:Didier Müller 5-2 octobre 2012


Python : objectif <strong>jeu</strong>x <strong>Chapitre</strong> 5Cela implique que si l'on modifie une <strong>de</strong>s <strong>de</strong>ux listes, l'autre sera modifiée <strong>de</strong> la même façon(voir ci-<strong>de</strong>ssous).Si l'on tapetype(spam), onobti<strong>en</strong>dra la réponse5.4.1. Création <strong>de</strong>s listesPour définir une liste vi<strong>de</strong>, l'instruction est logiquem<strong>en</strong>t :spam = []On peut évi<strong>de</strong>mm<strong>en</strong>t directem<strong>en</strong>t créer une liste avec <strong>de</strong>s élém<strong>en</strong>ts. Par exemple :spam = [2,3,5,7,11]On peut faire <strong>de</strong>slistes <strong>de</strong> listes, parexemple pourreprés<strong>en</strong>ter untableaubidim<strong>en</strong>sionnel.<strong>Le</strong>s élém<strong>en</strong>ts <strong>de</strong> la liste peuv<strong>en</strong>t être <strong>de</strong> types différ<strong>en</strong>ts (ici, l'ordre, un <strong>en</strong>tier, une chaîne <strong>de</strong>caractères, un réel, un caractère et une liste) :spam = [3,"salut",3.1415,"x",[1,2,3]]Si tous les élém<strong>en</strong>ts <strong>de</strong> la liste doiv<strong>en</strong>t avoir la même valeur au départ, on peut multiplier lavaleur désirée par le nombre d'élém<strong>en</strong>ts que l'on veut. Si on veut une liste <strong>de</strong> 10 zéros, on écrira :spam = [0]*10ce qui donnera la liste [0,0,0,0,0,0,0,0,0,0].La fonction range() génère par défaut une séqu<strong>en</strong>ce <strong>de</strong> nombres <strong>en</strong>tiers <strong>de</strong> valeurs croissantes,et différant d'une unité. Si vous appelez range() avec un seul argum<strong>en</strong>t, la liste conti<strong>en</strong>dra unnombre <strong>de</strong> valeurs égal à l'argum<strong>en</strong>t fourni, <strong>en</strong> comm<strong>en</strong>çant à partir <strong>de</strong> zéro (c'est-à-dire querange(n) génère les nombres <strong>en</strong>tiers <strong>de</strong> 0 à n−1). Ainsi,spam = list(range(10))créera la liste [0,1,2,3,4,5,6,7,8,9].On peut aussi utiliser range() avec <strong>de</strong>ux, ou même trois argum<strong>en</strong>ts séparés par <strong>de</strong>s virgules,afin <strong>de</strong> générer <strong>de</strong>s séqu<strong>en</strong>ces <strong>de</strong> nombres plus « sophistiquées » :spam = list(range(3,12))produira la liste [3,4,5,6,7,8,9,10,11]. On voit que range(a,b) génère tous les nombres<strong>en</strong>tiers <strong>de</strong> a jusqu'à b−1.spam = list(range(3,12,2))produira la liste [3,5,7,9,11]. Donc range(a,b,p) génère <strong>de</strong>s nombres <strong>en</strong>tiers <strong>de</strong> a à b−1avec un pas <strong>de</strong> p.Didier Müller 5-3 octobre 2012


<strong>Le</strong> <strong>jeu</strong> <strong>de</strong> <strong>Juniper</strong> <strong>Gre<strong>en</strong></strong>La fonction l<strong>en</strong>s'applique aussiaux chaînes <strong>de</strong>caractères, auxtuples, ... Ce n'estpas une métho<strong>de</strong>spécifique auxlistes.5.4.2. Manipulation <strong>de</strong>s listesLa fonction intégrée l<strong>en</strong> permet <strong>de</strong> connaître la longueur (l<strong>en</strong>gth <strong>en</strong> anglais) <strong>de</strong> la liste :l<strong>en</strong>(spam)donnera comme résultat 5. <strong>Le</strong>s indices <strong>de</strong> la liste spam vont donc <strong>de</strong> 0 à 4.Pour ajouter un élém<strong>en</strong>t <strong>en</strong> fin <strong>de</strong> liste, on a la métho<strong>de</strong> app<strong>en</strong>d() :spam.app<strong>en</strong>d(13)qui donnera la liste [2,3,5,7,11,13]. Remarquez la forme caractéristique d'une métho<strong>de</strong> :objet.métho<strong>de</strong>().On peut aussi <strong>en</strong>lever un élém<strong>en</strong>t <strong>de</strong> la liste avec la métho<strong>de</strong> remove() :spam.remove(5)donnera comme résultat [2,3,7,11,13].Il ne faut pas confondre cette instruction avec <strong>de</strong>l(spam[5]), qui permet d'<strong>en</strong>lever l'élém<strong>en</strong>td'indice 5, donc le 6 ème élém<strong>en</strong>t <strong>de</strong> la liste. Par exemple, si spam=[2,3,5,7,11,13], alors<strong>de</strong>l(spam[5])donnera comme résultat [2,3,5,7,11].On peut aussi facilem<strong>en</strong>t concaténer <strong>de</strong>ux listes avec un simple + :spam = [2,3,5,7,11]cheese = [9,8,7,6,5]fusion = cheese + spamdonnera la liste [9,8,7,6,5,2,3,5,7,11].On peut trier la liste avec la métho<strong>de</strong> sort() :fusion = cheese + spamfusion.sort()donnera la liste [2,3,5,6,7,7,8,9,11,13].Il arrive parfois que l'on doive inverser la liste :fusion.reverse()donnera la liste [11,7,5,3,2,5,6,7,8,9].5.4.3. Accès aux élém<strong>en</strong>ts d'une listeOn peut accé<strong>de</strong>r à un élém<strong>en</strong>t d'une liste <strong>en</strong> précisant son indice, mais on peut aussi accé<strong>de</strong>r àplusieurs élém<strong>en</strong>ts <strong>en</strong> donnant un intervalle ; le résultat sera alors une liste. Repr<strong>en</strong>ons notre listespam et observons quelques exemples :spam = [2,3,5,7,11,13]print(spam[2])donnera comme résultat 5. C'est un nombre <strong>en</strong>tier.print(spam[1:3])donnera comme résultat [3,5]. C'est une liste composée <strong>de</strong>s élém<strong>en</strong>ts spam[1] et spam[2].Didier Müller 5-4 octobre 2012


Python : objectif <strong>jeu</strong>x <strong>Chapitre</strong> 5print(spam[2:3])donnera comme résultat [5]. C'est une liste cont<strong>en</strong>ant un seul élém<strong>en</strong>t.print(spam[2:])donnera comme résultat [5,7,11,13].print(spam[:2])donnera comme résultat [2,3].print(spam[-2])donnera comme résultat 11. C'est le <strong>de</strong>uxième élém<strong>en</strong>t <strong>de</strong>puis la fin <strong>de</strong> la liste.print(spam[-1])donnera comme résultat 13. C'est le <strong>de</strong>rnier élém<strong>en</strong>t <strong>de</strong> la liste.On peut savoir si un élém<strong>en</strong>t apparti<strong>en</strong>t à une liste avec l'instruction in.5 in spamdonnera comme résultat True. On peut aussi connaître l'indice <strong>de</strong> cet élém<strong>en</strong>t :spam.in<strong>de</strong>x(5)donnera comme résultat 2. L'élém<strong>en</strong>t 5 est bi<strong>en</strong> <strong>en</strong> 3 ème position <strong>de</strong> [2,3,5,7,11,13].On peut modifier un élém<strong>en</strong>t <strong>de</strong> la liste. Par exemple,spam[0]=1modifiera la liste spam ainsi :[1,3,5,7,11,13]5.4.4. Copie d'une liste et insertion dans une listeIl y a plusieurs façons <strong>de</strong> copier une liste. La plus courte est :cheese = spam[:]Rappelons <strong>en</strong>core une fois. car c'est important. que cheese = spam ne copie pas la liste, maiscrée une nouvelle référ<strong>en</strong>ce sur la liste spam.Didier Müller 5-5 octobre 2012


<strong>Le</strong> <strong>jeu</strong> <strong>de</strong> <strong>Juniper</strong> <strong>Gre<strong>en</strong></strong>Insertion d'un ou plusieurs élém<strong>en</strong>ts n'importe où dans une listeLa technique du « slicing » (découpage <strong>en</strong> tranches) permet <strong>de</strong> modifier une liste à l'ai<strong>de</strong> du seulopérateur []. On peut insérer un ou <strong>de</strong>s élém<strong>en</strong>ts dans une liste. Par exemple,capitales = ['Paris', 'Rome', 'Berne', 'Vi<strong>en</strong>ne']capitales[2:2] =['Berlin']donnera comme résultat :['Paris', 'Rome', 'Berlin', 'Berne', 'Vi<strong>en</strong>ne']etcapitales[5:5] = ['Oslo', 'Londres']donnera comme résultat :['Paris', 'Rome', 'Berlin', 'Berne', 'Vi<strong>en</strong>ne', 'Oslo', 'Londres']Att<strong>en</strong>tion aux particularités suivantes :• Si vous utilisez l'opérateur [] à la gauche du signe égal pour effectuer une insertion ou unesuppression d'élém<strong>en</strong>t(s) dans une liste, vous <strong>de</strong>vez obligatoirem<strong>en</strong>t y indiquer une« tranche » dans la liste cible (c'est-à-dire <strong>de</strong>ux in<strong>de</strong>x réunis par le symbole :), et non unélém<strong>en</strong>t isolé dans cette liste.• L'élém<strong>en</strong>t que vous fournissez à la droite du signe égal doit lui-même être une liste. Si vousn'insérez qu'un seul élém<strong>en</strong>t, il vous faut donc le mettre <strong>en</strong>tre crochets pour le transformerd'abord <strong>en</strong> une liste d'un seul élém<strong>en</strong>t. Notez bi<strong>en</strong> que l'élém<strong>en</strong>t capitales[1] n'est pas uneliste (c'est la chaîne 'Rome'), alors que l'élém<strong>en</strong>t capitales[1:3] <strong>en</strong> est une.Suppression / remplacem<strong>en</strong>t d'élém<strong>en</strong>tsOn peut aussi supprimer et/ou remplacer <strong>de</strong>s élém<strong>en</strong>ts par « slicing ». Partons <strong>de</strong> cette liste :['Paris', 'Rome', 'Berlin', 'Berne', 'Vi<strong>en</strong>ne', 'Oslo', 'Londres']Remplaçons la tranche [2:5] par une liste vi<strong>de</strong>, ce qui correspond à un effacem<strong>en</strong>t.capitales[2:5] = []produira la liste :['Paris', 'Rome', 'Oslo', 'Londres']Remplaçons une tranche par un seul élém<strong>en</strong>t. Notez <strong>en</strong>core une fois que cet élém<strong>en</strong>t doit luimêmeêtre une liste.capitales[1:3] = ['Madrid']produira la liste :['Paris', 'Madrid', 'Londres']Remplaçons une tranche <strong>de</strong> <strong>de</strong>ux élém<strong>en</strong>ts par une autre qui <strong>en</strong> compte trois.capitales[1:] = ['Lisbonne', 'Prague', 'Moscou']produira la liste :['Paris', 'Lisbonne', 'Prague', 'Moscou']Didier Müller 5-6 octobre 2012


Python : objectif <strong>jeu</strong>x <strong>Chapitre</strong> 55.4.5. <strong>Le</strong>s boucles forEn Python, une boucle for parcourt simplem<strong>en</strong>t une liste :liste = ['a','b','c']for i in liste:print(i,<strong>en</strong>d=' ')écrira a b c.On peut aussi faire <strong>de</strong> simples compteurs avec une boucle for :for i in range(5):print(i,<strong>en</strong>d=' ')écrira 0 1 2 3 4.Exercice 5.1Créez une liste <strong>de</strong> 15 nombres <strong>en</strong>tiers générés au hasard <strong>en</strong>tre 1 et 10. Certains nombres pourronty figurer à plusieurs exemplaires. Écrivez un programme qui recopie cette liste dans une autre, <strong>en</strong>omettant les doublons. La liste finale <strong>de</strong>vra être triée.Exercice 5.2Soi<strong>en</strong>t les listes suivantes :liste1 = [31,28,31,30,31,30,31,31,30,31,30,31]liste2 = ['Janvier','Février','Mars','Avril','Mai','Juin','Juillet','Août','Septembre','Octobre','Novembre','Décembre']Écrivez un programme qui insère dans la secon<strong>de</strong> liste tous les élém<strong>en</strong>ts <strong>de</strong> la première, <strong>de</strong> tellesorte que chaque nom <strong>de</strong> mois soit suivi du nombre <strong>de</strong> jours correspondant :liste2 = ['Janvier',31,'Février',28,'Mars',31, ...]Insérez <strong>en</strong>suite le nombre 29 <strong>en</strong>tre 28 et 'Mars'.liste2 = ['Janvier',31,'Février',28,29,'Mars',31, ...]Exercice 5.3Un nombre premier est un nombre qui n'est divisible que par un et par lui-même (par conv<strong>en</strong>tion,1 n'est pas un nombre premier).Écrivez un programme qui établit la liste <strong>de</strong> tous les nombres premiers compris <strong>en</strong>tre 1 et n, <strong>en</strong>utilisant la métho<strong>de</strong> du crible d'Eratosthène :• Créer une liste <strong>de</strong> n+1 élém<strong>en</strong>ts (disons n=1000), chacun initialisé à la valeur 1.• Pour les indices i allant <strong>de</strong> 2 à n faire :si l'élém<strong>en</strong>t d'indice i vaut 1, mettre à 0 tous les autres élém<strong>en</strong>ts <strong>de</strong> la liste dont lesindices sont <strong>de</strong>s multiples <strong>de</strong> i.• Parcourir toute la liste et écrire les indices <strong>de</strong>s élém<strong>en</strong>ts qui sont restés à 1. Ce sont <strong>de</strong>snombres premiers.5.5. Co<strong>de</strong> du programme# Jeu <strong>de</strong> <strong>Juniper</strong>-<strong>Gre<strong>en</strong></strong>from random import randintDidier Müller 5-7 octobre 2012


<strong>Le</strong> <strong>jeu</strong> <strong>de</strong> <strong>Juniper</strong> <strong>Gre<strong>en</strong></strong>juniper-gre<strong>en</strong>.pyhttp://ow.ly/fkeUw<strong>de</strong>f multiples(n):#r<strong>en</strong>voie la liste <strong>de</strong>s multiples <strong>de</strong> n


<strong>Le</strong> <strong>jeu</strong> <strong>de</strong> <strong>Juniper</strong> <strong>Gre<strong>en</strong></strong>But du <strong>jeu</strong><strong>Le</strong> but du <strong>jeu</strong> est <strong>de</strong> récupérer tous les fruits avant d'avoir reconstitué le puzzle corbeau.Règles du <strong>jeu</strong><strong>Le</strong> plus <strong>jeu</strong>ne joueur comm<strong>en</strong>ce <strong>en</strong> lançant le dé. Ce dé a quatre faces <strong>de</strong> couleur (jaune pour lapoire, vert pour la pomme, bleu pour la prune et rouge pour la cerise), ainsi qu'une face « panier », etune face « corbeau ».• S'il tombe sur une face couleur, il pr<strong>en</strong>d le fruit correspondant à la couleur, et le met dansson panier. S'il n'y a plus <strong>de</strong> fruit sur l'arbre, le joueur passe son tour.• S'il tombe sur « panier », il pr<strong>en</strong>d <strong>de</strong>ux fruits <strong>de</strong> son choix.• S'il tombe sur « corbeau », il place une <strong>de</strong>s pièces <strong>de</strong> puzzle corbeau sur le plateau <strong>de</strong> <strong>jeu</strong>.<strong>Le</strong> <strong>jeu</strong> continue avec le joueur suivant.<strong>Le</strong> gagnant<strong>Le</strong>s joueurs gagn<strong>en</strong>t tous <strong>en</strong>semble s'ils ont réussi à cueillir tous les fruits <strong>de</strong>s arbres.<strong>Le</strong>s joueurs per<strong>de</strong>nt <strong>en</strong>semble si le puzzle corbeau <strong>de</strong> 9 pièces est reconstitué <strong>en</strong>tièrem<strong>en</strong>t avantqu'ils n'ai<strong>en</strong>t pu récupérer tous les fruits.ProgrammeÉcrivez un programme qui simulera 100'000 parties <strong>de</strong> ce <strong>jeu</strong>. Vous indiquerez comme résultat lepourc<strong>en</strong>tage <strong>de</strong> victoires <strong>de</strong>s joueurs, ainsi que le nombre <strong>de</strong> coups moy<strong>en</strong> dans une partie.Exercice 5.8Réécrivez le co<strong>de</strong> <strong>de</strong> l'exercice 2.13 (calcul <strong>de</strong>s probabilités au <strong>jeu</strong> « Risk ») <strong>en</strong> utilisant <strong>de</strong>sboucles for et <strong>de</strong>s listes.5.7. TuplesPython propose un type <strong>de</strong> données appelé tuple, qui est semblable à une liste mais qui n'est pasmodifiable.Du point <strong>de</strong> vue syntaxique, un tuple est une collection d'élém<strong>en</strong>ts séparés par <strong>de</strong>s virgules :alpha = 'a', 'b', 'c', 'd', 'e'print(alpha)donnera comme résultat :('a', 'b', 'c', 'd', 'e')Bi<strong>en</strong> que cela ne soit pas nécessaire, il est fortem<strong>en</strong>t conseillé <strong>de</strong> mettre le tuple <strong>en</strong> évi<strong>de</strong>nce <strong>en</strong>trepar<strong>en</strong>thèses pour améliorer la lisibilité du co<strong>de</strong>. Comme ceci :alpha = ('a', 'b', 'c', 'd', 'e')<strong>Le</strong>s opérations que l'on peut effectuer sur <strong>de</strong>s tuples sont les mêmes que celles que pour les listes,si ce n'est que les tuples ne sont pas modifiables. Il est donc impossible d'ajouter ou <strong>de</strong> supprimer <strong>de</strong>sélém<strong>en</strong>ts d'un tuple. Pour cette raison, ils sont préférables aux listes partout où l'on veut être certainque les données transmises ne soi<strong>en</strong>t pas modifiées par erreur au sein d'un programme.Exercice 5.9Réécrivez le co<strong>de</strong> <strong>de</strong> l'exercice 4.4 (chapitre précé<strong>de</strong>nt), <strong>en</strong> utilisant un tuple pour désigner lestrois coups possibles (pierre, papier ou ciseaux).Didier Müller 5-10 octobre 2012

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!