基于python的扫雷游戏

游戏

游戏目标:

揭开所有非地雷的格子。
如果揭开地雷,游戏失败。
使用标记功能(🚩)来标记可能的地雷位置。

格子类型:

空白格子:表示周围没有地雷。
数字格子:显示周围 8 个格子中有多少地雷。
地雷格子:揭开后游戏失败。
标记格子:玩家标记为可能的地雷位置。

操作方式:

左键点击:揭开格子。
右键点击:标记或取消标记地雷。

界面

在这里插入图片描述

代码

import tkinter as tk
from tkinter import messagebox
import random

class Minesweeper:
    def __init__(self, root, width=10, height=10, mines=10):
        self.root = root
        self.width = width
        self.height = height
        self.mines = mines
        self.board = [[0 for _ in range(width)] for _ in range(height)]
        self.revealed = [[False for _ in range(width)] for _ in range(height)]
        self.flags = [[False for _ in range(width)] for _ in range(height)]
        self.game_over = False
        self.buttons = [[None for _ in range(width)] for _ in range(height)]
        self.remaining_mines = mines
        self.create_top_panel()
        self.place_mines()
        self.calculate_numbers()
        self.create_widgets()

    def create_top_panel(self):
        self.top_panel = tk.Frame(self.root, bg="lightgray")
        self.top_panel.grid(row=0, column=0, columnspan=self.width, sticky="ew")

        self.mine_label = tk.Label(self.top_panel, text=f"Mines: {self.remaining_mines}", font=("Arial", 12), bg="lightgray")
        self.mine_label.pack(side="left", padx=10)

        self.reset_button = tk.Button(self.top_panel, text="Reset", font=("Arial", 12), command=self.reset_game)
        self.reset_button.pack(side="right", padx=10)

    def place_mines(self):
        mines_placed = 0
        while mines_placed < self.mines:
            x = random.randint(0, self.width - 1)
            y = random.randint(0, self.height - 1)
            if self.board[y][x] != -1:
                self.board[y][x] = -1
                mines_placed += 1

    def calculate_numbers(self):
        for y in range(self.height):
            for x in range(self.width):
                if self.board[y][x] == -1:
                    continue
                count = 0
                for dy in [-1, 0, 1]:
                    for dx in [-1, 0, 1]:
                        if dy == 0 and dx == 0:
                            continue
                        ny, nx = y + dy, x + dx
                        if 0 <= ny < self.height and 0 <= nx < self.width and self.board[ny][nx] == -1:
                            count += 1
                self.board[y][x] = count

    def create_widgets(self):
        for y in range(self.height):
            for x in range(self.width):
                button = tk.Button(
                    self.root,
                    text="",
                    width=2,
                    height=1,
                    font=("Arial", 12, "bold"),
                    relief=tk.RAISED,
                    command=lambda x=x, y=y: self.reveal(x, y),
                )
                button.bind("<Button-3>", lambda event, x=x, y=y: self.toggle_flag(x, y))
                button.grid(row=y + 1, column=x, padx=1, pady=1)
                self.buttons[y][x] = button

    def reveal(self, x, y):
        if self.game_over or self.flags[y][x]:
            return
        if self.board[y][x] == -1:
            self.game_over = True
            self.buttons[y][x].config(text="💣", bg="red", relief=tk.SUNKEN)
            self.show_all_mines()
            messagebox.showinfo("Game Over", "You hit a mine! Game over.")
            return
        self.revealed[y][x] = True
        self.buttons[y][x].config(text=str(self.board[y][x]), relief=tk.SUNKEN, bg="lightgray")
        self.set_number_color(x, y)
        if self.board[y][x] == 0:
            for dy in [-1, 0, 1]:
                for dx in [-1, 0, 1]:
                    if 0 <= y + dy < self.height and 0 <= x + dx < self.width:
                        if not self.revealed[y + dy][x + dx]:
                            self.reveal(x + dx, y + dy)
        if self.check_win():
            messagebox.showinfo("Congratulations!", "You won!")

    def toggle_flag(self, x, y):
        if self.game_over or self.revealed[y][x]:
            return
        self.flags[y][x] = not self.flags[y][x]
        if self.flags[y][x]:
            self.buttons[y][x].config(text="🚩", fg="red")
            self.remaining_mines -= 1
        else:
            self.buttons[y][x].config(text="", fg="black")
            self.remaining_mines += 1
        self.mine_label.config(text=f"Mines: {self.remaining_mines}")

    def set_number_color(self, x, y):
        number = self.board[y][x]
        if number == 1:
            self.buttons[y][x].config(fg="blue")
        elif number == 2:
            self.buttons[y][x].config(fg="green")
        elif number == 3:
            self.buttons[y][x].config(fg="red")
        elif number == 4:
            self.buttons[y][x].config(fg="purple")
        elif number >= 5:
            self.buttons[y][x].config(fg="orange")

    def show_all_mines(self):
        for y in range(self.height):
            for x in range(self.width):
                if self.board[y][x] == -1:
                    self.buttons[y][x].config(text="💣", bg="yellow", relief=tk.SUNKEN)

    def check_win(self):
        for y in range(self.height):
            for x in range(self.width):
                if self.board[y][x] != -1 and not self.revealed[y][x]:
                    return False
        return True

    def reset_game(self):
        for y in range(self.height):
            for x in range(self.width):
                self.buttons[y][x].config(text="", bg="SystemButtonFace", relief=tk.RAISED, fg="black")
        self.board = [[0 for _ in range(self.width)] for _ in range(self.height)]
        self.revealed = [[False for _ in range(self.width)] for _ in range(self.height)]
        self.flags = [[False for _ in range(self.width)] for _ in range(self.height)]
        self.game_over = False
        self.remaining_mines = self.mines
        self.mine_label.config(text=f"Mines: {self.remaining_mines}")
        self.place_mines()
        self.calculate_numbers()

def main():
    root = tk.Tk()
    root.title("Minesweeper")
    game = Minesweeper(root)
    root.mainloop()

if __name__ == "__main__":
    main()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/944952.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【K8S系列】深入解析K8S服务的无状态与有状态

在容器编排领域&#xff0c;Kubernetes&#xff08;K8S&#xff09;无疑是占据主导地位的工具。它提供了强大的功能来管理和部署容器化应用程序&#xff0c;其中服务分类是理解和有效使用K8S的关键。K8S中的服务主要分为无状态服务和有状态服务&#xff0c;这两种类型在基础概念…

Linux第100步_Linux之设置LCD作为终端控制台和LCD背光调节

KMS是Kemmel Mode Setting的缩写&#xff0c;内核显示模式设置。它主要负责显示的控制&#xff0c;包括屏幕分辨率、屏幕刷新率和颜色深度等等。 CRTC是指显示控制器&#xff0c;在DRM里有多个显存&#xff0c;通过操作CRTC来控制要显示那个显存。 KMS包含了FB框架。DRM驱动默…

3_TCP/IP连接三次握手与断开四次挥手

TCP/IP 通信是网络通信的基础协议&#xff0c;分为以下主要步骤&#xff1a; 1、建立连接&#xff08;三次握手&#xff09; 目的&#xff1a;保证双方建立可靠的通信连接。 过程&#xff1a; 1>客户端发送 SYN&#xff1a;客户端向服务器发送一个 SYN&#xff08;同步&…

SpringCloud 系列教程:微服务的未来(三)IService接口的业务实现

本文将介绍 IService 接口的基本业务操作、复杂业务操作、Lambda 方法的使用以及批量增加操作&#xff0c;帮助开发者深入了解如何高效地利用 MyBatis-Plus 提供的功能进行数据库操作。无论是简单的单表查询&#xff0c;还是复杂的多表联动&#xff0c;甚至是大数据量的批量操作…

kubernetes学习-集群搭建部署(一)

一、开三台虚拟机进行试验&#xff08;centos7) 1、初始操作 # 关闭防火墙 systemctl stop firewalld systemctl disable firewalld# 关闭selinux sudo sed -i s/enforcing/disabled/ /etc/selinux/config # 永久 setenforce 0 # 临时# 关闭swap sudo swapoff -a # 临时 s…

【AUTOSAR 基础软件】Can模块详解(Can栈之驱动模块)

文章包含了AUTOSAR基础软件&#xff08;BSW&#xff09;中Can模块相关的内容详解。本文从AUTOSAR规范解析&#xff0c;ISOLAR-AB配置以及模块相关代码三个维度来帮读者清晰的认识和了解Can驱动软件模块。文中涉及的ISOLAR-AB配置以及生成的ARXML均依托于ETAS工具链&#xff0c;…

Vite内网ip访问,两种配置方式和修改端口号教程

目录 问题 两种解决方式 结果 总结 preview.host preview.port 问题 使用vite运行项目的时候&#xff0c;控制台会只出现127.0.0.1&#xff08;localhost&#xff09;本地地址访问项目。不可以通过公司内网ip访问&#xff0c;其他团队成员无法访问&#xff0c;这是因为没…

【maven】什么是坐标(依赖)继承与模块、web项目启动访问

目录 2. Maven 基础 2.1 坐标 2.1.0 什么是坐标&#xff08;依赖&#xff09; 2.1.1 获得坐标 2.1.2 使用坐标 2.1.3 依赖范围 2.1.4 依赖传递 2.1.5 依赖冲突&调节原则 2.1.6 依赖排除 2.1.7 使用第三方jar包 2.2 继承与模块 2.2.1 概述 2.2.2 分析 2.2.3 实…

【面试系列】深入浅出 Spring Boot

熟悉SpringBoot&#xff0c;对常用注解、自动装配原理、Jar启动流程、自定义Starter有一定的理解&#xff1b; 面试题 Spring Boot 的核心注解是哪个&#xff1f;它主要由哪几个注解组成的&#xff1f;Spring Boot的自动配置原理是什么&#xff1f;你如何理解 Spring Boot 配置…

VS Code AI开发之Copilot配置和使用详解

随着AI开发工具的迅速发展&#xff0c;GitHub Copilot在Cursor、Winsuf、V0等一众工具的冲击下&#xff0c;推出了免费版本。接下来&#xff0c;我将为大家介绍GitHub Copilot的配置和使用方法。GitHub Copilot基于OpenAI Codex模型&#xff0c;旨在为软件开发者提供智能化的代…

meshy的文本到3d的使用

Meshy官方网站&#xff1a; 中文官网&#xff1a; Meshy官网中文站 ​编辑 Opens in a new window ​编辑www.meshycn.com Meshy AI 中文官网首页 英文官网&#xff1a; Meshy目前似乎还没有单独的英文官网&#xff0c;但您可以在中文官网上找到英文界面或相关英文资料。 链…

快速打造智能应用:从设计到上线的全流程指南

随着人工智能技术的快速发展&#xff0c;如何将大模型技术转化为实际应用成为了各行业关注的焦点。本文将以一个经典的 RAG&#xff08;检索增强生成&#xff09;知识问答系统为例&#xff0c;详细介绍从智能体设计到最终应用部署的全流程。通过结合阿里云的魔笔低代码平台和丰…

影刀进阶指令 | liblib反推 (SD AI绘图反推)

文章目录 影刀进阶指令 | liblib反推 (SD AI绘图反推)一. 需求二. 流程三. 实现3.1 流程概览3.2 流程步骤讲解1\. 获取png地址2\. 打开页面3\. 上传png文件4\. 获取png的prompt信息 四. 运维 影刀进阶指令 | liblib反推 (SD AI绘图反推) 先看看我们要实现的功能&#xff0c;li…

[单master节点k8s部署]43.全链路监控(二)

部署pinpoint服务端 这里安装的是pinpoint-docker&#xff0c;可以从GitHub - pinpoint-apm/pinpoint-docker: Officix 下载。通过readme可以看到&#xff0c;该项目提供的镜像&#xff1a; Pinpoint-Web ServerPinpoint-CollectorPinpoint-AgentPinpoint-FlinkPinpoint-Hba…

EasyExcel(环境搭建以及常用写入操作)

文章目录 EasyExcel环境搭建1.创建模块 easyexcel-demo2.引入依赖3.启动类创建 EasyExcel写1.最简单的写入1.模板2.方法3.结果 Write01.xlsx 2.指定字段不写入Excel1.模板2.方法3.结果 Write02.xlsx 3.指定字段写入excel1.模板2.方法3.结果 Write03.xlsx 4.按照index顺序写入ex…

SpringBoot对静态资源的映射规则

目录 什么是SpringBoot静态资源映射&#xff1f; 如何实现SpringBoot静态资源映射&#xff1f; 1. webjars&#xff1a;以jar包的方式引入静态资源 示例&#xff1a; 2. /** 访问当前项目的任何资源 示例一&#xff1a; 示例二&#xff1a; 3. 静态首页&#xff08;欢…

Redis - Token JWT 概念解析及双token实现分布式session存储实战

Token 定义&#xff1a;令牌&#xff0c;访问资源接口&#xff08;API&#xff09;时所需要的资源凭证 一、Access Token 定义&#xff1a;访问资源接口&#xff08;API&#xff09;时所需要的资源凭证&#xff0c;存储在客户端 组成 组成部分说明uid用户唯一的身份标识time…

集成RabbitMQ+MQ常用操作

文章目录 1.环境搭建1.Docker安装RabbitMQ1.拉取镜像2.安装命令3.开启5672和15672端口4.登录控制台 2.整合Spring AMQP1.sun-common模块下创建新模块2.引入amqp依赖和fastjson 3.新建一个mq-demo的模块1.在sun-frame下创建mq-demo2.然后在mq-demo下创建生产者和消费者子模块3.查…

CMSeasy;大米CMS漏洞复现

一、越权漏洞 pikachu-Over permission 水平越权 ⽔平越权&#xff1a;指攻击者尝试访问与他拥有相同权限的⽤户资源。 登录lucy 查看lucy个人信息 在lucy页面修改usernamelili 可以跳转lili的个人信息页面 pikachu-Over permission 垂直越权 垂直越权&#xff1a;通过低权…

【HarmonyOS之旅】ArkTS语法(一)

目录 1 -> 基本UI描述 1.1 -> 基本概念 1.2 -> UI描述规范 1.2.1 -> 无参数构造配置 1.2.2 -> 必选参数构造配置 1.2.3 -> 属性配置 1.2.4 -> 事件配置 1.2.5 -> 子组件配置 2 -> 状态管理 2.1 -> 基本概念 2.2 -> 页面级变量的状…