def __init__(self, player_one: str, player_two: str): self.player_one = Player(player_one) self.player_two = Player(player_two) self.view = GameView(self) self.select_match = \ re.compile(r'^([0-7])\s([0-7])\s([\d])\s([LRUDlrud])\s*$') self.game_match = re.compile(r'^([0-7])\s([0-7])\s*$')
def test_viewIsRenderedWithoutException(self): try: view = GameView(gridDimensions=(4, 4)) view.render(self.grid) except: self.fail( "Instantiating view and rendering grid raised an exception")
def main(): # program runner global main_word, game_limit, game_hints, bool_index, game_score hm_app = QApplication(sys.argv) while True: view = GameView(game_limit, game_hints, game_score, H.word_output(main_word, bool_index)) view.show() Controller(view=view) print(main_word) hm_app.exec_() __start__()
def __init__(self): with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as self.s: self.s.connect(('127.0.0.1', 8123)) self.log: List[str] = [] self.view = GameView(self) p: packet.Packet = packet.receive(self.s) if isinstance(p, packet.WelcomePacket): self.login()
def __init__(self, master: tk.Tk, delay: int = 20): """Construct a tower defence game in a root window Parameters: master (tk.Tk): Window to place the game into """ self._master = master super().__init__(master, delay=delay) self._game = game = TowerGame() self.setup_menu() # create a game view and draw grid borders self._view = view = GameView(master, size=game.grid.cells, cell_size=game.grid.cell_size, bg='antique white') view.pack(side=tk.LEFT, expand=True) self.sidebar_container = tk.Frame(master) self.sidebar_container.pack(side=tk.LEFT, expand=True, fill='both') # Task 1.3 (Status Bar): instantiate status bar self._statusbar = statusbar = StatusBar(self.sidebar_container) statusbar.pack(side=tk.TOP, anchor=tk.N) # Task 1.5 (Play Controls): instantiate widgets here self._play_controls = playcontrols = PlayControls(self.sidebar_container, self.next_wave, self._toggle_paused) playcontrols.pack(side=tk.BOTTOM, anchor=tk.S) # bind game events game.on("enemy_death", self._handle_death) game.on("enemy_escape", self._handle_escape) game.on("cleared", self._handle_wave_clear) # Task 1.2 (Tower Placement): bind mouse events to canvas here self._view.bind("<Button-1>", self._left_click) self._view.bind("<Motion>", self._move) self._view.bind("<Leave>", self._mouse_leave) self._view.bind("<Button-2>", self._sell_tower) self._view.bind("<Button-3>", self._sell_tower) # Level self._level = MyLevel() self.select_tower(SimpleTower) view.draw_borders(game.grid.get_border_coordinates()) # Get ready for the game self._setup_game()
def __init__(self, master: tk.Tk, delay: int = 20): """Construct a tower defence game in a root window Parameters: master (tk.Tk): Window to place the game into """ self._master = master super().__init__(master, delay=delay) self._game = game = TowerGame() self.setup_menu() # create a game view and draw grid borders self._view = view = GameView(master, size=game.grid.cells, cell_size=game.grid.cell_size, bg='antique white') view.pack(side=tk.LEFT, expand=True) self._master.title("Towers") # initialise the status bar self._statusbar = StatusBar(master) self._statusbar.pack(side=tk.TOP) # Initialise the frame for the play, next wave buttown self._Frame = tk.Frame(self._master, bg="#4a2f48") self._Frame.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True) self._button_next_wave = tk.Button(self._Frame, text="Next Wave", command=self.next_wave) self._button_next_wave.pack(side=tk.LEFT, anchor=S, padx=(40, 0)) self._button_pause = tk.Button(self._Frame, text="Play", state=ACTIVE, command=self._toggle_paused) self._button_pause.pack(side=tk.LEFT, anchor=S) # initialise the shop window self._towers = [ SimpleTower, EnerygyTower, PulseTower, MissileTower, IceTower ] # Create views for each tower & store to update if availability changes shop = tk.Frame(self._master, bg="#4a2f48") shop.pack(fill=tk.X) self._tower_views = [] for tower_class in self._towers: tower = tower_class(self._game.grid.cell_size // 2) tower_view = ShopTowerView(shop, tower, click_command=lambda class_=tower_class: self.select_tower(class_)) tower_view.pack(fill=tk.BOTH) self._tower_views.append( (tower, tower_view) ) # Can use to check if tower is affordable when refreshing view # bind game events game.on("enemy_death", self._handle_death) game.on("enemy_escape", self._handle_escape) game.on("cleared", self._handle_wave_clear) # bind the game event to the functions self._view.bind("<Button-1>", self._left_click) self._view.bind("<Button-2>", self._right_click) self._view.bind("<Motion>", self._move) self._view.bind("<Leave>", self._mouse_leave) # Level self._level = MyLevel() self.select_tower(SimpleTower) view.draw_borders(game.grid.get_border_coordinates()) # Get ready for the game self._setup_game()
str(self._player_2_cards[i][lastIndex].getSuit())) image = pygame.image.load(img_string) screen.blit(image, ((DIST_BETWEEN_COLUMNS * (i + 1)) + (TRANS_COL_WIDTH / 4), (HEIGHT / 3.3) + ((lastIndex + 1) * DIST_BETWEEN_NUMBERS) + DIST_FROM_BOTTOM + 10)) except IndexError: pass def displaySideCard(self, screen, card): if card is None: SIDE_CARD_IMG = pygame.image.load('resources/backCard.gif') screen.blit(SIDE_CARD_IMG, (WIDTH - DIST_FROM_RIGHT_SIDE, HEIGHT // 2)) else: try: img_string = 'resources/{0}{1}.gif'.format( str(card.getRank()), str(card.getSuit())) image = pygame.image.load(img_string) screen.blit(image, (WIDTH - DIST_FROM_RIGHT_SIDE, HEIGHT // 2)) except IndexError: pass if __name__ == '__main__': play = Play() view = GameView() game = GameController(play, view, play.__getPlayer1Hands__(), play.__getPlayer2Hands__()) game.start()
def __init__(self, master: tk.Tk, delay: int = 20): """Construct a tower defence game in a root window Parameters: master (tk.Tk): Window to place the game into """ self._master = master super().__init__(master, delay=delay) self._game = game = TowerGame() self.setup_menu() # create a game view and draw grid borders self._view = view = GameView(master, size=game.grid.cells, cell_size=game.grid.cell_size, bg='antique white') view.pack(side=tk.LEFT, expand=True) # Task 1.3 (Status Bar): instantiate status bar # ... self._player = tk.Frame(master, bg='pink') self._player.pack(side=tk.LEFT, expand=True, fill=tk.BOTH) self._status = StatusBar(self._player) # Task 1.5 (Play Controls): instantiate widgets here # ... self._controlsArea = tk.Frame(self._player) self._controlsArea.pack(side=tk.BOTTOM) self._nextWave = tk.Button(self._controlsArea, text='Next wave', command=self.next_wave) self._nextWave.pack(side=tk.LEFT) self._pause = tk.Button(self._controlsArea, text='Play', command=self._toggle_paused) self._pause.pack(side=tk.LEFT) self._highscorefile = HighScoreManager() # bind game events game.on("enemy_death", self._handle_death) game.on("enemy_escape", self._handle_escape) game.on("cleared", self._handle_wave_clear) # Task 1.2 (Tower Placement): bind mouse events to canvas here # ... self._view.bind("<Motion>", self._move) self._view.bind("<Button-1>", self._left_click) self._view.bind("<Leave>", self._mouse_leave) self._view.bind("<Button-3>",self._right_click) # Level self._level = MyLevel() self.select_tower(SimpleTower) view.draw_borders(game.grid.get_border_coordinates()) # Get ready for the game self._setup_game() # Remove the relevant lines while attempting the corresponding section # Hint: Comment them out to keep for reference # Task 1.2 (Tower Placement): remove these lines towers = [ ([(2, 2), (3, 0), (4, 1), (4, 2), (4, 3)], MissileTower), ([(2, 5)], EnergyTower) ] for positions, tower in towers: for position in positions: game.place(position, tower_type=tower) # Task 1.5 (Tower Placement): remove these lines #game.queue_wave([], clear=True) #self.next_wave() # Task 1.5 (Play Controls): remove this line #self.start() #shop towers = [ SimpleTower, MissileTower, EnergyTower ] # Create views for each tower & store to update if availability changes self._tower_views = [] for tower_class in towers: tower = tower_class(self._game.grid.cell_size // 2) # bg=BACKGROUND_COLOUR, highlight="#4b3b4a", shopView = ShopTowerView(self._player, tower, click_command=lambda class_=tower_class: self.select_tower(class_)) shopView.pack(side=tk.TOP) # Can use to check if tower is affordable when refreshing view self._tower_views.append((tower, shopView)) self.refresh_view()
from controller import BasicController, UserController from ai_controller import AIController from game_model import GameModel from view import GameView if __name__ == '__main__': model = GameModel(board_size=30) view = GameView(model.board_size) # controller = UserController(model, view) controller = AIController(model, view, delay=0) controller.play()
def __init__(self, master: tk.Tk, delay: int = 20): """Construct a tower defence game in a root window Parameters: master (tk.Tk): Window to place the game into """ self._master = master master.title("Towers") super().__init__(master, delay=delay) self._game = game = TowerGame() self.setup_menu() # setup the HighScoreManager to process records. self._score_manager = high_score_manager.HighScoreManager() # create a game view and draw grid borders self._view = GameView(master, size=game.grid.cells, cell_size=game.grid.cell_size, bg='antique white') self._view.pack(side=tk.LEFT, expand=True) # Task 1.3 (Status Bar): instantiate status bar self._status_bar = StatusBar(master, bg='white', width=80, height=16) self._status_bar.pack(side=tk.TOP, fill=tk.X) # Task 1.5 (Play Controls): instantiate widgets here self._control_frame = tk.Frame(master, bg="#4B2E49") self._control_frame.pack(side=tk.BOTTOM, fill=tk.X) self._frame1 = tk.Frame(self._control_frame) self._frame1.pack(anchor=tk.CENTER) self._button1 = tk.Button(self._frame1, text='Next Wave', state=tk.NORMAL, command=self.next_wave) self._button1.pack(side=tk.LEFT, padx=1, pady=1) self._button2 = tk.Button(self._frame1, text='Play', state=tk.NORMAL, command=self._toggle_paused) self._button2.pack(side=tk.LEFT, padx=1, pady=1) # A frame for checkbox and it will be created by _show_checkbox method. self._frame2 = tk.Frame(self._control_frame) # bind game events game.on("enemy_death", self._handle_death) game.on("enemy_escape", self._handle_escape) game.on("cleared", self._handle_wave_clear) # Task 1.2 (Tower Placement): bind mouse events to canvas here self._view.bind("<Button-1>", self._left_click) self._view.bind("<Motion>", self._move) self._view.bind("<Leave>", self._mouse_leave) self._view.bind("<Button-3>", self._right_click) # instantiate shop bar self._shop = tk.Frame(master, bg='#4B2E49') self._shop.pack(side=tk.TOP, fill=tk.BOTH, expand=True) towers = [ SimpleTower, MissileTower, custom.CustomTower, custom.AdvancedTower ] self._tower_views = [] # Create views for each tower & store to update if availability changes for tower_class in towers: tower = tower_class(self._game.grid.cell_size // 2) tower_view = ShopTowerView(self._shop, tower, click_command=lambda class_=tower_class: self.select_tower(class_), bg="#4B2E49") tower_view.pack(fill=tk.X) self._tower_views.append((tower, tower_view)) # Level self._level = MyLevel() self.select_tower(SimpleTower) self._view.draw_borders(game.grid.get_border_coordinates()) # Get ready for the game self._setup_game()
def __init__(self, master: tk.Tk, delay: int = 20): """ Construct a tower defence game in a root window Parameters: master (tk.Tk): Window to place the game into """ #Initiating the basics of the GUI self._master = master master.title("Towers") master.maxsize(700, 400) master.minsize(700, 400) super().__init__(master, delay=delay) self._game = game = TowerGame() self.setup_menu() #Create a game view and draw grid borders to pack into a game frame self._game_frame = tk.Frame(master, bg="black") self._game_frame.pack(side=tk.LEFT, anchor=tk.NW, expand=True, fill=tk.BOTH) self._view = view = GameView(self._game_frame, size=game.grid.cells, cell_size=game.grid.cell_size, bg="light yellow") view.pack(side=tk.LEFT, expand=True) #Bind game events game.on("enemy_death", self._handle_death) game.on("enemy_escape", self._handle_escape) game.on("cleared", self._handle_wave_clear) #1.2 Bind mouse events to canvas view.bind("<Motion>", self._move) view.bind("<Leave>", self._mouse_leave) view.bind("<Button-1>", self._left_click) view.bind("<Button-3>", self._right_click) #Create Right Frame for all the stuff next to GameView self._right_frame = tk.Frame(master, bg="light blue") self._right_frame.pack(side=tk.RIGHT, anchor=tk.NE, expand=True, fill=tk.BOTH) #1.3 Status Bar self._up_frame = tk.Frame(self._right_frame, bg="pink") self._up_frame.pack(side=tk.TOP, expand=False, fill=tk.BOTH) self._down_frame = tk.Frame(self._right_frame, bg="pink") self._down_frame.pack(side=tk.TOP, expand=False, fill=tk.BOTH) self._lives_img = tk.PhotoImage(file="images/heart.gif") self._lives_image = tk.Button(self._down_frame, image=self._lives_img, bg="pink", command=self.buy_lives) self._lives_image.bind( "<Motion>", lambda event, : self.toggle_callback( event, self._lives_image, "violet")) self._lives_image.bind( "<Leave>", lambda event, : self.toggle_callback( event, self._lives_image, "pink")) self._status = StatusBar(self._up_frame, self._down_frame, self._lives_image, "images/coins.gif") self._status.pack(side=tk.TOP, anchor=tk.N, expand=True, fill=tk.BOTH) #1.5 Play Controls self._controls_frame = tk.Frame(self._right_frame, bg="light green") self._controls_frame.pack(side=tk.BOTTOM, fill=tk.BOTH, anchor=tk.S) self._button_frame = tk.Frame(self._controls_frame, bg="black") self._button_frame.pack(side=tk.BOTTOM, anchor=tk.S, expand=True) self._next_wave_button = tk.Button(self._button_frame, bg="white", text="Next Wave", command=self.next_wave) self._next_wave_button.pack(side=tk.LEFT, expand=True) self._next_wave_button.bind( "<Motion>", lambda event, : self.toggle_callback( event, self._next_wave_button, "grey")) self._next_wave_button.bind( "<Leave>", lambda event, : self.toggle_callback( event, self._next_wave_button, "white")) self._play_button = tk.Button(self._button_frame, bg="white", text="Play", command=self._toggle_paused) self._play_button.pack(side=tk.RIGHT, expand=True) self._play_button.bind( "<Enter>", lambda event, : self.toggle_callback( event, self._play_button, "grey")) self._play_button.bind( "<Leave>", lambda event, : self.toggle_callback( event, self._play_button, "white")) #Shop Frame (2.3) towers = [SimpleTower, MissileTower, EnergyTower, FireTower] self._shop_frame = tk.Frame(self._right_frame, bg="light blue") self._shop_frame.pack(fill=tk.BOTH) #Create views for each tower & store to update if availability changes self._tower_views = [] for tower_class in towers: tower = tower_class(self._game.grid.cell_size // 2) self._shop_view = ShopTowerView( self._shop_frame, tower, click_command=lambda event, class_=tower_class: self. select_tower(class_)) self._shop_view.pack(expand=True, fill=tk.BOTH) #Can use to check if tower is affordable when refreshing view self._tower_views.append((tower, self._shop_view)) #Getting ready for the game self.game_over_restart()
def __init__(self): self.model = SpiteAndMaliceModel() self.players = [HumanPlayer(), ComputerPlayer()] self.view = GameView(self.model, self.players)
def __init__(self, master: tk.Tk, delay: int = 20): """Construct a tower defence game in a root window Parameters: master (tk.Tk): Window to place the game into """ #Setting title of the Window master.title("Towers") self._master = master super().__init__(master, delay=delay) self._game = game = TowerGame() self.setup_menu() # create a game view and draw grid borders self._view = view = GameView(master, size=game.grid.cells, cell_size=game.grid.cell_size, bg='antique white') view.pack(side=tk.LEFT, expand=True) # Task 4.1 Postgraduate advanced feature. Initialise pygame and sounds pygame.init() mixer.init() self.build_sound = pygame.mixer.Sound("sound/build.wav") self.increase_coin = pygame.mixer.Sound("sound/coin.wav") self.decrease_life = pygame.mixer.Sound("sound/heart.wav") self.wave_m = pygame.mixer.Sound("sound/next_wave.wav") self.pause_play = pygame.mixer.Sound("sound/pause_play.wav") self.quit_m = pygame.mixer.Sound("sound/quit.wav") # Task 4.1 Postgraduate advanced feature. Play music pygame.mixer.music.load("sound/game_music.mp3") pygame.mixer.music.play(-1) # Task 1.3 (Status Bar): instantiate status bar # Put the status bar in a frame self._right_frame = tk.Frame(master, bg="white") self._right_frame.pack(fill=tk.BOTH, expand=True) self._status_bar = StatusBar(self._right_frame) self._status_bar.pack(side=tk.TOP) # Task 2.4 (High Score): instantiate highscore self._high_score = HighScoreManager() # Task 1.5 (Play Controls): instantiate widgets here # Create a frame for widgets self._bottom_frame = tk.Frame(master, bg=BACKGROUND_COLOUR) self._bottom_frame.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True) #Create button for next wave self._next_wave_btn = tk.Button(self._bottom_frame, text="Next Wave", state=tk.NORMAL, command=self.next_wave) self._next_wave_btn.pack(side=tk.LEFT, ipadx=10, padx=10, ipady=10, pady=10) #Create button for play/pause self._play_btn = tk.Button(self._bottom_frame, text="Pause", state=tk.NORMAL, command=self._toggle_paused) self._play_btn.pack(side=tk.LEFT, ipadx=10, padx=10, ipady=10) # bind game events game.on("enemy_death", self._handle_death) game.on("enemy_escape", self._handle_escape) game.on("cleared", self._handle_wave_clear) # Task 1.2 (Tower Placement): bind mouse events to canvas here # On leaving canvas hide mouse # On left click place tower # On right click sell tower self._view.bind('<Motion>', self._move) self._view.bind('<Leave>', self._mouse_leave) self._view.bind('<Button-1>', self._left_click) self._view.bind('<Button-3>', self._right_click) # Level self._level = MyLevel() #Choose tower on initialisation self.select_tower(SimpleTower) #Draw borders view.draw_borders(game.grid.get_border_coordinates()) # Get ready for the game self._setup_game() # Task 2.3 (Shop) Creating Shop #Store towers present in the game for Shop towers = [ SimpleTower, EnergyTower, PulseTower, MissileTower, SlowTower ] #Create frmae for Shop window self._right_middle_frame = tk.Frame(master, bg=BACKGROUND_COLOUR) self._right_middle_frame.pack(fill=tk.BOTH, expand=True) #Put shop in the frame created shop = tk.Frame(self._right_middle_frame, bg=BACKGROUND_COLOUR) shop.pack(side=tk.BOTTOM, fill=tk.X) # Create views for each tower & store to update if availability changes self._tower_views = [] for tower_class in towers: tower = tower_class(self._game.grid.cell_size // 2) view = ShopTowerView(shop, tower, bg=BACKGROUND_COLOUR, click_command=lambda class_=tower_class: self. select_tower(class_)) view.pack(fill=tk.X) self._tower_views.append( (tower, view) ) # Can use to check if tower is affordable when refreshing view # Task 1.4 On pressing delete(X) button in window prompt user before exit def callback(): """Prompt user on pressing delete(X)""" if messagebox.askokcancel("Quit", "Do you really wish to quit?"): self._high_score.save() pygame.mixer.Sound.play(self.quit_m) master.destroy() master.protocol("WM_DELETE_WINDOW", callback)
def __init__(self, master: tk.Tk, delay: int = 20): """Construct a tower defence game in a root window Parameters: master (tk.Tk): Window to place the game into """ self._master = master super().__init__(master, delay=delay) master.title("tkDefend") self._game = game = TowerGame() self._highscores = {} self.setup_menu() self._master.configure(menu=self._menu) #create a game view and draw grid borders self._view = view = GameView(master, size=game.grid.cells, cell_size=game.grid.cell_size, bg='#000033') #was antique white view.pack(side=tk.LEFT, expand=True) #have a menu frame on the right self._right_frame = tk.Frame(self._master) self._right_frame.pack(side=tk.RIGHT, expand=True, fill=tk.Y) #Task 1.3 (Status Bar): instantiate status bar self._status_bar = StatusBar(self._right_frame) #shop goes between status bar and control frame shop = tk.Frame(self._right_frame, bg="#ff6600") shop.pack(side=tk.TOP, expand = True, anchor=tk.N, fill=tk.BOTH) self._towers = towers = [ SimpleTower, SlowTower, InfernoTower, LaserTower, MissileTower, GunTower, ] self._towers.sort(key=lambda tower_class:tower_class.base_cost) #Create views for each tower & store to update if availability changes self._tower_views = [] for tower_class in towers: tower = tower_class(self._game.grid.cell_size // 2) #lambda class_=tower_class: self.select_tower(class_) view = ShopTowerView(shop, tower, lambda class_=tower_class: self.select_tower(class_), bg="#ff6600", highlightbackground="#4b3b4a",bd=0,highlightthickness=0) view.pack(fill=tk.X) #Used to check if tower is affordable when refreshing view self._tower_views.append((tower, view)) #Task 1.5 (Play Controls): instantiate widgets here self._control_frame = tk.Frame(self._right_frame) self._control_frame.pack(expand=True) self._wave_button = tk.Button(self._control_frame, text="next wave", command=self.next_wave) self._wave_button.pack(side=tk.LEFT) self._play_button_text = tk.StringVar() self._play_button_text.set("play") self._play_button = tk.Button(self._control_frame, textvariable=self._play_button_text, command=self._toggle_paused) self._play_button.pack(side=tk.RIGHT) #6.3 initiate upgrade dictionary to store upgrade controls for each tower self._upgrade_controls = {} #bind game events game.on("enemy_death", self._handle_death) game.on("enemy_escape", self._handle_escape) game.on("cleared", self._handle_wave_clear) #Task 1.2 (Tower Placement): bind mouse events to canvas here #Binds left click, mouse motion and mouse leave self._view.bind("<Button-1>", self._left_click) self._view.bind("<Motion>", self._move) #self._view.bind("<ButtonRelease-1>", self._mouse_leave) self._view.bind("<Leave>",self._mouse_leave) self._view.bind("<Button-2>", self._right_click) #high scores self._high_score_manager = HighScoreManager() #handling close window import sys if len(sys.argv) == 1: self._master.protocol("WM_DELETE_WINDOW", self._exit) #catching keyboard event Destroy #self._master.bind("<Destroy>", self._exit) #Level self._level = MyLevel() #self.select_tower(SimpleTower) self.select_tower(SimpleTower) self._view.draw_borders(game.grid.get_border_coordinates(), "#66ff66") #Get ready for the game self._setup_game() #laser count self._laser_count = 0
from controller import GameController import time square_width = 10 # pixels grid_width = 51 pixels_wide = square_width * grid_width ms_per_block = 2 # screen refreshes per move score_font_size = 14 if __name__ == '__main__': pygame.init() size = (pixels_wide, int(pixels_wide*1.08) )# + score_font_size + 14) screen = pygame.display.set_mode(size) model = GameModel(grid_width) view = GameView(model, screen, square_width) controller = GameController(model) running = True count = 0 while running: view.draw() for event in pygame.event.get(): # if event.type == pygame.QUIT: # running = False running = controller.handle_event(event) count += 1 if count == ms_per_block: model.update_snake() model.check_collision() count = 0
class Main: def __init__(self, player_one: str, player_two: str): self.player_one = Player(player_one) self.player_two = Player(player_two) self.view = GameView(self) self.select_match = \ re.compile(r'^([0-7])\s([0-7])\s([\d])\s([LRUDlrud])\s*$') self.game_match = re.compile(r'^([0-7])\s([0-7])\s*$') def play(self): # Note: Switch the 'DisplayMode' enum type before use. self.view.play() def swap_turn(self) -> None: self.player_one, self.player_two = self.player_two, self.player_one def judge(self): ## zeina: needs to be implemented ''' Returns a tuple with the first index being the winner and the second index being the loser. ''' if self.player_one.number_of_ships == 0: return (self.player_two, self.player_one) elif self.player_two.number_of_ships == 0: return (self.player_one, self.player_two) def game_over(self) -> bool: #not sure if its a necessary function to have return (self.player_one.number_of_ships == 0 or self.player_two.number_of_ships == 0) def on_loop(self): if self.game_over(): winner, loser = self.judge() def current_player(self) -> Player: return self.player_one def current_board(self) -> Board: return self.player_one.board def other_board(self) -> Board: return self.player_two.board def switch_stage(self, new_stage: DisplayMode, new_page=None): if new_stage == DisplayMode.Title: self.set_page(p.TitlePage(self.view.screen, self)) elif new_stage == DisplayMode.Selection: self.set_page(p.SelectionPage(self.view.screen, self)) elif new_stage == DisplayMode.BotSelection: self.set_page(p.BotSelectionPage(self.view.screen, self)) elif new_stage == DisplayMode.Gameplay: self.set_page(p.GameplayPage(self.view.screen, self)) elif new_stage == DisplayMode.Transiton: self.set_page(new_page) elif new_stage == DisplayMode.GameOver: self.set_page(p.GameOver(self.view.screen, self)) elif new_stage == DisplayMode.BotGameplay: self.set_page(p.BotGameplayPage(self.view.screen, self)) self.view.current_page.switch_stage() def set_page(self, stage: p.Stage): self.view.current_page = stage def add_ship(self, row, col, direction, ship: S.ShipAbstract) -> None: return self.player_one.add_ship(row, col, direction, ship) def parse_select(self, string) -> tuple: match = self.select_match.match(string) if not bool(match): print("Incorrect formatting for ship placement") print("Make sure ROW *SPACE* COL *SPACE* SHIP ID *SPACE* DIRECTION (U or D or L or R)") return None row, col, ship_num, d_string = match.groups() row, col, ship_num = int(row), int(col), int(ship_num) direction = direction_map.get(d_string.upper(), None) ship = self.get_ship(ship_num) if not ship: print("Invalid Ship Number") return None return (row, col, direction, ship) def parse_game(self, string) -> tuple: match = self.game_match.match(string) if not bool(match): print("Incorrect format for ship move. Make sure ROW *SPACE* COL") return None return tuple(map(int, match.groups())) def make_attack(self, row, col): return self.other_board().add_attack(row, col) def make_scout(self, row, col): return self.other_board().add_scout(row, col) def get_ship(self, ship_num: int) -> S.ShipAbstract: if ship_num == 5: return S.Carrier() elif ship_num == 4: return S.Battleship() elif ship_num == 3: return S.Cruiser() elif ship_num == 2: return S.Destroyer() elif ship_num == 1: return S.Scout() else: return None
def __init__(self, master: tk.Tk, delay: int = 20): """Construct a tower defence game in a root window Parameters: master (tk.Tk): Window to place the game into """ self._master = master super().__init__(master, delay=delay) master.title('Towers') self._game = game = TowerGame() self.setup_menu() # create a game view and draw grid borders self._view = view = GameView(master, size=game.grid.cells, cell_size=game.grid.cell_size, bg='antique white') view.pack(side=tk.LEFT, expand=True) self._right_frame = tk.Frame(master, bg=BACKGROUND_COLOUR) self._right_frame.pack(side=tk.LEFT, fill=tk.Y) # Task 2.4 (High Scores): load files into a high score manager instance self._high_score_manager = HighScoreManager() self._high_score_manager.load(self._high_score_manager._filename) # Task 1.3 (Status Bar): instantiate status bar self._status = status = StatusBar(self._right_frame) status.pack(side=tk.TOP, fill=tk.X, anchor=tk.N, expand=False) # Task 2.3 (Shop): instantiation towers = [SimpleTower, MissileTower, EnergyTower, SlowTower] shop = tk.Frame(self._right_frame) shop.pack(side=tk.TOP, anchor=tk.N, fill=tk.X) # Create views for each tower & store to update if availability changes self._tower_views = [] for tower_class in towers: tower = tower_class(self._game.grid.cell_size // 2) v = ShopTowerView(shop, tower, bg=BACKGROUND_COLOUR, highlight="#4b3b4a", click_command=lambda class_=tower_class: self. select_tower(class_)) v.pack(fill=tk.X) self._tower_views.append( (tower, v) ) # Can use to check if tower is affordable when refreshing view # Task 1.5 (Play Controls): instantiate widgets here self._control = control = tk.Frame(self._right_frame) self._next_wave = tk.Button(control, text="Next Wave", command=self.next_wave, font=("TkDefaultFont", 12, "normal")) self._next_wave.pack(side=tk.LEFT) self._play = tk.Button(control, text="Play", command=self._toggle_paused, font=("TkDefaultFont", 12, "normal")) self._play.pack(side=tk.LEFT) self._control.pack(side=tk.BOTTOM, anchor=tk.S) # Task 3.3 (Upgrade Tower): GUI self._upgrade_button = tk.Button(self._right_frame, text="Upgrade selected tower", state="disabled", command=self.upgrade_selected_tower, font=("TkDefaultFont", 12, "normal")) self._upgrade_button.pack(side=tk.BOTTOM, anchor=tk.S) self._selected_tower_level_up_cost = tk.Label( self._right_frame, text="Cost to upgrade: N/A", bg=BACKGROUND_COLOUR, fg="white", font=("TkDefaultFont", 12, "normal")) self._selected_tower_level_up_cost.pack(side=tk.BOTTOM, anchor=tk.S) self._selected_tower_level = tk.Label( self._right_frame, text="Selected tower level: None", bg=BACKGROUND_COLOUR, fg="white", font=("TkDefaultFont", 12, "normal")) self._selected_tower_level.pack(side=tk.BOTTOM, anchor=tk.S) # bind game events game.on("enemy_death", self._handle_death) game.on("enemy_escape", self._handle_escape) game.on("cleared", self._handle_wave_clear) # Task 1.2 (Tower Placement): bind mouse events to canvas here self._view.bind("<Motion>", self._move) self._view.bind("<Button-1>", self._left_click) self._view.bind("<Leave>", self._mouse_leave) # Task 2.1: bind mouse event self._view.bind("<Button-2>", self._sell_tower) # Level self._level = MyLevel() self.select_tower(SimpleTower) view.draw_borders(game.grid.get_border_coordinates()) # Get ready for the game self._setup_game() self._check_availability()
from model import GameModel from view import GameView import pprint pp = pprint.PrettyPrinter(indent=4) # just trying out model = GameModel() model.init() pp.pprint(model.generateGrid()) view = GameView() view.init() input()
def main() -> None: model = GameModel() controller = GameController(model) view = GameView(controller, board_size=300, grid_size=3)
class TowerGameApp(Stepper): """Top-level GUI application for a simple tower defence game""" # All private attributes for ease of reading _current_tower = None _paused = False _won = None _level = None _wave = None _score = None _coins = None _lives = None _master = None _game = None _view = None def __init__(self, master: tk.Tk, delay: int = 20): """Construct a tower defence game in a root window Parameters: master (tk.Tk): Window to place the game into """ self._master = master master.title("Towers") super().__init__(master, delay=delay) self._game = game = TowerGame() self.setup_menu() # setup the HighScoreManager to process records. self._score_manager = high_score_manager.HighScoreManager() # create a game view and draw grid borders self._view = GameView(master, size=game.grid.cells, cell_size=game.grid.cell_size, bg='antique white') self._view.pack(side=tk.LEFT, expand=True) # Task 1.3 (Status Bar): instantiate status bar self._status_bar = StatusBar(master, bg='white', width=80, height=16) self._status_bar.pack(side=tk.TOP, fill=tk.X) # Task 1.5 (Play Controls): instantiate widgets here self._control_frame = tk.Frame(master, bg="#4B2E49") self._control_frame.pack(side=tk.BOTTOM, fill=tk.X) self._frame1 = tk.Frame(self._control_frame) self._frame1.pack(anchor=tk.CENTER) self._button1 = tk.Button(self._frame1, text='Next Wave', state=tk.NORMAL, command=self.next_wave) self._button1.pack(side=tk.LEFT, padx=1, pady=1) self._button2 = tk.Button(self._frame1, text='Play', state=tk.NORMAL, command=self._toggle_paused) self._button2.pack(side=tk.LEFT, padx=1, pady=1) # A frame for checkbox and it will be created by _show_checkbox method. self._frame2 = tk.Frame(self._control_frame) # bind game events game.on("enemy_death", self._handle_death) game.on("enemy_escape", self._handle_escape) game.on("cleared", self._handle_wave_clear) # Task 1.2 (Tower Placement): bind mouse events to canvas here self._view.bind("<Button-1>", self._left_click) self._view.bind("<Motion>", self._move) self._view.bind("<Leave>", self._mouse_leave) self._view.bind("<Button-3>", self._right_click) # instantiate shop bar self._shop = tk.Frame(master, bg='#4B2E49') self._shop.pack(side=tk.TOP, fill=tk.BOTH, expand=True) towers = [ SimpleTower, MissileTower, custom.CustomTower, custom.AdvancedTower ] self._tower_views = [] # Create views for each tower & store to update if availability changes for tower_class in towers: tower = tower_class(self._game.grid.cell_size // 2) tower_view = ShopTowerView(self._shop, tower, click_command=lambda class_=tower_class: self.select_tower(class_), bg="#4B2E49") tower_view.pack(fill=tk.X) self._tower_views.append((tower, tower_view)) # Level self._level = MyLevel() self.select_tower(SimpleTower) self._view.draw_borders(game.grid.get_border_coordinates()) # Get ready for the game self._setup_game() # Remove the relevant lines while attempting the corresponding section # Hint: Comment them out to keep for reference # Task 1.2 (Tower Placement): remove these lines # towers = [ # ([(2, 2), (3, 0), (4, 1), (4, 2), (4, 3)], SimpleTower), # ([(2, 5)], MissileTower) # ] # # for positions, tower in towers: # for position in positions: # game.place(position, tower_type=tower) # Task 1.5 (Tower Placement): remove these lines # game.queue_wave([], clear=True) # self._wave = 4 - 1 # first (next) wave will be wave 4 # self.next_wave() # Task 1.5 (Play Controls): remove this line # self.start() def _toggle_paused(self, paused=None): """Toggles or sets the paused state Parameters: paused (bool): Toggles/pauses/unpauses if None/True/False, respectively """ if paused is None: paused = not self._paused # Task 1.5 (Play Controls): Reconfigure the pause button here if paused: self.pause() self._button2.config(text="Play") else: self.start() self._button2.config(text="Pause") self._paused = paused def _setup_game(self): """Sets up the game""" self._wave = 0 self._score = 0 self._coins = 200 self._lives = 100 self._won = False # Task 1.3 (Status Bar): Update status here self._status_bar.waves_update(self._wave, self._level.get_max_wave()) self._status_bar.score_update(self._score) self._status_bar.coin_update(self._coins) self._status_bar.life_update(self._lives) # Task 1.5 (Play Controls): Re-enable the play controls here (if they were ever disabled) self._button1.configure(state=tk.NORMAL) self._button2.configure(state=tk.NORMAL) self._game.reset() # Auto-start the first wave self.next_wave() self._toggle_paused(paused=True) # display each of the available towers self._available_towers() # destroy checkbox if it exist. self._frame2.destroy() def _available_towers(self): """display each of the available towers""" for tower in self._tower_views: if self._coins < tower[0].get_value(): tower[1].red_text(False) else: tower[1].red_text(True) # Task 1.4 (File Menu): Complete menu item handlers here (including docstrings!) def setup_menu(self): """Sets up the application menu""" # Task 1.4: construct file menu here menubar = tk.Menu(self._master) self._master.config(menu=menubar) filemenu = tk.Menu(menubar) menubar.add_cascade(label="File", menu=filemenu) filemenu.add_command(label="New Game", command=self._new_game) filemenu.add_command(label="Exit", command=self._exit) filemenu.add_command(label="HighScores", command=self._display) filemenu.add_command(label="Simple level", command=lambda: self._change_level(1)) filemenu.add_command(label="Intermediate level", command=lambda: self._change_level(2)) filemenu.add_command(label="Advanced level", command=lambda: self._change_level(3)) def _change_level(self, level): """Change the current game level. Parameters: level (int): the game level """ if level == 1: self._level = MyLevel() for tower in self._tower_views: tower[0].level = 1 tower[1].update_price() self._new_game() elif level == 2: self._level = IntermediateLevel() # change the level of each tower. for tower in self._tower_views: tower[0].level = 2 tower[1].update_price() self._new_game() elif level == 3: self._level = AdvancedLevel() # change the level of each tower. for tower in self._tower_views: tower[0].level = 3 tower[1].update_price() self._new_game() def _new_game(self): """Start a new game""" self._setup_game() self.refresh_view() def _exit(self): """Exit the current game""" if messagebox.askokcancel("EXIT", "Do you want to exit?"): self._master.destroy() def _display(self): """Creates a window to displays the names and scores of the top ten scoring players""" window = tk.Toplevel() window.minsize(height=200, width=400) window.title("High Scores") records = "" for record in self._score_manager.get_entries(): # Oder the records from top to bottom. records = records + "Name: {}, Score: {}, Data: {}\n".format( record['name'], record['score'], record['data']) label = tk.Label(window, text=records).pack() window.mainloop() def _show_checkbox(self, tower): """Show the checkbox when a player left-clicks on a tower in the grid Parameters: tower (AbstractTower): the current tower """ # Creates a frame for checkbox. self._frame2 = tk.Frame(self._control_frame) self._frame2.pack(side=tk.BOTTOM, anchor=tk.CENTER) label = tk.Label(self._frame2, text="Upgrade Tower:").pack(side=tk.TOP, fill=tk.X) # upgrade damage of SimpleTower or EnergyTower. if not (isinstance(tower, MissileTower) or isinstance(tower, custom.AdvancedTower)): var1 = tk.IntVar() button5 = tk.Checkbutton(self._frame2, text="increase damage: 10 coins", variable=var1).pack(side=tk.LEFT) button6 = tk.Button( self._frame2, text='submit', state=tk.NORMAL, command=lambda: self._update_damage(var1.get(), tower)).pack( side=tk.LEFT) # upgrade cool down time of MissileTower or SlowTower. if isinstance(tower, MissileTower) or isinstance( tower, custom.AdvancedTower): var2 = tk.IntVar() button7 = tk.Checkbutton(self._frame2, text="reduce cool down time: 10 coins", variable=var2).pack(side=tk.LEFT) button8 = tk.Button(self._frame2, text='submit', state=tk.NORMAL, command=lambda: self._update_cool_time( var2.get(), tower)).pack(side=tk.LEFT) def _update_damage(self, var, tower): """Update the damage of selected tower. Parameters: var (int): the value of Checkbutton tower (AbstractTower): the selected tower """ if var == 1: # print(111) tower.base_damage = tower.base_damage + 5 self._coins = self._coins - 10 self.refresh_view() self._available_towers() self._frame2.destroy() elif var == 0: self._frame2.destroy() def _update_cool_time(self, var, tower): """Update the cool down time of selected tower. Parameters: var (int): the value of Checkbutton tower (AbstractTower): the selected tower """ if var == 1 and tower.cool_down_steps > 2: tower.cool_down_steps = tower.cool_down_steps - 2 self._coins = self._coins - 10 self.refresh_view() self._available_towers() self._frame2.destroy() elif tower.cool_down_steps <= 2: messagebox.showinfo("Message", "cool down time is already the minimum") self._frame2.destroy() elif var == 0: self._frame2.destroy() def refresh_view(self): """Refreshes the game view""" if self._step_number % 2 == 0: self._view.draw_enemies(self._game.enemies) self._view.draw_towers(self._game.towers) self._view.draw_obstacles(self._game.obstacles) def _step(self): """ Perform a step every interval Triggers a game step and updates the view Returns: (bool) True if the game is still running """ self._game.step() self.refresh_view() return not self._won # Task 1.2 (Tower Placement): Complete event handlers here (including # docstrings!) Event handlers: _move, _mouse_leave, _left_click def _right_click(self, event): """ Handles the mouse right click to remove the current tower. Parameter: event (tk.Event): Tkinter mouse event """ position = event.x, event.y cell_position = self._game.grid.pixel_to_cell(position) self._coins = self._coins + self._game.towers.get( cell_position).get_value() * 0.8 self._game.remove(cell_position) # display each of the available towers self._available_towers() def _move(self, event): """ Handles the mouse moving over the game view canvas Parameter: event (tk.Event): Tkinter mouse event """ if self._current_tower.get_value() > self._coins: return # move the shadow tower to mouse position position = event.x, event.y self._current_tower.position = position legal, grid_path = self._game.attempt_placement(position) # find the best path and covert positions to pixel positions path = [ self._game.grid.cell_to_pixel_centre(position) for position in grid_path.get_shortest() ] # Task 1.2 (Tower placement): Draw the tower preview here self._view.draw_preview(self._current_tower, legal) self._view.draw_path(path) def _mouse_leave(self, event): """" Handles the mouse left click to place the current tower. Parameter: event (tk.Event): Tkinter mouse event """ # Task 1.2 (Tower placement): Delete the preview # Hint: Relevant canvas items are tagged with: 'path', 'range', 'shadow' # See tk.Canvas.delete (delete all with tag) self._view.delete('path', 'range', 'shadow') def _left_click(self, event): """" Handles the mouse left click to place the current tower or active the checkbox. Parameter: event (tk.Event): Tkinter mouse event """ # retrieve position to place tower if self._current_tower is None: return if self._coins < self._current_tower.get_value(): return position = event.x, event.y cell_position = self._game.grid.pixel_to_cell(position) if self._game.place(cell_position, tower_type=self._current_tower.__class__): # Task 1.2 (Tower Placement): Attempt to place the tower being previewed self._coins = self._coins - self._current_tower.get_value() # Store the initialized wave to the tower which we bought. self._game.towers.get(cell_position).my_wave = self._wave self.refresh_view() # display each of the available towers self._available_towers() else: # show the checkBox for the selected tower. tower = self._game.towers.get(cell_position) if tower.base_cost == 0: # aging tower cannot be upgrade. self._frame2.destroy() return self._frame2.destroy() self._show_checkbox(tower) def next_wave(self): """Sends the next wave of enemies against the player""" if self._wave == self._level.get_max_wave(): return self._wave += 1 # In intermediate game level, the maximum age of tower is 15 waves. # In advanced game level, the maximum age of tower is 10 waves. if isinstance(self._level, IntermediateLevel): for tower in self._game.towers.values(): if self._wave - tower.my_wave > 14: tower.tower_aging() elif isinstance(self._level, AdvancedLevel): for tower in self._game.towers.values(): if self._wave - tower.my_wave > 9: tower.tower_aging() self.refresh_view() # Task 1.3 (Status Bar): Update the current wave display here self._status_bar.waves_update(self._wave, self._level.get_max_wave()) # Task 1.5 (Play Controls): Disable the add wave button here (if this is the last wave) if self._wave == self._level.get_max_wave(): self._button1.configure(state=tk.DISABLED) # Generate wave and enqueue wave = self._level.get_wave(self._wave) for step, enemy in wave: enemy.set_cell_size(self._game.grid.cell_size) self._game.queue_wave(wave) def select_tower(self, tower): """ Set 'tower' as the current tower Parameters: tower (AbstractTower): The new tower type """ self._current_tower = tower(self._game.grid.cell_size) def _handle_death(self, enemies): """ Handles enemies dying Parameters: enemies (list<AbstractEnemy>): The enemies which died in a step """ bonus = len(enemies)**.5 for enemy in enemies: self._coins += enemy.points self._score += int(enemy.points * bonus) # Task 1.3 (Status Bar): Update coins & score displays here self._status_bar.score_update(self._score) self._status_bar.coin_update(self._coins) # display each of the available towers self._available_towers() def _handle_escape(self, enemies): """ Handles enemies escaping (not being killed before moving through the grid Parameters: enemies (list<AbstractEnemy>): The enemies which escaped in a step """ self._lives -= len(enemies) if self._lives < 0: self._lives = 0 # Task 1.3 (Status Bar): Update lives display here self._status_bar.life_update(self._lives) # Handle game over if self._lives == 0: self._handle_game_over(won=False) def _handle_wave_clear(self): """Handles an entire wave being cleared (all enemies killed)""" if self._wave == self._level.get_max_wave(): self._handle_game_over(won=True) # Task 1.5 (Play Controls): remove this line # self.next_wave() def _handle_game_over(self, won=False): """Handles game over Parameter: won (bool): If True, signals the game was won (otherwise lost) """ self._won = won self.stop() # Task 1.4 (Dialogs): show game over dialog here self._button1.configure(state=tk.DISABLED) self._button2.configure(state=tk.DISABLED) if self._won: messagebox.showinfo("Message", "You won!") self._high_score_prompt() if self._lives == 0: messagebox.showinfo("Message", "Game over!") self._high_score_prompt() def _high_score_prompt(self): """Check if score is enough to get in the high scores list""" if self._score_manager.does_score_qualify(self._score): prompt = tk.simpledialog.askstring("Input", "What is your name?") # Add a new record into the high scores list. self._score_manager.add_entry(prompt, self._score)
def __init__(self, master: tk.Tk, delay: int = 30): """Construct a tower defence game in a root window Parameters: master (tk.Tk): Window to place the game into """ self._master = master master.title('Towers') super().__init__(master, delay=delay) self._game = game = TowerGame() self.setup_menu() # create a game view and draw grid borders self._view = view = GameView(master, size=game.grid.cells, cell_size=game.grid.cell_size, bg='antique white') view.pack(side=tk.LEFT, fill=tk.BOTH, expand=False) # # Task 1.3 (Status Bar): instantiate status bar self._level = MyLevel() self._status_bar = StatusBar(master, self._level.get_max_wave()) self._status_bar.pack(fill=tk.BOTH, side=tk.TOP, expand=False) self._play_and_upgrades = tk.Frame(master, bg='white', height=40, width=200) self._play_and_upgrades.pack(side=tk.BOTTOM, expand=True, fill=tk.BOTH) self._pause_button = tk.Button(self._play_and_upgrades, text='Pause', command=self._toggle_paused) self._pause_button.pack(side=tk.LEFT, anchor=tk.N, expand=False) self._pause_button.place(x=160, y=0) self._next_wave_button = tk.Button(self._play_and_upgrades, text='Next Wave', command=self.next_wave) self._next_wave_button.pack(side=tk.LEFT, anchor=tk.N, expand=False) self._next_wave_button.place(x=90, y=0) #highscores object self._high_scores = HighScoreManager() #Used for fixing bug where clicking New Game would make game faster try: if self._new_game_called: pass except AttributeError: #raised when new_game hasn't been called self._new_game_count = 0 #whether upgrades has been called before. Whether to clear upgrade buttons #or not. self._called_before = 0 self._speed_upgrade = 0 self._simple_upgrade = 0 self._no_coins_ice = 0 self._no_coins_speed = 0 self._missile_upgrade = 0 self._no_coins_simple = 0 self._ice_upgrade = 0 self._confirm_upgrades = 0 #Shop Class instantiation self._towers = towers = [ MissileTower, IceTower, PulseTower, EnergyTower ] self._shop = tk.Frame(master, bg='purple') self._shop.pack(fill=tk.BOTH, side=tk.BOTTOM, expand=False) # ## Create views for each tower & store to update if availability changes # self._tower_views = [] # col = 0 # for tower_class in towers: # tower = tower_class(self._game.grid.cell_size) # self._shop_view = ShopTowerView(self._shop, tower_class, #highlight="#4b3b4a", # click_command=lambda class_=tower_class: self.select_tower(class_), bg=colours[col]) # self._shop_view.pack(fill=tk.BOTH, side=tk.TOP, expand=True) # self._tower_views.append((tower, self._shop_view)) # Can use to check if tower is affordable when refreshing view # col+=1 self._tower_views = [] col = 0 for tower_class in towers: # tower = tower_class(self._game.grid.cell_size // 2) tower = tower_class(30) view = ShopTowerView( self._shop, tower, bg='purple', #, highlight="#4b3b4a", click_command=lambda class_=tower_class: self.select_tower( class_)) view.pack(fill=tk.X) self._tower_views.append((tower, view)) col += 1 # Task 1.5 (Play Controls): instantiate widgets here # bind game events game.on("enemy_death", self._handle_death) game.on("enemy_escape", self._handle_escape) game.on("cleared", self._handle_wave_clear) # Task 1.2 (Tower Placement): bind mouse events to canvas here self._view.bind("<Button-1>", self._left_click) self._view.bind("<Motion>", self._move) self._view.bind("<Leave>", self._mouse_leave) self._view.bind("<Button-3>", self._right_click) # Level self._level = MyLevel() self.select_tower(MissileTower) self._view.draw_borders(game.grid.get_border_coordinates()) # Get ready for the game self._setup_game()
def __init__(self, master: tk.Tk, delay: int = 20): """Construct a tower defence game in a root window Parameters: master (tk.Tk): Window to place the game into """ self._master = master super().__init__(master, delay=delay) self._game = game = TowerGame() self.setup_menu() # create a game view and draw grid borders self._view = view = GameView(master, size=game.grid.cells, cell_size=game.grid.cell_size, bg='antique white') view.pack(side=tk.LEFT, expand=True) # Task 1.3 (Status Bar): instantiate status bar # ... # Task 1.5 (Play Controls): instantiate widgets here # ... # bind game events game.on("enemy_death", self._handle_death) game.on("enemy_escape", self._handle_escape) game.on("cleared", self._handle_wave_clear) # Task 1.2 (Tower Placement): bind mouse events to canvas here # ... # Level self._level = MyLevel() self.select_tower(SimpleTower) view.draw_borders(game.grid.get_border_coordinates()) # Get ready for the game self._setup_game() # Remove the relevant lines while attempting the corresponding section # Hint: Comment them out to keep for reference # Task 1.2 (Tower Placement): remove these lines towers = [ ([(2, 2), (3, 0), (4, 1), (4, 2), (4, 3)], SimpleTower), ([(2, 5)], MissileTower) ] for positions, tower in towers: for position in positions: self._game.place(position, tower_type=tower) # Task 1.5 (Tower Placement): remove these lines self._game.queue_wave([], clear=True) self._wave = 4 - 1 # first (next) wave will be wave 4 self.next_wave() # Task 1.5 (Play Controls): remove this line self.start()
def __init__(self, master: tk.Tk, delay: int = 20): """Construct a tower defence game in a root window Parameters: master (tk.Tk): Window to place the game into """ self._master = master super().__init__(master, delay=delay) self._highscore = highscore = HighScoreManager() highscore.load(filename='high_scores.json') self._game = game = TowerGame() master.title("Tower of Defence by Minjae Lee") self.setup_menu(master) # create a game view and draw grid borders self._view = view = GameView(master, size=game.grid.cells, cell_size=game.grid.cell_size, bg='antique white') view.pack(side=tk.LEFT, expand=True) # Task 1.3 (Status Bar): instantiate status bar self._status_bar = StatusBar(master) self._status_bar.pack(fill = tk.X) # Task 1.5 (Play Controls): instantiate widgets here self.play_control = tk.Frame(master, bg = 'white') self.play_control.pack(side = tk.BOTTOM, fill = tk.Y) self.click_next_wave = tk.Button(self.play_control, text = "Next Wave", command = self.next_wave) self.click_next_wave.pack(side = tk.LEFT) self.click_play = tk.Button(self.play_control, text = "Play", command =self._toggle_paused) self.click_play.pack(side = tk.LEFT) # bind game events game.on("enemy_death", self._handle_death) game.on("enemy_escape", self._handle_escape) game.on("cleared", self._handle_wave_clear) # Task 1.2 (Tower Placement): bind mouse events to canvas here self._view.bind('<Button-1>', self._left_click) self._view.bind('<Motion>', self._move) self._view.bind('<Leave>', self._mouse_leave) self._view.bind('<Button-3>', self._right_click) # Level self._level = MyLevel() self.select_tower(SimpleTower) view.draw_borders(game.grid.get_border_coordinates()) # Get ready for the game self._setup_game() towers = [ ] for positions, tower in towers: for position in positions: self._game.place(position, tower_type=tower) ## # Task 2.3 (ShopTowerView): instantiate gui here self.towers = [ SimpleTower, MissileTower, EnergyTower, PulseTower, TurretTower, CoinTower ] shop = tk.Frame(master) shop.pack(fill=tk.X) # Create views for each tower & store to update if availability changes self._tower_views = [] for tower_class in self.towers: tower = tower_class(self._game.grid.cell_size // 2) self._shop_view = view= ShopTowerView(shop, tower, bg=BACKGROUND_COLOUR, highlight="#4b3b4a", click_command=lambda class_=tower_class: self.select_tower(class_)) view.pack(fill=tk.X) self._tower_views.append((tower, view)) # Can use to check if tower is affordable when refreshing view
class SpiteAndMalice(object): " Controller class for the game " def __init__(self): self.model = SpiteAndMaliceModel() self.players = [HumanPlayer(), ComputerPlayer()] self.view = GameView(self.model, self.players) def run(self): " Lets go. " # find out which player goes first if Card.to_numeric_value(self.model.players[0][PAY_OFF][-1]) > Card.to_numeric_value( self.model.players[1][PAY_OFF][-1] ): self.model.active_player = 0 else: self.model.active_player = 1 prev_active = None while True: active_player = self.model.active_player other_player = int(not self.model.active_player) # special case for both human players, blank the screen if it's a new players turn if ( type(self.players[active_player]) == type(self.players[other_player]) == HumanPlayer and prev_active != active_player ): self.view.wait_screen() prev_active = active_player # draw the board for the human player(s) if type(self.players[active_player]) == HumanPlayer: self.view.draw_board(active_player) elif type(self.players[other_player]) == HumanPlayer: self.view.draw_board(other_player) # get the next move if type(self.players[active_player]) == HumanPlayer: player_move = self.players[active_player].play_card(self.view.select_group, self.view.target_group) else: game_state = self.model.build_view_for_player() player_move = self.players[active_player].play_card(game_state) if player_move == None: log.warn("Got None move. Ending") return # play the move try: self.model.place_card(player_move) except InvalidMove, inv: self.view.show_error(inv) continue # check for win if self.model.is_won(): self.view.game_over() return # mix completed stacks back in self.model.mix_into_stock() # fill player hand if empty, and not a discard hand = self.model.players[active_player][HAND] if player_move.to_pile != DISCARD and len(hand) == 0: self.model.fill_hand() # swap players if move was a discard if player_move.to_pile == DISCARD: # tell view and model to end the round self.model.swap_players() self.model.fill_hand()