class Game(): WIDTH = 300 HEIGHT = 500 def start(self): self.level = 1 self.score = 0 self.speed = 500 self.counter = 0 self.create_new_game = True self.root = Tk() self.root.title("Tetris") self.status_var = StringVar() self.status_var.set("Level: 1, Score: 0") self.status = Label(self.root, textvariable=self.status_var, font=("Helvetica", 10, "bold")) self.status.pack() self.canvas = Canvas( self.root, width=Game.WIDTH, height=Game.HEIGHT) self.canvas.pack() self.root.bind("<Key>", self.handle_events) self.timer() self.root.mainloop() def timer(self): if self.create_new_game == True: self.current_shape = Shape(self.canvas) self.create_new_game = False if not self.current_shape.fall(): lines = self.remove_complete_lines() if lines: self.score += 10 * self.level**2 * lines**2 self.status_var.set("Level: %d, Score: %d" % (self.level, self.score)) self.current_shape = Shape(self.canvas) if self.is_game_over(): self.create_new_game = True self.game_over() self.counter += 1 if self.counter == 5: self.level += 1 self.speed -= 20 self.counter = 0 self.status_var.set("Level: %d, Score: %d" % (self.level, self.score)) self.root.after(self.speed, self.timer) def handle_events(self, event): if event.keysym == "Left": self.current_shape.move(-1, 0) if event.keysym == "Right": self.current_shape.move(1, 0) if event.keysym == "Down": self.current_shape.move(0, 1) if event.keysym == "Up": self.current_shape.rotate() def is_game_over(self): for box in self.current_shape.boxes: if not self.current_shape.can_move_box(box, 0, 1): return True return False def remove_complete_lines(self): shape_boxes_coords = [self.canvas.coords(box)[3] for box in self.current_shape.boxes] all_boxes = self.canvas.find_all() all_boxes_coords = {k : v for k, v in zip(all_boxes, [self.canvas.coords(box)[3] for box in all_boxes])} lines_to_check = set(shape_boxes_coords) boxes_to_check = dict((k, v) for k, v in all_boxes_coords.iteritems() if any(v == line for line in lines_to_check)) counter = Counter() for box in boxes_to_check.values(): counter[box] += 1 complete_lines = [k for k, v in counter.iteritems() if v == (Game.WIDTH/Shape.BOX_SIZE)] if not complete_lines: return False for k, v in boxes_to_check.iteritems(): if v in complete_lines: self.canvas.delete(k) del all_boxes_coords[k] for (box, coords) in all_boxes_coords.iteritems(): for line in complete_lines: if coords < line: self.canvas.move(box, 0, Shape.BOX_SIZE) return len(complete_lines) def game_over(self): self.canvas.delete(Tkinter.ALL) tkMessageBox.showinfo( "Game Over", "You scored %d points." % self.score)
class Game(): WIDTH = 300 HEIGHT = 500 def start(self): '''Starts the game. Creates a window, a canvas, and a first shape. Binds the event handler. Then starts a GUI timer of ms interval self.speed and starts the GUI main loop. ''' #TODO start() needs to be refactored so that the creation of the # window, label, and canvas are independent from setting them to # defaults and starting the game. # # There should also be a way for the user to restart and pause # the game if he or she wishes. # # It's a little weird that level is based only on time and that # as a result it increases faster and faster. Wouldn't it make # more sense for level to be a result of completed lines? self.level = 1 self.score = 0 self.speed = 500 self.counter = 0 self.create_new_game = True self.root = Tk() self.root.title("Tetris") self.status_var = StringVar() self.status_var.set("Level: 1, Score: 0") self.status = Label(self.root, textvariable=self.status_var, font=("Helvetica", 10, "bold")) self.status.pack() self.canvas = Canvas(self.root, width=Game.WIDTH, height=Game.HEIGHT) self.canvas.pack() self.root.bind("<Key>", self.handle_events) self.timer() self.root.mainloop() def timer(self): '''Every self.speed ms, attempt to cause the current_shape to fall(). If fall() returns False, create a new shape and check if it can fall. If it can't, then the game is over. ''' if self.create_new_game == True: self.current_shape = Shape(self.canvas) self.create_new_game = False if not self.current_shape.fall(): lines = self.remove_complete_lines() if lines: self.score += 10 * self.level**2 * lines**2 self.status_var.set("Level: %d, Score: %d" % (self.level, self.score)) self.current_shape = Shape(self.canvas) if self.is_game_over(): #TODO This is a problem. You rely on the timer method to # create a new game rather than creating it here. As a # result, there is an intermittent error where the user # event keypress Down eventually causes can_move_box # to throw an IndexError, since the current shape has # no boxes. Instead, you need to cleanly start a new # game. I think refactoring start() might help a lot # here. # # Furthermore, starting a new game currently doesn't reset # the levels. You should place all your starting constants # in the same place so it's clear what needs to be reset # when. self.create_new_game = True self.game_over() self.counter += 1 if self.counter == 5: self.level += 1 self.speed -= 20 self.counter = 0 self.status_var.set("Level: %d, Score: %d" % (self.level, self.score)) self.root.after(self.speed, self.timer) def handle_events(self, event): '''Handle all user events.''' if event.keysym == "Left": self.current_shape.move(-1, 0) if event.keysym == "Right": self.current_shape.move(1, 0) if event.keysym == "Down": self.current_shape.move(0, 1) if event.keysym == "Up": self.current_shape.rotate() def is_game_over(self): '''Check if a newly created shape is able to fall. If it can't fall, then the game is over. ''' for box in self.current_shape.boxes: if not self.current_shape.can_move_box(box, 0, 1): return True return False def remove_complete_lines(self): shape_boxes_coords = [ self.canvas.coords(box)[3] for box in self.current_shape.boxes ] all_boxes = self.canvas.find_all() all_boxes_coords = { k: v for k, v in zip(all_boxes, [self.canvas.coords(box)[3] for box in all_boxes]) } lines_to_check = set(shape_boxes_coords) boxes_to_check = dict((k, v) for k, v in all_boxes_coords.iteritems() if any(v == line for line in lines_to_check)) counter = Counter() for box in boxes_to_check.values(): counter[box] += 1 complete_lines = [ k for k, v in counter.iteritems() if v == (Game.WIDTH / Shape.BOX_SIZE) ] if not complete_lines: return False for k, v in boxes_to_check.iteritems(): if v in complete_lines: self.canvas.delete(k) del all_boxes_coords[k] #TODO Would be cooler if the line flashed or something for (box, coords) in all_boxes_coords.iteritems(): for line in complete_lines: if coords < line: self.canvas.move(box, 0, Shape.BOX_SIZE) return len(complete_lines) def game_over(self): self.canvas.delete(Tkinter.ALL) tkMessageBox.showinfo("Game Over", "You scored %d points." % self.score)
class Game(): WIDTH = 300 HEIGHT = 500 def start(self): '''Starts the game. Creates a window, a canvas, and a first shape. Binds the event handler. Then starts a GUI timer of ms interval self.speed and starts the GUI main loop. ''' #TODO start() needs to be refactored so that the creation of the # window, label, and canvas are independent from setting them to # defaults and starting the game. # # There should also be a way for the user to restart and pause # the game if he or she wishes. # # It's a little weird that level is based only on time and that # as a result it increases faster and faster. Wouldn't it make # more sense for level to be a result of completed lines? self.level = 1 self.score = 0 self.speed = 500 self.counter = 0 self.create_new_game = True self.root = Tk() self.root.title("Tetris") self.status_var = StringVar() self.status_var.set("Level: 1, Score: 0") self.status = Label(self.root, textvariable=self.status_var, font=("Helvetica", 10, "bold")) self.status.pack() self.canvas = Canvas( self.root, width=Game.WIDTH, height=Game.HEIGHT) self.canvas.pack() self.root.bind("<Key>", self.handle_events) self.timer() self.root.mainloop() def timer(self): '''Every self.speed ms, attempt to cause the current_shape to fall(). If fall() returns False, create a new shape and check if it can fall. If it can't, then the game is over. ''' if self.create_new_game == True: self.current_shape = Shape(self.canvas) self.create_new_game = False if not self.current_shape.fall(): lines = self.remove_complete_lines() if lines: self.score += 10 * self.level**2 * lines**2 self.status_var.set("Level: %d, Score: %d" % (self.level, self.score)) self.current_shape = Shape(self.canvas) if self.is_game_over(): #TODO This is a problem. You rely on the timer method to # create a new game rather than creating it here. As a # result, there is an intermittent error where the user # event keypress Down eventually causes can_move_box # to throw an IndexError, since the current shape has # no boxes. Instead, you need to cleanly start a new # game. I think refactoring start() might help a lot # here. # # Furthermore, starting a new game currently doesn't reset # the levels. You should place all your starting constants # in the same place so it's clear what needs to be reset # when. self.create_new_game = True self.game_over() self.counter += 1 if self.counter == 5: self.level += 1 self.speed -= 20 self.counter = 0 self.status_var.set("Level: %d, Score: %d" % (self.level, self.score)) self.root.after(self.speed, self.timer) def handle_events(self, event): '''Handle all user events.''' if event.keysym == "Left": self.current_shape.move(-1, 0) if event.keysym == "Right": self.current_shape.move(1, 0) if event.keysym == "Down": self.current_shape.move(0, 1) if event.keysym == "Up": self.current_shape.rotate() def is_game_over(self): '''Check if a newly created shape is able to fall. If it can't fall, then the game is over. ''' for box in self.current_shape.boxes: if not self.current_shape.can_move_box(box, 0, 1): return True return False def remove_complete_lines(self): shape_boxes_coords = [self.canvas.coords(box)[3] for box in self.current_shape.boxes] all_boxes = self.canvas.find_all() all_boxes_coords = {k : v for k, v in zip(all_boxes, [self.canvas.coords(box)[3] for box in all_boxes])} lines_to_check = set(shape_boxes_coords) boxes_to_check = dict((k, v) for k, v in all_boxes_coords.iteritems() if any(v == line for line in lines_to_check)) counter = Counter() for box in boxes_to_check.values(): counter[box] += 1 complete_lines = [k for k, v in counter.iteritems() if v == (Game.WIDTH/Shape.BOX_SIZE)] if not complete_lines: return False for k, v in boxes_to_check.iteritems(): if v in complete_lines: self.canvas.delete(k) del all_boxes_coords[k] #TODO Would be cooler if the line flashed or something for (box, coords) in all_boxes_coords.iteritems(): for line in complete_lines: if coords < line: self.canvas.move(box, 0, Shape.BOX_SIZE) return len(complete_lines) def game_over(self): self.canvas.delete(Tkinter.ALL) tkMessageBox.showinfo( "Game Over", "You scored %d points." % self.score)
class DrawDigit(object): def __init__(self, digitsData): self.digitsData = digitsData self.checkingDigit = False self.master = Tk() self.master.title("Draw Digit") self.master.config(bg='grey',width=canvasWidth*2, height=625,padx=50,pady=50) self.isClicking = False self.currentX = -1 self.currentY = -1 self.canvas = Canvas(self.master, width=canvasWidth, height=canvasHeight) self.canvas.config(bg='white') self.canvas.pack() self.recognizeButton = Button(self.master, text="Recognize", command=self.recognize) self.recognizeButton.pack() self.clearButton = Button(self.master, text="Clear", command=self.clearCanvas) self.clearButton.pack() self.rightButton = Button(self.master, text="Right!", command=self.digitRecognized) self.rightButton.pack_forget() self.wrongButton = Button(self.master, text="Wrong!", command=self.digitNotRecognized) self.wrongButton.pack_forget() self.retryButton = Button(self.master, text="Retry!", command=self.resetGUI) self.retryButton.pack_forget() self.master.bind('<Button-1>', self.mousePress) self.master.bind('<B1-Motion>', self.mouseMove) self.master.bind('<ButtonRelease-1>', self.mouseRelease) self.image = Image.new("L",(canvasWidth,canvasHeight)) self.draw = ImageDraw.Draw(self.image) return def mousePress(self, event): if not self.isClicking and not self.checkingDigit: self.currentX = event.x self.currentY = event.y self.isClicking = True return def mouseMove(self, event): if self.isClicking and not self.checkingDigit: self.draw.line([(self.currentX,self.currentY),(event.x,event.y)],(0,0,0),width=5) self.canvas.create_line(self.currentX, self.currentY, event.x, event.y, width=5.0) self.currentX = event.x self.currentY = event.y return def mouseRelease(self, event): self.isClicking = False return def clearCanvas(self): self.canvas.delete('all') self.image = Image.new("L",(canvasWidth,canvasHeight)) self.draw = ImageDraw.Draw(self.image) return def recognize(self): if len(self.canvas.find_all()) != 0: self.checkingDigit = True self.originalImage = ImageOps.invert(self.image) print "***************************************************" print 'Recognizing the digit...' featureVector = ocr_machine_learning.getVector(self.originalImage, self.digitsData) print 'The feature vector for the image is: {0}'.format(featureVector) finalDigit = ocr_machine_learning.recognizeDigit(featureVector) print 'The digit in the image is:' print digitASCII.digits[finalDigit] self.checkCorrectDigitGUI(finalDigit) return def startGUI(self): print 'Please draw the digit in the white square of the GUI window...' self.master.mainloop() return def checkCorrectDigitGUI(self, finalDigit): self.finalDigit = finalDigit self.recognizeButton.pack_forget() self.clearButton.pack_forget() self.rightButton.pack() self.wrongButton.pack() self.retryButton.pack() self.master.update() return def digitRecognized(self): ocr_utils.saveImageToCorrectDigitFolder(self.originalImage, self.finalDigit) self.resetGUI() return def digitNotRecognized(self): ocr_utils.guessedWrong(self.originalImage) self.resetGUI() return def resetGUI(self): self.clearCanvas() self.rightButton.pack_forget() self.wrongButton.pack_forget() self.retryButton.pack_forget() self.canvas.pack() self.recognizeButton.pack() self.clearButton.pack() self.checkingDigit = False print "***************************************************" print "Please draw another digit..." self.master.update() return
def displayFromBrowser(Canvas,flag): try: import webbrowser if flag=='ktail': if len(Canvas.find_all())==0: tkMessageBox.showinfo("FSM", 'Nothing to show.Please generate an FSM first') return webbrowser.open('../graph/ktail.png') elif flag=='sample': if len(Canvas.find_all())==0: tkMessageBox.showinfo("FSM", 'Nothing to show.Please generate an FSM first') return webbrowser.open('../graph/sample0.5.png') except Exception: tkMessageBox.showerror("Error", "Error encountered while opening the FSM") pass