Jeu de la vie, TP n°10

Un menu au démarrage

Ajouter un menu au début du programme, pour avoir le choix entre « hasard » et « dessin de la configuration ». Pour l'instant le choix « dessin de la configuration » se contentera d'afficher le terrain vide, d'attendre l'appui sur une touche (au choix), et de construire un planeur (Planeur).
vie04.py [Cacher les numéros de ligne]
  1. # -*- coding: utf-8 -*-
  2. import random,curses
  3.  
  4. ##############################################
  5. ####    CALCUL DE LA TAILLE DE L'ÉCRAN    ####
  6. ##############################################
  7. def tailleecran() :
  8.     nblgn,nbcol=ecran.getmaxyx()            # nombre de lignes et de colonnes
  9.     nblgn=nblgn-haut-bas                    # ajuster en fonction des lignes vides
  10.     nbcol=nbcol-gauche-droite               # ajuster en fonction des colonnes vides
  11.     return nblgn,nbcol
  12.  
  13. #####################################
  14. ####    CREATION DES TABLEAUX    ####
  15. #####################################
  16. def creation() :
  17.     global tableau
  18.     for l in range(0,nblgn) :               # pour chaque ligne
  19.         tableau.append([vide]*nbcol)        # créer la ligne
  20.         prochaine.append([vide]*nbcol)      # créer la ligne
  21.  
  22. #####################################
  23. ####    REMPLISSAGE ALÉATOIRE    ####
  24. #####################################
  25. def remplissage_aleatoire() :
  26.     global tableau
  27.     proportion=random.random()              # proportion espace/étoile
  28.     for l in range(0,nblgn) :               # pour chaque ligne
  29.         for c in range(0,nbcol) :           # pour chaque colonne
  30.             if random.random()<proportion : # si tirage aléatoire dans la bonne proportion
  31.                 tableau[l][c]=vide          # ajouter un espace
  32.             else :                          # sinon
  33.                 tableau[l][c]=plein         # ajouter une étoile
  34.  
  35. #####################################
  36. ####    REMPLISSAGE À LA MAIN    ####
  37. #####################################
  38. def remplissage_dessine() :
  39.     global tableau
  40.     tableau[1][1]=plein
  41.     tableau[1][2]=plein
  42.     tableau[1][3]=plein
  43.     tableau[2][3]=plein
  44.     tableau[3][2]=plein
  45.  
  46. ##############################################
  47. ####    PREMIER REMPLISSAGE DU TABLEAU    ####
  48. ##############################################
  49. def remplissage() :
  50.     choisir=[ord(" ")]                             # liste des touches pour sortir
  51.     liste=["hasard","dessin de la configuration"]  # liste des messages
  52.     l0,c0=4,4                                      # décalages horizontal et vertical
  53.     # message d'invite
  54.     ecran.addstr(l0-1,c0,"Faites votre choix, puis appuyez sur \"espace\" :")
  55.     # calcul de longueur maximale
  56.     l=0
  57.     for i in range(0,len(liste)) :
  58.         if len(liste[i])>l :
  59.             l=len(liste[i])
  60.     # égalisation des longueurs des message
  61.     for i in range(0,len(liste)) :
  62.         while len(liste[i])<l :
  63.             liste[i]+=" "
  64.     choix=0                                    # initialisation du choix
  65.     k=0                                        # touche tapée
  66.     while k not in choisir :                   # TQ pas une touche de sortie
  67.         if k==curses.KEY_DOWN :   # descendre
  68.             choix=(choix+1) % len(liste)
  69.         elif k==curses.KEY_UP :   # monter
  70.             choix=(choix-1) % len(liste)
  71.         # afficher les messages
  72.         for i in range(0,len(liste)) :
  73.             if i==choix :         # le choix actuellement sélectionné
  74.                 ecran.addstr(l0+i,c0+2," "+liste[i]+" ",INVERSE)
  75.             else :                # un autre choix
  76.                 ecran.addstr(l0+i,c0+2," "+liste[i]+" ",NORMAL)
  77.         k=ecran.getch()                        # attendre frappe au clavier
  78.     if choix==0:
  79.         remplissage_aleatoire()
  80.     elif choix==1:
  81.         remplissage_dessine()
  82.  
  83. #################################################
  84. ####    CALCUL DE LA PROCHAINE GÉNÉRATION    ####
  85. #################################################
  86. def generation() :
  87.     global tableau,prochaine,generations
  88.     for l in range(0,nblgn) :               # pour chaque ligne
  89.         for c in range(0,nbcol) :           # pour chaque colonne
  90.             n=voisins(l,c)                  # nombres de voisiuns de la case
  91.             #  si (case vivante avec 2 voisins) ou si 3 voisins
  92.             if (n==2 and tableau[l][c]==plein) or (n==3) :
  93.                 prochaine[l][c]=plein       # case vivante à la prochaine génération
  94.             else :
  95.                 prochaine[l][c]=vide        # case vide à la prochaine génération
  96.     for l in range(0,nblgn) :               # pour chaque ligne
  97.         for c in range(0,nbcol) :           # pour chaque colonne
  98.             tableau[l][c]=prochaine[l][c]   # recopier la nouvelle génération
  99.     generations+=1                          # une génération de plus
  100.  
  101. #########################
  102. ####    AFFICHAGE    ####
  103. #########################
  104. def affichage() :
  105.     global nblgn,nbcol,tableau,prochaine
  106.     exnblgn,exnbcol=nblgn,nbcol                   # auvegarde de la taille ancienne
  107.     nblgn,nbcol=tailleecran()                     # calcul de la taille de l'écran
  108.     if (exnblgn,exnbcol)!=(nblgn,nbcol) :         # si le monde a changé de taille
  109.         ## sauvegarde du monde actuel ##
  110.         for l in range(0,exnblgn) :               # pour chaque ligne
  111.             for c in range(0,exnbcol) :           # pour chaque colonne
  112.                 prochaine[l][c]=tableau[l][c]     # recopier la nouvelle génération
  113.         ## re-création du monde à la bonne taille ##
  114.         tableau=[]                                # tableau vide
  115.         for l in range(0,nblgn) :                 # pour chaque ligne
  116.             tableau.append([vide]*nbcol)          # créer la ligne
  117.         ## recopie des données sauvegardées ##
  118.         for l in range(0,min(nblgn,exnblgn)) :    # pour chaque ligne
  119.             for c in range(0,min(nbcol,exnbcol)) :# pour chaque colonne
  120.                 tableau[l][c]=prochaine[l][c]     # recopier la nouvelle génération
  121.         ## re-création du tableau "prochaine" à la bonne taille ##
  122.         prochaine=[]                              # tableau vide
  123.         for l in range(0,nblgn) :                 # pour chaque ligne
  124.             prochaine.append([vide]*nbcol)        # créer la ligne
  125.         ecran.clear()                             # effacer les restes
  126.     for l in range(0,nblgn) :                     # pour chaque ligne
  127.         for c in range(0,nbcol) :                 # pour chaque colonne
  128.             ecran.addstr(l+haut,c+gauche,tableau[l][c])   # case correspondante
  129.     ecran.addstr(nblgn+haut,gauche,str(generations)+"° génération. ") # n° de génération
  130.     ecran.addstr(str(nbcol)+"x"+str(nblgn))       # affiche la taille du monde
  131.     ou=""                                         # entre les choix (vide pour le 1er)
  132.     sortir=""                                     # message à afficher
  133.     for q in sortie :                             # pour toutes les touches de sortie
  134.         sortir=sortir+ou+"« "+chr(q)+" »"         # ajouter la touche
  135.         ou=" ou "                                 # entre les choix ("ou" à partir du 2°)
  136.     ecran.addstr(". Pour sortir, appuyer sur "+sortir+".") # afficher le message
  137.  
  138. ###################################
  139. ####    COMPTER LES VOISINS    ####
  140. ###################################
  141. def voisins(l,c) :
  142.     lavant,lapres,cavant,capres=l-1,l+1,c-1,c+1 # les bornes d'exploration
  143.     if lavant<0 : lavant=nblgn-1                # pour la ligne du haut
  144.     if lapres>=nblgn : lapres=0                 # pour la ligne du bas
  145.     if cavant<0 : cavant=nbcol-1                # pour la colonne de gauche
  146.     if capres>=nbcol : capres=0                 # pour la colonne de droite
  147.     nbre=0                                      # initialisation du compteur
  148.     for ll in [lavant,l,lapres] :               # pour les 3 lignes entourant la case
  149.         for cc in [cavant,c,capres] :           #  pour les 3 colonnes entourant la case
  150.             # pour chaque case occupée qui n'est pas la case elle-même
  151.             if (ll!=l or cc!=c) and tableau[ll][cc]==plein :
  152.                 nbre+=1                         # ajouter 1 au compteur
  153.     return nbre                                 # retourner la valeur du compteur
  154.  
  155. ####################################
  156. ####    ATTENTE ET FERMETURE    ####
  157. ####################################
  158. def finir() :
  159.     curses.endwin()             # revenir à la console
  160.  
  161. ###############################
  162. ####    INITIALISATIONS    ####
  163. ###############################
  164. ecran=curses.initscr()           # créer l'écran graphique
  165. ecran.nodelay(1)                 # getch() non bloquant
  166. curses.curs_set(False)           # pas d'affichage du curseur
  167. ecran.keypad(True)               # codage des touches de fonctions en 1 octet
  168. curses.start_color()             # utilisation des couleurs
  169. # premier jeu de couleur pour l'affichage normal
  170. curses.init_pair(1,curses.COLOR_WHITE,curses.COLOR_BLACK)
  171. NORMAL=curses.color_pair(1)+curses.A_BOLD
  172. # deuxième jeu de couleur pour l'affichage inversé
  173. curses.init_pair(2,curses.COLOR_BLACK,curses.COLOR_WHITE)
  174. INVERSE=curses.color_pair(2)+curses.A_BOLD
  175. gauche,droite=1,1                # décalage horizontal
  176. haut,bas=1,2                     # décalage vertical
  177. nblgn,nbcol=tailleecran()        # calcul de la taille de l'écran
  178. sortie=[ord('q'),ord('Q')]       # touches pour finir
  179. tableau=[]                       # création du tableau vide
  180. prochaine=[]                     # création du tableau pour la prochaine génération
  181. plein="*"                        # contenu d'une case pleine
  182. vide=" "                         # contenu d'une case vide
  183. generations=0                    # nombre de générations
  184.  
  185. ##################################
  186. ####    CORPS DU PROGRAMME    ####
  187. ##################################
  188. creation()                      # création des tableaux
  189. remplissage()                   # remplissage initial du tableau
  190. k=0                             # initialisation pour rentrer dans la boucle
  191. while k not in sortie :         # TQ on n'a pas appuyé sur une touche pour sortir
  192.     affichage()                 # affichage de la génération courante
  193.     generation()                # calcul de la génération suivante
  194.     k=ecran.getch()             # récupérér la touche sur laquelle on a appuyé
  195. finir()                         # sortir de l'écran graphique
Dernière modification : 25/8/2016