Children and old people are not deceived. The main program is definitely less than 60 lines (and it is still the kind of blank line)!!!
Don't say much nonsense, just talk about the process.
1. Draw a horizontal line and a vertical line to separate the grid (please, Xiaobian. This is known to everyone. OK, can't you pick the key points to talk about!)
2. Create a 20 * 20 array, all initialized to 0, indicating a blank game map.
3. 40 mines are randomly generated in the map (X is used in the code implementation). Each time a mine is generated, the number of the square around it (not the square of the mine) should be added by 1.
4. Create a class to manage the grids that have not been clicked. Use the list to store the coordinates of all the grids that have not been clicked. After the mouse clicks a grid, judge the legitimacy of the location of the single machine. If it is legal, remove the coordinates of the grid clicked by the mouse from the list, representing that the grid has been clicked. Each time the screen is updated, the corresponding grid cover is drawn according to the elements in the list.
5. Create a class to manage the clicked grid, use a list to store the coordinates of all the clicked grids, and draw the corresponding pattern according to the array in 2 (if the corresponding number is 0, then don't draw anything, just display the background color).
6. Every time a grid is opened, if the number is 0, use the width search to display all the grids directly connected to it with the number of 0
Well, I don't want to say anything superfluous. More detailed explanations are presented in the form of comments in the corresponding code.
If you don't believe your own numbers, plus all the blank lines, the main program (the life-saving guy can't lose it!) The last line is also line 59 (this wave is actually licking blood on the blade tip!!!)
import sys #Call the exit() function to end the game import pygame from covers import Cover #Cover on the surface when the square is not clicked from map_of_game import Map #Map inside the game box from settings import setting #Game parameter settings class Game: """Manage the main program of the game""" def __init__(self): pygame.init() self.setting = setting() #Create the game main interface self.screen = pygame.display.set_mode(self.setting.screen_size) self.screen_rect = self.screen.get_rect() pygame.display.set_caption('mine clearance') self.covers = Cover(self.setting, self.screen) #Surface covering self.maps = Map(self.setting, self.covers, self.screen) # internal map def run_game(self): while True: self._event_check_() #Detection event self._update_screen_() #Update screen def _event_check_(self): for event in pygame.event.get(): if event.type == pygame.QUIT: #End the game sys.exit() elif event.type == pygame.MOUSEBUTTONDOWN: x, y = pygame.mouse.get_pos() #A mouse click event is detected, and the mouse position is passed in self.covers.delete(x, y) #Delete the cover on the corresponding box self.maps.add(x, y) #Add the game map under the cover of this position to the team to be displayed def _update_screen_(self): self.screen.fill(self.setting.background_color) #Fill background color for i in range(25): #Draw squares pygame.draw.line(self.screen, self.setting.line_color, [0, i * 25], [500, i * 25], self.setting.line_width) #Horizontal line pygame.draw.line(self.screen, self.setting.line_color, [i * 25, 0], [i * 25, 500], self.setting.line_width) #Vertical line self.maps.show() #Show the numbers under all the clicked squares self.covers.show() #Show the numbers that have not been clicked pygame.display.update() #Update the screen display and show the above work on the game interface if __name__ == '__main__': my_game = Game() my_game.run_game()
class setting: """A class that manages parameters in a game""" def __init__(self): self.screen_size = (500, 500) # Screen size: self.background_color = (255, 255, 255) # Background color self.line_width = 1 # Line thickness self.line_color = (120, 120,120) # line color self.block_width = 24 #Width of each square self.screen_color = (150, 150, 150) # Display interface color
import pygame class Cover: """Classes that manage game coverings""" def __init__(self, setting, screen): #Game parameter setting and game main interface self.setting = setting self.screen = screen self.covers =  # Stores the location of the cover of the square that has not been clicked for i in range(20): for j in range(20): self.covers.append([i, j]) #At the beginning, the entire interface was covered def delete(self, x, y): #Pass in the position of the stand-alone mouse to determine whether it is legal. If yes, delete the current box x = x // 25 y = y // 25 if [x, y] in self.covers: self.covers.remove([x, y]) def show(self): #Show all the squares that have not been clicked for cur in self.covers: pygame.draw.rect(self.screen, self.setting.screen_color, ((cur * 25, cur * 25), (24, 24)))
from random import randint import pygame from game_over import Over class Map: """Manage thunder and numbers in the game""" def __init__(self, setting, covers, screen): #Game parameters, game coverage, game interface self.setting = setting self.bg_color = self.setting.background_color self.screen = screen self.covers = covers #All initial values are 0 at the beginning, indicating that there is nothing in the current box self.maps = [[0 for _ in range(20)] for _ in range(20)] #In the state transition array, all (x+moves[i], y+moves[i]) represent the other 8 blocks surrounding the (x, y) block, #It is used to update the number on the square around the mine after it is randomly generated self.moves = [[-1, -1], [0, -1], [1, -1], [-1, 0], [1, 0], [-1, 1], [0, 1], [1, 1]] #What is stored is the subscript in the corresponding moves array of the upper, left, right and lower state transitions of (x,y) self.move_to = [1, 3, 4, 6] #Stores the current number box that needs to be displayed self.now_show =  #Click on the mine to end the game self.over = Over(self.screen) #Randomly generate game map self._born_map() def _born_map(self): """Randomly generated map""" for i in range(40): x = randint(0, 19) y = randint(0, 19) while self.maps[x][y] != 0: x = randint(0, 19) y = randint(0, 19) self.maps[x][y] = 'X' self._connect_(x, y) #Update figures around mines def _connect_(self, x, y): """Function to update numbers around mines""" for cur in self.moves: i = x + cur j = y + cur if i >= 0 and i < 20 and j >= 0 and j < 20 and self.maps[i][j] != 'X': self.maps[i][j] += 1 def add(self, x, y): #Pass in the position of the current mouse click to judge the validity. If it is legal, pass the left side of the corresponding box into the list to be displayed i = x // 25 j = y // 25 if i >= 0 and i < 20 and j >= 0 and j < 20: self.now_show.append([i, j]) if self.maps[i][j] == 0: self._add_connect_(i, j) #If a landmine is currently clicked, mark the landmine as a red square and display it. Pause the game for 3 seconds and automatically exit the game if self.maps[i][j] == 'X': pygame.draw.rect(self.screen, (255, 0, 0), ((i * 25, j * 25), (25, 25))) self.over.show() # The blank squares directly connected to (x,y) are also displayed def _add_connect_(self, x, y): que =  que.append([x, y]) while que: cur = que[-1] del (que[-1]) for k in self.move_to: i, j = cur + self.moves[k], cur + self.moves[k] if i >= 0 and i < 20 and j >= 0 and j < 20 and self.maps[i][j] == 0 and [i, j] not in self.now_show: self.now_show.append([i, j]) self.covers.delete(i * 25, j * 25) que.append([i, j]) def show(self): """Display the generated map on the screen""" for cur in self.now_show: i = cur j = cur if self.maps[i][j] == 0: continue else: self.msg = str(self.maps[i][j]) self.font = pygame.font.SysFont(None, 45) self.font_image = self.font.render(self.msg, True, (60, 0, 0), None) self.image_ract = self.font_image.get_rect() self.image_ract.x = i * 25 self.image_ract.y = j * 25 self.image_ract.width = 24 self.image_ract.height = 24 self.screen.blit(self.font_image, self.image_ract)
import sys #End the game from time import sleep #Pause the game import pygame class Over: """Class that controls the end of the game""" def __init__(self, screen): #Game main interface self.is_over = False self.screen = screen self.screen_rect = self.screen.get_rect() self.msg = 'GAME OVER' #Render the text 'GAME OVER' to the game main interface self.font = pygame.font.SysFont(None, 48) self.image = self.font.render(self.msg, True, (100, 0, 0), (0, 0, 60)) self.rect = self.image.get_rect() self.rect.center = self.screen_rect.center #Place text in the center of the interface def show(self): #When you encounter a bomb, the game ends. Before the end, mark the bomb that the player encounters with a red square and draw it before the end self.screen.blit(self.image, self.rect) pygame.display.update() sleep(3) sys.exit()
See here, don't want to praise!!! (sobbing)