Petit jeu. Adaptation pour la NumWorks de ma participation au concours Python Jam # 2 organisé par Planète-Casio du 19 au 27 avril 2025.
from kandinsky import * from time import * from random import * from ion import * from math import atan # la fonction suivante n'est pas utile sur Upsilon mais est nécessaire sur Epsilon pour avoir un affichage correct def d_s(chaine,x,y,clr): texte=chaine.split("\n") for k in range(len(texte)): draw_string(texte[k],x,y+18*k,clr) def efface_ecran(b=1): fill_rect(17,22,282,168,"w") fill_rect(17,204,282,18*b,"w") def Titres_scores(): for i in range(3): d_s(("retenus\n nb pts","sortis\nnb pts","score\ntotal")[i],(100,180,250)[i],20,("b","r",("brown","w")[manche==4])[i]) d_s("clients\n+caddie\nemployés\n+caddie",17,60,"purple") dessin_consommateur(100,96,1,"purple")#("r","purple")[k]) dessin_consommateur(90,114,1,"purple")#("r","purple")[k]) dessin_caddie(98,115,1,"purple")#("r","purple")[k]) def dessin(x,y,motif,palette=("w","g",(0,128,0))): for i in range(len(motif)): for j in range(len(motif[0])): if int(motif[i][j])>0: set_pixel(x+j,y+i,palette[int(motif[i][j])]) def dessin_comptoir(x,y,cote="gauche"): D=(cote!="droite") fill_rect(x+7*D,y,1,14,"k") fill_rect(x+1+5*D,y,1,14,(204,204,204)) fill_rect(x+1+5*D,y+14,1,5,"k") fill_rect(x+2+3*D,y,1,13,"k") for k in range(3): fill_rect(x+2-2*D,y+13+k,6,1+2*(k==2),((204,204,204),"k",(153,153,153))[k]) fill_rect(x+2-2*D,y+18,6,1,"k") fill_rect(x+3-2*D,y,4,12,(153,153,153)) fill_rect(x+3-3*D,y+12,5,1,"k") fill_rect(x+7-7*D,y,1,10,"k") # chaise fill_rect(x+9-11*D,y+6,1,2,"k") fill_rect(x+10-15*D,y+5,3,1,"k") fill_rect(x+13-19*D,y+1,1,4,"k") fill_rect(x+13-19*D,y+6,1,2,"k") def dessin_bas_comptoir(x,y,longueur): for k in range(longueur+1): dessin(x+k,y,"3223132223",("w",(204,204,204),(153,153,153),"k")) def dessin_gardien(x,y): fill_rect(x+3,y+1,5,3,"k") fill_rect(x+2,y+5,7,2,"b") # épaules fill_rect(x+3,y+7,5,3,"b") # ventre fill_rect(x+3,y+10,5,1,(120,50,0)) # ceinture fill_rect(x+3,y+11,5,2,"k") # hanches for k in (0,1): fill_rect(x+9*k,y+5,2,5,"k") # bras gauche + bras droit fill_rect(x+4,y+4*k,3,1,"k") # tete fill_rect(x+3+3*k,y+13,2,4,"k") # jambe gauche + jambe droite fill_rect(x+2+4*k,y+17,3,1,"brown") # pied gauche + pied droit set_pixel(x+4+2*k,y+2,"w") # yeux set_pixel(x+6-k,y+6+4*k,(200,120,0)) # insigne + boucle ceinture def dessin_consommateur(x,y,sens,couleur): fill_rect(x+2,y,3,1,"k") fill_rect(x+2,y+2,3,1,"k") for i in range(5): set_pixel(x+1+i,y+1,("k","cyan")[i%2]) set_pixel(x+3,y+3,"k") # cou set_pixel(x+3+3*sens,y+3,"k") # bras haut set_pixel(x+3+4*sens,y+2,"k") # main haute fill_rect(x+3-3*sens,y+5,1,2,"k") # bras bas fill_rect(x+1,y+4,5,1,couleur) # épaules for i in range(2): fill_rect(x+2,y+5+3*i,3,2,couleur) # torse+pantalon fill_rect(x+2,y+7,3,1,"k") # ceinture fill_rect(x+3+2*sens,y+10,1,3,couleur) # jambe tendue fill_rect(x+3-sens,y+10,1,2,couleur) # jambe pliée set_pixel(x+3-2*sens,y+12,couleur) set_pixel(x+1,y+13,"k") set_pixel(x+5,y+13,"k") set_pixel(x+3+3*sens,y+13,"k") set_pixel(x+3-sens,y+13,"k") def dessin_caddie(x,y,sens,couleur): fill_rect(x+int(8.5-8.5*sens),y,2,1,couleur) # poignee fill_rect(x+9-7*sens,y,1,2,"k") fill_rect(x+9-6*sens,y+1,1,3,"k") fill_rect(x+9-5*sens,y+4,1,2,"k") fill_rect(x+9-4*sens,y+6,1,2,"k") for k in range(3): fill_rect(x+(4+k)*(sens==1),y+2+2*k,15-k,1,"k") # barre haut du caddie #fill_rect(x+5,y+4,14,1,"k") #fill_rect(x+6,y+6,13,1,"k") fill_rect(x+3+3*sens,y+8,13,1,"k") # barre basse du caddie for i in range(-1,4): for j in range(3): set_pixel(x+9+3*i*sens,y+3+2*j,"k") fill_rect(x+9-5*sens,y+10,1,2,"k") set_pixel(x+9-4*sens,y+9,"k") fill_rect(x+int(8.5-3.5*sens),y+11,2,1,couleur) fill_rect(x+int(8.5+6.5*sens),y+11,2,1,couleur) fill_rect(x+int(5.5+1.5*sens),y+11,8,1,"k") # barre des roues set_pixel(x+9+8*sens,y+11,"k") fill_rect(x+int(8.5-3.5*sens),y+12,2,2,"k") # roue arriere fill_rect(x+int(8.5+6.5*sens),y+12,2,2,"k") # roue avant def dessin_pot(x,y,style=randint(1,3)): dessin(x,y,("222202222","211222112","222111222","021222120","021111120",("021111120","002111200")[style>1],("002222200","000222000")[style>2]),("w",(255,128,0),(128,64,0))) def dessin_plante(x,y,style=0,quatrieme=0): if style<5: # feuilles du bas dessin(x-2,y-3,("0222000002220","2111200021112","0222122212220")) set_pixel(x+4,y,(0,128,0)) # 3ème feuille dessin(x+4,y-6,(("00000","00220")[style>2],("00220","02200","02112","02112")[style-1],("02112","21120","21120","02120")[style-1],("21100","21200")[style>1],"22000")) if quatrieme==1: # 4ème feuille dessin(x+1,y-5,("0220","2112","0210")) set_pixel(x+3,y-2,(0,128,0)) elif quatrieme==2: # fleur (clr1,clr2,clr3)=(("y","orange","r"),("y","b","purple"),("y","purple","pink"))[randint(0,2)] dessin(x+1,y-7,("01210","12321","23132","12324","01200"),("w",clr1,clr2,clr3,(0,128,0))) set_pixel(x+3,y-2,(0,128,0)) elif style in (5,6): # plante fine avec tige clr=(206,178,38) fill_rect(x+4,y-9,1,10,clr) if style==5: set_pixel(x+3,y-7,clr) set_pixel(x+3,y-2,clr) set_pixel(x+5,y-5,clr) # feuille gauche for k in (0,6): dessin(x+(style==6),y-11+k,("220","212","021","002")) # feuille droite dessin(x+6-(style==6),y-14+k,("022","212","120","200")) elif style in (7,8): # cactus clr=(0,128,0) fill_rect(x+3,y-9,3,9,clr) set_pixel(x+4,y-10,clr) set_pixel(x+4,y,clr) fill_rect(x,y-6,1,3,clr) fill_rect(x+1,y-7,1,5,clr) fill_rect(x+2,y-4,1,2,clr) fill_rect(x+8,y-9,1,3,clr) fill_rect(x+7,y-10,1,5,clr) fill_rect(x+6,y-7,1,2,clr) if style==8: # fleur dessin(x+2,y-10,("010","121","010"),(("w","orange","r"),("w","b","y"))[randint(0,1)]) def dessin_panneau_verre(x,y): for i in range(2): fill_rect(x+2,y+6*i,11,1,"gray") fill_rect(x+1+12*i,y+1,1,8,"gray") fill_rect(x+12*i,y+9,3,1,"gray") for k in range(5): fill_rect(x+2,y+1+k,4-k,1,"cyan") fill_rect(x+7-k,y+1+k,2,1,"cyan") set_pixel(x+6-k,y+1+k,"w") fill_rect(x+9-k,y+1+k,3,1,"w") fill_rect(x+12-k,y+1+k,2-(k==0),1,"cyan") for k in range(3): set_pixel(x+10+k,y+5-k,"w") fill_rect(x+11,y+5,2,1,"cyan") set_pixel(x+12,y+4,"cyan") def dessin_barriere(x,y,cote="gauche"): for i in range(2): fill_rect(x+1,y+4*i,11,1,"gray") fill_rect(x+12*i,y+1,1,3,"gray") fill_rect(x+2+8*(cote=="droite"),y+1,1,8,"gray") fill_rect(x+1+8*(cote=="droite"),y+9,3,1,"gray") fill_rect(x+5-2*(cote=="droite"),y+1,5,3,(204,204,204)) def consommateur_clignotant(): clr=("g","b","r","y","orange","magenta","cyan")[int(monotonic())%7] dessin_consommateur(90,60,1,clr) dessin_consommateur(90,78,1,clr) dessin_caddie(98,79,1,clr) # écran de titre for i in range(9): pot=randint(1,3) type_=randint(1,8) quatrieme=randint(0,2) for k in (0,1): dessin_pot(5+300*k,32+20*i,pot) dessin_plante(5+300*k,32+20*i,type_,quatrieme) for j in range(16): pot=randint(1,3) type_=randint(1,8) quatrieme=randint(0,2) for k in (0,1): dessin_pot(5+20*j,13+199*k,pot) dessin_plante(5+20*j,13+199*k,type_,quatrieme) for k in (0,1): fill_rect(30,40+k*142,260,1,"purple") d_s("Le Gardien du temple\n(de la consommation)",60,50,"magenta") d_s("Choix du mode : ",80,100,"purple") d_s("Classique Sans fin",50,130,"b") d_s("EXE pour valider",80,160,"g") classique=0 chg=1 while not (keydown(KEY_EXE) or keydown(KEY_OK)): if chg: for k in (0,1): d_s("[]"[k],170-135*classique+110*k,130,"w") classique=1-classique for k in (0,1): d_s("[]"[k],170-135*classique+110*k,130,"r") sleep(0.2) chg=keydown(KEY_RIGHT)-keydown(KEY_LEFT) while keydown(KEY_EXE) or keydown(KEY_OK):1 fill_rect(0,0,320,222,"w") # la devanture du magasin : for i in range(3): fill_rect(159,7*i,2,6,"k") dessin_comptoir(30,0,"gauche") dessin_bas_comptoir(-1,9,31) dessin_comptoir(282,0,"droite") dessin_bas_comptoir(289,9,30) for k in (71,194): dessin_comptoir(k,0,"droite") dessin_bas_comptoir(k+7,9,40) dessin_comptoir(k+47,0,"gauche") # dessin de la sortie for i in range(2): for k in range(3): dessin_panneau_verre(18+142*i+42*k,202-10) dessin_barriere(33+142*i+42*k,202-10,"gauche") dessin_barriere(47+142*i+42*k,202-10,"droite") dessin_panneau_verre(18+142*i+42*3,202-10) # dessin des plantes for i in range(9): pot=randint(1,3) type_=randint(1,8) quatrieme=randint(0,2) for k in (0,1): dessin_pot(5+300*k,32+20*i,pot) dessin_plante(5+300*k,32+20*i,type_,quatrieme) class Client: def __init__(self,porte): self.x=320//6-12+(320//3)*porte + 18*(2*randint(0,1)-1)*(porte==1) -(porte>0) self.y=0 self.dx=-1 #2*randint(0,1)-1 self.couleur=("g","b","r","y","orange","magenta","cyan","purple")[randint(0,7)] self.Type=("","caddie")[randint(1,3)<manche] def affiche(self): dessin_consommateur(self.x,self.y,-self.dx,self.couleur) if self.Type=="caddie": dessin_caddie(self.x+(8,-20)[self.dx==1],self.y+1,-self.dx,self.couleur) def efface(self): fill_rect(self.x-(self.dx==1)-19*(self.dx==1)*(self.Type=="caddie"),self.y,8+20*(self.Type=="caddie"),15,"w") class Boite: def __init__(self,x,y): self.x=x self.y=y self.dx=atan(abs(X-self.x)/max(1,abs(Y-self.y)))*(-1,1)[X>self.x] self.dy=atan(abs(Y-self.y)/max(1,abs(X-self.x)))*(-1,1)[Y>self.y] def affiche(self): for i in range(3): fill_rect(int(self.x),int(self.y)+2*i,3,1,(128,128,128)) for i in range(2): fill_rect(int(self.x),int(self.y)+1+2*i,3,1,(192,192,192)) def efface(self): fill_rect(int(self.x),int(self.y),3,5,"w") Message=("Une pandémie a entrainé une\nruée des gens dans les\ntemples (de la consommation)\npour acheter des provisions.\nOh, ils partent sans payer,\net les employés aussi !\nAide le Gardien à les\nintercepter !",\ "Les gens viennent avec des\ncaddies pour faire du stock\nde papier toilette ! \n\nOn risque la pénurie !\n\nAide le Gardien à les\nintercepter !",\ "Les gens s'affolent et\ndeviennent aggressifs envers\nle Gardien.\nIls lui jettent des boîtes\nde conserve et ça fait mal !\n\nAide le Gardien à les\néviter !") scores=[0,0,0] echappes=[[0,0,0],[0,0,0],[0,0,0],[0,0,0]] attrapes=[[0,0,0],[0,0,0],[0,0,0],[0,0,0]] manche=1 if not classique: manche=3 while manche<4: #manche+=1 d_s("Manche "+(str(manche),"sans fin")[not classique],120-35*(not classique),25,"magenta") d_s(Message[manche-1],20,45,"purple") # gardien : X,Y=179,153 dessin_gardien(X,Y) fill_rect(0,202,320,20,"w") while not (keydown(KEY_EXE) or keydown(KEY_OK)): for i in range(1,20): d_s("EXE pour lancer",85,203,(255-10*abs(10-i),250-25*abs(10-i),255)) sleep(0.1) if keydown(KEY_EXE) or keydown(KEY_OK):break #while keydown(KEY_EXE) or keydown(KEY_OK):1 efface_ecran() dessin_gardien(X,Y) Liste_boites=[] Liste_clients=[] scores[manche-1]=0 for i in range(4): echappes[i][manche-1]=0 attrapes[i][manche-1]=0 total_echappes=sum(echappes[i][manche-1] for i in range(4))#echappes[0][manche-1]+echappes[1][manche-1]+echappes[2][manche-1]+echappes[3][manche-1] PV=9 fill_rect(0,202,320,1,"purple") d_s("Score "+str(scores[manche-1])+" ",23,203,"g") d_s("Sortis "+str(total_echappes),210,203,"r") d_s("PV "+str(PV),140,203,"b") while (scores[manche-1]<30 or not classique) and PV>0: total_echappes=sum(echappes[i][manche-1] for i in range(4))#echappes=echappes[0][manche-1]+echappes[1][manche-1]+echappes[2][manche-1]+echappes[3][manche-1] d_s(str(total_echappes)+" ",280,203,"r") N=50 # 50 pour une apparition toutes les 5 sec environ if int(monotonic()*N)%N==0: Liste_clients.append(Client(randint(0,2))) sleep(0.02) for client in Liste_clients: if manche>2: if int(monotonic()*3*N)%(3*N)==2: Liste_boites.append(Boite(client.x,client.y)) client.efface() if client.y>=177: # un client s'échappe echappes[(client.Type=="caddie")+2*(client.couleur=="purple")][manche-1]+=1 total_echappes+=1 scores[manche-1]=attrapes[0][manche-1]+2*attrapes[1][manche-1]+2*attrapes[2][manche-1]+3*attrapes[3][manche-1]-2*total_echappes#5 d_s(str(scores[manche-1])+" ",83,203,"g") Liste_clients.remove(client) #client.efface() elif -10-22*(client.Type=="caddie")*(client.dx==1)<X-client.x<10+19*(client.Type=="caddie")*(client.dx==-1) and -20<Y-client.y<15: #[attrapes[0][manche-1],attrapes[1][manche-1],attrapes[2][manche-1],attrapes[3][manche-1]][2*(client.couleur=="purple")+(client.Type=="caddie")]+=1 attrapes[(client.Type=="caddie")+2*(client.couleur=="purple")][manche-1]+=1 scores[manche-1]=attrapes[0][manche-1]+2*attrapes[1][manche-1]+2*attrapes[2][manche-1]+3*attrapes[3][manche-1]-2*total_echappes#5 d_s(str(scores[manche-1])+" ",83,203,"g") Liste_clients.remove(client) #client.efface() else: if client.y>20:# or 100<client.x<L-100: client.dx=(client.dx,-client.dx)[randint(0,9)>8] client.x=min(max(18+19*(client.Type=="caddie"),client.x-client.dx),294-20*(client.Type=="caddie")) # client.x-V*client.dx client.y+=1 # V client.affiche() for boite in Liste_boites: boite.efface() if -10<X-boite.x<2 and -17<Y-boite.y<4: PV-=1 fill_rect(X,Y,11,18,"r") sleep(0.02) d_s(str(PV),170,203,"b") Liste_boites.remove(boite) fill_rect(X,Y,11,18,"w") dessin_gardien(X,Y) elif 20<boite.x<298 and 22<boite.y<186: boite.x+=boite.dx boite.y+=boite.dy boite.affiche() else: Liste_boites.remove(boite) dx=4*(keydown(KEY_RIGHT)-keydown(KEY_LEFT)) # modifier le 4 pour accélerer ou ralentir le gardien dy=4*(keydown(KEY_DOWN)-keydown(KEY_UP)) # modifier le 4 pour accélerer ou ralentir le gardien if dx or dy: fill_rect(X,Y,11,18,"w") X=min(max(17,X+dx),292) Y=min(max(20,Y+dy),174) dessin_gardien(X,Y) # fin de la manche, on efface tout le monde efface_ecran(0) for client in Liste_clients: client.efface() #for boite in Liste_boites: # boite.efface() #fill_rect(X,Y,11,18,"w") # bilan de la manche d_s("Manche "+(str(manche),"sans fin")[not classique],120-35*(not classique),25,"magenta") d_s((" Félicitations !\nLe gardien est parvenu\n à protéger le temple\n(de la consommation) !"," Le Gardien n'a pas\n tenu le choc !")[PV<1],50,55,"br"[PV<1]) d_s("Appuie sur EXE pour\n accéder au bilan.",65,140,"purple") while not (keydown(KEY_EXE) or keydown(KEY_OK)):1 while keydown(KEY_EXE) or keydown(KEY_OK):1 efface_ecran(0) # affichage du bilan de la manche scoreplus=[(1+(i>0)+(i>2))*attrapes[i][manche-1] for i in range(4)] scoremoins=[2*echappes[i][manche-1] for i in range(4)] for i in range(4): #d_s(("clients","+caddie","employés","+caddie")[i],17,60+18*i,"purple") d_s("{:>3}{:>+4}".format(attrapes[i][manche-1],scoreplus[i]),100,60+18*i,"b") d_s("{:>3}{:>4}".format(echappes[i][manche-1],-scoremoins[i]),170,60+18*i,"r") d_s("{:>+4}".format(scoreplus[i]-scoremoins[i]),250,60+18*i,"brown") d_s("Total {:>3}{: >+4}{: >3}{: >4} {: >+4}".format(sum(attrapes[i][manche-1] for i in range(4)),sum(scoreplus),total_echappes,-sum(scoremoins),sum(scoreplus)-sum(scoremoins)),30,135,"g") Titres_scores() if PV<1: d_s("Appuie sur EXE pour\nrelancer la manche.",65,155,"purple") else: d_s(("Appuie sur EXE pour lancer\n la manche suivante.","Appuie sur EXE pour\nvoir le bilan final.")[manche==3],30+30*(manche==3),155,"purple") manche+=1 while not (keydown(KEY_EXE) or keydown(KEY_OK)): consommateur_clignotant() #while keydown(KEY_EXE) or keydown(KEY_OK):1 efface_ecran(0) for i in range(4): #d_s(("clients","+caddie","employés","+caddie")[i],17,60+18*i,"purple") d_s("{:>3}".format(sum(attrapes[i])),130,60+18*i,"b") d_s("{:>3}".format(sum(echappes[i])),200,60+18*i,"r") d_s("Total {:>3} {: >3}".format(sum(sum(attrapes[i]) for i in range(4)),sum(sum(echappes[i]) for i in range(4))),30,135,"g") Titres_scores() d_s(" total",110,37,"b") d_s(" total",180,37,"r") d_s("La partie est terminée\n Merci d'avoir joué !",50,155,"purple") while 1: consommateur_clignotant()