예제 #1
0
class GameWindow(object):
    def __init__(self):
        self.game_over = False

    def win(self):
        if not self.check_high_score():
            showinfo('You Win!', 'Congratulations, you won')
        self.game_over = True

    def lose(self):
        showinfo('You lose',
                 'BOOM! You stepped on a mine.\r\nYou Lost the game.')
        self.game_over = True

    def check_high_score(self):
        connection_string = settings.get_db_path(settings.storage_type)
        rows = settings.get_high_scores(connection_string,
                                        self.current_difficulty['name'],
                                        settings.storage['high_score_count'])
        skip = True
        dt = datetime.now() - self.start_time
        seconds = dt.seconds
        if len(rows) > settings.storage['high_score_count']:
            for row in rows:
                if row['seconds'] > seconds:
                    skip = False
                    break
        else:
            skip = False

        if not skip:
            dialog = EnterHighScore(self.current_difficulty['name'], seconds,
                                    self.root)
            self.root.wait_window(dialog.top)
            return True
        else:
            return False

    def open(self, col, row, event):
        if not self.game_over:
            self.grid.open(col, row)
            self.redraw_grid()
            if self.grid.get(col, row).is_bomb:
                self.lose()
            elif self.grid.get_count_remaining_to_open() == 0:
                self.win()

    def toggle_flagged(self, col, row, event):
        if not self.game_over:
            self.grid.toggle_flagged(col, row)
            self.redraw_cell(col, row)

    def init_icons(self):
        file_path = os.path.dirname(os.path.realpath(__file__))
        self.icons = {}
        for i in range(1, 9):
            self.icons[i] = PhotoImage(
                file=os.path.join(file_path, f'../res/{i}.ppm'))
        self.icons['blank'] = PhotoImage(
            file=os.path.join(file_path, '../res/blank.ppm'))
        self.icons['bomb'] = PhotoImage(
            file=os.path.join(file_path, '../res/bomb.ppm'))
        self.icons['default'] = PhotoImage(
            file=os.path.join(file_path, '../res/default.ppm'))
        self.icons['flagged'] = PhotoImage(
            file=os.path.join(file_path, '../res/flagged.ppm'))
        self.icons['logo'] = PhotoImage(
            file=os.path.join(file_path, '../res/logo.gif'))

    def redraw_grid(self):
        for j in range(self.grid.height):
            for i in range(self.grid.width):
                self.redraw_cell(i, j)

    def redraw_cell(self, col, row):
        cell = self.grid_frame.nametowidget(f'cell_{col}_{row}')
        if self.grid.get(col, row).state == State.FLAGGED:
            icon = self.icons['flagged']
        elif self.grid.get(col, row).state == State.DEFAULT:
            icon = self.icons['default']
        else:
            bomb_count = self.grid.get_bomb_count(col, row)
            icon = self.icons['blank']
            if self.grid.get(col, row).is_bomb:
                icon = self.icons['bomb']
            elif bomb_count >= 1 and bomb_count <= 8:
                icon = self.icons[bomb_count]
        cell.config(image=icon)

    def show_about(self):
        dialog = About(self.root)
        self.root.wait_window(dialog.top)

    def show_help(self):
        HelpWindow(self.root)

    def show_high_scores(self):
        dialog = HighScore(self.root)
        self.root.wait_window(dialog.top)

    def change_difficulty(self):
        self.grid = Grid(self.current_difficulty['width'],
                         self.current_difficulty['height'])
        self.grid.seed_grid(self.current_difficulty['bombs'])

        icon = self.icons['default']
        for j in range(self.grid.height):
            for i in range(self.grid.width):
                cell = Label(self.grid_frame,
                             width=icon.width(),
                             height=icon.height(),
                             borderwidth=0,
                             image=icon,
                             name=f'cell_{i}_{j}')
                cell.bind('<Button-1>', partial(self.open, i, j))
                cell.bind('<Button-3>', partial(self.toggle_flagged, i, j))
                cell.grid(column=i, row=j, ipadx=0, ipady=0, padx=0, pady=0)

        self.redraw_grid()
        self.game_over = False
        self.start_time = datetime.now()

    def menu_change_difficulty(self):
        widgets = self.grid_frame.grid_slaves()
        for widget in widgets:
            widget.destroy()

        self.current_difficulty = settings.storage["difficulty"][
            self.difficulty_idx.get()]
        settings.storage["default_difficulty"] = self.current_difficulty[
            "name"]
        self.change_difficulty()

    def not_yet_implemented(self):
        showinfo('OK', 'This has not yet been implemented.')

    def build_gui(self):
        self.root = Tk()

        main_menu = Menu(self.root)
        game_menu = Menu(main_menu, tearoff=0)
        game_menu.add_command(label='New Game',
                              command=self.menu_change_difficulty)
        game_menu.add_command(label='High Scores',
                              command=self.show_high_scores)
        game_menu.add_separator()
        game_menu.add_command(label='Exit', command=self.root.quit)
        main_menu.add_cascade(label='Game', menu=game_menu)

        self.difficulty_idx = IntVar()
        difficulty_menu = Menu(main_menu, tearoff=0)
        for idx, item in enumerate(settings.storage['difficulty']):
            #difficulty_menu.add_radiobutton(label=item['name'], variable=self.current_difficulty, value=item, command=self.not_yet_implemented)
            difficulty_menu.add_radiobutton(
                label=item['name'],
                variable=self.difficulty_idx,
                value=idx,
                indicatoron=1,
                command=self.menu_change_difficulty)
            if item == self.current_difficulty:
                self.difficulty_idx.set(idx)
                print(f'Set Difficulty Index = {idx}')

        main_menu.add_cascade(label='Difficulty', menu=difficulty_menu)

        help_menu = Menu(main_menu, tearoff=0)
        help_menu.add_command(label='Index', command=self.show_help)
        help_menu.add_separator()
        help_menu.add_command(label='About', command=self.show_about)
        main_menu.add_cascade(label='Help', menu=help_menu)

        self.root.config(menu=main_menu)
        self.root.title('Minesweeper')

        self.init_icons()
        self.grid_frame = Frame()
        self.grid_frame.pack()

        self.change_difficulty()

        file_path = os.path.dirname(os.path.realpath(__file__))
        icon = PhotoImage(file=os.path.join(file_path, '../res/logo.gif'))
        self.root.icon = icon  # don't garbage collect me please.
        #self.icons['logo'] = icon
        self.root.tk.call('wm', 'iconphoto', self.root._w, self.icons['logo'])

    def run_game(self, default_difficulty):
        self.current_difficulty = reduce(
            lambda x, y: x
            if x['name'] == settings.storage['default_difficulty'] else y,
            settings.storage['difficulty'], settings.storage['difficulty'][0])
        self.build_gui()
        self.game_over = False
        self.root.mainloop()
예제 #2
0
    def test_seed_grid(self):
        my_grid = Grid(10, 20)
        my_grid.seed_grid(10)
        self.assertEqual(my_grid.get_count_bombs(), 10)

        with self.assertRaises(TypeError,
                               msg='Num_Bombs needs to be an integer.'):
            my_grid.seed_grid(1.1)
            my_grid.seed_grid(True)
            my_grid.seed_grid('stuff')
            my_grid.seed_grid([1, 2, 3])

        with self.assertRaises(ValueError, msg='Too many bombs.'):
            my_grid.seed_grid(300)

        with self.assertRaises(ValueError, msg='Too many bombs.'):
            my_grid.seed_grid(200)

        my_grid.seed_grid(199)
        self.assertEqual(my_grid.get_count_bombs(), 199)

        my_grid.seed_grid(0)
        self.assertEqual(my_grid.get_count_bombs(), 0)