here2share

# Tk_Sudoku.py - Generic GUI

Nov 28th, 2015 (edited)
293
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.24 KB | None | 0 0
  1. # Tk_Sudoku.py -- Generic GUI
  2.  
  3. from Tkinter import *
  4. from PIL import ImageGrab,ImageTk
  5. import random,time,datetime
  6.  
  7. root=Tk()
  8. root.title("Tk Pydoku")
  9. sq=60
  10. numsq=9
  11. w=4
  12. prev=0,0
  13. xm=ym=0
  14. y=9*sq+6
  15. midsq=int(sq/2)+(w/2)
  16. level=(36,30,27,24,21,18) # (0 to 5) from easy to expert
  17. hints=level[0]
  18.  
  19. aaa='abcdefghxdgfxhabcehxecgbfdafedgxhabcxhgabcefdbcaefdxgheahbdgcxfgdxfcehabcfbhaxdeg'
  20. bbb='..X.X.X..X.X......X.........X..X..X........XX........X.X....X..X..X........X.....'
  21. grid=range(81)
  22. numbers=range(1,10)
  23.  
  24. cue=[0,3,6,27,30,33,54,57,60]
  25. ccc=[0,1,2,9,10,11,18,19,20]
  26. box=[[i+ii for i in ccc] for ii in cue]
  27.  
  28. clock_bg=sq*3+6,10*sq+6,6*sq,11*sq
  29. clockwork=sq*4+midsq,sq*10+20
  30.  
  31. rgb_102='grey40' ### '#'+('%02x' % (102))*3
  32. root.geometry("{0}x{1}+10+10".format(9*sq+8,11*sq+8))
  33. cvw,cvh=numsq*sq+4,11*sq+8
  34. canvas=Canvas(root,width=cvw,height=cvh)
  35.  
  36. def grabwidget(widget,xy):
  37.     xx,yy,x2,y2=xy
  38.     x=widget.winfo_rootx()
  39.     y=widget.winfo_rooty()
  40.     w=widget.winfo_width()
  41.     h=widget.winfo_height()
  42.     time.sleep(0.3)
  43.     img=ImageGrab.grab((x+xx,y+yy,x+x2,y+y2))
  44.     return ImageTk.PhotoImage(img)
  45. xy9=6,6+sq*9,sq*9,sq*10
  46.  
  47. canvas.create_rectangle(0,0,sq*10,sq*12,fill='grey',width=0)
  48. for i in range(1,10):
  49.     canvas.create_text(sq*i-midsq+w,sq*9+midsq,font=("Calibri",sq-8),text=i,fill='grey40')
  50. canvas.pack()
  51. canvas.update()
  52. img9=grabwidget(canvas,xy9)
  53.  
  54. def curSq():
  55.     canvas.create_rectangle(xm+2+w,ym+2+w,xm-2+sq+w,ym-2+sq+w,fill='green',width=0)
  56. #
  57. def alive():
  58.     canvas.create_text(sq*active-midsq+w,sq*9+midsq,font=("Calibri",sq-8),text=active,fill='yellow')
  59. def line9():
  60.     canvas.create_image(xy9[:2],anchor=NW,image=img9)
  61.     curSq()
  62.     canvas.create_text(xm+midsq,sq*9+midsq,font=("Calibri",sq-8),text=xm/sq+1,fill='grey40')
  63.     alive()
  64. #
  65. def update_check(xx,yy,z):
  66.     if yy/sq < 9:
  67.         xx=xx+midsq
  68.         yy=yy+midsq
  69.         tmp=(xx/sq)*9+(yy/sq)
  70.         c='black'
  71.         if mask[tmp] is ' ':
  72.             c='blue'
  73.             if mode is '9x9' and z is 1:
  74.                 if check[tmp] is ' ': check[tmp]=str(active)
  75.                 else: check[tmp]=' '
  76.         canvas.create_text(xx,yy,font=("Calibri",sq-8),text=check[tmp],fill=c)
  77. #
  78. def callback(event):
  79.     global mode
  80.     x,y=event.x,event.y
  81.     ### print "clicked at",x,y
  82.     if check != solution:
  83.         if y < sq*9+w: mode='9x9'; return
  84.         else: mode=x/sq+1
  85.     if y > sq*10+w:
  86.         if x > sq*6+w: mode='quit'
  87.         elif x < sq*3+w and s >= '01': mode='new'
  88. root.bind("<Button-1>",callback)
  89.  
  90. def key(event):
  91.     global mode
  92.     if check != solution:
  93.         e=str(event.char)
  94.         if e.isdigit() and e != '0':
  95.             mode=int(e)
  96. root.bind("<Key>",key)
  97.  
  98. def motion(event):
  99.     global xm,ym
  100.     x,y=event.x/sq,event.y/sq
  101.     if x > 8 or y > 9: return
  102.     xm=x*sq; ym=y*sq
  103. root.bind('<Motion>',motion)
  104.  
  105. def progress(z):
  106.     for i in range(9):
  107.         print
  108.         for ii in range(9):
  109.             print z[ii*9+i],
  110.     print
  111.     print
  112. def shfl(z):
  113.     z=[[z[i*9+ii] for i in range(9)] for ii in range(9)]
  114.     z=[z[0:3],z[3:6],z[6:9]]
  115.     for i in range(3):
  116.         random.shuffle(z[i])
  117.     random.shuffle(z)
  118.     return sum(sum(z,[]),[])
  119. def gen():
  120.     sq=grid
  121.     random.shuffle(numbers) # for an added measure
  122.     for i in range(numbers[-1]):
  123.         sq=shfl(sq)
  124.     a=b=''
  125.     for i in sq:
  126.         a+=aaa[i]
  127.         b+=bbb[i]
  128.     for i in range(9):
  129.         tmp=str(numbers[i])
  130.         a=a.replace(a[i],tmp)
  131.         b=b.replace(a[i],tmp)
  132.     random.shuffle(sq)
  133.     b=list(b)
  134.     for i in sq:
  135.         if b[i] is 'X': b[i]=a[i]
  136.         elif 81-b.count('.') < hints:
  137.             for z in box:
  138.                 if i in z:
  139.                     c=''.join([b[r] for r in z])
  140.                     break
  141.             c=c.count('.')
  142.             if c > 5:
  143.                 b[i]=a[i]
  144.     b=''.join(b)
  145.     progress(a)
  146.     progress(b)
  147.     print 81-b.count('.'),'hints'
  148.     print
  149.     print b
  150.     b=b.replace('.',' ')
  151.     return list(a),b
  152. #
  153.  
  154. init=True
  155. while init:
  156.     solution,mask=gen()
  157.     check=list(mask[:])
  158.     canvas.create_rectangle(0,0,11*sq+w,11*sq+w,fill='white')
  159.     for yy in range(9):
  160.         for xx in range(9):
  161.             x2=xx*sq+midsq
  162.             y2=yy*sq+midsq
  163.             canvas.create_text(x2,y2,font=("Calibri",sq-8),text=mask[xx*9+yy])
  164.     a=(sq,sq*numsq,sq),'grey'
  165.     b=(0,sq*(numsq+1),sq*3),'black'
  166.     canvas.create_rectangle(w,9*sq+w,9*sq+w,11*sq+w,fill='grey')
  167.     canvas.create_rectangle(0,sq*10+w,sq*3+w,sq*11+w,fill='green',width=0)
  168.     canvas.create_rectangle(sq*6+w,sq*10+w,sq*9+w,sq*11+w,fill='red',width=0)
  169.     for r,c in [a,b]:
  170.         for i in range(*r): ### will unpack lists and tuples
  171.             x=i+w
  172.             # draw horizontal lines
  173.             canvas.create_line(0,x,y,x,width=w,fill=c)
  174.             # draw vertical lines
  175.             canvas.create_line(x,0,x,y,width=w,fill=c)
  176.     for i in [sq*3,sq*6]:
  177.         x=i+w
  178.         canvas.create_line(x,sq*10+w,x,sq*11+w,width=w,fill=c)
  179.     canvas.create_rectangle(w,9*sq+w,9*sq+w,11*sq+w,width=w)
  180.     canvas.create_line(0,sq*10+w,sq*9+w,sq*10+w,width=w)
  181.     active=1
  182.     mode='initiated'
  183.     line9()
  184.     dt=datetime.datetime.now()
  185.     while mode:
  186.         if check is solution: pass
  187.         elif prev != (xm,ym) or mode != 'standby':
  188.             x2,y2=prev
  189.             prev=xm,ym
  190.             if mode in numbers: active=mode
  191.             c='white'
  192.             if y2/sq is 9:
  193.                 c='grey'
  194.             canvas.create_rectangle(x2+2+w,y2+2+w,x2-2+sq+w,y2-2+sq+w,fill=c,width=0)
  195.             if sq*9 in (ym,y2) or mode in numbers:
  196.                 line9()
  197.             elif check: curSq()
  198.             update_check(xm,ym,1)
  199.             update_check(x2,y2,0)
  200.             mode='standby'
  201.         ss=str(datetime.datetime.now()-dt)
  202.         h,m,s=ss.split('.')[0].split(':')
  203.         try:
  204.             if check != solution:
  205.                 clock='%s:%s' % (m,s)
  206.                 if m > '20': clock='+20 Mins?'
  207.                 canvas.create_rectangle(*clock_bg,fill='grey',width=0)
  208.                 canvas.create_text(*clockwork,font=("Ariel",16),text=clock)
  209.             elif check != '':
  210.                 canvas.create_rectangle(0,0,sq*9+w,sq*9+w,fill='black',width=0)
  211.                 for yy in range(9):
  212.                     for xx in range(9):
  213.                         x2=xx*sq+6
  214.                         y2=yy*sq+6
  215.                         c,t='light blue','black'
  216.                         area=mask[xx*9+yy]
  217.                         if area is ' ':
  218.                             area=solution[xx*9+yy]
  219.                             t='white'
  220.                         canvas.create_rectangle(x2,y2,x2+(sq-w),y2+(sq-w),fill=c,width=0)
  221.                         canvas.create_text(x2+midsq-w,y2+midsq-6,font=("Calibri",sq-8),text=area,fill=t)
  222.                         canvas.create_image(xy9[:2],anchor=NW,image=img9)
  223.                 solution=check=''
  224.                 print "Board Completed @",clock # ZZZ
  225.             canvas.update()
  226.             if mode is 'quit': root.destroy(); Trigger-Exception
  227.             elif mode is'new':
  228.                 canvas.create_rectangle(0,7*sq+w,9*sq+6,9*sq+w,fill='purple',width=0)
  229.                 canvas.create_text(sq*4+midsq,sq*8,font=("Ariel",10*sq/20),text="STARTING NEW GAME...",fill='white')
  230.                 canvas.update()
  231.                 mode=False
  232.         except: mode=init='' ;root.quit()
  233.  
  234. root.mainloop()
Add Comment
Please, Sign In to add comment