def __init__(self, master, infoPanel, intervalBar): """Constructor Parameters: master (tk.Tk|tk.Frame): The parent widget """ self._master = master self._infoPanel = infoPanel self._infoPanel.init_window(master, self) self._intervalBar = intervalBar self._playing = True self._image_manager = ImageManager('images/dots/', loader=load_image) # Game counts = [10, 15, 25, 25] random.shuffle(counts) # randomly pair counts with each kind of dot objectives = zip( [BasicDot(1), BasicDot(2), BasicDot(4), BasicDot(3)], counts) self._objectives = ObjectiveManager(objectives) self._infoPanel.set_objectives( [self._objectives.get_status()[i][1] for i in range(4)]) # Game dead_cells = {(2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4), (4, 2), (4, 3), (4, 4), (0, 7), (1, 7), (6, 7), (7, 7)} self._game = DotGame({ButterflyDot: 1}, objectives=self._objectives, kinds=(1, 2, 3, 4), size=(8, 8), dead_cells=dead_cells) # The following code may be useful when you are implementing task 2: for i in range(0, 4): for j in range(0, 2): position = i, j self._game.grid[position].set_dot(ButterflyDot(3)) self._game.grid[(7, 3)].set_dot(ButterflyDot(1)) # Grid View self._grid_view = GridView(master, size=self._game.grid.size(), image_manager=self._image_manager) self._grid_view.pack() self._grid_view.draw(self._game.grid) self.draw_grid_borders() # Events self.bind_events() # Set initial score again to trigger view update automatically self._refresh_status()
def reset_with_com(self): # initialize pygame pygame.init() # load background music pygame.mixer.music.load('bgm2.ogg') pygame.mixer.music.play(-1, 0.0) pygame.mixer.music.set_volume(0.3) counts = [10, 15, 25, 25] random.shuffle(counts) # randomly pair counts with each kind of dot objectives = zip( [BasicDot(1), BasicDot(2), BasicDot(4), BasicDot(3)], counts) self._objectives = ObjectiveManager(list(objectives)) # reset the objectives self._obj.draw(self._objectives.get_status()) dead_cells = {(2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4), (4, 2), (4, 3), (4, 4), (0, 7), (1, 7), (6, 7), (7, 7)} self._game = CompanionGame({ BasicDot: 1, CompanionDot: 1 }, companion=EskimoCompanion(), objectives=self._objectives, kinds=(1, 2, 3, 4), size=(8, 8), dead_cells=dead_cells) # reset the game(score, move) self._game.reset() # reset the grid self.draw_grid() # reset the score scores = self.info_panel.set_scores() scores.config(text=str(self._game.get_score())) # reset the move moves = self.info_panel.remain_moves() moves.config(text=str(self._game.get_moves())) # reset the interval bar self.interval_bar.progress_bar(0) self._game.companion.reset() # reset the companion bar self.interval_bar.com_charge_bar_reset() # reset the companion charge button self.action_bar.companion_charge().config(state='normal') # reset the color remover button self.action_bar.colour_remove().config(state='normal')
def generate_objectives(cls, data): """(ObjectiveManager) Create the new objectives from data Parameters: data (list<list>): The list of objective dot, kind and count """ objectives = [] for name, kind, count in data: objective = (cls.generate_dot(name, kind), count) objectives.append(objective) return ObjectiveManager(objectives)
def __init__(self, dot_weights, kinds=(1, 2, 3), size=(6, 6), dead_cells=None, min_group=2, animation=True): self.companion = UselessCompanion(max_charge=0) super().__init__(dot_weights, companion=self.companion, kinds=kinds, size=size, dead_cells=dead_cells, min_group=min_group, moves=0, animation=animation) self.objectives = ObjectiveManager(())
def __init__(self, master, icon=None, switch=False): """Constructor Parameters: master (tk.Tk|tk.Frame): The parent widget """ self._master = master master.title(self.DEFAULT_TITLE) self.flag = False self.default_icon = tk.PhotoImage(file='images/companions/useless.gif') self.extra_icon = tk.PhotoImage(file='images/companions/penguin.gif') self.icon = icon if icon else self.default_icon self.default_step = 1 self.score = 0 self._playing = True self._image_manager = ImageManager('images/dots/', loader=load_image) menu_bar = tk.Menu(master) master.config(menu=menu_bar) file_menu = tk.Menu(menu_bar) menu_bar.add_cascade(label='File', menu=file_menu) file_menu.add_command(label='New Game', command=self.reset) file_menu.add_command(label='Exit Game', command=self.close) master.protocol('WM_DELETE_WINDOW', self.close) # Game counts = [10, 15, 25, 25] random.shuffle(counts) # randomly pair counts with each kind of dot objectives = zip( [BasicDot(1), BasicDot(2), BasicDot(4), BasicDot(3)], counts) self._objectives = ObjectiveManager(objectives) dead_cells = {(2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4), (4, 2), (4, 3), (4, 4), (0, 7), (1, 7), (6, 7), (7, 7)} self.dot_game = DotGame({BasicDot: 1}, objectives=self._objectives, kinds=(1, 2, 3, 4), size=(8, 8), dead_cells=dead_cells) self.companion_game = CompanionGame( { BasicDot: 43, CompanionDot: 9, WildcardDot: 6 }, BuffaloCompanion(), objectives=self._objectives, kinds=(1, 2, 3, 4), size=(8, 8), dead_cells=dead_cells) # Game self._game = self.companion_game if switch else self.dot_game if self.FIRST: reply = askquestion( type=messagebox.YESNO, title='Select Model', message= 'Would you like to start a new game with "Companion Dot"?') if reply == messagebox.YES: showinfo('"Companion Dot" Model', 'Enjoy the game with "Companion Dot"!') self.icon = self.extra_icon self._game = self.companion_game self._master.title('Dots & Co - "Companion Dot"') else: showinfo('New Game', 'Enjoy the basic game!') self._game = self.dot_game self.FIRST = False # The following code may be useful when you are implementing task 2: # for i in range(0, 4): # for j in range(0, 2): # position = i, j # self._game.grid[position].set_dot(BasicDot(3)) # self._game.grid[(7, 3)].set_dot(BasicDot(1)) # InfoPanel self.info_panel = InfoPanel(master) self.info_panel.set_default_icon(self.icon) self.info_panel.decrease_remaining_moves_and_increase_score( self._game.get_moves(), self._game.get_score()) self.info_panel.set_objectives(self._image_manager, self._objectives.get_status()) self.info_panel.pack() # IntervalBar self.interval_bar = IntervalBar(master) self.interval_bar.draw_step(self.default_step) self.interval_bar.pack() # Grid View self._grid_view = GridView(master, size=self._game.grid.size(), image_manager=self._image_manager) self._grid_view.pack() self._grid_view.draw(self._game.grid) self.draw_grid_borders() # Events self.bind_events() # Set initial score again to trigger view update automatically self._refresh_status()
class DotsApp: """Top level GUI class for simple Dots & Co game""" DEFAULT_TITLE = 'Dots & Co' FIRST = True def __init__(self, master, icon=None, switch=False): """Constructor Parameters: master (tk.Tk|tk.Frame): The parent widget """ self._master = master master.title(self.DEFAULT_TITLE) self.flag = False self.default_icon = tk.PhotoImage(file='images/companions/useless.gif') self.extra_icon = tk.PhotoImage(file='images/companions/penguin.gif') self.icon = icon if icon else self.default_icon self.default_step = 1 self.score = 0 self._playing = True self._image_manager = ImageManager('images/dots/', loader=load_image) menu_bar = tk.Menu(master) master.config(menu=menu_bar) file_menu = tk.Menu(menu_bar) menu_bar.add_cascade(label='File', menu=file_menu) file_menu.add_command(label='New Game', command=self.reset) file_menu.add_command(label='Exit Game', command=self.close) master.protocol('WM_DELETE_WINDOW', self.close) # Game counts = [10, 15, 25, 25] random.shuffle(counts) # randomly pair counts with each kind of dot objectives = zip( [BasicDot(1), BasicDot(2), BasicDot(4), BasicDot(3)], counts) self._objectives = ObjectiveManager(objectives) dead_cells = {(2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4), (4, 2), (4, 3), (4, 4), (0, 7), (1, 7), (6, 7), (7, 7)} self.dot_game = DotGame({BasicDot: 1}, objectives=self._objectives, kinds=(1, 2, 3, 4), size=(8, 8), dead_cells=dead_cells) self.companion_game = CompanionGame( { BasicDot: 43, CompanionDot: 9, WildcardDot: 6 }, BuffaloCompanion(), objectives=self._objectives, kinds=(1, 2, 3, 4), size=(8, 8), dead_cells=dead_cells) # Game self._game = self.companion_game if switch else self.dot_game if self.FIRST: reply = askquestion( type=messagebox.YESNO, title='Select Model', message= 'Would you like to start a new game with "Companion Dot"?') if reply == messagebox.YES: showinfo('"Companion Dot" Model', 'Enjoy the game with "Companion Dot"!') self.icon = self.extra_icon self._game = self.companion_game self._master.title('Dots & Co - "Companion Dot"') else: showinfo('New Game', 'Enjoy the basic game!') self._game = self.dot_game self.FIRST = False # The following code may be useful when you are implementing task 2: # for i in range(0, 4): # for j in range(0, 2): # position = i, j # self._game.grid[position].set_dot(BasicDot(3)) # self._game.grid[(7, 3)].set_dot(BasicDot(1)) # InfoPanel self.info_panel = InfoPanel(master) self.info_panel.set_default_icon(self.icon) self.info_panel.decrease_remaining_moves_and_increase_score( self._game.get_moves(), self._game.get_score()) self.info_panel.set_objectives(self._image_manager, self._objectives.get_status()) self.info_panel.pack() # IntervalBar self.interval_bar = IntervalBar(master) self.interval_bar.draw_step(self.default_step) self.interval_bar.pack() # Grid View self._grid_view = GridView(master, size=self._game.grid.size(), image_manager=self._image_manager) self._grid_view.pack() self._grid_view.draw(self._game.grid) self.draw_grid_borders() # Events self.bind_events() # Set initial score again to trigger view update automatically self._refresh_status() def close(self): if self.can_close(): self._master.destroy() def can_close(self): reply = askquestion(type=messagebox.YESNO, title='Confirm Exit', message='Are you sure you want to quit?') if reply == messagebox.YES: return True else: return False def draw_grid_borders(self): """Draws borders around the game grid""" borders = list(self._game.grid.get_borders()) # this is a hack that won't work well for multiple separate clusters outside = max(borders, key=lambda border: len(set(border))) for border in borders: self._grid_view.draw_border(border, fill=border != outside) def bind_events(self): """Binds relevant events""" self._grid_view.on('start_connection', self._drag) self._grid_view.on('move_connection', self._drag) self._grid_view.on('end_connection', self._drop) self._game.on('reset', self._refresh_status) self._game.on('complete', self._drop_complete) self._game.on('connect', self._connect) self._game.on('undo', self._undo) def _animation_step(self, step_name): """Runs for each step of an animation Parameters: step_name (str): The name (type) of the step """ print(step_name) self._refresh_status() self.draw_grid() def animate(self, steps, callback=lambda: None): """Animates some steps (i.e. from selecting some dots, activating companion, etc. Parameters: steps (generator): Generator which yields step_name (str) for each step in the animation """ if steps is None: steps = (None for _ in range(1)) animation = create_animation(self._master, steps, delays=ANIMATION_DELAYS, delay=DEFAULT_ANIMATION_DELAY, step=self._animation_step, callback=callback) animation() def _drop(self, position): # pylint: disable=unused-argument """Handles the dropping of the dragged connection Parameters: position (tuple<int, int>): The position where the connection was dropped """ if not self._playing: return if self._game.is_resolving(): return self._grid_view.clear_dragged_connections() self._grid_view.clear_connections() self.animate(self._game.drop()) def _connect(self, start, end): """Draws a connection from the start point to the end point Parameters: start (tuple<int, int>): The position of the starting dot end (tuple<int, int>): The position of the ending dot """ if self._game.is_resolving(): return if not self._playing: return self._grid_view.draw_connection( start, end, self._game.grid[start].get_dot().get_kind()) def _undo(self, positions): """Removes all the given dot connections from the grid view Parameters: positions (list<tuple<int, int>>): The dot connects to remove """ for _ in positions: self._grid_view.undo_connection() def _drag(self, position): """Attempts to connect to the given position, otherwise draws a dragged line from the start Parameters: position (tuple<int, int>): The position to drag to """ if self._game.is_resolving(): return if not self._playing: return tile_position = self._grid_view.xy_to_rc(position) if tile_position is not None: cell = self._game.grid[tile_position] dot = cell.get_dot() if dot and self._game.connect(tile_position): self._grid_view.clear_dragged_connections() return kind = self._game.get_connection_kind() if not len(self._game.get_connection_path()): return start = self._game.get_connection_path()[-1] if start: self._grid_view.draw_dragged_connection(start, position, kind) @staticmethod def remove(*_): """Deprecated in 1.1.0""" raise DeprecationWarning("Deprecated in 1.1.0") def draw_grid(self): """Draws the grid""" self._grid_view.draw(self._game.grid) def reset(self): """Resets the game""" # raise NotImplementedError() if self._playing: reply = askquestion(type=messagebox.YESNO, title='Now Playing', message='Are you sure you want to restart?') if reply == messagebox.YES: self.select_model() else: pass else: self.select_model() def select_model(self): reply = askquestion( type=messagebox.YESNOCANCEL, title='Select Model', message='Would you like to start a new game with "Companion Dot"?') if reply == messagebox.YES: showinfo('"Companion Dot" Model', 'Enjoy the game with "Companion Dot"!') self.restart(True) # self.restart_o() self._master.title('Dots & Co - "Companion Dot"') elif reply == messagebox.NO: showinfo('New Game', 'Enjoy the basic game!') self.restart() else: pass def restart(self, flag=False): self.info_panel.destroy() self.interval_bar.destroy() self._grid_view.destroy() if flag: self.__init__(self._master, self.extra_icon, True) else: self.__init__(self._master) def check_game_over(self): """Checks whether the game is over and shows an appropriate message box if so""" state = self._game.get_game_state() if state == self._game.GameState.WON: showinfo("Game Over!", "You won!!!") self._playing = False elif state == self._game.GameState.LOST: showinfo( "Game Over!", f"You didn't reach the objective(s) in time. You connected {self._game.get_score()} points" ) self._playing = False def _drop_complete(self): """Handles the end of a drop animation""" # Useful for when implementing a companion # if self._game.companion.is_fully_charged(): # self._game.companion.reset() # steps = self._game.companion.activate(self._game) # self._refresh_status() # # return self.animate(steps) # Need to check whether the game is over # raise NotImplementedError() # no mercy for stooges print(self._game.get_game_state()) if self.flag: if self._game.companion.is_fully_charged(): self._game.companion.reset() showinfo('Ultimate Skill!!!!', 'BOOM SHAKALAKA!!!!!!!') self._game.companion.activate(self._game) self.interval_bar.draw_step(self._game.companion.get_charge() + 1) self.flag = False self.check_game_over() if not self._playing: print('ok') def _refresh_status(self): """Handles change in game status""" # Normally, this should raise the following error: # raise NotImplementedError() # But so that the game can work prior to this method being implemented, # we'll just print some information # Sometimes I believe Python ignores all my comments :( score = self._game.get_score() print("Score is now {}.".format(score)) if self.score < score: if type(self._game) is type(self.dot_game): self.basic_progress() else: self.companion_progress() self.score = score self.info_panel.decrease_remaining_moves_and_increase_score( self._game.get_moves(), score) self.info_panel.refresh_objectives(self._objectives.get_status()) def basic_progress(self): self.default_step += 1 if self.default_step > 6: self.default_step = 1 self.interval_bar.draw_step(self.default_step) def companion_progress(self): if self._game.companion.get_charge() < 6: self.interval_bar.draw_step(self._game.companion.get_charge() + 1) else: self.interval_bar.draw_step(self._game.companion.get_charge()) self.flag = True
def __init__(self, master): """Constructor Parameters: master (tk.Tk|tk.Frame): The parent widget """ pygame.init() self._master = master master.title('Dots') self._playing = True self._over = None self._player = 'None' self._scores = {} self._steps = 0 self._image_manager = ImageManager('images/dots/', loader=load_image) # InfoPanel self._info = InfoPanel(master) self._info.pack(fill=tk.BOTH, expand=1) # Login top = tk.Toplevel() top.title('Login') tk.Label(top, text='Welcome to the Dots & Co game!').pack() frame = tk.Frame(top) frame.pack(side=tk.BOTTOM) tk.Label(frame, text="Name: ").pack(side=tk.LEFT) entry = tk.Entry(frame, width=20) entry.pack(side=tk.LEFT) def record(*args): self._player = entry.get() if self.read_score() == None: self.save_score() top.destroy() tk.Button(frame, text="Start!", command=record).pack(side=tk.RIGHT) top.bind('<Return>', record) # Menu menubar = tk.Menu(master) master.config(menu=menubar) filemenu = tk.Menu(menubar) menubar.add_cascade(label='File', menu=filemenu) newgame = tk.Menu(menubar) filemenu.add_cascade(label='New Game', menu=newgame) newgame.add_command(label='With a Companion', command=self.with_companion) newgame.add_command(label='Without a Companion', command=self.without_companion) filemenu.add_command(label='Exit', command=self.exit) master.protocol("WM_DELETE_WINDOW", self.exit) # Game counts = [10, 15, 25, 25] random.shuffle(counts) # randomly pair counts with each kind of dot objectives = zip( [BasicDot(1), BasicDot(2), BasicDot(4), BasicDot(3)], counts) self._objectives = ObjectiveManager(list(objectives)) self._info.set_objectives(list(objectives)) self._dead_cells = {(2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4), (4, 2), (4, 3), (4, 4), (0, 7), (1, 7), (6, 7), (7, 7)} self._companion = EskimoCompanion() self._game = CompanionGame( { TurtleDot: 1, CompanionDot: 4, BasicDot: 11 }, objectives=self._objectives, companion=self._companion, kinds=(1, 2, 3, 4), size=(8, 8), dead_cells=self._dead_cells) # Grid View self._grid_view = GridView(self._master, size=self._game.grid.size(), image_manager=self._image_manager) self._grid_view.pack() self._grid_view.draw(self._game.grid) self.draw_grid_borders() # Events self.bind_events() # Set initial score again to trigger view update automatically self._refresh_status() self.read_score()
class DotsApp(object): """Top level GUI class for simple Dots & Co game""" def __init__(self, master): """Constructor Parameters: master (tk.Tk|tk.Frame): The parent widget """ pygame.init() self._master = master master.title('Dots') self._playing = True self._over = None self._player = 'None' self._scores = {} self._steps = 0 self._image_manager = ImageManager('images/dots/', loader=load_image) # InfoPanel self._info = InfoPanel(master) self._info.pack(fill=tk.BOTH, expand=1) # Login top = tk.Toplevel() top.title('Login') tk.Label(top, text='Welcome to the Dots & Co game!').pack() frame = tk.Frame(top) frame.pack(side=tk.BOTTOM) tk.Label(frame, text="Name: ").pack(side=tk.LEFT) entry = tk.Entry(frame, width=20) entry.pack(side=tk.LEFT) def record(*args): self._player = entry.get() if self.read_score() == None: self.save_score() top.destroy() tk.Button(frame, text="Start!", command=record).pack(side=tk.RIGHT) top.bind('<Return>', record) # Menu menubar = tk.Menu(master) master.config(menu=menubar) filemenu = tk.Menu(menubar) menubar.add_cascade(label='File', menu=filemenu) newgame = tk.Menu(menubar) filemenu.add_cascade(label='New Game', menu=newgame) newgame.add_command(label='With a Companion', command=self.with_companion) newgame.add_command(label='Without a Companion', command=self.without_companion) filemenu.add_command(label='Exit', command=self.exit) master.protocol("WM_DELETE_WINDOW", self.exit) # Game counts = [10, 15, 25, 25] random.shuffle(counts) # randomly pair counts with each kind of dot objectives = zip( [BasicDot(1), BasicDot(2), BasicDot(4), BasicDot(3)], counts) self._objectives = ObjectiveManager(list(objectives)) self._info.set_objectives(list(objectives)) self._dead_cells = {(2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4), (4, 2), (4, 3), (4, 4), (0, 7), (1, 7), (6, 7), (7, 7)} self._companion = EskimoCompanion() self._game = CompanionGame( { TurtleDot: 1, CompanionDot: 4, BasicDot: 11 }, objectives=self._objectives, companion=self._companion, kinds=(1, 2, 3, 4), size=(8, 8), dead_cells=self._dead_cells) # Grid View self._grid_view = GridView(self._master, size=self._game.grid.size(), image_manager=self._image_manager) self._grid_view.pack() self._grid_view.draw(self._game.grid) self.draw_grid_borders() # Events self.bind_events() # Set initial score again to trigger view update automatically self._refresh_status() self.read_score() # mixer not working under Ubuntu # pygame.mixer.Sound('Sounds/start.wav').play() def draw_grid_borders(self): """Draws borders around the game grid""" borders = list(self._game.grid.get_borders()) # this is a hack that won't work well for multiple separate clusters outside = max(borders, key=lambda border: len(set(border))) for border in borders: self._grid_view.draw_border(border, fill=border != outside) def bind_events(self): """Binds relevant events""" self._grid_view.on('start_connection', self._drag) self._grid_view.on('move_connection', self._drag) self._grid_view.on('end_connection', self._drop) self._game.on('reset', self._refresh_status) self._game.on('complete', self._drop_complete) self._game.on('connect', self._connect) self._game.on('undo', self._undo) def _animation_step(self, step_name): """Runs for each step of an animation Parameters: step_name (str): The name (type) of the step """ self._refresh_status() self.draw_grid() def animate(self, steps, callback=lambda: None): """Animates some steps (i.e. from selecting some dots, activating companion, etc. Parameters: steps (generator): Generator which yields step_name (str) for each step in the animation """ if steps is None: steps = (None for _ in range(1)) animation = create_animation(self._master, steps, delays=ANIMATION_DELAYS, delay=DEFAULT_ANIMATION_DELAY, step=self._animation_step, callback=callback) animation() def _drop(self, position): # pylint: disable=unused-argument """Handles the dropping of the dragged connection Parameters: position (tuple<int, int>): The position where the connection was dropped """ if not self._playing: return if self._game.is_resolving(): return self._grid_view.clear_dragged_connections() self._grid_view.clear_connections() self.animate(self._game.drop()) # drop_sound = pygame.mixer.Sound('Sounds/drop.wav') # drop_sound.play() def _connect(self, start, end): """Draws a connection from the start point to the end point Parameters: start (tuple<int, int>): The position of the starting dot end (tuple<int, int>): The position of the ending dot """ if self._game.is_resolving(): return if not self._playing: return self._grid_view.draw_connection( start, end, self._game.grid[start].get_dot().get_kind()) def _undo(self, positions): """Removes all the given dot connections from the grid view Parameters: positions (list<tuple<int, int>>): The dot connects to remove """ for _ in positions: self._grid_view.undo_connection() def _drag(self, position): """Attempts to connect to the given position, otherwise draws a dragged line from the start Parameters: position (tuple<int, int>): The position to drag to """ if self._game.is_resolving(): return if not self._playing: return tile_position = self._grid_view.xy_to_rc(position) if tile_position is not None: cell = self._game.grid[tile_position] dot = cell.get_dot() if dot and self._game.connect(tile_position): self._grid_view.clear_dragged_connections() return kind = self._game.get_connection_kind() if not len(self._game.get_connection_path()): return start = self._game.get_connection_path()[-1] if start: self._grid_view.draw_dragged_connection(start, position, kind) def draw_grid(self): """Draws the grid""" self._grid_view.draw(self._game.grid) def with_companion(self): """Sets the companion for the new game with a companion and resets""" self._companion = EskimoCompanion() self.reset() def without_companion(self): """Cancels the companion for the new game witout a companion and resets""" self._companion = None self.reset() def reset(self): """Resets the game""" self._playing = True self._steps = 0 self._game.reset() self._objectives.reset() self._refresh_status() self._info.reset_bar() # start_sound = pygame.mixer.Sound('Sounds/start.wav') # start_sound.play() if self._over is not None: self._info.after_cancel(self._animation) if self._companion: img = tk.PhotoImage(file='images/companions/eskimo.png') self._info.set_companion(img) self._game = CompanionGame( { TurtleDot: 1, CompanionDot: 4, BasicDot: 11 }, objectives=self._objectives, companion=self._companion, kinds=(1, 2, 3, 4), size=(8, 8), dead_cells=self._dead_cells) if not self._companion: img = tk.PhotoImage(file='images/companions/useless.gif') self._info.set_companion(img) self._game = DotGame({BasicDot: 1}, objectives=self._objectives, kinds=(1, 2, 3, 4), size=(8, 8), dead_cells=self._dead_cells) self._info.set_bar(0) self._grid_view.draw(self._game.grid) self.bind_events() def exit(self): """Checks if the user wants to exit and closes the application if so""" reply = messagebox.askokcancel('Verify exit', 'Really quit?') if reply: self._master.destroy() def change_win(self): """Shows an animation when the user wins""" self._over = not self._over if self._over: img = tk.PhotoImage(file='images/win1.gif') self._info.set_companion(img) else: img = tk.PhotoImage(file='images/win2.gif') self._info.set_companion(img) self._animation = self._info.after(800, self.change_win) def change_lose(self): """Shows an animation when the user loses""" self._over = not self._over if self._over: img = tk.PhotoImage(file='images/gameover1.png') self._info.set_companion(img) else: img = tk.PhotoImage(file='images/gameover2.png') self._info.set_companion(img) self._animation = self._info.after(800, self.change_lose) def check_game_over(self): """Checks whether the game is over and shows an appropriate message box if so""" state = self._game.get_game_state() if state == self._game.GameState.WON: # Shows the animation and plays sound effects self._over = True self.change_win() # pygame.mixer.Sound('Sounds/success.wav').play() # Saves the best score if self._player == 'None': self.save_score() elif self._game.get_score() > self.read_score(): self.save_score() # Shows the user's highest ranking and the top 3 players ranking = sorted(self._scores, key=self._scores.__getitem__, reverse=True) position = ranking.index(self._player) + 1 top = '' for name in ranking[:3]: top += "{0}--{1} ".format(name, self._scores.get(name)) messagebox.showinfo( "Game Over!", "You won!!!\nYour best socre: {0}. Your highest ranking: {1}.\n Top 3: " .format(self.read_score(), position) + top) self._playing = False elif state == self._game.GameState.LOST: self._over = True self.change_lose() # pygame.mixer.Sound('Sounds/lose.wav').play() messagebox.showinfo( "Game Over!", f"You didn't reach the objective(s) in time. You connected {self._game.get_score()} points" ) self._playing = False def read_score(self): """(int) Returns the user's former best score. Returns None if the user plays the game for the first time Precondition: The user's name does not consist ',' """ f = open('score.txt', 'r') lines = f.readlines() for l in lines: if l: s = l.split(',') self._scores[s[0]] = int(s[1]) score = self._scores.get(self._player) f.close return score def save_score(self): """Saves the user's score""" self._scores[self._player] = self._game.get_score() result = '' for n in self._scores: line = str(n) + "," + str(self._scores[n]) + "\n" result += line f = open('score.txt', 'w') f.write(result) f.close def _drop_complete(self): """Handles the end of a drop animation""" if not self._companion: self._steps += 1 step = self._steps % 6 if step == 0: self._info.reset_bar() self._info.set_bar(step) if self._companion: charge = self._game.companion.get_charge() for i in range(charge): self._info.set_bar(i) if self._game.companion.is_fully_charged(): # pygame.mixer.Sound('Sounds/companion.wav').play() steps = self._game.companion.activate(self._game) self._grid_view.draw(self._game.grid) self._game.companion.reset() self._info.reset_bar() self.check_game_over() return self.animate(steps) self._grid_view.draw(self._game.grid) self.check_game_over() def _refresh_status(self): """Handles change in objectives, remaining moves, and score.""" status = self._objectives.get_status() self._info.set_objectives(status) moves = self._game.get_moves() self._info.set_moves(moves) score = self._game.get_score() self._info.set_score(score)
def __init__(self, master): """Constructor Parameters: master (tk.Tk|tk.Frame): The parent widget """ self._master = master self._master.title('Dot') self._playing = True self._image_manager = ImageManager('images/dots/', loader=load_image) # initialize pygame pygame.init() # load background music pygame.mixer.music.load('bgm2.ogg') pygame.mixer.music.play(-1, 0.0) pygame.mixer.music.set_volume(0.3) # create an instance of InfoPanel self.info_panel = InfoPanel(master) self.info_panel.pack() # create an instance of IntervalBar self.interval_bar = IntervalBar(master) self.interval_bar.pack() # create an instance of ActionBar self.action_bar = ActionBar(master) self.action_bar.pack(side=tk.BOTTOM) # add command to two button self.action_bar.companion_charge().config(command=self.com_button) self.action_bar.colour_remove().config(command=self.colour_activate) # File menu menubar = tk.Menu(self._master) # tell master what it's menu is self._master.config(menu=menubar) filemenu = tk.Menu(menubar) menubar.add_cascade(label="File", menu=filemenu) filemenu.add_command(label="New Game(companion)", command=self.reset_with_com) filemenu.add_command(label="New Game(no-companion)", command=self.reset_without_com) filemenu.add_command(label="Exit", command=self.exit) # Game counts = [10, 15, 25, 25] random.shuffle(counts) # randomly pair counts with each kind of dot objectives = zip( [BasicDot(1), BasicDot(2), BasicDot(4), BasicDot(3)], counts) self._objectives = ObjectiveManager(list(objectives)) # show the objectives self._obj = self.info_panel.set_object() self._obj.draw(self._objectives.get_status()) # Game dead_cells = {(2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4), (4, 2), (4, 3), (4, 4), (0, 7), (1, 7), (6, 7), (7, 7)} self._game = CompanionGame({ BasicDot: 1, CompanionDot: 1 }, companion=EskimoCompanion(), objectives=self._objectives, kinds=(1, 2, 3, 4), size=(8, 8), dead_cells=dead_cells) # show the remaining moves moves = self.info_panel.remain_moves() moves.config(text=str(self._game.get_moves())) # show the scores scores = self.info_panel.set_scores() scores.config(text=str(self._game.get_score())) # control the reset type(with/without companion) self._play_with_com = True # Grid View self._grid_view = GridView(master, size=self._game.grid.size(), image_manager=self._image_manager) self._grid_view.pack() self._grid_view.draw(self._game.grid) self.draw_grid_borders() # Events self.bind_events() # Set initial score again to trigger view update automatically self._refresh_status()
class DotsApp: """Top level GUI class for simple Dots & Co game""" def __init__(self, master): """Constructor Parameters: master (tk.Tk|tk.Frame): The parent widget """ self._master = master self._master.title('Dot') self._playing = True self._image_manager = ImageManager('images/dots/', loader=load_image) # initialize pygame pygame.init() # load background music pygame.mixer.music.load('bgm2.ogg') pygame.mixer.music.play(-1, 0.0) pygame.mixer.music.set_volume(0.3) # create an instance of InfoPanel self.info_panel = InfoPanel(master) self.info_panel.pack() # create an instance of IntervalBar self.interval_bar = IntervalBar(master) self.interval_bar.pack() # create an instance of ActionBar self.action_bar = ActionBar(master) self.action_bar.pack(side=tk.BOTTOM) # add command to two button self.action_bar.companion_charge().config(command=self.com_button) self.action_bar.colour_remove().config(command=self.colour_activate) # File menu menubar = tk.Menu(self._master) # tell master what it's menu is self._master.config(menu=menubar) filemenu = tk.Menu(menubar) menubar.add_cascade(label="File", menu=filemenu) filemenu.add_command(label="New Game(companion)", command=self.reset_with_com) filemenu.add_command(label="New Game(no-companion)", command=self.reset_without_com) filemenu.add_command(label="Exit", command=self.exit) # Game counts = [10, 15, 25, 25] random.shuffle(counts) # randomly pair counts with each kind of dot objectives = zip( [BasicDot(1), BasicDot(2), BasicDot(4), BasicDot(3)], counts) self._objectives = ObjectiveManager(list(objectives)) # show the objectives self._obj = self.info_panel.set_object() self._obj.draw(self._objectives.get_status()) # Game dead_cells = {(2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4), (4, 2), (4, 3), (4, 4), (0, 7), (1, 7), (6, 7), (7, 7)} self._game = CompanionGame({ BasicDot: 1, CompanionDot: 1 }, companion=EskimoCompanion(), objectives=self._objectives, kinds=(1, 2, 3, 4), size=(8, 8), dead_cells=dead_cells) # show the remaining moves moves = self.info_panel.remain_moves() moves.config(text=str(self._game.get_moves())) # show the scores scores = self.info_panel.set_scores() scores.config(text=str(self._game.get_score())) # control the reset type(with/without companion) self._play_with_com = True # Grid View self._grid_view = GridView(master, size=self._game.grid.size(), image_manager=self._image_manager) self._grid_view.pack() self._grid_view.draw(self._game.grid) self.draw_grid_borders() # Events self.bind_events() # Set initial score again to trigger view update automatically self._refresh_status() def draw_grid_borders(self): """Draws borders around the game grid""" borders = list(self._game.grid.get_borders()) # this is a hack that won't work well for multiple separate clusters outside = max(borders, key=lambda border: len(set(border))) for border in borders: self._grid_view.draw_border(border, fill=border != outside) def bind_events(self): """Binds relevant events""" self._grid_view.on('start_connection', self._drag) self._grid_view.on('move_connection', self._drag) self._grid_view.on('end_connection', self._drop) self._game.on('reset', self._refresh_status) self._game.on('complete', self._drop_complete) self._game.on('connect', self._connect) self._game.on('undo', self._undo) def _animation_step(self, step_name): """Runs for each step of an animation Parameters: step_name (str): The name (type) of the step """ # add sound effect sound = pygame.mixer.Sound('boble1.wav') sound.play() print(step_name) self._refresh_status() self.draw_grid() def animate(self, steps, callback=lambda: None): """Animates some steps (i.e. from selecting some dots, activating companion, etc. Parameters: steps (generator): Generator which yields step_name (str) for each step in the animation """ if steps is None: steps = (None for _ in range(1)) animation = create_animation(self._master, steps, delays=ANIMATION_DELAYS, delay=DEFAULT_ANIMATION_DELAY, step=self._animation_step, callback=callback) animation() def _drop(self, position): # pylint: disable=unused-argument """Handles the dropping of the dragged connection Parameters: position (tuple<int, int>): The position where the connection was dropped """ if not self._playing: return if self._game.is_resolving(): return self._grid_view.clear_dragged_connections() self._grid_view.clear_connections() self.animate(self._game.drop()) def _connect(self, start, end): """Draws a connection from the start point to the end point Parameters: start (tuple<int, int>): The position of the starting dot end (tuple<int, int>): The position of the ending dot """ # add sound effect when two connects sound = pygame.mixer.Sound('cartoon-boing.ogg') sound.play() if self._game.is_resolving(): return if not self._playing: return self._grid_view.draw_connection( start, end, self._game.grid[start].get_dot().get_kind()) def _undo(self, positions): """Removes all the given dot connections from the grid view Parameters: positions (list<tuple<int, int>>): The dot connects to remove """ for _ in positions: self._grid_view.undo_connection() def _drag(self, position): """Attempts to connect to the given position, otherwise draws a dragged line from the start Parameters: position (tuple<int, int>): The position to drag to """ if self._game.is_resolving(): return if not self._playing: return tile_position = self._grid_view.xy_to_rc(position) if tile_position is not None: cell = self._game.grid[tile_position] dot = cell.get_dot() if dot and self._game.connect(tile_position): self._grid_view.clear_dragged_connections() return kind = self._game.get_connection_kind() if not len(self._game.get_connection_path()): return start = self._game.get_connection_path()[-1] if start: self._grid_view.draw_dragged_connection(start, position, kind) @staticmethod def remove(*_): """Deprecated in 1.1.0""" raise DeprecationWarning("Deprecated in 1.1.0") def draw_grid(self): """Draws the grid""" self._grid_view.draw(self._game.grid) def reset_without_com(self): """Resets the game""" # initialize pygame pygame.init() # load background music pygame.mixer.music.load('bgm2.ogg') pygame.mixer.music.play(-1, 0.0) pygame.mixer.music.set_volume(0.3) counts = [10, 15, 25, 25] random.shuffle(counts) # randomly pair counts with each kind of dot objectives = zip( [BasicDot(1), BasicDot(2), BasicDot(4), BasicDot(3)], counts) self._objectives = ObjectiveManager(list(objectives)) dead_cells = {(2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4), (4, 2), (4, 3), (4, 4), (0, 7), (1, 7), (6, 7), (7, 7)} self._game = DotGame({BasicDot: 1}, objectives=self._objectives, kinds=(1, 2, 3, 4), size=(8, 8), dead_cells=dead_cells) # reset the game(score, move) self._game.reset() # reset the score scores = self.info_panel.set_scores() scores.config(text=str(self._game.get_score())) # reset the move moves = self.info_panel.remain_moves() moves.config(text=str(self._game.get_moves())) # reset the objectives self._obj.draw(self._objectives.get_status()) # reset the grid self.draw_grid() # reset the interval bar self.interval_bar.progress_bar(0) self.interval_bar.com_charge_bar_reset() # player choose to play without companion self._play_with_com = False # reset the companion charge button as disable self.action_bar.companion_charge().config(state='disable') # reset the color remover button self.action_bar.colour_remove().config(state='normal') def reset_with_com(self): # initialize pygame pygame.init() # load background music pygame.mixer.music.load('bgm2.ogg') pygame.mixer.music.play(-1, 0.0) pygame.mixer.music.set_volume(0.3) counts = [10, 15, 25, 25] random.shuffle(counts) # randomly pair counts with each kind of dot objectives = zip( [BasicDot(1), BasicDot(2), BasicDot(4), BasicDot(3)], counts) self._objectives = ObjectiveManager(list(objectives)) # reset the objectives self._obj.draw(self._objectives.get_status()) dead_cells = {(2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4), (4, 2), (4, 3), (4, 4), (0, 7), (1, 7), (6, 7), (7, 7)} self._game = CompanionGame({ BasicDot: 1, CompanionDot: 1 }, companion=EskimoCompanion(), objectives=self._objectives, kinds=(1, 2, 3, 4), size=(8, 8), dead_cells=dead_cells) # reset the game(score, move) self._game.reset() # reset the grid self.draw_grid() # reset the score scores = self.info_panel.set_scores() scores.config(text=str(self._game.get_score())) # reset the move moves = self.info_panel.remain_moves() moves.config(text=str(self._game.get_moves())) # reset the interval bar self.interval_bar.progress_bar(0) self._game.companion.reset() # reset the companion bar self.interval_bar.com_charge_bar_reset() # reset the companion charge button self.action_bar.companion_charge().config(state='normal') # reset the color remover button self.action_bar.colour_remove().config(state='normal') def check_game_over(self): """Checks whether the game is over and shows an appropriate message box if so""" state = self._game.get_game_state() if state == self._game.GameState.WON: # load the gamewin music pygame.mixer.music.load('breaking slient.ogg') pygame.mixer.music.play() showinfo("Game Over!", "You won!!!") self._playing = False elif state == self._game.GameState.LOST: # load the gameover music pygame.mixer.music.load('gameOver.wav') pygame.mixer.music.play() showinfo( "Game Over!", f"You didn't reach the objective(s) in time. You connected {self._game.get_score()} points" ) self._playing = False def _drop_complete(self): """Handles the end of a drop animation""" # Need to check whether the game is over # check whether the game is over self.check_game_over() def _refresh_status(self): """Handles change in score""" # Normally, this should raise the following error: # raise NotImplementedError() # But so that the game can work prior to this method being implemented, # we'll just print some information # Sometimes I believe Python ignores all my comments :( # show the remaining objectives using get_status() function self._obj.draw(self._objectives.get_status()) # show the interval bar(max==6) bar_num = (20 - self._game.get_moves()) % 6 self.interval_bar.progress_bar(bar_num) # show the current score scores = self.info_panel.set_scores() scores.config(text=str(self._game.get_score())) # show the remaining moves moves = self.info_panel.remain_moves() moves.config(text=str(self._game.get_moves())) # if player choose to play without companion, then undo the following part if self._play_with_com == True: charge_num = self._game.companion.get_charge() for i in range(charge_num): self.interval_bar.com_charge_bar(i) # reset the companion when fully-charged if self._game.companion.is_fully_charged(): self._game.companion.reset() steps = self._game.companion.activate(self._game) self._refresh_status() return self.animate(steps) score = self._game.get_score() print("Score is now {}.".format(score)) # exit function def exit(self): """Ask exit or not when click exit button""" ans = messagebox.askokcancel('Verify exit', 'Really exit?') if ans: # close the game window self._master.destroy() def com_button(self): """Immediately activates the companion""" # set the button disabled after first use self.action_bar.companion_charge().config(state='disable') # charge the companion dot for 6 times to activate the companion self._game.companion.charge(6) charge_num = self._game.companion.get_charge() # change the interval bar for i in range(charge_num): self.interval_bar.com_charge_bar(i) self._game.companion.reset() steps = self._game.companion.activate(self._game) self._refresh_status() return self.animate(steps) def colour_activate(self): """Immediately activates (& removes) all dots of a random kind (colour)""" # set the button disabled after first use self.action_bar.colour_remove().config(state='disable') # generate a random kind kind = random.randint(1, 4) dead_cells = {(2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4), (4, 2), (4, 3), (4, 4), (0, 7), (1, 7), (6, 7), (7, 7)} # create a set to save all the positions to be activated to_activate = set() for i in range(0, 8): for j in range(0, 8): # generate a random position position = (i, j) # the position is not in dead_cells and its kind is the random kind if position not in dead_cells and self._game.grid[ position].get_dot().get_kind() == kind: # add the position into set to_activate.add(position) # activate all the position in set steps = self._game.activate_all(to_activate) return self.animate(steps)
def __init__(self, master): """Constructor Parameters: master (tk.Tk|tk.Frame): The parent widget """ self._master = master self._playing = True self._image_manager = ImageManager('images/dots/', loader=load_image) # Game self._size = (8, 8) counts = [20, 15, 20, 25] random.shuffle(counts) # Randomly pair counts with each kind of dot objectives = zip( [BasicDot(1), BasicDot(2), BasicDot(8), BasicDot(3)], counts) self._objectives = ObjectiveManager(objectives) # Define companions self._companions = { 'penguin': PenguinCompanion(max_charge=6), 'eskimo': EskimoCompanion(max_charge=6, dot_count=4), 'buffalo': BuffaloCompanion(max_charge=5, dot_count=5), 'captain': CaptainCompanion(max_charge=5, dot_count=4), 'aristotle': AristotleCompanion(max_charge=4, dot_count=2) } # Define dead cell maps dead_cells = { 'endless': {}, 'companion': {(2, 1), (2, 2), (3, 1), (3, 2), (5, 4), (5, 5), (5, 6)}, } # Define game types self._games = { 'endless': EndlessGame({BasicDot: 1}, size=self._size, dead_cells=dead_cells['endless'], kinds=(1, 2, 3, 4, 8)), 'companion': AdvancedGame( { BasicDot: 1, CompanionDot: COMPANION_DOT_RATE }, size=self._size, dead_cells=dead_cells['companion'], kinds=(1, 2, 3, 8), companion=random.choice(list(self._companions.values())), objectives=self._objectives, moves=20, ) } # Choose a initial game to play self._game_mode = 'companion' self._game = self._games[self._game_mode] # Info Panel self._info_panel = InfoPanel(master, image_manager=self._image_manager) self._info_panel.pack(expand=True, fill=tk.BOTH) self._info_panel.set_companion(self._game.companion.get_name()) self._info_panel.set_interval(self._game.companion.get_max_charge(), self._game.companion.get_charge()) # Grid View self._grid_view = AdvancedGridView(master, size=self._game.grid.size(), image_manager=self._image_manager) self._grid_view.pack() self.draw_grid() self.draw_grid_borders() # Action Panel self._action_bar = ActionBar(master) self._action_bar.pack() # Menu & Title self._main_menu = MainMenu(master) self._master.config(menu=self._main_menu) # Events self.bind_events() for game in self._games.values(): self.bind_game_events(game) # Set initial score again to trigger view update automatically self._refresh_status() # Set windows position to center self._update_title() self._move_to_center()
class DotsApp: """Top level GUI class for simple Dots & Co game""" def __init__(self, master, infoPanel, intervalBar): """Constructor Parameters: master (tk.Tk|tk.Frame): The parent widget """ self._master = master self._infoPanel = infoPanel self._infoPanel.init_window(master, self) self._intervalBar = intervalBar self._playing = True self._image_manager = ImageManager('images/dots/', loader=load_image) # Game counts = [10, 15, 25, 25] random.shuffle(counts) # randomly pair counts with each kind of dot objectives = zip( [BasicDot(1), BasicDot(2), BasicDot(4), BasicDot(3)], counts) self._objectives = ObjectiveManager(objectives) self._infoPanel.set_objectives( [self._objectives.get_status()[i][1] for i in range(4)]) # Game dead_cells = {(2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4), (4, 2), (4, 3), (4, 4), (0, 7), (1, 7), (6, 7), (7, 7)} self._game = DotGame({ButterflyDot: 1}, objectives=self._objectives, kinds=(1, 2, 3, 4), size=(8, 8), dead_cells=dead_cells) # The following code may be useful when you are implementing task 2: for i in range(0, 4): for j in range(0, 2): position = i, j self._game.grid[position].set_dot(ButterflyDot(3)) self._game.grid[(7, 3)].set_dot(ButterflyDot(1)) # Grid View self._grid_view = GridView(master, size=self._game.grid.size(), image_manager=self._image_manager) self._grid_view.pack() self._grid_view.draw(self._game.grid) self.draw_grid_borders() # Events self.bind_events() # Set initial score again to trigger view update automatically self._refresh_status() def draw_grid_borders(self): """Draws borders around the game grid""" borders = list(self._game.grid.get_borders()) # this is a hack that won't work well for multiple separate clusters outside = max(borders, key=lambda border: len(set(border))) for border in borders: self._grid_view.draw_border(border, fill=border != outside) def bind_events(self): """Binds relevant events""" self._grid_view.on('start_connection', self._drag) self._grid_view.on('move_connection', self._drag) self._grid_view.on('end_connection', self._drop) self._game.on('reset', self._refresh_status) self._game.on('complete', self._drop_complete) self._game.on('connect', self._connect) self._game.on('undo', self._undo) def _animation_step(self, step_name): """Runs for each step of an animation Parameters: step_name (str): The name (type) of the step """ # print(step_name) self._refresh_status() self.draw_grid() def animate(self, steps, callback=lambda: None): """Animates some steps (i.e. from selecting some dots, activating companion, etc. Parameters: steps (generator): Generator which yields step_name (str) for each step in the animation """ if steps is None: steps = (None for _ in range(1)) animation = create_animation(self._master, steps, delays=ANIMATION_DELAYS, delay=DEFAULT_ANIMATION_DELAY, step=self._animation_step, callback=callback) animation() def _drop(self, position): # pylint: disable=unused-argument """Handles the dropping of the dragged connection Parameters: position (tuple<int, int>): The position where the connection was dropped """ if not self._playing: return if self._game.is_resolving(): return self._grid_view.clear_dragged_connections() self._grid_view.clear_connections() self.animate(self._game.drop()) def _connect(self, start, end): """Draws a connection from the start point to the end point Parameters: start (tuple<int, int>): The position of the starting dot end (tuple<int, int>): The position of the ending dot """ if self._game.is_resolving(): return if not self._playing: return self._grid_view.draw_connection( start, end, self._game.grid[start].get_dot().get_kind()) def _undo(self, positions): """Removes all the given dot connections from the grid view Parameters: positions (list<tuple<int, int>>): The dot connects to remove """ for _ in positions: self._grid_view.undo_connection() def _drag(self, position): """Attempts to connect to the given position, otherwise draws a dragged line from the start Parameters: position (tuple<int, int>): The position to drag to """ if self._game.is_resolving(): return if not self._playing: return tile_position = self._grid_view.xy_to_rc(position) if tile_position is not None: cell = self._game.grid[tile_position] dot = cell.get_dot() if dot and self._game.connect(tile_position): self._grid_view.clear_dragged_connections() return kind = self._game.get_connection_kind() if not len(self._game.get_connection_path()): return start = self._game.get_connection_path()[-1] if start: self._grid_view.draw_dragged_connection(start, position, kind) @staticmethod def remove(*_): """Deprecated in 1.1.0""" raise DeprecationWarning("Deprecated in 1.1.0") def draw_grid(self): """Draws the grid""" self._grid_view.draw(self._game.grid) def reset(self): """Resets the game""" print("hello,start reset ") self._game.reset() self._infoPanel.set_score(0) self._infoPanel.set_remaining_moves(20) self._infoPanel.set_objectives( [self._objectives.get_status()[i][1] for i in range(4)]) self._playing = True def check_game_over(self): """Checks whether the game is over and shows an appropriate message box if so""" state = self._game.get_game_state() if state == self._game.GameState.WON: showinfo("Game Over!", "You won!!!") self._playing = False elif state == self._game.GameState.LOST: showinfo( "Game Over!", f"You didn't reach the objective(s) in time. You connected {self._game.get_score()} points" ) self._playing = False def _drop_complete(self): """Handles the end of a drop animation""" self.check_game_over() self._infoPanel.set_objectives( ([self._objectives.get_status()[i][1] for i in range(4)])) remaining_steps = self._game.get_moves() if remaining_steps > 0: self._intervalBar.next_step() self._infoPanel.set_remaining_moves(remaining_steps) # Useful for when implementing a companion # if self._game.companion.is_fully_charged(): # self._game.companion.reset() # # self._intervalBar.next_step() # self._refresh_status() # # return self.animate(steps) # Need to check whether the game is over # raise NotImplementedError() # no mercy for stooges def _refresh_status(self): """Handles change in score""" # Normally, this should raise the following error: # raise NotImplementedError() # But so that the game can work prior to this method being implemented, # we'll just print some information # Sometimes I believe Python ignores all my comments :( score = self._game.get_score() self._infoPanel.set_score(score)