Jeu de la vie, TP n°9

Modifier la taille du monde

Le programme doit adapter son affichage quand la taille du terminal change. Afficher la taille du monde.
vie03.py [Cacher les numéros de ligne]
  1. # -*- coding: utf-8 -*-
  2. import random,curses
  3. ##############################################
  4. ####    CALCUL DE LA TAILLE DE L'ÉCRAN    ####
  5. ##############################################
  6. def tailleecran() :
  7.     nblgn,nbcol=ecran.getmaxyx()            # nombre de lignes et de colonnes
  8.     nblgn=nblgn-haut-bas                    # ajuster en fonction des lignes vides
  9.     nbcol=nbcol-gauche-droite               # ajuster en fonction des colonnes vides
  10.     return nblgn,nbcol
  11. #####################################
  12. ####    CREATION DES TABLEAUX    ####
  13. #####################################
  14. def creation() :
  15.     global tableau
  16.     for l in range(0,nblgn) :               # pour chaque ligne
  17.         tableau.append([vide]*nbcol)        # créer la ligne
  18.         prochaine.append([vide]*nbcol)      # créer la ligne
  19. ##############################################
  20. ####    PREMIER REMPLISSAGE DU TABLEAU    ####
  21. ##############################################
  22. def remplissage() :
  23.     global tableau
  24.     proportion=random.random()              # proportion espace/étoile
  25.     for l in range(0,nblgn) :               # pour chaque ligne
  26.         for c in range(0,nbcol) :           # pour chaque colonne
  27.             if random.random()<proportion : # si tirage aléatoire dans la bonne proportion
  28.                 tableau[l][c]=vide          # ajouter un espace
  29.             else :                          # sinon
  30.                 tableau[l][c]=plein         # ajouter une étoile
  31. #################################################
  32. ####    CALCUL DE LA PROCHAINE GÉNÉRATION    ####
  33. #################################################
  34. def generation() :
  35.     global tableau,prochaine,generations
  36.     for l in range(0,nblgn) :               # pour chaque ligne
  37.         for c in range(0,nbcol) :           # pour chaque colonne
  38.             n=voisins(l,c)                  # nombres de voisiuns de la case
  39.             #  si (case vivante avec 2 voisins) ou si 3 voisins
  40.             if (n==2 and tableau[l][c]==plein) or (n==3) :
  41.                 prochaine[l][c]=plein       # case vivante à la prochaine génération
  42.             else :
  43.                 prochaine[l][c]=vide        # case vide à la prochaine génération
  44.     for l in range(0,nblgn) :               # pour chaque ligne
  45.         for c in range(0,nbcol) :           # pour chaque colonne
  46.             tableau[l][c]=prochaine[l][c]   # recopier la nouvelle génération
  47.     generations+=1                          # une génération de plus
  48. #########################
  49. ####    AFFICHAGE    ####
  50. #########################
  51. def affichage() :
  52.     global nblgn,nbcol,tableau,prochaine
  53.     exnblgn,exnbcol=nblgn,nbcol                    # auvegarde de la taille ancienne
  54.     nblgn,nbcol=tailleecran()                      # calcul de la taille de l'écran
  55.     if (exnblgn,exnbcol)!=(nblgn,nbcol) :          # si le monde a changé de taille
  56.         ## sauvegarde du monde actuel ##
  57.         for l in range(0,exnblgn) :                # pour chaque ligne
  58.             for c in range(0,exnbcol) :            # pour chaque colonne
  59.                 prochaine[l][c]=tableau[l][c]      # recopier la nouvelle génération
  60.         ## re-création du monde à la bonne taille ##
  61.         tableau=[]                                 # tableau vide
  62.         for l in range(0,nblgn) :                  # pour chaque ligne
  63.             tableau.append([vide]*nbcol)           # créer la ligne
  64.         ## recopie des données sauvegardées ##
  65.         for l in range(0,min(nblgn,exnblgn)) :     # pour chaque ligne
  66.             for c in range(0,min(nbcol,exnbcol)) : # pour chaque colonne
  67.                 tableau[l][c]=prochaine[l][c]      # recopier la nouvelle génération
  68.         ## re-création du tableau "prochaine" à la bonne taille ##
  69.         prochaine=[]                               # tableau vide
  70.         for l in range(0,nblgn) :                  # pour chaque ligne
  71.             prochaine.append([vide]*nbcol)         # créer la ligne
  72.         ecran.clear()                              # effacer les restes
  73.     for l in range(0,nblgn) :                      # pour chaque ligne
  74.         for c in range(0,nbcol) :                  # pour chaque colonne
  75.             ecran.addstr(l+haut,c+gauche,tableau[l][c])    # la case correspondante
  76.     ecran.addstr(nblgn+haut,gauche,str(generations)+"° génération. ") # n° de génération
  77.     ecran.addstr(str(nbcol)+"x"+str(nblgn))        # affiche la taille du monde
  78.     ou=""                                          # entre les choix (vide pour le 1er)
  79.     sortir=""                                      # message à afficher
  80.     for q in sortie :                              # pour toutes les touches de sortie
  81.         sortir=sortir+ou+"« "+chr(q)+" »"          # ajouter la touche
  82.         ou=" ou "                                  # entre les choix ("ou" à partir du 2°)
  83.     ecran.addstr(". Pour sortir, appuyer sur "+sortir+".") # afficher le message
  84. ###################################
  85. ####    COMPTER LES VOISINS    ####
  86. ###################################
  87. def voisins(l,c) :
  88.     lavant,lapres,cavant,capres=l-1,l+1,c-1,c+1  # les bornes d'exploration
  89.     if lavant<0 : lavant=nblgn-1                 # pour la ligne du haut
  90.     if lapres>=nblgn : lapres=0                  # pour la ligne du bas
  91.     if cavant<0 : cavant=nbcol-1                 # pour la colonne de gauche
  92.     if capres>=nbcol : capres=0                  # pour la colonne de droite
  93.     nbre=0                                       # initialisation du compteur
  94.     for ll in [lavant,l,lapres] :                # pour les 3 lignes entourant la case
  95.         for cc in [cavant,c,capres] :            #  pour les 3 colonnes entourant la case
  96.             # pour chaque case occupée qui n'est pas la case elle-même
  97.             if (ll!=l or cc!=c) and tableau[ll][cc]==plein :
  98.                 nbre+=1                          # ajouter 1 au compteur
  99.     return nbre                                  # retourner la valeur du compteur
  100. ####################################
  101. ####    ATTENTE ET FERMETURE    ####
  102. ####################################
  103. def finir() :
  104.     curses.endwin()             # revenir à la console
  105. ###############################
  106. ####    INITIALISATIONS    ####
  107. ###############################
  108. ecran=curses.initscr()          # créer l'écran graphique
  109. ecran.nodelay(1)                # getch() non bloquant
  110. curses.curs_set(False)          # pas d'affichage du curseur
  111. gauche,droite=1,1               # décalage horizontal
  112. haut,bas=1,2                    # décalage vertical
  113. nblgn,nbcol=tailleecran()       # calcul de la taille de l'écran
  114. sortie=[ord('q'),ord('Q')]      # touches pour finir
  115. tableau=[]                      # création du tableau vide
  116. prochaine=[]                    # création du tableau pour la prochaine génération
  117. plein="*"                       # contenu d'une case pleine
  118. vide=" "                        # contenu d'une case vide
  119. generations=0                   # nombre de générations
  120. ##################################
  121. ####    CORPS DU PROGRAMME    ####
  122. ##################################
  123. creation()                      # création des tableaux
  124. remplissage()                   # remplissage initial du tableau
  125. k=0                             # initialisation pour rentrer dans la boucle
  126. while k not in sortie :         # TQ on n'a pas appuyé sur une touche pour sortir
  127.     affichage()                 # affichage de la génération courante
  128.     generation()                # calcul de la génération suivante
  129.     k=ecran.getch()             # récupérér la touche sur laquelle on a appuyé
  130. finir()                         # sortir de l'écran graphique
Dernière modification : 25/8/2016