當前位置: 妍妍網 > 碼農

Python 踩地雷遊戲

2024-02-09碼農

大家好!今天給你們帶來了使用pygame寫的踩地雷遊戲。

完整例項:

  • import pygameimport randomimport sysfrom collections import deque# 遊戲初始化pygame.init()# 設定視窗大小和標題cell_size = 20cols, rows = 20, 15width = cols * cell_sizeheight = rows * cell_size + 40# 額外空間用於顯示資訊screen = pygame.display.set_mode((width, height))pygame.display.set_caption("Minesweeper")# 顏色定義WHITE = (255, 255, 255)GRAY = (192, 192, 192)BLACK = (0, 0, 0)RED = (255, 0, 0)GREEN = (0, 255, 0)# 地雷數量和字型設定mines_count = 40font = pygame.font.SysFont("SimHei", 24) # 支持中文的字型defplace_mines(): mines = set()while len(mines) < mines_count: mine = (random.randint(0, cols - 1), random.randint(0, rows - 1)) mines.add(mine)return minesdefcalculate_hints(mines): hints = [[0for _ in range(cols)] for _ in range(rows)]for mine in mines: x, y = minefor dx in [-1, 0, 1]:for dy in [-1, 0, 1]: nx, ny = x + dx, y + dyif0 <= nx < cols and0 <= ny < rows and (nx, ny) notin mines: hints[ny][nx] += 1return hintsdefdraw_grid():for x in range(0, width, cell_size): pygame.draw.line(screen, GRAY, (x, 40), (x, height))for y in range(40, height, cell_size): pygame.draw.line(screen, GRAY, (0, y), (width, y))defdraw_cells(hints, revealed, flags, mines, show_mines):for y in range(rows):for x in range(cols): rect = pygame.Rect(x * cell_size, y * cell_size + 40, cell_size, cell_size)if (x, y) in revealed or (x, y) in show_mines: color = RED if (x, y) in mines else WHITE pygame.draw.rect(screen, color, rect)if hints[y][x] > 0and (x, y) notin mines: # Draw hints# 居中顯示數位1和2 hint_text = font.render(str(hints[y][x]), True, BLACK) text_rect = hint_text.get_rect(center=rect.center) screen.blit(hint_text, text_rect.topleft)else: pygame.draw.rect(screen, GRAY, rect) pygame.draw.rect(screen, BLACK, rect, 1)defdraw_info_panel(revealed): text = font.render(f"得分: {len(revealed)}", True, GREEN) screen.blit(text, (5, 10))defreveal_cells(x, y, hints, revealed, flags, mines):if (x, y) in mines or (x, y) in revealed:return queue = deque([(x, y)])while queue: x, y = queue.popleft()if (x, y) notin revealed: revealed.add((x, y))if hints[y][x] == 0:for dx in [-1, 0, 1]:for dy in [-1, 0, 1]: nx, ny = x + dx, y + dyif0 <= nx < cols and0 <= ny < rows: queue.append((nx, ny))defrestart_game(): new_mines = place_mines() new_hints = calculate_hints(new_mines)return new_mines, new_hints, set(), set(), set()defcheck_win_condition(mines, revealed):if len(revealed) + len(mines) == cols * rows:returnTruereturnFalsedefmain(): mines, hints, revealed, flags, show_mines = restart_game() running = True game_over = Falsewhile running:for event in pygame.event.get():if event.type == pygame.QUIT: running = Falseelif event.type == pygame.MOUSEBUTTONDOWN: x, y = event.pos col, row = x // cell_size, (y - 40) // cell_sizeif row >= 0andnot game_over:if event.button == 1: # Left clickif (col, row) notin flags: reveal_cells(col, row, hints, revealed, flags, mines)if (col, row) in mines: print("遊戲結束! 右鍵點選重新開始。") show_mines = mines.copy() # 顯示所有地雷 game_over = Trueelif event.button == 3: # Right clickif (col, row) notin revealed and (col, row) notin show_mines:if (col, row) in flags: flags.remove((col, row))else: flags.add((col, row))elif row >= 0and game_over and event.button == 3: # 重設遊戲 mines, hints, revealed, flags, show_mines = restart_game() game_over = False screen.fill(BLACK) draw_grid() draw_cells(hints, revealed, flags, mines, show_mines) draw_info_panel(revealed) pygame.display.flip() pygame.quit() sys.exit()if __name__ == "__main__": main()