Skip to content

Instantly share code, notes, and snippets.

@jul
Last active December 13, 2021 11:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jul/d9aafc55d178a7fdd15a59de851fe53f to your computer and use it in GitHub Desktop.
Save jul/d9aafc55d178a7fdd15a59de851fe53f to your computer and use it in GitHub Desktop.
jeu de la vie (à réécrire (kleenex)) en pavage triangulaire
import PySimpleGUI as sg
from operator import itemgetter
### uitliser ipython -i argv[0] pour être en interactif et faire joujou
can = sg.Canvas(size=(1412,998))
status=sg.Text('status')
win = sg.Window("titre",[[can,],[status,],], finalize=True)
c = can.TKCanvas
from time import sleep, time
from random import randint
from os import system
system("rm *ps output2.mp4 ev*.jpg")
SZ=25
DIMX=56
DIMY=46
seed=int(time())
print("seed %d" % seed)
ORD=1
def save(canvas, name="save"):
global ORD
with open("%s-%04d.ps"% (name, ORD), "w") as f:
ORD+=1
f.write(canvas.postscript())
def cell(x,y, **kw):
hs=0.866 # heigth of an equilateral triangle
px,py=x/2-1/2*(y%2),y-2/3
#px,py=x-(y%2),y-2/3
xr,yr=px*SZ+SZ,py*hs*SZ+SZ
# triangle compliqué à dessiner
r=SZ/2
i=c.create_oval(xr-r,yr-r,xr+r,yr+r,
fill=["","black"][kw.get("state","dead")=="alive"], outline="",
tags=(
"os:%s" % (kw.get("state","dead" )),
"p:%d,%d" % (x/2,y),
"rp:%d,%d,%d" % (xr,yr,r),
"bb:%d,%d,%d,%d" % (xr-r, yr-r, xr+r, yr+r),
))
c.update()
return i
def get_info(*tag,c=c):
tag = len(tag)==1 and tag or "p:%d,%d" % tag
e = c.gettags(tag)
sw=dict(
p = lambda s:("pos", tuple(map(int,s.split(",")))),
rp = lambda s:("real_pos", tuple(map(int,s.split(",")))),
os = lambda s:("old_state", s),
bb = lambda s:("box", tuple(map(int,s.split(",")))),
)
return dict(
sw.get(k,lambda v:v)(v) for k,v in map(lambda s:s.split(":"), e))
def get_neighbour(x,y):
ye = [(-1, -1), (1, 0), (0, -1), (-1, 1), (-1, 0), (0, 1)]
yo= [(1, 1), (-1, 0), (0, -1), (1, 0), (0, 1), (1, -1)]
return set( ((dxdy[0]+x)%DIMX,(y+dxdy[1])%DIMY) for dxdy in [yo,ye][y%2])
def get_real_neighbour(x,y):
return set(
map(itemgetter("pos"),
map(get_info, c.find_overlapping(*get_info(x,y)["box"])
)))-{(x,y)}
c.configure(bg="white")
seen=set()
old_alive=set()
new_alive=set()
for x in range(0,DIMX*2,2):
for y in range(DIMY):
# state="alive" if (x in {6,12} or y in {2,7}) else "dead"
#state="alive" if (x,y) in {
# (6,4),(8,3),(6,2),(10,3),
# (14,6),(14,5),(12,5),(14,4),
# (10,4),
# (10,5),
# } else "dead
state = randint(-5, 7) >= 0 and "alive" or "dead"
if state=="alive":
old_alive.update(((x/2,y),),)
assert {(x,y)} not in seen
elt=cell(
x,
y,
state=state,
outline="black")
seen.update(((x,y),),)
assert get_real_neighbour(3,3)==get_neighbour(3,3)
def live_neighbour(x,y,c=c):
return sum(map(lambda x : x in old_alive,get_neighbour(x,y)))
def will_live(x,y,c=c):
global new_alive, old_alive
#ostate=get_info(x,y)["old_state"]
ostate = (x,y) not in old_alive and 'dead' or "alive"
lively = live_neighbour(x,y)
#print("%d-%d:%s:%d" % (x,y,ostate,lively))
state = ( ostate == "alive" and lively in {4,5} ) or (
ostate == "dead" and lively in { 2 } )
if(state): new_alive.update(((x,y),))
return state
ORD=0
save(c, "ev")
for i in range(100):
for x in range(DIMX):
for y in range(DIMY):
will_live(x,y)
c.itemconfigure("p:%d,%d" % (x,y),fill="black" if (x,y) in new_alive else '')
c.update()
sleep(.1)
old_alive=new_alive
save(c, "ev")
new_alive=set()
@jul
Copy link
Author

jul commented Dec 12, 2021

output2.mp4

@jul
Copy link
Author

jul commented Dec 12, 2021

output.mp4

@jul
Copy link
Author

jul commented Dec 13, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment