Premier article sur le calendrier de l'Avent Playground!
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 □.
import matplotlib.pyplot as plt
import numpy as np
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 ...)
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»)
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).
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.
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`.
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
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)
.
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()
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