snake_lite.py

Created by zetamap

Created on April 10, 2024

7.13 KB

The most small and configurable snake ever (on numworks).
I used the library called pymenu to make the options menu.


Features

  • Very VEERRYY small program, only 240 lines and 7KB of storage
  • A leaderboard
  • Configurable game options :
    • Speed [default: 10]: Speed of snake.
    • Power [default: 2]: Size added after eat a cherry.
    • Snake Size [default: 10]: The size of snake (1 –> 80).
    • Score [default: 1]: Score added when eating a cherry.
    • Expert Mode [default: False]: Snake’s body will grow infinitely.
    • Babu Mode [default: False]: Literary a gost, it can eat walls and itself. 🀣
    • Darkmode [default: True]: A mode for g@mers.
    • Rainbow [default: False]: Enjoy the rainbow!
    • Walls [default: True]: Enable/Disable walls.
  • Dynamic accent color according to OS
  • A start menu to play with default settings
  • Automatic darkmode


from random import randint as ri
from kandinsky import fill_rect as fr,draw_string as ds
from ion import keydown as kd
from time import monotonic as mt,sleep as sl

DEC=lambda v:((v&0xfff000)>>12,v&0xfff)
ENC=lambda x,y:x<<12|y
BOOL=lambda t:(t.lower()if type(t)==str else t) in("yes","on","enabled","activated","true","1",1)
def wk(*b):
 while 1:
  for i in b:
   if kd(i):
    while kd(i):pass
    return i
mjust=lambda l,r,s,f=' ': l+f*((s-len(l))//len(f))+r
class Snake:
 c=["0.95","0.2","#00ff00","green","red","blue","#ffb531","1.0"]
 try:
  import os
  u=os.getlogin()or "You"
  try:
   from kandinsky import get_palette as gp
   c[6]=gp()["Toolbar"]
   c[7]=gp()["HomeBackground"]
  except:c[6]="#c53431"
 except:u="You"
 def __init__(s,leader_board=[],speed=10,power=2,size=10,score=1,inf_snake=False,gost=False,darkmode=True,rainbow=False,walls=True):
  if BOOL(inf_snake):power=float("inf")
  if BOOL(darkmode):s.c[0],s.c[1]=s.c[1],s.c[0]
  s.lb,s.s,s.p,s.m,s.t,s.g,s.go,s.r,s.w=leader_board,1/speed,power,score,size,(320//size,220//size),BOOL(gost),BOOL(rainbow),BOOL(walls)
 def nc(s):
  s.h=[ri(s.w,s.g[i]-s.w-1)for i in(0,1)]
  while ENC(s.h[0],s.h[1])in s.b:s.h=[ri(s.w,s.g[i]-s.w-1)for i in(0,1)]
  fr(s.h[0]*s.t,2+s.h[1]*s.t,s.t,s.t,s.c[4])
 def dl(s):
  fr(0,2,320,220,"0.0")
  fr(0,2,s.g[0]*s.t,s.g[1]*s.t,s.c[5*s.w])
  if s.w:fr(s.t//2,2+s.t//2,(s.g[0]-1)*s.t,(s.g[1]-1)*s.t,s.c[0])
 def dt(s,t,x,y):
  for i,l in enumerate(t.replace('\t',"    ")):
   ds(l,x+10*i,y,s.c[1],s.c[0])
   if l!=' ':sl(0.02)
 def ub(s,l1,l2):
  fr(20,82,280,50,s.c[4])
  fr(25,87,270,40,s.c[0])
  s.dt(l1,25,87)
  s.dt(l2,25,107)
  sl(0.2)
  while 1:
   sl(0.01)
   if kd(4):return 1
   elif kd(17):return 0
 def wu(s):
  s.mt=mt()
  s.ta,s.e=(s.b[-1],DEC(s.b[-1])),DEC(s.b[0])
  if kd(0)and s.d[0]!=1:s.d=[-1,0]
  elif kd(1)and s.d[1]!=1:s.d=[0,-1]
  elif kd(2)and s.d[1]!=-1:s.d=[0,1]
  elif kd(3)and s.d[0]!=-1:s.d=[1,0]
  fr(s.e[0]*s.t,2+s.e[1]*s.t,s.t,s.t,s.r and[ri(0,255) for _ in(0,1,2)]or s.c[3])
  for x in range(len(s.b)-1,0,-1):s.b[x]=s.b[x-1]
  s.b[0]=ENC((s.e[0]+s.d[0])%s.g[0],(s.e[1]+s.d[1])%s.g[1])
  if s.a>0:
   s.b.append(s.ta[0])
   s.a-=1
  elif s.ta[0]not in s.b:fr(s.ta[1][0]*s.t,2+s.ta[1][1]*s.t,s.t,s.t,s.c[0])
  if s.b[0]==ENC(s.h[0],s.h[1]):
   s.a,s.sc=s.a+s.p,s.sc+s.m
   s.nc()
  s.e=DEC(s.b[0])
  fr(s.e[0]*s.t,2+s.e[1]*s.t,s.t,s.t,s.c[2])
  ds(str(s.sc),7,7,s.c[1],s.c[0])
  if not s.go:
   if s.w and(s.e[0]==s.g[0]-1 or s.e[1]==s.g[1]-1 or s.e[0]==0 or s.e[1]==0):return 0
   for x in range(1,len(s.b)):
    if s.b[x]==s.b[0]:return 0
  return 1
 def start(s):
  fr(0,0,320,2,s.c[6])
  try:
   while 1:
    s.b,s.a,s.d,s.sc=[ENC(s.g[0]//2,s.g[1]//2)],4,(1,0),0
    s.dl()
    s.nc()
    while s.wu():
     if kd(17):
      s.ub("\t\tGame Paused!","  (OK, DELETE = Continue)")
      sl(0.2)
      s.dl()
      fr(s.h[0]*s.t,2+s.h[1]*s.t,s.t,s.t,s.c[4])
      for i in s.b:
       s.e=DEC(i)
       fr(s.e[0]*s.t,2+s.e[1]*s.t,s.t,s.t,s.r and[ri(0,255) for _ in(0,1,2)]or s.c[3])
     while mt()-s.mt<s.s:sl(0.01)
    if not s.ub(' '*(3-len(str(s.sc))//2)+"You lose!\tScore: %d"%s.sc,"(OK = Retry, DELETE = Quit)"):break
   e,p,s.lb,x,t=0,0,sorted(s.lb+((s.u,s.sc),),key=lambda v:v[1],reverse=1),"Your score:","Leader board:"
   print(x,s.sc,"\n",t+" (default settings)")
   for i,sc in enumerate(s.lb):
    if len(sc[0])>e:e=len(sc[0])+len(str(sc[1]))
    if sc[0]==s.u:p=i
    print(' %d-'%(i+1),sc[0]+':',sc[1])
   fr(0,2,320,220,s.c[0])
   s.dt(x+" %d"%s.sc,5,7)
   s.dt(t,5,32)
   for i,sc in enumerate(s.lb):
    s.lb[i]=mjust(sc[0]+':',str(sc[1]),e+3)
    s.dt(s.lb[i],60,52+20*i)
   while not kd(4)and not kd(17):
    for i in range(4):
     if kd(4)or kd(17):break
     ds('>'*i+' '*(4-i),20,52,s.c[6],s.c[0])
     ds(' '*(4-i)+'<'*i,20+(e+1)*16,52,s.c[6],s.c[0])
     ds(s.lb[p],60,52+20*p,s.c[bool(i%3)*5+1],s.c[0])
     sl(0.2)
  except KeyboardInterrupt:pass
class Menu:
 colors=[Snake.c[0],Snake.c[1],"0.38",Snake.c[6],"#2a78e0"]
 r,u=colors,1
 options=lambda s:[s.p[i][s.c[i]]for i in range(s.s)]
 def __init__(s,title,action,*options):
  s.t,s.a,s.p=title[0:25],action[0:28],options
  s.s=len(s.p)
  s.c,s.b=[],len(s.a)
  for i in s.p :
   assert len(i)>2,"need [label,default,values...]"
   s.c.append(int(i[1])+2)
 def mo(s,i,o,u):
  t,l=str(s.p[i][s.c[i]])[0:15],i%6
  ds('<'*u+' '*(17-2*u)+'>'*u,140,65+l*25,s.r[2],s.r[1])
  ds(t,150+(150-10*len(t))//2,65+l*25,o,s.r[1])
 def do(s):
  u=s.u-1*(s.u>0)
  u=(u-(u and u==u//6*6))//6*6
  for i in range(6):
   if u+i<s.s:
    t=str(s.p[u+i][0])[0:12]
    ds(t+' '*(12-len(t)),10,65+i*25,s.r[0],s.r[1])
    s.mo(u+i,s.r[2],0)
   else:fr(10,65+i*25,300,18,s.r[1])
  if s.s>6:s.sb(u)
 def sb(s,u):
  fr(314,65,3,140,s.r[2])
  o=140//((s.s+5)//6)
  p=o*(u//6)
  fr(314,65+p,3,o+(u==s.s//6*6)*(140-o-p),s.r[3])
 def da(s,i):
  c=s.r[3*(i==0)]
  ds("<",10,8,c,s.r[1])
  fr(13,16,13,1,c)
  fr(26,10,1,6,c)
  ds(s.a,160-5*s.b,36,s.r[3*(i==1)],s.r[1])
 def ds(s):
  fr(0,0,320,222,s.r[1])
  ds(s.t,160-5*len(s.t),8,s.r[4],s.r[1])
  s.da(s.u)
  s.do()
 def close(s,b=0):
  fr(0,0,320,222,s.r[1])
  if b:s.u=1
  return[]if b else s.options()
 def open(s):
  s.ds()
  r=-1
  while 1:
   if r in(5,17):return s.close(1)
   elif r in(4,52):
    if s.u<2:return s.close(s.u==0)
    r=-2
   elif r in(-1,1,2):
    if s.u<2:s.da(s.u+1)
    s.u=(s.u-1*(r==1)+1*(r==2))%(s.s+2)
    s.do()
    if s.u>1:s.mo(s.u-2,s.r[3],1)
    else:s.da(s.u)
   if r in(-2,0,3)and s.u>1:
    v=s.u-2
    s.c[v],l=s.c[v]+1*(r==3)-1*(r==0)if r>=0 else s.p[v][1]+2,s.c[v]
    o=s.c[v]
    if o==1:s.c[v]=len(s.p[v])-1
    if o==len(s.p[v]):s.c[v]=2
    if l!=o and s.p[v][0].lower()=="darkmode":#special
     s.r[0],s.r[1]=s.r[1],s.r[0]
     s.ds()
    s.mo(v,s.r[3],1)
   r=wk(0,1,2,3,4,5,17,52)
def intro(d):
 def pl(letter,x,y,size,color):
  for i,l in enumerate(letter):
   if l=='1':fr(x+size*(i%3),y+size*(i//3),size,size,color)
 a,x,ax,r,c,b,o,e='1'*9+"44334411",0,-110,0,Snake.c[6],Menu.r[1],["Play","Options","Quit"],0
 y=ay=120
 fr(0,0,320,222,b)
 for i,l in enumerate((31597,31725,23469,31207)):
  pl(bin(l)[2:],110+40*i,80,10,"0.0")
  sl(0.008)
 for i in range(len(a)):
  f=int(a[i])
  x+=((f==1)-(f==3))*10
  y+=((f==2)-(f==4))*10
  if ax<0:ax+=10
  else:
   i=int(a[i-11])
   ax+=((i==1)-(i==3))*10
   ay+=((i==2)-(i==4))*10
   fr(ax,ay,10,10,b)
  fr(x,y,10,10,"#00cc00")
  sl(0.05)
 pl("001001000001001",x,y,2,"0.0")
 pl("000001110001",x+10,y,2,"red")
 while 1:
  for i,l in enumerate(o):
   f=e==i
   fr(100,140+i*25,140,18,b)
   ds("> "*f+l+f*" <",110+(110-10*(len(l)+4*f))//2,140+i*25,c if f else Menu.r[0],b)
  r=wk(1,2,4,17,52)
  e=(e-1*(r==1)+1*(r==2))%3
  if r==17:return 1
  if r in(4,52):return[]if e==1 else 1 if e==2 else d
def game(*lb):
 o=[]
 while not o:
  o=intro(menu.options())or menu.open()
  if o==1:return
 Snake(lb,*o).start()

menu = Menu("Game Settings","Start Game",
 ["Speed",9]+list(range(1,26)),
 ["Power",1]+list(range(1,21)),
 ["Snake Size",9]+list(range(1,51)),
 ["Added Score",0]+list(range(1,21)),
 ["Expert Mode",1,"Yes","No"],
 ["Babu Mode",1,"Yes","No"],
 ["Darkmode",0,"Enabled","Disabled"],
 ["Rainbow",1,"On","Off"],
 ["Walls",0,"Yes","No"]
)

game(# Leader board: ("name",score),
  ("Alteur",38),
  ("Lidl Man",37),
  ("ZetaMap",31),
  ("Nios",23),
  ("Alpha6Frost",17),

)

During your visit to our site, NumWorks needs to install "cookies" or use other technologies to collect data about you in order to:

With the exception of Cookies essential to the operation of the site, NumWorks leaves you the choice: you can accept Cookies for audience measurement by clicking on the "Accept and continue" button, or refuse these Cookies by clicking on the "Continue without accepting" button or by continuing your browsing. You can update your choice at any time by clicking on the link "Manage my cookies" at the bottom of the page. For more information, please consult our <a href="https://www.numworks.com/legal/cookies-policy/">cookies policy</a>.