Advertisement
gusreibo

2048.py

Apr 10th, 2014
7,782
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.22 KB | None | 0 0
  1. import random, colorsys
  2. from Tkinter import *
  3.  
  4. class Game:
  5.     def __init__(self, size):
  6.         self.grid = [[Tile() for i in range(size)] for j in range(size)]
  7.         self.addRandomTile()
  8.         self.addRandomTile()
  9.  
  10.     def __str__(self):
  11.         ret = ''
  12.         iS = {}
  13.         for j in self.grid:
  14.             for i in range(len(j)):
  15.                 iS[i] = max(iS.get(i), len(str(j[i])))
  16.         for j in self.grid:
  17.             for i in range(len(j)):
  18.                 ret = ret + str(j[i]) + ' ' + ' '*(iS[i]-len(str(j[i])))
  19.             ret = ret + '\n'
  20.         return ret.replace(' 0', '  ').replace('0 ', '  ')
  21.         return '\n'.join([' '.join([str(i) for i in j]) for j in self.grid]).replace(' 0', '  ').replace('0 ', '  ')
  22.  
  23.     def addRandomTile(self):
  24.         availableTiles = self.getAvailableTiles()
  25.         findTile = self.findTile(random.choice(availableTiles))
  26.         self.grid[findTile[0]][findTile[1]] = Tile(2)
  27.  
  28.     def getAvailableTiles(self):
  29.         ret = []
  30.         for i in self.grid:
  31.             for j in i:
  32.                 if j.value == 0:
  33.                     ret.append(j)
  34.         return ret
  35.  
  36.     def findTile(self, tile):
  37.         for i in range(len(self.grid)):
  38.             for j in range(len(self.grid[i])):
  39.                 if self.grid[i][j] == tile:
  40.                     return i, j
  41.  
  42.     def move(self, direction):
  43.         merged = []
  44.         moved = False
  45.         lines = rotate(self.grid, direction+1)
  46.         for line in lines:
  47.             while len(line) and line[-1].value == 0:
  48.                 line.pop(-1)
  49.             i = len(line)-1
  50.             while i >= 0:
  51.                 if line[i].value == 0:
  52.                     moved = True
  53.                     line.pop(i)
  54.                 i -= 1
  55.             i = 0
  56.             while i < len(line)-1:
  57.                 if line[i].value == line[i+1].value and not (line[i] in merged or line[i+1] in merged):
  58.                     moved = True
  59.                     line[i] = Tile(line[i].value*2)
  60.                     merged.append(line[i])
  61.                     line.pop(i+1)
  62.                 else:
  63.                     i += 1
  64.             while len(line) < len(self.grid):
  65.                 line.append(Tile())
  66.         for line in lines:
  67.             if not len(lines):
  68.                 line = [Tile() for i in self.grid]
  69.         self.grid = rotate(lines, 0-(direction+1))
  70.         if moved:
  71.             self.addRandomTile()
  72.  
  73.     def playGame(self):
  74.         done = False
  75.         while not done:
  76.             print self
  77.             inp = raw_input()
  78.             if inp == 'q':
  79.                 break
  80.             elif inp in ['0', '1', '2', '3']:
  81.                 self.move(int(inp))
  82.             if self.lost():
  83.                 print "You have lost"
  84.                 break
  85.             if self.won():
  86.                 print "You have won"
  87.                 break
  88.  
  89.     def lost(self):
  90.         s = len(self.grid)-1
  91.         b = True
  92.         for i in range(len(self.grid)):
  93.             for j in range(len(self.grid[i])):
  94.                 val = self.grid[i][j].value
  95.                 if val == 0:
  96.                     b = False
  97.                 if i > 0 and self.grid[i-1][j].value == val:
  98.                     b = False
  99.                 if j > 0 and self.grid[i][j-1].value == val:
  100.                     b = False
  101.                 if i < s and self.grid[i+1][j].value == val:
  102.                     b = False
  103.                 if j < s and self.grid[i][j+1].value == val:
  104.                     b = False
  105.         return b
  106.  
  107.     def won(self):
  108.         for i in range(len(self.grid)):
  109.             for j in range(len(self.grid[i])):
  110.                 if self.grid[i][j].value == 2048:
  111.                     return True
  112.         return False
  113.  
  114.     def getValues(self):
  115.         ret = []
  116.         for i in self.grid:
  117.             for j in i:
  118.                 ret.append(j)
  119.         return ret
  120.  
  121. class Tile:
  122.     def __init__(self, value=0):
  123.         self.value = value
  124.  
  125.     def __str__(self):
  126.         return str(self.value)
  127.  
  128. def rotate(l, num):
  129.     num = num % 4
  130.     s = len(l)-1
  131.     l2 = []
  132.     if num == 0:
  133.         l2 = l
  134.     elif num == 1:
  135.         l2 = [[None for i in j] for j in l]
  136.         for y in range(len(l)):
  137.             for x in range(len(l[y])):
  138.                 l2[x][s-y] = l[y][x]
  139.     elif num == 2:
  140.         l2 = l
  141.         l2.reverse()
  142.         for i in l:
  143.             i.reverse()
  144.     elif num == 3:
  145.         l2 = [[None for i in j] for j in l]
  146.         for y in range(len(l)):
  147.             for x in range(len(l[y])):
  148.                 l2[y][x] = l[x][s-y]
  149.     return l2
  150.  
  151.  
  152. def onKeyPress(event):
  153.     global g
  154.     global b
  155.     for i in b:
  156.         for j in i:
  157.             j.destroy()
  158.     if event.keycode == 37:
  159.         g.move(3)
  160.     elif event.keycode == 38:
  161.         g.move(2)
  162.     elif event.keycode == 39:
  163.         g.move(1)
  164.     elif event.keycode == 40:
  165.         g.move(0)
  166.     makeButtons(g)
  167.     if g.lost():
  168.         for i in range(len(b)):
  169.             for j in range(len(b[i])):
  170.                 if b[i][j].config('text')[-1] != str(g.grid[i][j]):
  171.                     b[i][j].destroy()
  172.                     b[i][j] = None
  173.         try:
  174.             g.q.destroy()
  175.         except Exception as e:
  176.             pass
  177.         g.q = Button(root, text="You lost")
  178.         g.q.pack()
  179.  
  180. def makeButtons(g):
  181.     global b
  182.     for i in range(len(g.grid)):
  183.         for j in range(len(g.grid[i])):
  184.             if g.grid[i][j].value:
  185.                 b[i][j] = Button(root, text=str(g.grid[i][j].value), bg=findColors(g.grid[i][j].value)[0], fg=findColors(g.grid[i][j].value)[1])
  186.             else:
  187.                 b[i][j] = Button(root, text='')
  188.             b[i][j].config(width=max(len(str(i)) for i in g.getValues()))
  189.             b[i][j].grid(row=i, column=j)
  190.  
  191. def findColors(num):
  192.     if (num != 0 and ((num & (num - 1)) == 0)):
  193.         bi = bin(num)
  194.         po = len(bi)
  195.         hue = 30.0 * po
  196.         rgb = colorsys.hls_to_rgb(hue/256.0, 0.5, 0.5)
  197.         rgb = [str(hex(int(256*x)))[2:3] for x in rgb]
  198.         return "#" + str(rgb[0]) + str(rgb[1]) + str(rgb[2]), "#FFFFFF"
  199.     else:
  200.         return "#000000", "#FFFFFF"
  201.  
  202. g = Game(4)
  203. b = [[None for i in j] for j in g.grid]
  204.  
  205. root = Tk()
  206. root.bind('<KeyPress>', onKeyPress)
  207.  
  208. makeButtons(g)
  209.  
  210. root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement