# 原檔 ```python= import pygame import random pygame.init() bg_color = (192, 192, 192) grid_color = (128, 128, 128) game_width = 10 # Change this to increase size game_height = 10 # Change this to increase size numMine = 9 # Number of mines grid_size = 32 # Size of grid (WARNING: macke sure to change the images dimension as well) border = 16 # Top border top_border = 100 # Left, Right, Bottom border display_width = grid_size * game_width + border * 2 # Display width display_height = grid_size * game_height + border + top_border # Display height gameDisplay = pygame.display.set_mode((display_width, display_height)) # Create display timer = pygame.time.Clock() # Create timer pygame.display.set_caption("Minesweeper") # S Set the caption of window # Import files spr_emptyGrid = pygame.image.load("Sprites/empty.png") spr_flag = pygame.image.load("Sprites/flag.png") spr_grid = pygame.image.load("Sprites/Grid.png") spr_grid1 = pygame.image.load("Sprites/grid1.png") spr_grid2 = pygame.image.load("Sprites/grid2.png") spr_grid3 = pygame.image.load("Sprites/grid3.png") spr_grid4 = pygame.image.load("Sprites/grid4.png") spr_grid5 = pygame.image.load("Sprites/grid5.png") spr_grid6 = pygame.image.load("Sprites/grid6.png") spr_grid7 = pygame.image.load("Sprites/grid7.png") spr_grid8 = pygame.image.load("Sprites/grid8.png") spr_grid7 = pygame.image.load("Sprites/grid7.png") spr_mine = pygame.image.load("Sprites/mine.png") spr_mineClicked = pygame.image.load("Sprites/mineClicked.png") spr_mineFalse = pygame.image.load("Sprites/mineFalse.png") # Create global values grid = [] # The main grid mines = [] # Pos of the mines # Create funtion to draw texts def drawText(txt, s, yOff=0): screen_text = pygame.font.SysFont("Calibri", s, True).render(txt, True, (0, 0, 0)) rect = screen_text.get_rect() rect.center = (game_width * grid_size / 2 + border, game_height * grid_size / 2 + top_border + yOff) gameDisplay.blit(screen_text, rect) # Create class grid class Grid: def __init__(self, xGrid, yGrid, type): self.xGrid = xGrid # X pos of grid self.yGrid = yGrid # Y pos of grid self.clicked = False # Boolean var to check if the grid has been clicked self.mineClicked = False # Bool var to check if the grid is clicked and its a mine self.mineFalse = False # Bool var to check if the player flagged the wrong grid self.flag = False # Bool var to check if player flagged the grid # Create rectObject to handle drawing and collisions self.rect = pygame.Rect(border + self.xGrid * grid_size, top_border + self.yGrid * grid_size, grid_size, grid_size) self.val = type # Value of the grid, -1 is mine def drawGrid(self): # Draw the grid according to bool variables and value of grid if self.mineFalse: gameDisplay.blit(spr_mineFalse, self.rect) else: if self.clicked: if self.val == -1: if self.mineClicked: gameDisplay.blit(spr_mineClicked, self.rect) else: gameDisplay.blit(spr_mine, self.rect) else: if self.val == 0: gameDisplay.blit(spr_emptyGrid, self.rect) elif self.val == 1: gameDisplay.blit(spr_grid1, self.rect) elif self.val == 2: gameDisplay.blit(spr_grid2, self.rect) elif self.val == 3: gameDisplay.blit(spr_grid3, self.rect) elif self.val == 4: gameDisplay.blit(spr_grid4, self.rect) elif self.val == 5: gameDisplay.blit(spr_grid5, self.rect) elif self.val == 6: gameDisplay.blit(spr_grid6, self.rect) elif self.val == 7: gameDisplay.blit(spr_grid7, self.rect) elif self.val == 8: gameDisplay.blit(spr_grid8, self.rect) else: if self.flag: gameDisplay.blit(spr_flag, self.rect) else: gameDisplay.blit(spr_grid, self.rect) def revealGrid(self): self.clicked = True # Auto reveal if it's a 0 if self.val == 0: for x in range(-1, 2): if self.xGrid + x >= 0 and self.xGrid + x < game_width: for y in range(-1, 2): if self.yGrid + y >= 0 and self.yGrid + y < game_height: if not grid[self.yGrid + y][self.xGrid + x].clicked: grid[self.yGrid + y][self.xGrid + x].revealGrid() elif self.val == -1: # Auto reveal all mines if it's a mine for m in mines: if not grid[m[1]][m[0]].clicked: grid[m[1]][m[0]].revealGrid() def updateValue(self): # Update the value when all grid is generated if self.val != -1: for x in range(-1, 2): if self.xGrid + x >= 0 and self.xGrid + x < game_width: for y in range(-1, 2): if self.yGrid + y >= 0 and self.yGrid + y < game_height: if grid[self.yGrid + y][self.xGrid + x].val == -1: self.val += 1 def gameLoop(): gameState = "Playing" # Game state mineLeft = numMine # Number of mine left global grid # Access global var grid = [] global mines t = 0 # Set time to 0 # Generating mines mines = [[random.randrange(0, game_width), random.randrange(0, game_height)]] for c in range(numMine - 1): pos = [random.randrange(0, game_width), random.randrange(0, game_height)] same = True while same: for i in range(len(mines)): if pos == mines[i]: pos = [random.randrange(0, game_width), random.randrange(0, game_height)] break if i == len(mines) - 1: same = False mines.append(pos) # Generating entire grid for j in range(game_height): line = [] for i in range(game_width): if [i, j] in mines: line.append(Grid(i, j, -1)) else: line.append(Grid(i, j, 0)) grid.append(line) # Update of the grid for i in grid: for j in i: j.updateValue() # Main Loop while gameState != "Exit": # Reset screen gameDisplay.fill(bg_color) # User inputs for event in pygame.event.get(): # Check if player close window if event.type == pygame.QUIT: gameState = "Exit" # Check if play restart if gameState == "Game Over" or gameState == "Win": if event.type == pygame.KEYDOWN: if event.key == pygame.K_r: gameState = "Exit" gameLoop() else: if event.type == pygame.MOUSEBUTTONUP: for i in grid: for j in i: if j.rect.collidepoint(event.pos): if event.button == 1: # If player left clicked of the grid j.revealGrid() # Toggle flag off if j.flag: mineLeft += 1 j.falg = False # If it's a mine if j.val == -1: gameState = "Game Over" j.mineClicked = True elif event.button == 3: # If the player right clicked if not j.clicked: if j.flag: j.flag = False mineLeft += 1 else: j.flag = True mineLeft -= 1 # Check if won w = True for i in grid: for j in i: j.drawGrid() if j.val != -1 and not j.clicked: w = False if w and gameState != "Exit": gameState = "Win" # Draw Texts if gameState != "Game Over" and gameState != "Win": t += 1 elif gameState == "Game Over": drawText("Game Over!", 50) drawText("R to restart", 35, 50) for i in grid: for j in i: if j.flag and j.val != -1: j.mineFalse = True else: drawText("You WON!", 50) drawText("R to restart", 35, 50) # Draw time s = str(t // 15) screen_text = pygame.font.SysFont("Calibri", 50).render(s, True, (0, 0, 0)) gameDisplay.blit(screen_text, (border, border)) # Draw mine left screen_text = pygame.font.SysFont("Calibri", 50).render(mineLeft.__str__(), True, (0, 0, 0)) gameDisplay.blit(screen_text, (display_width - border - 50, border)) pygame.display.update() # Update screen timer.tick(15) # Tick fps gameLoop() pygame.quit() quit() ```