From 8547761458888ce21b24516010b5b80059be216f Mon Sep 17 00:00:00 2001 From: filifa Date: Tue, 19 Mar 2024 20:38:20 -0500 Subject: [PATCH] Add user options to set rows, columns, and mines --- board.py | 4 +- main.py | 130 +++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 99 insertions(+), 35 deletions(-) diff --git a/board.py b/board.py index 4511024..23b6033 100644 --- a/board.py +++ b/board.py @@ -4,7 +4,7 @@ import time from square import Square class Board: - def __init__(self, size, square_size, surface): + def __init__(self, size, mines, surface, square_size=40): self.surface = surface self.size = size self.square_size = square_size @@ -15,7 +15,7 @@ class Board: self.game_started = False self.unclicked_squares = size[0] * size[1] - self.total_mines = round(.2*self.unclicked_squares) + self.total_mines = mines len_x = self.square_size*size[1] len_y = self.square_size*size[0] diff --git a/main.py b/main.py index 1e98a03..d522e2f 100755 --- a/main.py +++ b/main.py @@ -1,47 +1,111 @@ #!/usr/bin/env python3 import pygame +import tkinter +from tkinter import messagebox import sys from pygame.locals import * from square import Square from board import Board -pygame.init() -# Pygame/ALSA has a bug that results in high CPU usage. This line reduces the -# CPU usage -pygame.mixer.quit() +def start_game(rows, cols, mines): + pygame.init() + # Pygame/ALSA has a bug that results in high CPU usage. This line reduces + # the CPU usage + pygame.mixer.quit() -DISPLAYSURF = pygame.display.set_mode((1280, 720)) -DISPLAYSURF.fill((185,185,185)) -pygame.display.set_caption("Minesweeper") + DISPLAYSURF = pygame.display.set_mode((1280, 720)) + DISPLAYSURF.fill((185,185,185)) + pygame.display.set_caption("Minesweeper") -board = Board((16, 31), 40, DISPLAYSURF) -# board = Board((9, 10), 48, DISPLAYSURF) + board = Board((rows, cols), mines, DISPLAYSURF) -# Prevents mouse movement from counting as an event, reducing CPU usage -pygame.event.set_blocked(MOUSEMOTION) + # Prevents mouse movement from counting as an event, reducing CPU usage + pygame.event.set_blocked(MOUSEMOTION) -while True: - board.update_mine_counter() - board.update_timer() - board.check_for_win() - pygame.display.update() + while True: + board.update_mine_counter() + board.update_timer() + board.check_for_win() + pygame.display.update() - # TODO: Add options to play again - if board.game_lost: - print("You lose") - break - elif board.game_won: - print("You win") - break + if board.game_lost or board.game_won: + break - for event in pygame.event.get(): - if event.type == QUIT: - pygame.quit() - sys.exit() - elif event.type == MOUSEBUTTONUP and event.button == 1: - if not board.game_started: - board.place_mines(event.pos) - board.left_click(event.pos) - elif event.type == MOUSEBUTTONUP and event.button == 3: - board.right_click(event.pos) + for event in pygame.event.get(): + if event.type == QUIT: + pygame.quit() + sys.exit() + elif event.type == MOUSEBUTTONUP and event.button == 1: + if not board.game_started: + board.place_mines(event.pos) + board.left_click(event.pos) + elif event.type == MOUSEBUTTONUP and event.button == 3: + board.right_click(event.pos) + +def play_pressed(option_box): + row_input = int(option_box.children['!frame'].children['!spinbox'].get()) + col_input = int(option_box.children['!frame2'].children['!spinbox'].get()) + mine_input = int(option_box.children['!frame3'].children['!spinbox'].get()) + + max_mines = row_input * col_input - 1 + if mine_input > max_mines: + messagebox.showerror("Input Error", + "Board is too small for this many mines!") + return + + option_box.destroy() + start_game(row_input, col_input, mine_input) + +def main(): + while True: + option_box = tkinter.Tk() + + # Sets up row number input + row_frame = tkinter.Frame(option_box) + row_frame.pack() + row_label = tkinter.Label(row_frame, text="Rows:") + row_label.pack(side=tkinter.LEFT) + rows = tkinter.Spinbox(row_frame, from_=1, to=99, width=2) + rows.pack(side=tkinter.LEFT) + + # Sets up column number input + col_frame = tkinter.Frame(option_box) + col_frame.pack() + col_label = tkinter.Label(col_frame, text="Columns:") + col_label.pack(side=tkinter.LEFT) + cols = tkinter.Spinbox(col_frame, from_=1, to=99, width=2) + cols.pack(side=tkinter.LEFT) + + # Sets up mine number input + # TODO: Set default number of mines (20% of board) + mine_frame = tkinter.Frame(option_box) + mine_frame.pack() + mine_label = tkinter.Label(mine_frame, text="Mines:") + mine_label.pack(side=tkinter.LEFT) + mines = tkinter.Spinbox(mine_frame, from_=0, to=9800, width=4) + mines.pack(side=tkinter.LEFT) + + # The lambda is so play_pressed(option_box) is not immediately executed + # Otherwise the window will close early + start_button = tkinter.Button(option_box, text="Play", + command=lambda: play_pressed(option_box)) + start_button.pack() + + option_box.mainloop() + + play_again_box = tkinter.Tk() + question = tkinter.Label(play_again_box, text="Play again?") + question.pack(side=tkinter.TOP) + + yes = tkinter.Button(play_again_box, text="Yes", + command=play_again_box.destroy) + yes.pack(side=tkinter.LEFT) + + no = tkinter.Button(play_again_box, text="No", command=sys.exit) + no.pack(side=tkinter.RIGHT) + + play_again_box.mainloop() + +if __name__ == "__main__": + main()