A new version of my punto game, with save function implemented for the users of Omega/Upsilon
from kandinsky import fill_rect as rect,draw_string as txt from random import randint,choice from ion import keydown as k import time deckfile="decks.sav" platefile="plate.sav" tourfile="tour.sav" coordsfile="coords.sav" SKY=(0,0,0) TXT=(255,)*3 IMP=(0,0,255) PC=[(255,0,0),(0,255,0),(0,0,255),(255,0,255)] PN=["Rouge","Vert","Bleu","Violet"] POINTS=[[5],[1,9],[1,5,9],[1,3,7,9],[1,3,5,7,9],[1,3,4,6,7,9],[1,3,4,5,6,7,9],[1,2,3,4,6,7,8,9],[1,2,3,4,5,6,7,8,9],] try: import os OS=True except:OS=False # Fill the screen with a color c clean=lambda c:rect(0,0,320,222,c) # Draw a centered text in the x axis txtc=lambda t,y,cf,cb:txt(str(t),160-5*len(str(t)),y,cf,cb) # Tests if keys are pressed v=lambda:k(4)|k(56) # Validate s=lambda:k(0)|k(1)|k(2)|k(3) # Directions # Calculate th sum of the cards in a collomn/row sumCollumn=lambda c:sum(PLATE[i][c]for i in range(7)) sumRow=lambda r:sum(PLATE[r]) # Draw a recct 3x3 in x,y point=lambda x,y:rect(x,y,3,3,SKY) # random.shuffle() because not existing in Numworks def shuffle(ol): l=ol[:] nl=[] for _ in range(len(l)): i=choice(l) nl.append(i) l.remove(i) return nl def draw_select(x,y,e,p): xb,yb=90,5 X=xb+31*x Y=yb+31*y c=p if e:c=SKY rect(X,Y,27,2,c) rect(X,Y+25,27,2,c) rect(X,Y,2,27,c) rect(X+25,Y,2,27,c) def draw_card(n,x=-1,y=-1,e=False): if x>-1: xb,yb=92,7 X=xb+31*x Y=yb+31*y elif x<-1:X,Y=(160-31*7//2)+31*-x-58,175 else:X,Y=25,100 p=getPcolor(n) c=PC[p] if e:c=SKY rect(X,Y,23,23,c) if e:return N=n-p*9 for y in range(3): for x in range(3): if 3*y+x+1 in POINTS[N-1]:point(X+4+x*6,Y+4+y*6) def isTouching(X,Y): if PLATE[X][Y]:return True if 0<X<6: if any([PLATE[Y][X-1],PLATE[Y][X+1]]):return True if 0<Y<6: if any([PLATE[Y-1][X-1],PLATE[Y-1][X],PLATE[Y-1][X+1],PLATE[Y+1][X-1],PLATE[Y+1][X],PLATE[Y+1][X+1]]):return True elif Y==0: if any([PLATE[Y+1][X-1],PLATE[Y+1][X],PLATE[Y+1][X+1]]):return True elif Y==6: if any([PLATE[Y-1][X-1],PLATE[Y-1][X],PLATE[Y-1][X+1]]):return True elif X==0: if PLATE[Y][X+1]:return True if 0<Y<6: if any([PLATE[Y+1][X],PLATE[Y+1][X+1],PLATE[Y-1][X],PLATE[Y-1][X+1]]):return True elif Y==0: if any([PLATE[Y+1][X],PLATE[Y+1][X+1]]):return True elif Y==6: if any([PLATE[Y-1][X],PLATE[Y-1][X+1],PLATE[Y][X+1]]):return True elif X==6: if PLATE[Y][X-1]:return True if 0<Y<6: if any([PLATE[Y-1][X-1],PLATE[Y-1][X],PLATE[Y+1][X-1],PLATE[Y+1][X]]):return True elif Y==0: if any([PLATE[Y+1][X-1],PLATE[Y+1][X]]):return True elif Y==6: if any([PLATE[Y-1][X-1]+PLATE[Y-1][X]]):return True return False def isSupperior(X,Y,C): if PLATE[Y][X]==0:return True pp=getPcolor(PLATE[Y][X]) pc=getPcolor(C) if PLATE[Y][X]-9*pp<C-9*pc:return True return False def isInPlate(X,Y): global l_x,l_y,s_x,s_y l_x=0 l_y=0 for i in range(7): if sumCollumn(i)>0: if l_x==0:s_x=i l_x+=1 if sumRow(i)>0: if l_y==0:s_y=i l_y+=1 if l_x==6: if X<s_x or X>=s_x+6:return False if l_y==6: if Y<s_y or Y>=s_y+6:return False return True def getPcolor(n): if n==0:p=-1 elif n<10:p=0 elif n<19:p=1 elif n<28:p=2 elif n<37:p=3 return p def draw_cards(): for i in range(7): for j in range(7): if PLATE[j][i]>0: draw_card(PLATE[j][i],i,j) else: draw_card(PLATE[j][i],i,j,True) def isVictory(p): for i in range(7): for j in range(7): if PLATE[i][j]>0: if( (j<4 and all(getPcolor(PLATE[i][j+k])==p for k in range(4)))or (i<4 and all(getPcolor(PLATE[i+k][j])==p for k in range(4)))or (i<4 and j<4 and all(getPcolor(PLATE[i+k][j+k])==p for k in range(4)))or (i<4 and j>2 and all(getPcolor(PLATE[i+k][j-k])==p for k in range(4)))):return True return False def move_if_close_to_border(): # Right to left if sumCollumn(6)>0 and l_x<5: for i in range(1,7): for j in range(1,7): PLATE[i][j-1]=PLATE[i][j] if i==6:PLATE[j][i]=0 # Left to right if sumCollumn(0)>0 and l_x<5: for i in range(6,-1,-1): for j in range(6,-1,-1): PLATE[i][j]=PLATE[i][j-1] if i==0:PLATE[i][j]=0 # Down to Up if sumRow(6)>0 and l_y<5: # print(PLATE[6][3]) for j in range(1,7): for i in range(1,7): PLATE[j-1][i]=PLATE[j][i] if j==6: PLATE[j][i]=0 print(j) # Up to Down if sumRow(0)>0 and l_x<5: for j in range(6,-1,-1): for i in range(6,-1,-1): PLATE[j][i]=PLATE[j-1][i] if j==0:PLATE[j][i]=0 def game(): global PT,PLATE,DECKS,X,Y menu=True if OS: if deckfile in os.listdir(): clean(SKY) txtc("Savefile found!",20,IMP,SKY) txtc("Continue game?",50,TXT,SKY) txt("No",40,100,(255,0,0),SKY) txt("Yes",250,100,(0,255,0),SKY) txt("[0]",35,120,(255,0,0),SKY) txt("[EXE]",240,120,(0,255,0),SKY) while v():1 while 1: if k(52): menu=False with open(deckfile,"r")as f: DECKS=eval(f.read()) with open(platefile,"r")as f: PLATE=eval(f.read()) with open(tourfile,"r")as f: PT=int(f.read()) with open(coordsfile,"r")as f: X,Y=eval(f.read()) N=len(DECKS) Save=True break elif k(48): break if menu: a=130 clean(SKY) txt("P",a,5,PC[0],SKY) txt("U",a+10,5,PC[1],SKY) txt("N",a+20,5,PC[2],SKY) txt("T",a+30,5,PC[3],SKY) txt("O",a+40,5,PC[0],SKY) txt("!",a+50,5,PC[0],SKY) txt("Number of players: < >",40,50,TXT,SKY) params=[0] if OS: params.append(False) txt("Enable saving: ",65,100,TXT,SKY) txt("False",210,100,(255,0,0),SKY) txtc("VALIDATE",50+len(params)*50,(0,255,0),SKY) while v():1 p=0 f=True t=False l=-1 pV=False pS=False while 1: if v()&pV: if (p==1)&OS: params[1]=not params[1] if params[1]:c=(0,255,0) else:c=(255,0,0) rect(210,100,50,18,SKY) txt(str(params[1]),210,100,c,SKY) elif (p==2)|((p==1)&(not OS)):break pV=False elif (s()|f)&pS: p=(p-k(1)+k(2))%(len(params)+1) if p==0:params[0]=(params[0]-k(0)+k(3))%3 if l!=p:rect(10,50+l*50,10,18,SKY) l=p txt("→",10,50+p*50,(255,255,0),SKY) txt(str(params[0]+2),250,50,TXT,SKY) pS=False if f:f=False if t==True: t=False a=time.monotonic() if not s():pS=True if not v():pV=True if time.monotonic()-a>0.5: t=True for i in range(1,8):draw_card(randint(0,36),-(i+1)) N=params[0]+2 if len(params)==2: Save=params[1] else:Save=False deck=[i for i in range(1,10)for _ in range(2)] DECKS=[shuffle(deck)for _ in range(N)] PLATE=[[0 for _ in range(7)]for _ in range(7)] PT=randint(0,N-1) # Player tour X,Y=3,3 V=0 clean(SKY) draw_cards() if(sum([sumCollumn(i)for i in range(7)]))==0: f2=True else:f2=False # Game loop for i in range(18*N-1):# Numbers of card*number of players rect(0,0,70,222,PC[PT]) txt("Tour:",10,2,SKY,PC[PT]) txt(PN[PT],35-len(PN[PT])*5,25,SKY,PC[PT]) rect(23,98,27,27,SKY) draw_card(DECKS[PT][0]+PT*9) f1=True p=True while 1: if s()|f1: draw_select(X,Y,1,PC[PT]) X=(X+k(3)-k(0))%7 Y=(Y+k(2)-k(1))%7 draw_select(X,Y,0,PC[PT]) # Test if the card can be placed ok=0 rect(13,202,11,11,SKY) if isTouching(X,Y): ok+=1 rect(16,205,5,5,PC[1]) else:rect(16,205,5,5,PC[0]) rect(31,202,11,11,SKY) if isSupperior(X,Y,DECKS[PT][0]): ok+=1 rect(34,205,5,5,PC[1]) else:rect(34,205,5,5,PC[0]) rect(48,202,11,11,SKY) if isInPlate(X,Y): ok+=1 rect(51,205,5,5,PC[1]) else:rect(51,205,5,5,PC[0]) if f1:f1=False while s():1 if v()&(not p): if (ok==3)|f2: PLATE[Y][X]=DECKS[PT][0]+PT*9 DECKS[PT].pop(0) move_if_close_to_border() draw_cards() if f2:f2=False break if not v():p=False for i in range(N): if isVictory(i): rect(99,90,120,62,TXT) rect(102,93,114,56,SKY) txtc("Victoire du",96,PC[i],SKY) txtc(PN[i],116,PC[i],SKY) if Save: os.remove(deckfile) os.remove(platefile) os.remove(coordsfile) os.remove(tourfile) while v():1 while not v():1 return PT=(PT+1)%N if Save: with open(deckfile,"w")as f: f.write(str(DECKS)) with open(platefile,"w")as f: f.write(str(PLATE)) with open(tourfile,"w")as f: f.write(str(PT)) with open(coordsfile,"w")as f: f.write(str([X,Y])) while 1:game()