jeu_de_la_vie
Différences
Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente | ||
jeu_de_la_vie [2019/10/04 09:36] – créée Camille | jeu_de_la_vie [2020/10/29 14:03] (Version actuelle) – ↷ 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 n’est pas un jeu, puisqu' | + | |
+ | 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 » 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 chute de « bombes » non périodique. | + | |
+ | * | ||
+ | * Une cellule vivante possédant deux ou trois voisines vivantes le reste, sinon elle meurt. | ||
+ | |||
+ | **La configuration | ||
- | 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' | ||
=====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) | + | |
- | Matériel | + | |
- | 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 | + | 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) |
- | Deux boutons d' | + | |
- | Un bouton marche/ | + | {{media_06: |
- | Une RaspberryPi pour la gestion des événements et l' | + | \\ |
- | Un écran | + | 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. \\ |
- | Logiciel | + | Enfin, un bouton marche/ |
+ | |||
+ | Montage des capteurs dans le plateau de jeu: | ||
+ | |||
+ | {{media_09: | ||
+ | |||
+ | Écran d' | ||
+ | |||
+ | {{media_07: | ||
+ | |||
+ | Une étape: | ||
+ | |||
+ | |||
+ | {{media_07: | ||
+ | |||
+ | =====Matériel===== | ||
+ | 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)\\ | ||
+ | https:// | ||
+ | Deux boutons d' | ||
+ | |||
+ | Un bouton marche/ | ||
+ | Une RaspberryPi pour la gestion des événements et l' | ||
+ | Un écran | ||
+ | |||
+ | =====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: |
- | Modifications | + | |
+ | |||
+ | 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' | ||
+ | |||
+ | 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. | ||
+ | Difficile sous les 20mm de diamètre de dépasser le seuil des 50 kohms soit un poids de 20 grammes (plexi ou bois) | ||
+ | Avec une bille inox de 30mm (110gr), la résistance chute à 4/5 k ohms ; mais elles sont trop facilement volées et très chères. | ||
+ | Les billes vertes type calot de 25mm pourraient être un compromis comme les cylindres de pvc denses : test concluant pour un cylindre de 26mm hauteur 50mm poids 45gr résistance mesurée 20kohms. | ||
+ | |||
+ | Il y a quelques incertitudes sur les mesures car faute d’ajustement précis du diamètre d’emboîtements, | ||
+ | |||
+ | Je modifie le plan de la manip avec un entraxe de 30mm et des trous de 27 de diamètre ; la profondeur des inserts sera de 20mm au moins | ||
+ | |||
+ | Le mieux pour simuler la pression du doigt c’est une « goutte d’eau », pieds autocollants antidérapant en forme de demi-hémisphère sur les cylindres | ||
+ | |||
+ | |||
+ | __Modifications | ||
Il s' | Il s' | ||
jeu_de_la_vie.1570181775.txt.gz · Dernière modification : 2019/10/04 09:36 de Camille