conway.py

Created by lokasku

Created on May 15, 2024

3.63 KB

Memory-free Conway’s Game of Life.


# Written by Lokasku, CoCoSol and Abdallah. Enjoy.
import numpy as np
from kandinsky import*
from random import randint as rdt
from ion import*
from time import*
a=color
IS_ALIVE=a(0,0,0)
IS_DEAD=a(255,255,255)
WAS_ALIVE=a(10,10,10)
WAS_DEAD=a(250,250,250)
CURSOR_ALIVE=a(60,60,60)
CURSOR_DEAD=a(200,200,200)
CS=20;ALIVE_CR=.5;SW=320;SH=222;MX=10;MY=11;XS=MX;XE=SW-MX;YS=MY;YE=SH-MY;VW=SW-2*MX;VH=SH-2*MY;W=VW//CS;H=VH//CS;cx=W//2;cy=H//2;LP=.5
def dr(x,y,w,h,s,c):fill_rect(x,y,w,s,c);fill_rect(x,y+h,w,s,c);fill_rect(x,y,1,h,c);fill_rect(x+w,y,1,h,c)
def clp(mn,x,mx):return max(mn,min(x,mx))
def g():fill_rect(XS+3*CS,YS,CS,CS,IS_ALIVE);fill_rect(XS+3*CS,YS+CS,CS,CS,IS_ALIVE);fill_rect(XS+3*CS,YS+CS*2,CS,CS,IS_ALIVE);fill_rect(XS+2*CS,YS+CS*2,CS,CS,IS_ALIVE);fill_rect(XS+1*CS,YS+CS,CS,CS,IS_ALIVE)
def ini(): [fill_rect(x,y,CS,CS,IS_ALIVE) for x in range(XS,XE,CS) for y in range(YS,YE,CS) if rdt(0,100)<ALIVE_CR*100]
def n(x,y):crd=[(XE-CS if int(x+i)<XS else XS if int(x+i)>XE-CS else int(x+i),YE-CS if int(y+j)<YS else YS if int(y+j)>YE-CS else int(y+j))for(i,j)in[(CS,0),(-CS,0),(0,CS),(0,-CS),(CS,CS),(-CS,-CS),(-CS,CS),(CS,-CS)]];return sum(1 for(nx,ny)in crd if get_pixel(nx,ny)in[IS_ALIVE,WAS_ALIVE])
def nxt():
  for x in range(XS,XE,CS):
    for y in range(YS,YE,CS):
      sn=n(x,y)
      if get_pixel(x,y)==IS_ALIVE and(sn<2 or sn>3):fill_rect(x,y,CS,CS,WAS_ALIVE)
      elif get_pixel(x,y)!=IS_ALIVE and sn==3:fill_rect(x,y,CS,CS,WAS_DEAD)
def clr():
  for x in range(XS,XE,CS):
    for y in range(YS,YE,CS):
      if get_pixel(x,y)==WAS_DEAD:fill_rect(x,y,CS,CS,IS_ALIVE)
      elif get_pixel(x,y)==WAS_ALIVE:fill_rect(x,y,CS,CS,IS_DEAD)
def mk(pressed,np,key,fn):
  if keydown(key):
    if key in pressed.keys():np[key]=pressed[key]
    else:np[key]=monotonic()
    if not key in pressed or monotonic()-np[key]>LP:fn()
def adj_vp():
  global MX,MY,VW,VH,XS,XE,YS,YE,H,W,cx,cy;pressed={};pm(MX,MY,VW,VH);do=False
  def u():global MY;nonlocal do;do=True;MY=clp(1,MY+(CS+1)//2,61)
  def d():global MY;nonlocal do;do=True;MY=clp(1,MY-(CS+1)//2,61)
  def l():global MX;nonlocal do;do=True;MX=clp(0,MX-(CS+1)//2,110)
  def r():global MX;nonlocal do;do=True;MX=clp(0,MX+(CS+1)//2,110)
  while not(keydown(KEY_EXE)and(VW%CS==0 and VH%CS==0)):
    do=False;np={};mk(pressed,np,KEY_UP,u);mk(pressed,np,KEY_DOWN,d);mk(pressed,np,KEY_LEFT,l);mk(pressed,np,KEY_RIGHT,r);pressed=np;sleep(.05);XS=MX;XE=SW-MX;YS=MY;YE=SH-MY;VW=SW-2*MX;VH=SH-2*MY;W=VW//CS;H=VH//CS;cx=W//2;cy=H//2
    if do:pm(MX,MY,VW,VH)
  fill_rect(0,0,SW,SH,IS_DEAD)
def pm(x1,y1,x2,y2):fill_rect(0,0,SW,SH,IS_DEAD);dr(x1,y1,x2,y2,1,IS_ALIVE);draw_string('W: {}, H: {}'.format(VW,VH),5,SH-20)
def dc():fill_rect(XS+cx*CS,YS+cy*CS,CS,CS,CURSOR_ALIVE if get_pixel(XS+CS*cx,YS+CS*cy)==IS_ALIVE else CURSOR_DEAD)
def udc():fill_rect(XS+cx*CS,YS+cy*CS,CS,CS,IS_ALIVE if get_pixel(XS+CS*cx,YS+CS*cy)==CURSOR_ALIVE else IS_DEAD)
def um():
  global cx,cy;exit=False;pressed={KEY_OK:monotonic(),KEY_EXE:monotonic()};dc()
  def exe():nonlocal exit;exit=True
  def ok():fill_rect(XS+cx*CS,YS+cy*CS,CS,CS,CURSOR_DEAD if get_pixel(XS+CS*cx,YS+CS*cy)==CURSOR_ALIVE else CURSOR_ALIVE)
  def l():global cx;udc();cx=W-1 if cx==0 else cx-1;dc()
  def u():global cy;udc();cy=H-1 if cy==0 else cy-1;dc()
  def r():global cx;udc();cx=0 if cx==W-1 else cx+1;dc()
  def d():global cy;udc();cy=0 if cy==H-1 else cy+1;dc()
  while not exit:np={};mk(pressed,np,KEY_EXE,exe);mk(pressed,np,KEY_OK,ok);mk(pressed,np,KEY_LEFT,l);mk(pressed,np,KEY_UP,u);mk(pressed,np,KEY_RIGHT,r);mk(pressed,np,KEY_DOWN,d);pressed=np;sleep(.05)
  udc()
adj_vp()
dr(MX-3,MY-3,VW+5,VH+5,1,a(220,220,220))
ini()
while 1:
  nxt();clr()
  if keydown(KEY_OK)or keydown(KEY_EXE):um()