首页 > 编程语言 >python+tkinter开发2048游戏

python+tkinter开发2048游戏

时间:2023-06-18 20:12:32浏览次数:37  
标签:tkinter randint python move 2048 item print data row

1. 界面设计

  如果开发这个游戏,相信一定玩过。这里不过多介绍。我最后的效果。

2. 代码

import random
import tkinter as tk
from tkinter import messagebox
from tkinter.constants import W, N, E, S

def random_2()->bool:
    """
    在空位置随机生成一个2
    :return:
    """
    count_0 = sum(row.count(0) for row in data)#统计0的个数
    if count_0==0:
        print_data()
        return False
    # 生成一个 [0, 3] 范围内的整数
    randint_row = random.randint(0, 3)
    randint_col = random.randint(0, 3)
    while True:
        print(data[randint_row][randint_col])
        if data[randint_row][randint_col]==0:
            data[randint_row][randint_col]=2
            break
        else:
            randint_row = random.randint(0, 3)
            randint_col = random.randint(0, 3)
    print_data()
    return True

def up_move():
    """
    得到上移后的data
    :return:
    """
    #相当于将原data先转置,再左移,再转置回来
    data[:] = [list(item) for item in zip(*data)]
    print("转置后")
    print_data()
    left_move()
    #再次转置
    data[:] = [list(item) for item in zip(*data)]

def down_move():
    """
    得到下移后的数据
    :return:
    """
    # 相当于将原data先转置,再右移,再转置回来
    data[:] = [list(item) for item in zip(*data)]
    print("转置后")
    print_data()
    right_move()
    # 再次转置
    data[:] = [list(item) for item in zip(*data)]

def print_data():
    for item in data:
        print(item,end="\n")
    print("=============")

def left_move(right=False):
    """
    得到左移后的数据
    :return:
    """
    global sum_score
    for row in data:
        for i in range(len(row)-1,-1,-1):
            if row[i]==0:
                del row[i]
                row.append(0)
        #合并
        for i in range(0,len(row)-1,1):
            if row[i]==row[i+1] and row[i]!=0:
                # 累计总分
                sum_score += row[i] * 2
                #合并
                row[i]=row[i]*2
                row[i+1]=0
        #合并后产生的0放最后面
        for i in range(len(row) - 1, -1, -1):
            if row[i] == 0:
                del row[i]
                row.append(0)
    if right==False:
        print_data()


def right_move():
    """
    得到右移后的数据
    :return:
    """
    for i in range(len(data)):
        data[i] = data[i][::-1]
    """
或者
for item in lst3: item[:]=reversed(item) """ #有个简单的做法,向右移动,相当于可以先将每行反转逆序,在向左移动,移动完后,再反转 #相当于调用向左移动left_move() left_move(True) #再次反转 for item in data: item[:] = reversed(item) print_data() def stop_game(): mb = messagebox.askyesno( title="退出游戏", message="是否退出游戏!") if mb: win.quit() def reset(): global data global sum_score sum_score = 0 data = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] # 随机生成两个2 random_2() random_2() def is_merge():#判断是否还能够合并 #遍历元素,判断元素的右方与下方是否相等,相等,则能合并 #最右边的元素右边没有元素,最下面的元素,下面没有元素 for i in range(len(data)):#[0,len(data)-1] for j in range(len(data)): #判断右边 if 0<=j+1<=len(data)-1 and data[i][j]==data[i][j+1]:#前面为False时,and后面语句不会执行到,不会越界报错 return True #能合并 elif 0<=i+1<=len(data)-1 and data[i][j]==data[i+1][j]: return True #能合并 return False#不能合并了 def is_game_over(): #遍历,如果不能合并了,且格子满了,就结束游戏了 if is_blank()==True or is_merge()==True: return True # else: return False def game_over(): print("游戏结束") mb = messagebox.askyesno( title="游戏结束", message="是否重新开始") if mb: #重新开始游戏 reset() update_ui() else: win.quit() move_dic={"Up":up_move,"Down":down_move,"Left":left_move,"Right":right_move} def condition(key): return move_dic[key] def is_blank()->bool: """ 如果有0元素存在,则返回True,否则返回False :return: """ return any(0 in row for row in data) def update_ui(): '''刷新界面函数 根据计算出的f地图数据,更新各个Label的设置 ''' for r in range(4): for c in range(len(data[0])): number = data[r][c] # 设置数字 label = data_labels[r][c] # 选中Lable控件 label['text'] = str(number) if number else '' label['bg'] = mapcolor[number][0] label['foreground'] = mapcolor[number][1] label_score['text'] = str(sum_score) # 重设置分数 def press_key(event): # move=condition(key) # move() print("调用了press_key") key=event.keysym print(f"按下了{key}键") if key in move_dic: move=move_dic[key] #移动 move() #计算得分 print("当前得分",sum_score) random_2() update_ui() if is_game_over()==False:#不能合并了 game_over() if key=="q": print("退出游戏吗?") stop_game()
#背景颜色与数字颜色 mapcolor = { 0: ("#cdc1b4", "#776e65"), 2: ("#eee4da", "#776e65"), 4: ("#ede0c8", "#f9f6f2"), 8: ("#f2b179", "#f9f6f2"), 16: ("#f59563", "#f9f6f2"), 32: ("#f67c5f", "#f9f6f2"), 64: ("#f65e3b", "#f9f6f2"), 128: ("#edcf72", "#f9f6f2"), 256: ("#edcc61", "#f9f6f2"), 512: ("#e4c02a", "#f9f6f2"), 1024: ("#e2ba13", "#f9f6f2"), 2048: ("#ecc400", "#f9f6f2"), } if __name__ == '__main__': #初始化全局变量 sum_score=0 data=[[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]] #随机生成两个2 random_2() random_2() print_data() # print(data) win = tk.Tk() win.title("2048游戏") # win.geometry("400x500") win.resizable(False, False)# 固定宽和高 #按键事件监听 game_bg_color = "#bbada0" # 设置背景颜色 frame = tk.Frame(win, bg=game_bg_color) frame.grid(sticky=N + E + W + S) # # 设置焦点能接收按键事件 frame.focus_set() frame.bind("<Key>", press_key) # 初始化图形界面 data_labels = [] for r in range(4): row = [] for c in range(len(data[0])): value = data[r][c] text = str(value) if value else '' print(text) label = tk.Label(frame, text=text, width=4, height=2, font=("黑体", 30, "bold")) label.grid(row=r, column=c, padx=2, pady=2, sticky=N + E + W + S) row.append(label) data_labels.append(row) # 设置显示分数的Lable label = tk.Label(frame, text='分数', font=("黑体", 30, "bold"), bg="#bbada0", fg="#eee4da") label.grid(row=4, column=0, padx=5, pady=5) label_score = tk.Label(frame, text='0', font=("黑体", 30, "bold"), bg="#bbada0", fg="#ffffff") label_score.grid(row=4, columnspan=2, column=1, padx=5, pady=5) win.mainloop()

3.  打包成exe程序

  先安装pyinstaller,可以将tkinter或者pyqt开发的带界面的程序打包成exe可执行文件。

pip install pyinstaller  -i https://pypi.tuna.tsinghua.edu.cn/simple

  再在pycharm的terminal中输入如下:

pyinstaller -Fw -i ./2048game.ico my2048.py

  关于参数:-F是将所有文件打包成一个exe文件,到处拷贝都可以执行,w参数是不显示控制台窗口(自己可以不要w尝试),-i是给exe程序加上图标。最后生成的dist文件夹有个exe程序。最后拷贝在桌面上就是下面这个样子。

4. 运行效果

  

 小结:可能程序存在冗余之处,还可以改善的。界面的tkinter程序参考了网上的。

  若存在不足之处,欢迎之处或评论。

 参考资料:

https://www.cnblogs.com/shijieli/p/10641299.htmlhttps://www.cnblogs.com/shijieli/p/10641299.html

http://www.xoxxoo.com/index.php/index/index/article/id/641.html

标签:tkinter,randint,python,move,2048,item,print,data,row
From: https://www.cnblogs.com/wancy/p/17489643.html

相关文章

  • python 并发编程-3
    Python中的并发编程-3爬虫是典型的I/O密集型任务,I/O密集型任务的特点就是程序会经常性的因为I/O操作而进入阻塞状态,比如我们之前使用requests获取页面代码或二进制内容,发出一个请求之后,程序必须要等待网站返回响应之后才能继续运行,如果目标网站不是很给力或者网络状况不是很......
  • Python之异常处理
    try: 可能会出现异常的代码except你要捕捉的异常1处理: 对这个异常的处理except你要捕捉的异常2处理: 对这个异常的处理else: 没出现异常时做的处理finally: 不管有没有出现异常,都会执行的代码#else,finally这些词的顺序不可以变importsystry:n=int(input()......
  • 【Python】在同一图形中更加优雅地绘制多个子图
    1.引言数据可视化非常重要,有一句俗语叫做一图顶千言,我相信好多小伙伴应该都听说过这句话;即使是有人第一次听到,我想应该也会觉得赞成,这足以说明数据可视化的重要性。我们在前一篇博客中,介绍了如何利用subplot来在一张子图里绘制多个子图,最近我又发现了一种更加优雅地实现,迫不及待地......
  • Python编程和数据科学中的数据处理:如何从数据中提取有用的信息和数据
    目录引言数据分析和数据处理是数据科学和人工智能领域的核心话题之一。数据科学家和工程师需要从大量的数据中提取有用的信息和知识,以便更好地理解和预测现实世界中的事件。本文将介绍Python编程和数据科学中的数据处理技术,帮助读者从数据中提取有用的信息和数据。技术原理......
  • Python编程和数据科学中的人工智能:如何创建复杂的智能系统并提高模型性能
    目录1.引言2.技术原理及概念3.实现步骤与流程4.应用示例与代码实现讲解标题:《Python编程和数据科学中的人工智能:如何创建复杂的智能系统并提高模型性能》1.引言人工智能(AI)是一个广泛的领域,涵盖了许多不同的技术和应用。在Python编程和数据科学中,人工智能是一个非常重要......
  • Python编程和数据科学中的大数据分析:如何从大量数据中提取有意义的信息和模式
    目录《Python编程和数据科学中的大数据分析:如何从大量数据中提取有意义的信息和模式》引言大数据时代已经来临,随着互联网和物联网的普及,海量数据的产生和存储已经成为一种普遍的现象。这些数据包含各种各样的信息,如文本、图像、音频和视频等,而大数据分析则是将这些海量数据中提......
  • python常用操作之代码操作大全
    目录列表操作大全(listoperations)字典操作大全(dictionaryoperations)表格操作大全(DataFrameoperations)MySQL操作大全(MySQLoperations)列表操作大全(listoperations)字典操作大全(dictionaryoperations)表格操作大全(DataFrameoperations)MySQL操作大全(MySQLoper......
  • Python和C++之间的主要区别点?
    Python和C++之间的区别可以简洁地概括如下:编程范式:Python是一种解释型、面向对象的动态语言,更注重代码的简洁性和可读性,适合快速开发和原型设计。C++是一种编译型、多范式语言,支持面向对象、过程式和泛型编程,更注重底层的控制和性能优化。语法复杂性:C++具有较为复杂的语法和......
  • Python:zip+dict将两个list列表对象转为dict字典对象
    将两个list列表对象转为dict字典对象代码示例keys=['one','two','three']values=[1,2,3]dct=dict(zip(keys,values))print(dct)#{'one':1,'two':2,'three':3}参考文章Python。将2个列表转换为一个字典对象[重复]......
  • Python学习日志一,初识Python
    一、向python说你好世界(print("Helloworld!!"))二、pycharm插件推荐使用上图这个插件就可以翻译代码里面的英文单词了三、Pycharm常用快捷键ctrl+alt+s:打开软件设置shift+alt+上/下:将当前行代码上移或者下移Ctrl+shift+f10:运行当前代码f6:重命名文件四......