jeu_de_la_vie
Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédenteProchaine révisionLes deux révisions suivantes | ||
jeu_de_la_vie [2019/10/07 09:06] – Camille | jeu_de_la_vie [2020/10/28 12:14] – ↷ Liens modifiés en raison d'un déplacement. serge | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | ====== | + | ====== Documentation du projet "Jeu de la vie" réalisé pour Centre Sciences en 2019 ====== |
===== Introduction: | ===== Introduction: | ||
==== Cadre ==== | ==== Cadre ==== | ||
- | L' | + | L' |
- | ==== Qu' | + | |
- | D' | + | ==== Qu' |
- | //Le jeu de la vie est un automate cellulaire imaginé par John Horton Conway en 1970 et qui est probablement le plus connu de tous les automates cellulaires. | + | D' |
+ | |||
+ | Le jeu de la vie est un automate cellulaire imaginé par John Horton Conway en 1970 et qui est probablement le plus connu de tous les automates cellulaires. | ||
Le jeu de la vie n’est pas un jeu, puisqu' | Le jeu de la vie n’est pas un jeu, puisqu' | ||
Le « jeu » se déroule sur une grille à deux dimensions, théoriquement infinie (mais de longueur et de largeur finies et plus ou moins grandes dans la pratique), dont les cases — qu’on appelle des « cellules », par analogie avec les cellules vivantes — peuvent prendre deux états distincts : « vivante » ou « morte ». | Le « jeu » se déroule sur une grille à deux dimensions, théoriquement infinie (mais de longueur et de largeur finies et plus ou moins grandes dans la pratique), dont les cases — qu’on appelle des « cellules », par analogie avec les cellules vivantes — peuvent prendre deux états distincts : « vivante » ou « morte ». | ||
- | **À chaque étape, l’évolution d’une cellule est entièrement déterminée par l’état de ses huit voisines** de la façon suivante : | + | **À chaque étape, l’évolution d’une cellule est entièrement déterminée par l’état de ses huit voisines** de la façon suivante : |
+ | |||
+ | * Une cellule morte possédant exactement trois voisines vivantes devient vivante (elle naît). | ||
+ | * Une cellule vivante possédant deux ou trois voisines vivantes le reste, sinon elle meurt. | ||
- | * Une cellule morte possédant exactement trois voisines vivantes devient vivante (elle naît).\\ | ||
- | * | ||
- | * Une cellule vivante possédant deux ou trois voisines vivantes le reste, sinon elle meurt.\\ // | ||
- | * | ||
**La configuration de départ détermine entièrement l' | **La configuration de départ détermine entièrement l' | ||
+ | |||
=====Cahier des charges===== | =====Cahier des charges===== | ||
Dans le cadre d'une exposition, il était nécessaire d' | Dans le cadre d'une exposition, il était nécessaire d' | ||
Le tout devait être assez compact et transportable. | Le tout devait être assez compact et transportable. | ||
+ | |||
=====Réalisation===== | =====Réalisation===== | ||
Les choix techniques ont été les suivants:\\ | Les choix techniques ont été les suivants:\\ | ||
la contrainte d' | la contrainte d' | ||
- | L' | + | L' |
- | Il était initialement question de pions qui se poseraient dans les trous du plateau de jeu. Le choix s'est porté sur des capteurs de pression (Force Sensing Resistance) pour la détection des pions. \\ | + | |
- | Un bouton pour amorcer le jeu et le faire et évoluer et un bouton pour revenir à la configuration initiale ont été ajoutés sur les GPIO du micro-iordinateur. \\ | + | |
- | Enfin, un bouton marche/ | + | \\ |
+ | Il était initialement question de pions qui se poseraient dans les trous du plateau de jeu. Le choix s'est porté sur des capteurs de pression (Force Sensing Resistance) pour la détection des pions. | ||
+ | |||
+ | {{media_06: | ||
+ | \\ | ||
+ | Un bouton pour amorcer le jeu et le faire et évoluer et un bouton pour revenir à la configuration initiale ont été ajoutés sur les GPIO du micro-ordinateur. \\ | ||
+ | Enfin, un bouton marche/ | ||
Montage des capteurs dans le plateau de jeu: | Montage des capteurs dans le plateau de jeu: | ||
Ligne 42: | Ligne 51: | ||
{{: | {{: | ||
+ | |||
=====Matériel===== | =====Matériel===== | ||
Un plateau de jeu dont un carré de 4x4 trous sont évidés de façon à laisser s' | Un plateau de jeu dont un carré de 4x4 trous sont évidés de façon à laisser s' | ||
16 capteurs FSR pour la détection des billes: Fournisseur Pololu, dimensions 0,2 pouces de diamètre (ce qui correspond à 0,5 cm de diamètre)\\ | 16 capteurs FSR pour la détection des billes: Fournisseur Pololu, dimensions 0,2 pouces de diamètre (ce qui correspond à 0,5 cm de diamètre)\\ | ||
+ | https:// | ||
Deux boutons d' | Deux boutons d' | ||
Un bouton marche/ | Un bouton marche/ | ||
- | Une RaspberryPi pour la gestion des événements et l' | + | Une RaspberryPi pour la gestion des événements et l' |
- | Un écran Waveshare 1920x1080 pixels | + | Un écran Waveshare 1920x1080 pixels: https:// |
=====Logiciel===== | =====Logiciel===== | ||
Un code python pour la prise en compte des billes et l' | Un code python pour la prise en compte des billes et l' | ||
OS Raspbian version Buster (10.4 (?)) | OS Raspbian version Buster (10.4 (?)) | ||
- | Modifications de l' | + | Modifications de l'OS:\\ |
- | -prise en compte du bouton marche/ | + | -prise en compte du bouton marche/ |
- | -lancement du programme Jeu de la vie au démarrage de l'OS | + | -lancement du programme Jeu de la vie au démarrage de l'OS\\ |
- | Sauvegarde du système complet sur une carte SD de secours: procédure | + | Sauvegarde du système complet sur une carte SD de secours: procédure\\ |
- | -copie de la carte SD d' | + | -copie de la carte SD d' |
- | -copie sur une autre carte SD | + | -copie sur une autre carte SD\\ |
- | Liste exhaustive du matériel: | + | Liste exhaustive du matériel:\\ |
- | Photos | + | |
- | Codes | + | écran Waveshare: |
- | Schéma électrique pour les FSR | + | https:// |
- | Schéma d' | + | |
- | Schéma de câblage sur la Raspberry | + | capteurs de pression: |
+ | |||
+ | |||
+ | Photos\\ | ||
+ | Codes\\ | ||
+ | Le code a été écrit en python et utilise la bibliothèque pygame. Il s'agit de l' | ||
+ | http:// | ||
+ | |||
+ | |||
+ | ======================================================= | ||
+ | |||
+ | <code python> | ||
+ | | ||
+ | from pygame.locals import * | ||
+ | | ||
+ | | ||
+ | from time import sleep | ||
+ | |||
+ | | ||
+ | # vérification du nombre de capteurs définis | ||
+ | | ||
+ | | ||
+ | | ||
+ | # les broches sur lesquelles se trouvent les capteurs, ainsi que les broches 14 et 15, sont configurées en entrée. | ||
+ | # Par défaut, les broches des capteurs sont à l' | ||
+ | # Les broches 14 et 15 (sur lesquelles sont câblés des boutons) sont au niveau électrique haut par défaut | ||
+ | for n in GPIOCasesInit: | ||
+ | | ||
+ | | ||
+ | | ||
+ | # les broches 14 et 15 détecteront un front descendant | ||
+ | | ||
+ | | ||
+ | # | ||
+ | FPS = 10 | ||
+ | |||
+ | ### | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | #les dimensions de la grille sont-elles des multiples du nombre de cellules | ||
+ | | ||
+ | | ||
+ | |||
+ | # | ||
+ | | ||
+ | | ||
+ | |||
+ | # fabrication des couleurs | ||
+ | BLACK = (0, 0, 0) | ||
+ | WHITE = (255, | ||
+ | | ||
+ | GREEN = (50, | ||
+ | RED = (255, 0, 100) | ||
+ | |||
+ | | ||
+ | |||
+ | def text_objects(text, | ||
+ | | ||
+ | | ||
+ | |||
+ | def afficheInit(text, | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | # | ||
+ | def drawGrid(): | ||
+ | for x in range(0, WINDOWWIDTH, | ||
+ | | ||
+ | for y in range (0, WINDOWHEIGHT, | ||
+ | | ||
+ | |||
+ | |||
+ | def drawGridExample(): | ||
+ | for n in BoxExample: | ||
+ | | ||
+ | |||
+ | # | ||
+ | def colourGrid(item, | ||
+ | x = item[0] | ||
+ | y = item[1] | ||
+ | y = y * CELLSIZE # transforme le tableau de dimension de la grille | ||
+ | x = x * CELLSIZE # transforme le tableau de dimension de la grille | ||
+ | if lifeDict[item] == 0: | ||
+ | | ||
+ | if lifeDict[item] == 1: | ||
+ | | ||
+ | | ||
+ | |||
+ | # | ||
+ | # | ||
+ | def blankGrid(): | ||
+ | | ||
+ | # | ||
+ | for y in range (CELLHEIGHT): | ||
+ | for x in range (CELLWIDTH): | ||
+ | | ||
+ | | ||
+ | |||
+ | def startingGridInit(lifeDict, | ||
+ | for ncapt in GPIOCasesInit: | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | # | ||
+ | def getNeighbours(item, | ||
+ | | ||
+ | for x in range (-1,2): | ||
+ | for y in range (-1,2): | ||
+ | | ||
+ | if checkCell[0] < CELLWIDTH | ||
+ | if checkCell [1] < CELLHEIGHT and checkCell[1]> | ||
+ | if lifeDict[checkCell] == 1: | ||
+ | if x == 0 and y == 0: # la cellule centrale n'est pas prise en compte | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | #Calcul de la nouvelle génération par appel à la fonction ' | ||
+ | def tick(lifeDict): | ||
+ | | ||
+ | for item in lifeDict: | ||
+ | # | ||
+ | | ||
+ | if lifeDict[item] == 1: # Pour les cellules encore vivantes | ||
+ | if numberNeighbours < 2: # mort par sous-population | ||
+ | | ||
+ | elif numberNeighbours > 3: #mort par surpopulation | ||
+ | | ||
+ | | ||
+ | | ||
+ | elif lifeDict[item] == 0: | ||
+ | if numberNeighbours == 3: # naissance d'une cellule | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | # | ||
+ | def main(): | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | |||
+ | # | ||
+ | for item in lifeDict: | ||
+ | | ||
+ | | ||
+ | | ||
+ | while True: #main game loop | ||
+ | for event in pygame.event.get(): | ||
+ | if event.type == QUIT: | ||
+ | | ||
+ | | ||
+ | # | ||
+ | if event.type == pygame.KEYUP: | ||
+ | | ||
+ | | ||
+ | | ||
+ | if ps14!=cs14: | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | doit_demarrer = True | ||
+ | nb_viv+=1 | ||
+ | print(GPIOCasesInit[elem]) | ||
+ | print(' | ||
+ | if doit_demarrer: | ||
+ | etat=1 | ||
+ | lifeDict = startingGridInit(lifeDict, | ||
+ | else: | ||
+ | etat=0 | ||
+ | elif(etat==1): | ||
+ | if(ps15==1 and cs15==0): | ||
+ | etat=0 | ||
+ | lifeDict=blankGrid() | ||
+ | if(ps14==1 and cs14==0): | ||
+ | #Calcul de l' | ||
+ | nb_viv=0 | ||
+ | lifeDict = tick(lifeDict) | ||
+ | print(' | ||
+ | for item in lifeDict: | ||
+ | if(lifeDict[item]): | ||
+ | nb_viv=nb_viv+1 | ||
+ | print(nb_viv) | ||
+ | if(nb_viv==0): | ||
+ | print(' | ||
+ | etat=0 | ||
+ | #Colours the live cells, blanks the dead | ||
+ | for item in lifeDict: | ||
+ | colourGrid(item, | ||
+ | drawGrid() | ||
+ | pygame.display.update() | ||
+ | ps14=cs14 | ||
+ | ps15=cs15 | ||
+ | sleep(0.1) | ||
+ | # | ||
+ | |||
+ | if __name__==' | ||
+ | main() | ||
+ | |||
+ | </ | ||
+ | ======================================================= | ||
+ | |||
+ | |||
+ | |||
+ | Schéma électrique pour les FSR\\ | ||
+ | Schéma d' | ||
+ | Schéma de câblage sur la Raspberry\\ | ||
=====Retour d' | =====Retour d' | ||
- | FSR: | ||
- | Tests effectués en mesurant la valeur de la résistance selon la pression exercée : | + | Il semble qu'il ne soit pas nécessaire de protéger la carte SD d'une extinction intempestive, |
+ | |||
+ | Par précaution, | ||
+ | |||
+ | Ce clone servira à graver une nouvelles carte SD si celle employée ne fonctionne plus. | ||
+ | |||
+ | |||
+ | **FSR:** | ||
+ | |||
+ | __ | ||
+ | Tests effectués en mesurant la valeur de la résistance selon la pression exercée :__ | ||
De 1 je passe à des valeurs plus ou moins pertinentes selon le poids. | De 1 je passe à des valeurs plus ou moins pertinentes selon le poids. | ||
Ligne 84: | Ligne 336: | ||
- | + | __Modifications | |
- | > | + | |
- | > Le 19.07.2019 11:01, Guy Antoine a écrit : | + | |
- | >> Bonjour Camille | + | |
- | >> Pour la manip du jeu de la vie, les jetons font 18mm donc découpe à | + | |
- | >> 19mm sur le support de 120x120 selon les plans ci-joint. | + | |
- | >> Peux tu me valider cette option ? J'ai regardé pour les joncs de 20mm | + | |
- | >> en plexi mais c'est très " | + | |
- | >> Donc on vérifieras au règlage s'il faut les lester. | + | |
- | + | ||
- | + | ||
- | + | ||
- | Modifications | + | |
Il s' | Il s' | ||
jeu_de_la_vie.txt · Dernière modification : 2020/10/29 14:03 de serge