optconway.py

Created by lokasku

Created on May 15, 2024

3.84 KB


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=10
ALIVE_CR=0.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=0.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():
  for x in range(XS,XE,CS):
    for y in range(YS,YE,CS):
      if rdt(0,100)<ALIVE_CR*100: fill_rect(x,y,CS,CS,IS_ALIVE)

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(0.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(0.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()