Advertisement
Guest User

Untitled

a guest
Jul 12th, 2013
296
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. '''
  2. Lights Out
  3.  
  4.  
  5.  
  6.  
  7. author: diverges
  8. last modified: 7/12/2013
  9. '''
  10. from tkinter import *
  11. from random import randrange, shuffle
  12.  
  13. import copy
  14.  
  15. DEBUG = True
  16.  
  17. W_WIDTH = 640 # width of window
  18. W_HEIGHT = 480 # height of window
  19. BOX_DIM = 80 # size of box width and height
  20. BOARDCOL= 5 # number of columns
  21. BOARDROW = 5 # number of rows
  22. BOARD_XINIT = 30 # leftmost x-coordinate of board
  23. BOARD_YINIT = 10 # topmost y_coordinate of board
  24. GAP = 2 # pixel gap between blocks
  25. DIFFICULTY = 10  # percentage of lights flipped and
  26.                  # number of moves made when
  27.                  # generating a board.
  28. assert (DIFFICULTY <= 100 and DIFFICULTY > 0)                
  29.  
  30. #          R G B
  31. GREEN  = '#55CC00'
  32. CYAN   = '#22CCff'
  33. DGREEN = '#A0AA00'
  34.  
  35. class Light:
  36.      def __init__(self, row, col, x, y, on=0):
  37.           self.id = 0
  38.           self.row = row
  39.           self.col = col
  40.           self.x = x # x-coordinate
  41.           self.y = y # y-coordinate
  42.           self.on = on
  43.  
  44.      def toggle(self):
  45.           self.on = not self.on
  46.  
  47.      # determine if a coordinate (x,y) is within the rectangle
  48.      def contains(self, cord):
  49.          
  50.           a =  (cord[0] > self.x and cord[0] < self.x + BOX_DIM and
  51.                    cord[1] > self.y and cord[1] < self.y + BOX_DIM)
  52.           if a: print(str(self) + " " + str(cord))
  53.          
  54.           return a
  55.                    
  56.      def __str__(self):
  57.           return "Row: %s Col: %s ON: %s (%s,%s)" %(self.row, self.col, self.on,
  58.                                                     self.x, self.y)
  59.  
  60. class Board(Frame):
  61. # Default game board
  62.      gameTextId = None
  63.  
  64.      def __init__(self, parent):
  65.           Frame.__init__(self, parent)  
  66.           self.parent = parent
  67.           self.board = Canvas(self)
  68.           self.gameOver = False
  69.          
  70.           # initial lights array
  71.           # index go from left to right, top to bottom
  72.           # value 0 = off and 1 = on  
  73.           self.lights = [ [None for _ in range(BOARDROW)] for _ in range(BOARDCOL)]
  74.           for r in range(BOARDROW):
  75.                for c in range(BOARDCOL):
  76.                     self.lights[r][c] = Light(r,c, BOARD_XINIT
  77.                                         + (BOX_DIM + GAP)*(c), BOARD_YINIT
  78.                                         + (BOX_DIM + GAP)*(r), 0)
  79.           self.shuffle(DIFFICULTY//30 + 1)
  80.           self.initBoard()
  81.          
  82.           self.save = copy.deepcopy(self.lights)
  83.            
  84.           # Add text
  85.           self.gameTextId = self.board.create_text(475,150, text="text")
  86.          
  87.           newgame_Label = Label(parent, anchor=NW, font="Calibri",
  88.                text="New Game")
  89.           newgame_Label.bind("<Button 1>", self.newgame_Click)      
  90.           newgame_Label.place(x=450, y=300)
  91.          
  92.           reset_Label = Label(parent, anchor=NW, font="Calibri",
  93.                text="Reset Board")
  94.           reset_Label.bind("<Button 1>", self.reset_Click)      
  95.           reset_Label.place(x=450, y=400)  
  96.          
  97.      
  98.      def initBoard(self):
  99.           self.parent.title("Board")
  100.           self.pack(fill=BOTH, expand=1)
  101.           self.board.pack(fill=BOTH, expand=1)          
  102.           self.drawBoard(self.board)
  103.            
  104.      # Backtracks a set number of moves from an end state to
  105.      # generate a board    
  106.      def shuffle(self, moves):
  107.           for x in range(moves):
  108.                rows = list(range(BOARDROW))
  109.                cols = list(range(BOARDCOL))
  110.                shuffle(rows)
  111.                shuffle(cols)
  112.                count = 0
  113.                for r in rows:
  114.                     for c in cols:
  115.                          if (DIFFICULTY >= randrange(100 + DIFFICULTY)
  116.                               and count <= (DIFFICULTY/100) * BOARDCOL
  117.                                                             * BOARDROW):
  118.                               self.toggleLight(self.lights[r][c])
  119.                               if DEBUG: print("Generated move: " +
  120.                                    str(self.lights[r][c]))
  121.                               count += 1
  122.      
  123.      # Draws the given canvas(board).
  124.      def drawBoard(self, board):
  125.           for rows in self.lights:
  126.                for light in rows:
  127.                     if DEBUG: print("drawing: " + str(light))
  128.                     x1 = light.x + BOX_DIM
  129.                     y1 = light.y + BOX_DIM
  130.                     color = GREEN
  131.                     if light.on:
  132.                          color = CYAN
  133.                     light.id = board.create_rectangle(light.x,light.y,x1,y1,
  134.                          outline=DGREEN, fill=color)    
  135.      
  136.      # Record mouse click event.    
  137.      def mouseEvent(self, event):
  138.           cord = (event.x, event.y)
  139.           if DEBUG: print(cord)
  140.           for rows in self.lights:
  141.                for light in rows:
  142.                     if light.contains(cord):
  143.                          self.toggleLight(light)
  144.                          print("light toggled")
  145.                          self.checkState()
  146.                          self.updateBoard()
  147.                          
  148.      # New game label click event.
  149.      def newgame_Click(self, event):
  150.           self.gameOver = False
  151.           self.board.itemconfigure(self.gameTextId, text="New Game!")
  152.           for rows in self.lights:
  153.                for light in rows: light.on = 0
  154.           self.shuffle(DIFFICULTY//20 + 1)
  155.           self.updateBoard()
  156.           self.save = copy.deepcopy(self.lights)
  157.          
  158.      # Reset label click event,
  159.      # loads saved board.
  160.      def reset_Click(self, event):
  161.           self.lights = copy.deepcopy(self.save)
  162.           self.updateBoard()
  163.           print("board loaded")    
  164.                              
  165.      # Handles click event.                        
  166.      def toggleLight(self, light):
  167.           light.toggle()    
  168.           row = light.row
  169.           col = light.col
  170.           if light.row > 0:
  171.                self.lights[row-1][col].toggle()  
  172.           if light.row < BOARDROW - 1:
  173.                self.lights[row+1][col].toggle()      
  174.           if light.col > 0:
  175.                self.lights[row][col-1].toggle()        
  176.           if light.col < BOARDCOL - 1:
  177.                self.lights[row][col+1].toggle()
  178.      
  179.      # Counts the number of lights on.
  180.      def lightsOn(self):
  181.           n_on = 0
  182.           for rows in self.lights:
  183.                for light in rows:
  184.                     if light.on: n_on += 1
  185.           return n_on          
  186.      
  187.      # Determines if the current board has been solved.
  188.      def checkState(self):
  189.           self.gameOver = True
  190.           for rows in self.lights:
  191.                for light in rows:
  192.                     if light.on: self.gameOver = False
  193.      
  194.      # Redraw the board.
  195.      def  updateBoard(self):
  196.           for rows in self.lights:
  197.                for light in rows:
  198.                     color = GREEN
  199.                     if light.on:
  200.                          color = CYAN
  201.                     self.board.itemconfigure(light.id, fill=color)
  202.           if self.gameOver:
  203.                self.board.itemconfigure(self.gameTextId, text="Game Over!")
  204.                if DEBUG: print("Game board has been solved")
  205.                    
  206. def main():
  207.      root = Tk()
  208.      ex = Board(root)
  209.      root.geometry('%sx%s+%s+%s' %(W_WIDTH, W_HEIGHT, 100, 100))
  210.      root.resizable(0,0)
  211.      root.bind('<Button 1>', ex.mouseEvent)
  212.      root.mainloop()
  213.        
  214. if __name__ == '__main__':
  215.         main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement