#! /usr/bin/python3 # www.jchr.be - 2007.02.07 - GPL2 # Rappel: sous Windows, il faut telecharger le module WCurses: voir www.jchr.be/python/modules.htm#curses from time import time from random import randrange import curses # cette première fonction dessine un tableau régulier # (après initialisation d'une session curses) # paramètres: offset ligne/colonne, nombre de rangées/colonnes, # hauteur de rangée, largeur de colonne def tableau(y,x,nrang,ncol,hrang,lcol): ymax=hrang*nrang+1; xmax=lcol*ncol+1 for j in range(0,ymax): for i in range(0,xmax): if j%hrang!=0 and i%lcol==0: fenetre.addch(y+j,x+i,curses.ACS_VLINE); continue # lignes if j%hrang==0 and i%lcol!=0: fenetre.addch(y+j,x+i,curses.ACS_HLINE); continue if j%hrang==0 and i%lcol==0: fenetre.addch(y+j,x+i,curses.ACS_PLUS) # croisements if j==0 and i%lcol==0: fenetre.addch(y+j,x+i,curses.ACS_TTEE) # remplacement de certains croisements par les bords if j==ymax-1 and i%lcol==0: fenetre.addch(y+j,x+i,curses.ACS_BTEE) if j%hrang==0 and i==0: fenetre.addch(y+j,x+i,curses.ACS_LTEE) if j%hrang==0 and i==xmax-1: fenetre.addch(y+j,x+i,curses.ACS_RTEE) if j==0 and i==0: fenetre.addch(y+j,x+i,curses.ACS_ULCORNER) # remplacement de certains bords par les coins if j==0 and i==xmax-1: fenetre.addch(y+j,x+i,curses.ACS_URCORNER) if j==ymax-1 and i==0: fenetre.addch(y+j,x+i,curses.ACS_LLCORNER) if j==ymax-1 and i==xmax-1: fenetre.addch(y+j,x+i,curses.ACS_LRCORNER) fenetre.refresh() # permute la case vide avec une case numerotée adjacente def permute(lieu1,lieu2): fenetre.move(2+lieu1//4*2,3+lieu1%4*4) if k[lieu1]>0: fenetre.addstr(str(k[lieu1]).rjust(2)) else: fenetre.addstr(' ') fenetre.move(2+lieu2//4*2,3+lieu2%4*4) if k[lieu2]>0: fenetre.addstr(str(k[lieu2]).rjust(2)) else: fenetre.addstr(' ') fenetre.refresh() def gauche(): global zero, cpt if (zero%4>0): k[zero],k[zero-1]=k[zero-1],k[zero] permute(zero,zero-1) zero-=1; cpt+=1 def droite(): global zero, cpt if (zero%4<3): k[zero],k[zero+1]=k[zero+1],k[zero] permute(zero,zero+1) zero+=1; cpt+=1 def bas(): global zero, cpt if (zero>3): k[zero],k[zero-4]=k[zero-4],k[zero] permute(zero,zero-4) zero-=4; cpt+=1 def haut(): global zero, cpt if (zero<12): k[zero],k[zero+4]=k[zero+4],k[zero] permute(zero,zero+4) zero+=4; cpt+=1 def initial(): # (ré)initialisation du jeu (mélange du taquin) global k, zero, ordre, sec, cpt ordre=range(1,16) ordre+=[0]; zero=15 k=ordre[:] i=0; anc=0 # le mélange se fait en glissant les pièces au hasard cela ne peut se faire # par random.shuffle: un taquin sur deux seulement serait soluble while i <1000: anc=(anc+2)%4 r=randrange(0,4) if (r==0) and r!=anc: haut(); anc=r; i+=1 if (r==1) and r!=anc: bas(); anc=r; i+=1 if (r==2) and r!=anc: gauche(); anc=r; i+=1 if (r==3) and r!=anc: droite(); anc=r; i+=1 cpt=0 for i in range(16): if (k[i]==0): zero=i fenetre.addstr(7,25,' '*20) # efface le score fenetre.addstr(8,25,' '*20) sec=time() # ****** Initialisation de l'application sec=0.; zero=15; cpt=0; fin=0 # Initialisation de la session 'curses' (à ne faire qu'une fois) ecran= curses.initscr() fenetre= curses.newwin(15,50,0,0) fenetre.keypad(1) curses.curs_set(0) curses.cbreak() curses.noecho() tableau(1,2,4,4,2,4) # dessin du tableau tableau(0,0,1,1,10,20) fenetre.addstr(1,25,'Taquin -- www.jchr.be') fenetre.addstr(2,25,'2007.01.27 -- GPL2') fenetre.addstr(4,27,'Quitter avec [q]') fenetre.addstr(5,27,'Melanger avec [Esc]') fenetre.refresh() initial() while (fin==0): if (ordre==k): # si la liste-taquin est en ordre tps=divmod(time()-sec,60); fenetre.addstr(7,25,'Resolu en '+str(int(tps[0]))+':'+str(int(tps[1])).zfill(2)+' et') fenetre.addstr(8,25,str(cpt)+' deplacements ') fenetre.refresh() key=fenetre.getch() if key==113 or key==81: break # touche [q] ou [Q] initial() key=fenetre.getch() if key==curses.KEY_LEFT: gauche(); continue if key==curses.KEY_RIGHT: droite(); continue if key==curses.KEY_DOWN: haut(); continue if key==curses.KEY_UP: bas(); continue if key==27: initial() if key==113 or key==81: break # le break permet de terminer la session 'curses' fenetre.keypad(0) curses.echo() curses.curs_set(1) curses.nocbreak() curses.endwin()