0
0

More than 1 year has passed since last update.

画面エディタ付きのライフゲームを作ってみた python3

Last updated at Posted at 2023-01-10

画面エディタ付きのlifegameを作ってみました。
エディットモードで、画面上をマウスでクリックすると、セルがオンオフします。
ゲームモードでも、セルをクリックしたら、画面が止まり、自動的にエディットモードになります。

キー操作:
w save.txtにセーブ
l save.txtからロード
e エディットモード
g ゲームモード
r ランダムに初期化する
c クリア
q quit

lifegame.py
#!/usr/bin/python3
from pygame.locals import *
from scipy import signal
import pygame
import sys
import numpy as np
import os
import binascii



scale=5
height=100
width=100

def draw_grid(screen):
  screen.fill((0,0,0))
  for i in range(width):
    pygame.draw.line(screen,(0,255,0),(0,i*scale),(scale*width,i*scale),1)
  for j in range(height):
    pygame.draw.line(screen,(0,255,0),(j*scale,0),(j*scale,scale*height),1)

def set(screen,cx,cy,c):
  screen.fill((c*255,c*255,c*255),(cx*scale+1,cy*scale+1,scale-1,scale-1))

def put(F,screen):
  for i in range(len(F)):
    for j in range(len(F[1])):
       set(screen,j,i,F[i][j])

def rev(F,cx,cy):
  F[cy][cx]=int(F[cy][cx])^1
  return(F)

def clear():
    return(np.zeros((height,width)))

def initrandomseed():
    f=open("/dev/random",'rb') # /dev/randomを開く
    random32bitdata=f.read(4) # 4バイト読み出し
    f.close()
    randomhex=binascii.hexlify(random32bitdata) #16進の文字列に変換
    randomint=int(randomhex,16) # 整数に変換
    np.random.seed(seed=randomint) # ランダムシードを初期化

def initrnd():
    N = width*height
    v = np.array(np.random.rand(N) + 0.1, dtype=int)
    return v.reshape(height, width)

def count_neighbor(F):
    return signal.correlate2d(F,np.ones((3, 3),dtype=int),mode="same",boundary="wrap")

def nextgen(F):
    N = count_neighbor(F)
    G = (N == 3) + F * (N == 4)
    return G

def eventloop(F,screen):
    run='e'
    while run!='q':
        for event in pygame.event.get():
            if event.type == QUIT:
                run='q'
            if event.type == KEYDOWN:  # キーを押したとき
                k=pygame.key.name(event.key)
                if k== 'q':
                    run='q'
                elif k=='e':
                    run='e'
                elif k=='g':
                    run='g'
                elif k=='r':
                    F = initrnd()
                    put(F,screen)
                elif k=='l':
                    if os.path.exists("save.txt"):
                      F = np.loadtxt("save.txt")
                    put(F,screen)
                elif k=='w':
                    np.savetxt("save.txt", F, "%d")
                elif k=='c':
                    F=clear()
                    put(F,screen)
            elif event.type == MOUSEBUTTONDOWN:
                    x, y = event.pos
                    F=rev(F,x//scale,y//scale)
                    put(F,screen)
                    run='e'
            elif event.type == MOUSEMOTION:
                    x, y = event.pos
        if run=='g':
          F=nextgen(F)
          put(F,screen)
        pygame.display.update()

def main():
    pygame.init()    # Pygameを初期化
    screen = pygame.display.set_mode((scale*width,scale*height))    # 画面を作成
    pygame.display.set_caption("lifegame")    # タイトルを作成
    initrandomseed()
    draw_grid(screen)
    F=clear()
    put(F,screen)
    eventloop(F,screen)
    pygame.quit()
    sys.exit()

if __name__=='__main__':
    main()

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0