[PYTHON] J'ai fait un jeu de vie avec Numpy

Premier article sur le calendrier de l'Avent Playground!

Qu'est-ce qu'un jeu de la vie?

Ci-dessous, [wikipedia](https://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B2%E3%83%BC%E3 Cité à partir de% 83% A0). ~~ Je pense que c'est plus facile à comprendre si vous passez au lien plutôt que de lire la citation ci-dessous w ~~

Dans le jeu de la vie, l'état suivant n'est déterminé que par l'état initial. Il y a une grille comme un tableau de bord, et une grille est appelée une cellule. Chaque cellule a huit cellules voisines. Chaque cellule a deux états, «vie» et «mort», et l'état de l'étape suivante (génération) d'une cellule est déterminé par l'état des huit cellules environnantes dans la génération actuelle.

La vie et la mort d'une cellule suivent les règles suivantes.

naissance S'il y a exactement trois cellules vivantes adjacentes à une cellule morte, la génération suivante naîtra. ** Survie ** S'il y a deux ou trois cellules vivantes adjacentes à une cellule vivante, elle survivra dans la génération suivante. ** Dépeuplé ** S'il y a moins d'une cellule vivante adjacente à une cellule vivante, elle mourra en raison du dépeuplement. ** Surpeuplé ** S'il y a 4 cellules vivantes ou plus adjacentes à une cellule vivante, elle mourra en raison de la surpopulation. Vous trouverez ci-dessous un exemple de vie ou de mort à l'étape suivante dans la cellule centrale. Les cellules vivantes sont indiquées par ■ et les cellules mortes sont indiquées par □.

Paquet utilisé

import matplotlib.pyplot as plt
import numpy as np

Etat initial

n = 50

#Créer une cellule aléatoire
cells = np.random.randint(0, 2, (n, n), dtype=bool)

La sélection aléatoire de «True» ou «False» crée une matrice n × n d'éléments. ("Life" pour "True", "Death" pour "False") (Si vous l'augmentez à environ n = 500, il deviendra lourd ...)

Compter le nombre de cellules "brutes" adjacentes

sum_around = lambda i, j : cells[max(0, i-1):i+2, max(0, j-1):j+2].sum() - cells[i, j]

Tout d'abord, une matrice 3x3 centrée sur le composant de colonne «i» ligne »j» de la matrice est extraite, et la somme des éléments de la matrice est obtenue. La soustraction du centre du résultat donne le nombre de cellules «brutes» adjacentes au composant de colonne «i» row »j». (Calculé comme «Vrai = 1, Faux = 0»)

Raison de l'utilisation de la fonction max

Lorsque vous souhaitez spécifier la cellule à gauche (ou au-dessus) de la cellule dans la 0ème ligne (ou la 0ème colonne), même si ʻi -1 = -1, alors max (0, -1) = 0` Par conséquent, seule la zone à l'intérieur du mur peut être mentionnée. Python semble convenir si l'index dépasse la taille de la matrice, et je n'ai pas eu à faire de même pour la nième ligne (ou la nième colonne).

Passez à la prochaine génération

def update(old):

    sum_around = lambda i, j : cells[max(0, i-1):i+2, max(0, j-1):j+2].sum() - cells[i, j]
    
    around = np.fromfunction(np.vectorize(sum_around), old.shape)
    new = np.where(old , ((2 <= around) & (around <= 3)), (around == 3))
    return new

En mettant la fonction sum_around dans le premier argument de la fonction np.fromfunction, une nouvelle matrice ʻaround` est créée dans laquelle ** la valeur de chaque élément = le nombre de cellules" brutes "adjacentes **. Lorsque chaque élément est "Vrai", c'est-à-dire lorsqu'il s'agit d'une cellule "brute", le résultat du jugement de ** survie / dépeuplement / surpeuplement ** est renvoyé, et lorsqu'il est "Faux", c'est-à-dire lorsqu'il s'agit d'une cellule "mort", le résultat du jugement est renvoyé. Renvoie le résultat du jugement de ** naissance **. La valeur de retour est de type «bool», qui sera la cellule de prochaine génération telle quelle.

Raisons d'utiliser la fonction np.vectorize

Il semble que la fonction du premier argument doit être une fonction universelle (ufunc).

Parameters :

function : callable The function is called with N parameters, where N is the rank of shape. Each parameter represents the coordinates of the array varying along a specific axis. For example, if shape were (2, 2), then the parameters would be array([[0, 0], [1, 1]]) and array([[0, 1], [0, 1]]) numpy.fromfunction

Puisque l'argument de la fonction sum_around assume le type ʻint, il est ufunced avec np.vectorize pour qu'il puisse recevoir le type ndarray`.

production

while True:
# for _ in range(200):  #Si vous souhaitez spécifier le nombre de fois

    cells = update(cells)
    
    plt.imshow(cells)
    plt.pause(.01)   # 0.Mis à jour toutes les 01 secondes
    plt.cla()        #Sans cela, il devient de plus en plus lourd

: santa: Couleur de Noël: christus_tree:

from matplotlib.colors import LinearSegmentedColormap

colors = ['green', 'red']
xmas = LinearSegmentedColormap.from_list('xmas', colors)
norm = plt.Normalize(0, 1)

plt.tick_params(labelbottom=False, labelleft=False,
                bottom=False, left=False)

Vous pouvez changer la couleur spécifiée en changeant l'intérieur de l'instruction while en plt.imshow (cells, cmap = xmas, norm = norm).

Résultat d'exécution

ezgif-3-866aafd6a847.gif

Code entier

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap


n = 15

cells = np.zeros([n, n], dtype=bool)

#Galaxie
cells[3:9, 3:5] = True
cells[3:5, 6:12] = True
cells[-5:-3, 3:9] = True
cells[6:12, -5:-3] = True

#Aléatoire
# cells = np.random.randint(0, 2, (n, n), dtype=bool)


def update(old):

    sum_around = lambda i, j : cells[max(0, i-1):i+2, max(0, j-1):j+2].sum() - cells[i, j]
    
    around = np.fromfunction(np.vectorize(sum_around), old.shape, dtype=int)
    new = np.where(old , ((2 <= around) & (around <= 3)), (around == 3))
    return new


colors = ['green', 'red']
xmas = LinearSegmentedColormap.from_list('xmas', colors)
norm = plt.Normalize(0, 1)

plt.tick_params(labelbottom=False, labelleft=False,
                bottom=False, left=False)

# for _ in range(200):
while True:

    cells = update(cells)
    
    plt.imshow(cells, cmap=xmas, norm=norm)
    plt.pause(.01)
    plt.cla()

: 8ball: Impressions: 8ball:

C'est probablement la première fois depuis que j'ai commencé à programmer que quelque chose que je faisais moi-même à partir de zéro fonctionnait ... Je l'ai fait (recrutement urgent: verbalisation de la joie)

Recommended Posts

J'ai fait un jeu de vie avec Numpy
〇✕ J'ai fait un jeu
J'ai fait un jeu rogue-like avec Python
J'ai fait un graphique de nombres aléatoires avec Numpy
J'ai fait un jeu de cueillette avec Python
J'ai fait un jeu d'éclairage de sapin de Noël avec Python
J'ai fait un jeu mono tombé avec Sense HAT
J'ai fait une loterie avec Python.
Zura fait comme un jeu de la vie
J'ai créé un démon avec Python
J'ai fait un jeu de frappe simple avec tkinter de Python
J'ai fait un jeu de puzzle (comme) avec Tkinter of Python
J'ai fait une carte hexadécimale avec Python
J'ai fait un générateur Hanko avec GAN
J'ai fait un simple blackjack avec Python
J'ai créé un fichier de configuration avec Python
J'ai fait une application WEB avec Django
J'ai fait un simulateur de neurones avec Python
Jeu de vie avec Python [je l'ai fait] (sur terminal et Tkinter)
J'ai créé un chat-holdem de serveur de jeu de poker en utilisant websocket avec python
J'ai fait un robot de remplacement de tampon avec une ligne
J'ai fait une prévision météo de type bot avec Python.
J'ai créé une application graphique avec Python + PyQt5
J'ai essayé de créer un bloqueur de filles pourries sur Twitter avec Python ①
Je veux faire un jeu avec Python
[Python] J'ai créé un téléchargeur Youtube avec Tkinter.
J'ai fait un simple portefeuille de Bitcoin avec pycoin
J'ai créé un Bot LINE avec Serverless Framework!
Made Mattermost Bot avec Python (+ Flask)
[AWS] J'ai créé un BOT de rappel avec LINE WORKS
J'ai écrit GP avec numpy
J'ai fait un Twitter BOT avec GAE (python) (avec une référence)
J'ai créé un bot de livre de compte de ménage avec LINE Bot
J'ai créé un serveur syslog prêt à l'emploi avec Play with Docker
J'ai créé une fenêtre pour la sortie du journal avec Tkinter
J'ai fait un blackjack avec du python!
J'ai créé une application de notification de nouvelles en ligne avec Python
J'ai créé un environnement Python3 sur Ubuntu avec direnv.
J'ai essayé de faire LINE BOT avec Python et Heroku
J'ai fait un texte Python
J'ai fait un robot discord
J'ai créé COVID19_simulator avec JupyterLab
J'ai créé Word2Vec avec Pytorch
J'ai fait un blackjack avec Python.
J'ai créé un jeu d'introduction au festival scolaire avec Ren'py
J'ai créé wordcloud avec Python.
Une histoire qui a trébuché lorsque j'ai créé un bot de chat avec Transformer
J'ai créé un package pour filtrer les séries chronologiques avec python
Créez un jeu de vie mis à jour manuellement avec tkinter
J'ai créé une application de livre simple avec python + Flask ~ Introduction ~
J'ai fait un jeu de combat Numer0n en Java (j'ai aussi fait de l'IA)
J'ai créé un moniteur de ressources pour Raspberry Pi avec une feuille de calcul
J'ai fait une minuterie pomodoro dure qui fonctionne avec CUI
J'ai fait une caméra de surveillance avec Raspberry PI pour la première fois.
J'ai essayé de simuler la probabilité d'un jeu de bingo avec Python
J'ai créé un plug-in qui peut faire "Daruma-san tombé" avec Minecraft
[AWS] J'ai créé un BOT de rappel avec LINE WORKS (implémentation)