Add user options to set rows, columns, and mines

This commit is contained in:
filifa 2024-03-19 20:38:20 -05:00
parent af0ec4a135
commit 8547761458
2 changed files with 99 additions and 35 deletions

View File

@ -4,7 +4,7 @@ import time
from square import Square from square import Square
class Board: class Board:
def __init__(self, size, square_size, surface): def __init__(self, size, mines, surface, square_size=40):
self.surface = surface self.surface = surface
self.size = size self.size = size
self.square_size = square_size self.square_size = square_size
@ -15,7 +15,7 @@ class Board:
self.game_started = False self.game_started = False
self.unclicked_squares = size[0] * size[1] 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_x = self.square_size*size[1]
len_y = self.square_size*size[0] len_y = self.square_size*size[0]

130
main.py
View File

@ -1,47 +1,111 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import pygame import pygame
import tkinter
from tkinter import messagebox
import sys import sys
from pygame.locals import * from pygame.locals import *
from square import Square from square import Square
from board import Board from board import Board
pygame.init() def start_game(rows, cols, mines):
# Pygame/ALSA has a bug that results in high CPU usage. This line reduces the pygame.init()
# CPU usage # Pygame/ALSA has a bug that results in high CPU usage. This line reduces
pygame.mixer.quit() # the CPU usage
pygame.mixer.quit()
DISPLAYSURF = pygame.display.set_mode((1280, 720)) DISPLAYSURF = pygame.display.set_mode((1280, 720))
DISPLAYSURF.fill((185,185,185)) DISPLAYSURF.fill((185,185,185))
pygame.display.set_caption("Minesweeper") pygame.display.set_caption("Minesweeper")
board = Board((16, 31), 40, DISPLAYSURF) board = Board((rows, cols), mines, DISPLAYSURF)
# board = Board((9, 10), 48, DISPLAYSURF)
# Prevents mouse movement from counting as an event, reducing CPU usage # Prevents mouse movement from counting as an event, reducing CPU usage
pygame.event.set_blocked(MOUSEMOTION) pygame.event.set_blocked(MOUSEMOTION)
while True: while True:
board.update_mine_counter() board.update_mine_counter()
board.update_timer() board.update_timer()
board.check_for_win() board.check_for_win()
pygame.display.update() pygame.display.update()
# TODO: Add options to play again if board.game_lost or board.game_won:
if board.game_lost: break
print("You lose")
break
elif board.game_won:
print("You win")
break
for event in pygame.event.get(): for event in pygame.event.get():
if event.type == QUIT: if event.type == QUIT:
pygame.quit() pygame.quit()
sys.exit() sys.exit()
elif event.type == MOUSEBUTTONUP and event.button == 1: elif event.type == MOUSEBUTTONUP and event.button == 1:
if not board.game_started: if not board.game_started:
board.place_mines(event.pos) board.place_mines(event.pos)
board.left_click(event.pos) board.left_click(event.pos)
elif event.type == MOUSEBUTTONUP and event.button == 3: elif event.type == MOUSEBUTTONUP and event.button == 3:
board.right_click(event.pos) 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()