Python和tkinter实现的字母记忆配对游戏

news2024/11/24 20:00:00

Python和tkinter实现的字母记忆配对游戏

因为这个小游戏用到了tkinter,先简要介绍一下它。tkinter是Python的标准GUI(图形用户界面)库,它提供了一种简单而强大的方式来创建图形界面应用程序。它提供了创建基本图形界面所需的所有工具,同时保持了相对简单的学习曲线。tkinter是Python的内置库,无需额外安装。

messagebox是tkinter中用于创建各种类型的消息对话框的模块,需要注意的是messagebox是tkinter的一个子模块。为了正确使用messagebox,你需要从tkinter中单独导入它。

这个小游戏具有重新开始和难度设置功能。

“游戏”菜单,包含“新游戏”选项,点击它或完成一局游戏后,会自动开始新游戏。

“难度”菜单,难度设置,包含简单、中等和困难三个选项。

简单难度: 4x2 网格,8个方块

中等难度: 4x3 网格,12个方块

困难难度: 4x4 网格,16个方块

运行界面:

现在Python和tkinter实现字母记忆配对游戏源码,先看使用面向过程风格的版本源码:

import tkinter as tk
import tkinter.messagebox 
import random

def setup_menu(root, difficulty, new_game_func):
    """设置游戏菜单"""
    menubar = tk.Menu(root)
    root.config(menu=menubar)
    
    # 创建"游戏"菜单
    game_menu = tk.Menu(menubar, tearoff=0)
    menubar.add_cascade(label="游戏", menu=game_menu)
    game_menu.add_command(label="新游戏", command=new_game_func)
    
    # 创建"难度"菜单
    difficulty_menu = tk.Menu(menubar, tearoff=0)
    menubar.add_cascade(label="难度", menu=difficulty_menu)
    difficulty_menu.add_radiobutton(label="简单", variable=difficulty, value="简单", command=new_game_func)
    difficulty_menu.add_radiobutton(label="中等", variable=difficulty, value="中等", command=new_game_func)
    difficulty_menu.add_radiobutton(label="困难", variable=difficulty, value="困难", command=new_game_func)

def create_button(frame, row, col, on_click_func):
    """创建游戏按钮"""
    button = tk.Button(frame, text='', width=10, height=5, 
                       command=lambda: on_click_func(row, col))
    button.grid(row=row, column=col, padx=5, pady=5)
    return button

def new_game():
    """开始新游戏"""
    global matches_found, first_click, buttons, symbols
    
    matches_found = 0
    first_click = None
    
    # 清除旧的游戏布局
    for widget in frame.winfo_children():
        widget.destroy()
    
    buttons = []
    
    # 根据难度设置游戏布局和符号
    if difficulty.get() == "简单":
        rows, cols = 4, 2
        symbols = ['A', 'B', 'C', 'D'] * 2
    elif difficulty.get() == "中等":
        rows, cols = 4, 3
        symbols = ['A', 'B', 'C', 'D', 'E', 'F'] * 2
    else:  # 困难
        rows, cols = 4, 4
        symbols = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'] * 2
    
    random.shuffle(symbols)
    
    # 创建游戏按钮
    for i in range(rows):
        for j in range(cols):
            button = create_button(frame, i, j, on_click)
            buttons.append(button)

def on_click(row, col):
    """处理按钮点击事件"""
    global first_click, matches_found
    
    index = row * len(frame.grid_slaves()) // 4 + col
    button = buttons[index]
    
    if button['text'] == '':
        button['text'] = symbols[index]
        
        if first_click is None:
            first_click = (index, button)
        else:
            if symbols[index] == first_click[1]['text']:
                matches_found += 1
                if matches_found == len(symbols) // 2:
                    tk.messagebox.showinfo("恭喜", "你赢了!")
                    new_game()
            else:
                # 如果不匹配,0.5秒后隐藏按钮
                root.after(500, hide_buttons, index, first_click[0])
            first_click = None

def hide_buttons(index1, index2):
    """隐藏不匹配的按钮"""
    buttons[index1]['text'] = ''
    buttons[index2]['text'] = ''

# 主程序
root = tk.Tk()
root.title("字母记忆配对游戏")
root.geometry("400x450")  # 设置窗口的宽度为400像素,高度为450像素

difficulty = tk.StringVar()
difficulty.set("简单")  # 默认难度为简单

frame = tk.Frame(root)
frame.pack()

setup_menu(root, difficulty, new_game)

# 初始化游戏变量
matches_found = 0
first_click = None
buttons = []
symbols = []

new_game()  # 开始第一局游戏

root.mainloop()  # 启动主事件循环

上面是使用面向过程风格的版本,下面改写为使用面向对象风格的版本,源码如下:

import tkinter as tk
import tkinter.messagebox 
import random

class MemoryGame:
    def __init__(self, master):
        self.master = master
        self.master.title("字母记忆配对游戏")
        self.master.geometry("400x450") #设置了窗体的宽度为400像素,高度为450像素
        
        self.buttons = []
        self.first_click = None
        self.matches_found = 0
        
        self.difficulty = tk.StringVar()
        self.difficulty.set("简单")
        
        self.setup_menu()
        self.setup_game()
        
    def setup_menu(self):
        menubar = tk.Menu(self.master)
        self.master.config(menu=menubar)
        
        game_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="游戏", menu=game_menu)
        game_menu.add_command(label="新游戏", command=self.new_game)
        
        difficulty_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="难度", menu=difficulty_menu)
        difficulty_menu.add_radiobutton(label="简单", variable=self.difficulty, value="简单", command=self.new_game)
        difficulty_menu.add_radiobutton(label="中等", variable=self.difficulty, value="中等", command=self.new_game)
        difficulty_menu.add_radiobutton(label="困难", variable=self.difficulty, value="困难", command=self.new_game)
        
    def setup_game(self):
        self.frame = tk.Frame(self.master)
        self.frame.pack()
        
        self.new_game()
        
    def new_game(self):
        self.matches_found = 0
        self.first_click = None
        
        for widget in self.frame.winfo_children():
            widget.destroy()
        
        self.buttons = []
        
        if self.difficulty.get() == "简单":
            rows, cols = 4, 2
            symbols = ['A', 'B', 'C', 'D'] * 2
        elif self.difficulty.get() == "中等":
            rows, cols = 4, 3
            symbols = ['A', 'B', 'C', 'D', 'E', 'F'] * 2
        else:  # 困难
            rows, cols = 4, 4
            symbols = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'] * 2
        
        random.shuffle(symbols)
        
        for i in range(rows):
            for j in range(cols):
                button = tk.Button(self.frame, text='', width=10, height=5, 
                                   command=lambda x=i, y=j: self.on_click(x, y))
                button.grid(row=i, column=j, padx=5, pady=5)
                self.buttons.append(button)
        
        self.symbols = symbols
    
    def on_click(self, row, col):
        index = row * len(self.frame.grid_slaves()) // 4 + col
        button = self.buttons[index]
        
        if button['text'] == '':
            button['text'] = self.symbols[index]
            
            if self.first_click is None:
                self.first_click = (index, button)
            else:
                if self.symbols[index] == self.first_click[1]['text']:
                    self.matches_found += 1
                    if self.matches_found == len(self.symbols) // 2:
                        tk.messagebox.showinfo("恭喜", "你赢了!")
                        self.new_game()
                else:
                    # 如果不匹配,0.5秒后隐藏按钮
                    self.master.after(500, self.hide_buttons, index, self.first_click[0])
                self.first_click = None
    
    def hide_buttons(self, index1, index2):
        self.buttons[index1]['text'] = ''
        self.buttons[index2]['text'] = ''

root = tk.Tk()
game = MemoryGame(root)
root.mainloop()

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Pillow】module ‘PIL.Image‘ has no attribute ‘ANTIALIAS‘问题解决

问题描述 我在使用 SummaryWriter 记录图片数据日志时,遇到了报错,如下图所示: 问题的原因在于,使用的pillow版本已经舍弃了ANTIALIAS,在新版本中已经改为了LANCZOS 问题解决 两种解决方式: 修改源码更…

C++之STL(十一)

1、迭代器适配器 2、插入迭代器 #include <iostream> #include <vector> #include <algorithm> #include <list> using namespace std;void showVec(const vector<int>& v) {for (vector<int>::const_iterator it v.begin(); it ! v.…

如何使用大模型进行文本分类任务?

暑期实习基本结束了&#xff0c;校招即将开启。 不同以往的是&#xff0c;当前职场环境已不再是那个双向奔赴时代了。求职者在变多&#xff0c;HC 在变少&#xff0c;岗位要求还更高了。 最近&#xff0c;我们又陆续整理了很多大厂的面试题&#xff0c;帮助一些球友解惑答疑&…

视频上面怎样编辑文字?4种视频编辑文字方法分享

视频已成为我们日常生活中不可或缺的一部分。无论是社交分享、商业宣传还是个人记录&#xff0c;视频都以其直观、生动的特点吸引着观众的眼球。然而&#xff0c;一个优质的视频&#xff0c;除了画面和音效&#xff0c;文字编辑也是提升观看体验的关键。那么&#xff0c;如何在…

2024百度之星第二场-小度的01串

补题链接&#xff1a; 码蹄集 一道经典线段树板子题。 区间修改01置换&#xff0c;区间查询子串权值。 唯一区别&#xff0c;权值要求的是相邻字符都不同所需修改的最小字符个数。 我们在线段树节点上分别维护当前连续区间&#xff1a; 奇数位是0的个数&#xff08;j0&…

03逻辑门电路

分立门电路&#xff1a; 集成门电路&#xff1a; TTL门电路 MOS门电路&#xff1a;NMOS门电路、PMOS门电路、CMOS门电路 BICMOS门电路&#xff1a;CMOS的高输入阻抗和TTL的高放大倍数的结合 向更低功耗、更高速度发展 MOS管的Rdson在可变电阻区的阻值也一般会小于1000欧姆 …

【自动化测试】Selenium自动化测试框架 | 相关介绍 | Selenium + Java环境搭建 | 常用API的使用

文章目录 自动化测试一、selenium1.相关介绍1.Selenium IDE2.Webdriverwebdriver的工作原理&#xff1a; 3.selenium Grid 2.Selenium Java环境搭建3.常用API的使用1.定位元素2.操作测试对象3.添加等待4.打印信息5.浏览器的操作6.键盘事件7.鼠标事件8.定位一组元素9.多层框架定…

prompt:我是晚餐盲盒,只要你问出“今晚吃什么”我就将为你生成美妙的食物推荐。

使用方法&#xff1a;在ChatGP粘贴下面提示词模型&#xff0c;点击输出。然后再问“晚餐有什么好吃的&#xff1f;”&#xff0c;AI输出丰种食物供你选择。抽到什么吃什么&#xff0c;极大的解决选择困难的问题。 客户需要生成1000条俏皮灵动&#xff0c;趣味盎然&#xff0c;比…

VS2019安装插件image watch

image watch的作用&#xff1a; &#xff08;1&#xff09;放大、缩小图像&#xff1b; &#xff08;2&#xff09;将图像保存到指定的目录&#xff1b; &#xff08;3&#xff09;显示图像大小、通道数&#xff1b; &#xff08;4&#xff09;拖拽图像&#xff1b; &…

动态流体工厂大屏

目录 一 设计原型 二 后台源码 一 设计原型 二 后台源码 namespace 动态流体工厂大屏 {public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){Task.Run(() >{while (true){this.Invoke(() >…

基于51单片机电子称—串口显示

基于51单片机电子称设计 &#xff08;仿真&#xff0b;程序&#xff09; 功能介绍 具体功能&#xff1a; 1.矩阵键盘组成按键&#xff0c;输入价格结算、打印&#xff1b; 2.用滑动变阻器和ADC0832模拟称重&#xff1b; 3.LCD1602可以显示重量、单价和总价&#xff1b; 4.…

关于新零售的一些思考

本文作为2024上半年大量输入之后的核心思考之一。工作到一定阶段之后&#xff0c;思考的重要性越来越高&#xff0c;后续会把自己的个人思考记录在这个新系列《施展爱思考》。背景是上半年面临业务转型从电商到新零售&#xff0c;本文是相关大量输入之后的思考&#xff0c;对新…

vue2中的组件自定义事件

1.绑定事件: <组件 :自定义名称"方法" /> 2.调用 this.$emit(方法,参数) 3.关闭 this.$off(方法) 案例: 1.提前准备好组件 Student组件 <template><div class"student"><h1>学校名称:{{ st…

JAVA每日作业day6.27

ok了家人们&#xff0c;今天学习了内部类&#xff0c;话不多说我们一起看看吧。 一&#xff0c;内部类 1.1 内部类概述 将一个类 A 定义在另一个类 B 里面&#xff0c;里面的那个类 A 就称为 内部 类 &#xff0c; B 则称为 外部类 。 内部类分为成员内部类与局部内部类。 1…

修改 app id - 鸿蒙 HarmonyOS Next

修改项目 app id 后通过真机 build run 的时候抛出了如下异常; 项目中更改后的配置与真机的不匹配; {app: {bundleName: "com.xxxxxx.xxx_harmony",vendor: "xxxxxx",versionCode: 1,versionName: "3.5.00",icon: "$media:app_icon",…

9.二维数组的遍历和存储

二维数组的遍历和存储 二维数组的遍历 二维数组a[3][4],可分解为三个一维数组,其数组名分别为: 这三个一维数组都有4个元素,例如:一维数组a[0]的 元素为a[0][0],a[0][1],a[0][2],a[0][3]。所以遍历二维数组无非就是先取出二维数组中得一维数组, 然后再从一维数组中取出每个元…

Open AI限制来袭?用上这个工具轻松破局!

【导语】近日&#xff0c;AI领域掀起了一场不小的波澜。Open AI宣布&#xff0c;从7月9日起&#xff0c;将对部分地区的开发者实施API调用限制。这一消息对于许多依赖Open AI技术的国内初创团队来说&#xff0c;无疑是一个沉重的打击。 对于这些团队而言&#xff0c;Open AI的A…

Spring相关面试题(三)

29 如何在所有的BeanDefinition注册完成后&#xff0c;进行扩展 Bean工厂的后置处理器&#xff0c;在所有的Bean注册完成后&#xff0c;就被执行。 public class A implements BeanFactoryPostProcessor {private String name "a class";private B b; ​public St…

如何使用ig507金融数据库的股票接口,股票API来获取MACD指标

一、MACD指标简介 MACD&#xff08;Moving Average Convergence Divergence&#xff0c;移动平均收敛/发散&#xff09;是一种趋势跟踪动量指标&#xff0c;用于分析股票或其他金融产品的价格趋势。MACD由两部分组成&#xff1a;差离值&#xff08;DIF&#xff09;和信号线&am…

麒麟系统安装MySQL

搞了一整天&#xff0c;终于搞定了&#xff0c;记录一下。 一、背景 项目的原因&#xff0c;基于JeecgBoot开发的系统需要国产化支持&#xff0c;这就需要在电脑上安装MySQL等支撑软件。 国产化项目的操作系统多是麒麟系统&#xff0c;我的系统如下&#xff1a; arm64架构。…