• 利用 Python_tkinter 完成 2048 游戏


    成品展示 

    具备基本的数据合并以及分数统计,不同数字的色块不同

    产生随机数, 数据无法合并判定以及重新开始选项

     同时可以判定游戏失败条件

     

    需求分析

    • 完成基本数据合并算法
    • 游戏结束条件
    • 界面展示
    • 重置按钮
    • 分数统计

    代码逻辑

    页面创建

    展示数据

    创建一个基本的数据结构地图数据来保存各位置的数值

    _map_data = [
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]
    ]

    展示图形

    利用 tkinter 通过遍历地图数据来循环创建标签

    创建时利用 tkinter 设置样式以及颜色

    同样维护一个列表来填入每行的标签

        map_labels = [] 
        for r in range(4):
            row = []
            for c in range(len(_map_data[0])):
                value = _map_data[r][c]
                text = str(value) if value else ''
                label = Label(frame, text=text, width=4, height=2,
                              font=("黑体", 30, "bold"))
                label.grid(row=r, column=c, padx=5, pady=5, sticky=N + E + W + S)
                row.append(label)
            map_labels.append(row)

    色块设置

    不同数值的色块以不同的颜色标识

        # 设置游戏中每个数据对应色块的颜色
        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"),
            4096: ("#ae84a8", "#f9f6f2"),
            8192: ("#b06ca8", "#f9f6f2"),
            # ----其它颜色都与8192相同---------
            2 ** 14: ("#b06ca8", "#f9f6f2"),
            2 ** 15: ("#b06ca8", "#f9f6f2"),
            2 ** 16: ("#b06ca8", "#f9f6f2"),
            2 ** 17: ("#b06ca8", "#f9f6f2"),
            2 ** 18: ("#b06ca8", "#f9f6f2"),
            2 ** 19: ("#b06ca8", "#f9f6f2"),
            2 ** 20: ("#b06ca8", "#f9f6f2"),
        }

    分数显示

    创建两个标签分别标识分数 , 以及数字

    label = Label(frame, text='分数', font=("黑体", 30, "bold"),
                      bg="#bbada0", fg="#eee4da")
    label.grid(row=4, column=0, padx=5, pady=5)
    label_score = Label(frame, text='0', font=("黑体", 30, "bold"),
                            bg="#bbada0", fg="#ffffff")
    label_score.grid(row=4, columnspan=2, column=1, padx=5, pady=5)

    重置按钮

    重置按钮需要做到将游戏重置

    即地图数据还原以及分数重置

    此部分需要设计相关 函数来负责重置以及刷新界面

    def reset():
        '''重新设置游戏数据,将地图恢复为初始状态,并加入两个数据 2 作用初始状态'''
        _map_data[:] = []  # _map_data.clear()
        _map_data.append([0, 0, 0, 0])
        _map_data.append([0, 0, 0, 0])
        _map_data.append([0, 0, 0, 0])
        _map_data.append([0, 0, 0, 0])
        # 在空白地图上填充两个2
        fill2()
        fill2()
        def reset_game():
            reset()
            update_ui()
    
        restart_button = Button(frame, text='重新开始', font=("黑体", 16, "bold"),
                                bg="#8f7a66", fg="#f9f6f2", command=reset_game)
        restart_button.grid(row=4, column=3, padx=5, pady=5)

    计算逻辑

    移动逻辑

    移动的逻辑分为两步

    移动数字和合并数字

    但是合并数字后又会发现存在空格, 因此需要第三步

    def _left_move_number(line):
        '''左移一行数字,如果有数据移动则返回True,否则返回False:
        如: line = [0, 2, 0, 8] 即表达如下一行:
            +---+---+---+---+
            | 0 | 2 | 0 | 8 |      <----向左移动
            +---+---+---+---+
        此行数据需要左移三次:
          第一次左移结果:
            +---+---+---+---+
            | 2 | 0 | 8 | 0 |
            +---+---+---+---+
          第二次左移结果:
            +---+---+---+---+
            | 2 | 8 | 0 | 0 |
            +---+---+---+---+
          第三次左移结果:
            +---+---+---+---+
            | 2 | 8 | 0 | 0 |  # 因为最左则为2,所以8不动
            +---+---+---+---+
         最终结果: line = [4, 8, 0, 0]
        '''
        moveflag = False  # 是否移动的标识,先假设没有移动
        for _ in range(3):  # 重复执行下面算法三次
            for i in range(3):  # i为索引
                if 0 == line[i]:  # 此处有空位,右侧相邻数字向左侧移动,右侧填空白
                    moveflag = True
                    line[i] = line[i + 1]
                    line[i + 1] = 0
        return moveflag
    
    
    def _left_marge_number(line):
        '''向左侧进行相同单元格合并,合并结果放在左侧,右侧补零
        如: line = [2, 2, 4, 4] 即表达如下一行:
            +---+---+---+---+
            | 2 | 2 | 4 | 4 |
            +---+---+---+---+
        全并后的结果为:
            +---+---+---+---+
            | 4 | 0 | 8 | 0 |
            +---+---+---+---+
        最终结果: line = [4, 8, 8, 0]
        '''
        for i in range(3):
            if line[i] == line[i + 1]:
                moveflag = True
                line[i] *= 2  # 左侧翻倍
                line[i + 1] = 0  # 右侧归零
    
    
    def _left_move_aline(line):
        '''左移一行数据,如果有数据移动则返回True,否则返回False:
        如: line = [2, 0, 2, 8] 即表达如下一行:
            +---+---+---+---+
            | 2 |   | 2 | 8 |      <----向左移动
            +---+---+---+---+
        左移算法分为三步:
            1. 将所有数字向左移动来填补左侧空格,即:
                +---+---+---+---+
                | 2 | 2 | 8 |   |
                +---+---+---+---+
            2. 判断是否发生碰幢,如果两个相临且相等的数值则说明有碰撞需要合并,
               合并结果靠左,右则填充空格 
                +---+---+---+---+
                | 4 |   | 8 |   |
                +---+---+---+---+
            3. 再重复第一步,将所有数字向左移动来填补左侧空格,即:
                +---+---+---+---+
                | 4 | 8 |   |   |
                +---+---+---+---+
            最终结果: line = [4, 8, 0, 0]
        '''
        moveflag = False
        if _left_move_number(line):
            moveflag = True
        if _left_marge_number(line):
            moveflag = True
        if _left_move_number(line):
            moveflag = True
        return moveflag

    上下左右移动实现

    基本实现了一个就可以全部实现了

    本质本身就是列表 , 翻转方向的就翻转列表即可. 但是记得要再转回来

    上下的列表就是4个列表的同索引位置重新拼接列表. 

    同样翻转后在翻转

    def left():
        """游戏左键按下时或向左滑动屏幕时的算法"""
        moveflag = False  # moveflag 是否成功移动数字标志位,如果有移动则为真值,原地图不变则为假值
    
        # 将第一行都向左移动.如果有移动就返回True
        for line in _map_data:
            if _left_move_aline(line):
                moveflag = True
        return moveflag
    
    
    def right():
        """游戏右键按下时或向右滑动屏幕时的算法
        选将屏幕进行左右对调,对调后,原来的向右滑动即为现在的向左滑动
        滑动完毕后,再次左右对调回来
        """
        # 左右对调
        for r in _map_data:
            r.reverse()
        moveflag = left()  # 向左滑动
        # 再次左右对调
        for r in _map_data:
            r.reverse()
        return moveflag
    
    
    def up():
        """游戏上键按下时或向上滑动屏幕时的算法
        先把每一列都自上而下放入一个列表中line中,然后执行向滑动,
        滑动完成后再将新位置摆回到原来的一列中
        """
        moveflag = False
        line = [0, 0, 0, 0]  # 先初始化一行,准备放入数据
        for col in range(4):  # 先取出每一列
            # 把一列中的每一行数入放入到line中
            for row in range(4):
                line[row] = _map_data[row][col]
            # 将当前列进行上移,即line 左移
            if (_left_move_aline(line)):
                moveflag = True
            # 把左移后的 line中的数据填充回原来的一列
            for row in range(4):
                _map_data[row][col] = line[row]
        return moveflag
    
    
    def down():
        """游戏下键按下时或向下滑动屏幕时的算法
        选将屏幕进行上下对调,对调后,原来的向下滑动即为现在的向上滑动
        滑动完毕后,再次上下对调回来
        """
        _map_data.reverse()
        moveflag = up()  # 上滑
        _map_data.reverse()
        return moveflag

    结束判定

    def is_gameover():
        """判断游戏是否结束,如果结束返回True,否是返回False
        """
        for r in _map_data:
            # 如果水平方向还有0,则游戏没有结束
            if r.count(0):
                return False
            # 水平方向如果有两个相邻的元素相同,应当是可以合并的,则游戏没有结束
            for i in range(3):
                if r[i] == r[i + 1]:
                    return False
        for c in range(4):
            # 竖直方向如果有两个相邻的元素相同,应当可以合并的,则游戏没有结束
            for r in range(3):
                if _map_data[r][c] == _map_data[r + 1][c]:
                    return False
        # 以上都没有,则游戏结束
        return True

    分数统计

    def get_score():
        '''获取游戏的分数,得分规则是每次有两个数加在一起则生成相应的分数。
        如 2 和 2 合并后得4分, 8 和 8 分并后得 16分.
        根据一个大于2的数字就可以知道他共合并了多少次,可以直接算出分数:
        如:
           4 一定由两个2合并,得4分
           8 一定由两个4合并,则计:8 + 4 + 4 得32分
           ... 以此类推
        '''
        score = 0
        for r in _map_data:
            for c in r:
                score += 0 if c < 4 else c * int((math.log(c, 2) - 1.0))
        return score  # 导入数学模块

    随机数添加

    随机数的添加形式为 添加一个 2 到任意一个为 0 的位置

    先进行一个 0 位置的数量统计

    def get_space_count():
        """获取没有数字的方格的数量,如果数量为0则说有无法填充新数据,游戏即将结束
        """
        count = 0
        for r in _map_data:
            count += r.count(0)
        return count

    利用定义偏移量来添加, 随机 0~0位置统计个数, 然后选一个后循环+1偏移量到被选到数字进行复制为 2 

    def fill2():
        '''填充2到空位置,如果填度成功返回True,如果已满,则返回False'''
        blank_count = get_space_count()  # 得到地图上空白位置的个数
        if 0 == blank_count:
            return False
        # 生成随机位置, 如,当只有四个空时,则生成0~3的数,代表自左至右,自上而下的空位置
        pos = random.randrange(0, blank_count)
        offset = 0
        for row in _map_data:  # row为行row
            for col in range(4):  # col 为列,column
                if 0 == row[col]:
                    if offset == pos:
                        # 把2填充到第row行,第col列的位置,返回True
                        row[col] = 2
                        return True
                    offset += 1

    键盘映射响应

    keymap = {
            'a': left,
            'd': right,
            'w': up,
            's': down,
            'Left': left,
            'Right': right,
            'Up': up,
            'Down': down,
            'q': root.quit,
        }
        def on_key_down(event):
            '键盘按下处理函数'
            keysym = event.keysym
            if keysym in keymap:
                if keymap[keysym]():  # 如果有数字移动
                    fill2()  # 填充一个新的2
            update_ui()
            if is_gameover():
                mb = messagebox.askyesno(
                    title="gameover", message="游戏结束!
    是否退出游戏!")
                if mb:
                    root.quit()
                else:
                    reset()
                    update_ui()
    # 设置焦点能接收按键事件
        frame.focus_set()
        frame.bind("<Key>", on_key_down)

    刷新界面

        def update_ui():
            '''刷新界面函数
            根据计算出的f地图数据,更新各个Label的设置
            '''
            for r in range(4):
                for c in range(len(_map_data[0])):
                    number = _map_data[r][c]  # 设置数字
                    label = map_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(get_score())  # 重设置分数

    全部代码

    """2048游戏
    本模块已完整实现2048游戏的算法及分数的计算算法
    本游戏的界面采用python 标准库 tkinter 来实现
    此界面的布局采用tkinter中的grid布局
    """
    
    import random
    import math
    import sys
    
    _map_data = [
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]
    ]
    
    
    # -------------------------以下为2048游戏的基本算法---------------------------
    
    # 重置
    def reset():
        '''重新设置游戏数据,将地图恢复为初始状态,并加入两个数据 2 作用初始状态'''
        _map_data[:] = []  # _map_data.clear()
        _map_data.append([0, 0, 0, 0])
        _map_data.append([0, 0, 0, 0])
        _map_data.append([0, 0, 0, 0])
        _map_data.append([0, 0, 0, 0])
        # 在空白地图上填充两个2
        fill2()
        fill2()
    
    
    # 获取 0 个数
    def get_space_count():
        """获取没有数字的方格的数量,如果数量为0则说有无法填充新数据,游戏即将结束
        """
        count = 0
        for r in _map_data:
            count += r.count(0)
        return count
    
    
    # 计算分数
    def get_score():
        '''获取游戏的分数,得分规则是每次有两个数加在一起则生成相应的分数。
        如 2 和 2 合并后得4分, 8 和 8 分并后得 16分.
        根据一个大于2的数字就可以知道他共合并了多少次,可以直接算出分数:
        如:
           4 一定由两个2合并,得4分
           8 一定由两个4合并,则计:8 + 4 + 4 得32分
           ... 以此类推
        '''
        score = 0
        for r in _map_data:
            for c in r:
                score += 0 if c < 4 else c * int((math.log(c, 2) - 1.0))
        return score  # 导入数学模块
    
    
    # 随机数生成
    def fill2():
        '''填充2到空位置,如果填度成功返回True,如果已满,则返回False'''
        blank_count = get_space_count()  # 得到地图上空白位置的个数
        if 0 == blank_count:
            return False
        # 生成随机位置, 如,当只有四个空时,则生成0~3的数,代表自左至右,自上而下的空位置
        pos = random.randrange(0, blank_count)
        offset = 0
        for row in _map_data:  # row为行row
            for col in range(4):  # col 为列,column
                if 0 == row[col]:
                    if offset == pos:
                        # 把2填充到第row行,第col列的位置,返回True
                        row[col] = 2
                        return True
                    offset += 1
    
    
    # 结束判定
    def is_gameover():
        """判断游戏是否结束,如果结束返回True,否是返回False
        """
        for r in _map_data:
            # 如果水平方向还有0,则游戏没有结束
            if r.count(0):
                return False
            # 水平方向如果有两个相邻的元素相同,应当是可以合并的,则游戏没有结束
            for i in range(3):
                if r[i] == r[i + 1]:
                    return False
        for c in range(4):
            # 竖直方向如果有两个相邻的元素相同,应当可以合并的,则游戏没有结束
            for r in range(3):
                if _map_data[r][c] == _map_data[r + 1][c]:
                    return False
        # 以上都没有,则游戏结束
        return True
    
    
    # 移动合并分数
    def _left_move_number(line):
        '''左移一行数字,如果有数据移动则返回True,否则返回False:
        如: line = [0, 2, 0, 8] 即表达如下一行:
            +---+---+---+---+
            | 0 | 2 | 0 | 8 |      <----向左移动
            +---+---+---+---+
        此行数据需要左移三次:
          第一次左移结果:
            +---+---+---+---+
            | 2 | 0 | 8 | 0 |
            +---+---+---+---+
          第二次左移结果:
            +---+---+---+---+
            | 2 | 8 | 0 | 0 |
            +---+---+---+---+
          第三次左移结果:
            +---+---+---+---+
            | 2 | 8 | 0 | 0 |  # 因为最左则为2,所以8不动
            +---+---+---+---+
         最终结果: line = [4, 8, 0, 0]
        '''
        moveflag = False  # 是否移动的标识,先假设没有移动
        for _ in range(3):  # 重复执行下面算法三次
            for i in range(3):  # i为索引
                if 0 == line[i]:  # 此处有空位,右侧相邻数字向左侧移动,右侧填空白
                    moveflag = True
                    line[i] = line[i + 1]
                    line[i + 1] = 0
        return moveflag
    
    
    # 移动位置
    def _left_marge_number(line):
        '''向左侧进行相同单元格合并,合并结果放在左侧,右侧补零
        如: line = [2, 2, 4, 4] 即表达如下一行:
            +---+---+---+---+
            | 2 | 2 | 4 | 4 |
            +---+---+---+---+
        全并后的结果为:
            +---+---+---+---+
            | 4 | 0 | 8 | 0 |
            +---+---+---+---+
        最终结果: line = [4, 8, 8, 0]
        '''
        for i in range(3):
            if line[i] == line[i + 1]:
                moveflag = True
                line[i] *= 2  # 左侧翻倍
                line[i + 1] = 0  # 右侧归零
    
    
    # 移动逻辑
    def _left_move_aline(line):
        '''左移一行数据,如果有数据移动则返回True,否则返回False:
        如: line = [2, 0, 2, 8] 即表达如下一行:
            +---+---+---+---+
            | 2 |   | 2 | 8 |      <----向左移动
            +---+---+---+---+
        左移算法分为三步:
            1. 将所有数字向左移动来填补左侧空格,即:
                +---+---+---+---+
                | 2 | 2 | 8 |   |
                +---+---+---+---+
            2. 判断是否发生碰幢,如果两个相临且相等的数值则说明有碰撞需要合并,
               合并结果靠左,右则填充空格 
                +---+---+---+---+
                | 4 |   | 8 |   |
                +---+---+---+---+
            3. 再重复第一步,将所有数字向左移动来填补左侧空格,即:
                +---+---+---+---+
                | 4 | 8 |   |   |
                +---+---+---+---+
            最终结果: line = [4, 8, 0, 0]
        '''
        moveflag = False
        if _left_move_number(line):
            moveflag = True
        if _left_marge_number(line):
            moveflag = True
        if _left_move_number(line):
            moveflag = True
        return moveflag
    
    
    def left():
        """游戏左键按下时或向左滑动屏幕时的算法"""
        moveflag = False  # moveflag 是否成功移动数字标志位,如果有移动则为真值,原地图不变则为假值
    
        # 将第一行都向左移动.如果有移动就返回True
        for line in _map_data:
            if _left_move_aline(line):
                moveflag = True
        return moveflag
    
    
    def right():
        """游戏右键按下时或向右滑动屏幕时的算法
        选将屏幕进行左右对调,对调后,原来的向右滑动即为现在的向左滑动
        滑动完毕后,再次左右对调回来
        """
        # 左右对调
        for r in _map_data:
            r.reverse()
        moveflag = left()  # 向左滑动
        # 再次左右对调
        for r in _map_data:
            r.reverse()
        return moveflag
    
    
    def up():
        """游戏上键按下时或向上滑动屏幕时的算法
        先把每一列都自上而下放入一个列表中line中,然后执行向滑动,
        滑动完成后再将新位置摆回到原来的一列中
        """
        moveflag = False
        line = [0, 0, 0, 0]  # 先初始化一行,准备放入数据
        for col in range(4):  # 先取出每一列
            # 把一列中的每一行数入放入到line中
            for row in range(4):
                line[row] = _map_data[row][col]
            # 将当前列进行上移,即line 左移
            if (_left_move_aline(line)):
                moveflag = True
            # 把左移后的 line中的数据填充回原来的一列
            for row in range(4):
                _map_data[row][col] = line[row]
        return moveflag
    
    
    def down():
        """游戏下键按下时或向下滑动屏幕时的算法
        选将屏幕进行上下对调,对调后,原来的向下滑动即为现在的向上滑动
        滑动完毕后,再次上下对调回来
        """
        _map_data.reverse()
        moveflag = up()  # 上滑
        _map_data.reverse()
        return moveflag
    
    
    # -------------------------以下为2048游戏的操作界面---------------------------
    
    if (sys.version_info > (3, 0)):
        from tkinter import *
        from tkinter import messagebox
    else:
        from Tkinter import *
    
    
    def main():
        reset()  # 先重新设置游戏数据
    
        root = Tk()  # 创建tkinter窗口
        root.title('2048游戏')  # 设置标题文字
        root.resizable(width=False, height=False)  # 固定宽和高
    
        # 以下是键盘映射
        keymap = {
            'a': left,
            'd': right,
            'w': up,
            's': down,
            'Left': left,
            'Right': right,
            'Up': up,
            'Down': down,
            'q': root.quit,
        }
    
        game_bg_color = "#bbada0"  # 设置背景颜色
    
        # 设置游戏中每个数据对应色块的颜色
        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"),
            4096: ("#ae84a8", "#f9f6f2"),
            8192: ("#b06ca8", "#f9f6f2"),
            # ----其它颜色都与8192相同---------
            2 ** 14: ("#b06ca8", "#f9f6f2"),
            2 ** 15: ("#b06ca8", "#f9f6f2"),
            2 ** 16: ("#b06ca8", "#f9f6f2"),
            2 ** 17: ("#b06ca8", "#f9f6f2"),
            2 ** 18: ("#b06ca8", "#f9f6f2"),
            2 ** 19: ("#b06ca8", "#f9f6f2"),
            2 ** 20: ("#b06ca8", "#f9f6f2"),
        }
    
        def on_key_down(event):
            '键盘按下处理函数'
            keysym = event.keysym
            if keysym in keymap:
                if keymap[keysym]():  # 如果有数字移动
                    fill2()  # 填充一个新的2
            update_ui()
            if is_gameover():
                mb = messagebox.askyesno(
                    title="gameover", message="游戏结束!
    是否退出游戏!")
                if mb:
                    root.quit()
                else:
                    reset()
                    update_ui()
    
        def update_ui():
            '''刷新界面函数
            根据计算出的f地图数据,更新各个Label的设置
            '''
            for r in range(4):
                for c in range(len(_map_data[0])):
                    number = _map_data[r][c]  # 设置数字
                    label = map_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(get_score())  # 重设置分数
    
        # 创建一个frame窗口,此创建将容纳全部的widget 部件
        frame = Frame(root, bg=game_bg_color)
        frame.grid(sticky=N + E + W + S)
        # 设置焦点能接收按键事件
        frame.focus_set()
        frame.bind("<Key>", on_key_down)
    
        # 初始化图形界面
        map_labels = []
        for r in range(4):
            row = []
            for c in range(len(_map_data[0])):
                value = _map_data[r][c]
                text = str(value) if value else ''
                label = Label(frame, text=text, width=4, height=2,
                              font=("黑体", 30, "bold"))
                label.grid(row=r, column=c, padx=5, pady=5, sticky=N + E + W + S)
                row.append(label)
            map_labels.append(row)
    
        # 设置显示分数的Lable
        label = Label(frame, text='分数', font=("黑体", 30, "bold"),
                      bg="#bbada0", fg="#eee4da")
        label.grid(row=4, column=0, padx=5, pady=5)
        label_score = Label(frame, text='0', font=("黑体", 30, "bold"),
                            bg="#bbada0", fg="#ffffff")
        label_score.grid(row=4, columnspan=2, column=1, padx=5, pady=5)
    
        # 以下设置重新开始按钮
        def reset_game():
            reset()
            update_ui()
    
        restart_button = Button(frame, text='重新开始', font=("黑体", 16, "bold"),
                                bg="#8f7a66", fg="#f9f6f2", command=reset_game)
        restart_button.grid(row=4, column=3, padx=5, pady=5)
    
        update_ui()  # 更新界面
    
        root.mainloop()  # 进入tkinter主事件循环
    
    
    main()  # 启动游戏
  • 相关阅读:
    Docker学习笔记
    SpringMVC学习笔记
    机器学习预测2022年考研成绩、考研分数线
    代码随想录贪心算法
    给定两个序列src,dst,src为入栈顺序,判断dst是否为src的一个出栈顺序(c++)
    代码随想录回溯算法
    代码随想录动态规划
    代码随想录二叉树
    Docker安装memcached
    OpenEuler镜像配置
  • 原文地址:https://www.cnblogs.com/shijieli/p/10641299.html
Copyright © 2020-2023  润新知