欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Python_2048(完结)

程序员文章站 2022-03-15 14:52:31
Python_2048(完结)前言本游戏的难点在于四个方向的操作响应.对四个操作的方向函数进行重新整理.以便更好的阅读与理解##对行操作把对行的操作拆分出来.因为四个方向的操作都要用到# 合并一个列表def change(rows: list): '''函数说明''' # 将一行进行合并重排,返回重排后的结果 # 参数: 要合并重排的列表 # 返回值: 重排后的列表 # 第一步,先去0 new_rows = [x for x in ro...

Python_2048(完结)

前言

本游戏的难点在于四个方向的操作响应.
对四个操作的方向函数进行重新整理.以便更好的阅读与理解

##对行操作
把对行的操作拆分出来.因为四个方向的操作都要用到

# 合并一个列表
def change(rows: list):
    '''函数说明'''
    # 将一行进行合并重排,返回重排后的结果
    # 参数: 要合并重排的列表
    # 返回值: 重排后的列表
    
    # 第一步,先去0
    new_rows = [x for x in rows if x != 0]  # 这里用了列表的推导式生成不含0的列表
 
    '''
    以上代码等价于:
    new_rows = []
    for x in rows:
        if x != 0
        new_rows.append(x)
    '''
    result = []  # 用来存放结果

    # 实现分析:
    '''
    如果只有最后一个数,直接返回
    如果当前的数a与后面的数b相同,则添加a*2到结果列表,并将索引指向b后一个数
    如果当前的数a与后面的数b不相同,则添加a到列表,并将索引指向b
    直到索引指向最后一个数为止
    '''
    i = 0
    while i < len(new_rows):
        if i == (len(new_rows) - 1):
            result.append(new_rows[i])
            i += 1
        elif new_rows[i] != new_rows[i + 1]:
            result.append(new_rows[i])
            i += 1
        else:
            result.append(new_rows[i] * 2)
            i += 2
        while len(result) < 4:
            result.append(0)
    return result

如果将这个函数搞懂,那整个就不难懂了

左移操作

def move_left(grids: list):
    '''函数说明'''
    # 功能: 左移操作响应
    # 参数: 游戏列表
    # 返回值: 是否移动过

    ischanged = False  # 移动标识
    for i in range(4):
        temp = grids[i][:]  # 保存原数据
        grids[i] = change(grids[i])
        if temp != grids[i]:  # 判断与原来的数据有没有改动,从而破定是不是移动过
            ischanged = True
    return ischanged

右移操作

与左移比,唯一的不同就是左右顺序的问题

def move_right(grids):
    ''' 函数说明 '''
    # 功能: 响应右移操作
    # 参数: 游戏列表
    # 返回值: 是否移动过

    ischanged = False  # 移动标识
    for i in range(4):
        temp = grids[i]  # 保存原数据
        grids[i] = change(grids[i][::-1])[::-1]  # 这是的两个反转操作要理解操作前反转,操作后反转即可
        if temp != grids[i]:  # 判断与原来的数据有没有改动,从而破定是不是移动过
            ischanged = True
    return ischanged

上移操作

def move_up(grids):
    ''' 函数说明 '''
    # 功能: 响应上移操作
    # 参数: 游戏列表
    # 返回值: 是否移动过

    ischanged = False  # 移动标识
    for i in range(4):
        temp = [grids[j][i] for j in range(4)]  # 保存原数据
        tempres = change(temp)
        for j in range(4):
            grids[j][i] = tempres[j]
        if temp != tempres:  # 判断与原来的数据有没有改动,从而破定是不是移动过
            ischanged = True
    return ischanged

下移操作

def move_down(grids):
    ''' 函数说明 '''
    # 功能: 响应下移操作
    # 参数: 游戏列表
    # 返回值: 是否移动过

    ischanged = False  # 移动标识
    for i in range(4):
        temp = [grids[j][i] for j in range(4)]  # 保存原数据
        tempres = change(temp[::-1])[::-1]
        for j in range(4):
            grids[j][i] = tempres[j]
        if temp != tempres:  # 判断与原来的数据有没有改动,从而破定是不是移动过
            ischanged = True
    return ischanged

检测结束

for i in range(4):
        # 末填满 可移
        if 0 in grids[i]:
            return False
        # 左右方向可移, 可移
        if grids[i] != change(grids[i]) or grids[i] != change(grids[i][::-1])[::-1]:
            return False

        # 上下方向可移,可移 
        temp = [grids[j][i] for j in range(4)]
        if temp  != change(temp) or temp != change(temp[::-1])[::-1]:
            return False
    return True

主程序

def main():
    grids = []
    for i in range(4):
        grids.append([0, 0, 0, 0])
    init_game(grids)
    ischanged = False
    while 1:
        n = input("请输入操作:")
        if n == "a":
            ischanged = move_left(grids)
        elif n == "d":
            ischanged = move_right(grids)
        elif n == "w":
            ischanged = move_up(grids)
        elif n == "s":
            ischanged = move_down(grids)
        else:  # 按键不符合要求跳过
            continue
        if ischanged:
            # 移动过才添加新的数,否则,保持不变
            print("移动过")
            add_num(grids)
            isover = check_game(grids)
            if isover:
                print("游戏失败")
                break
        else:
            print("没有移动过")
        draw_grids(grids)

完整示例代码

from random import randint

'''程序说明'''
# 本程序实现了2048小游戏的命令行版
# 操作说明:a向左滑,d向右滑,w向上滑,s向下滑


def main():
    grids = []
    for i in range(4):
        grids.append([0, 0, 0, 0])
    init_game(grids)
    ischanged = False
    while 1:
        n = input("请输入操作:a向左滑,d向右滑,w向上滑,s向下滑")
        if n == "a":
            ischanged = move_left(grids)
        elif n == "d":
            ischanged = move_right(grids)
        elif n == "w":
            ischanged = move_up(grids)
        elif n == "s":
            ischanged = move_down(grids)
        else:  # 按键不符合要求跳过
            continue
        if ischanged:
            # 移动过才添加新的数,否则,保持不变
            print("移动过")
            add_num(grids)
            isover = check_game(grids)
            if isover:
                print("游戏失败")
                break
        else:
            print("没有移动过")
        draw_grids(grids)


# 游戏初始化
def init_game(grids):
    ''' 函数说明 '''
    # 用来初始游戏相关
    # grids: 二维四元素列表

    # 调用两次生成数字,参数为2,即生成数字是2数
    add_num(grids, 2)
    add_num(grids, 2)
    # 画游戏界面
    draw_grids(grids)


# 新增数字
def add_num(grids, *args):
    ''' 函数说明 '''
    # 用来往表格新增数字
    # grids: 二维四元素列表
    # *args: 没有参数时,随机生成,有参数时用参数
    i = randint(0, 3)
    j = randint(0, 3)
    while grids[i][j] != 0:
        i = randint(0, 3)
        j = randint(0, 3)

    # 如果args不为空,则用args的参数来作为新增的数
    if args:
        grids[i][j] = args[0]
        return

    num = randint(0, 9)  # 数字2的比例比数字4的比例稍大点.可以通过下述的条件来改变2者之间的比例
    if num < 7:
        grids[i][j] = 2
        return
    else:
        grids[i][j] = 4
        return

# 画格子
def draw_grids(grids):
    '''函数说明'''
    # 将游戏数据显示出来
    # grids:二维四元素列表

    print("#" * 25)  # 上辚框
    for i in range(4):
        for j in range(4):
            print("#" + str(grids[i][j]).rjust(5), end="")  # 格式化输出数字
        print("#")
    print("#" * 25)  # 下边框


# 左移
def move_left(grids: list):
    '''函数说明'''
    # 功能: 左移操作响应
    # 参数: 游戏列表
    # 返回值: 是否移动过

    ischanged = False  # 移动标识
    for i in range(4):
        temp = grids[i][:]  # 保存原数据
        grids[i] = change(grids[i])
        if temp != grids[i]:  # 判断与原来的数据有没有改动,从而破定是不是移动过
            ischanged = True
    return ischanged

# 右移


def move_right(grids):
    ''' 函数说明 '''
    # 功能: 响应右移操作
    # 参数: 游戏列表
    # 返回值: 是否移动过

    ischanged = False  # 移动标识
    for i in range(4):
        temp = grids[i]  # 保存原数据
        grids[i] = change(grids[i][::-1])[::-1]
        if temp != grids[i]:  # 判断与原来的数据有没有改动,从而破定是不是移动过
            ischanged = True
    return ischanged

# 上移


def move_up(grids):
    ''' 函数说明 '''
    # 功能: 响应上移操作
    # 参数: 游戏列表
    # 返回值: 是否移动过

    ischanged = False  # 移动标识
    for i in range(4):
        temp = [grids[j][i] for j in range(4)]  # 保存原数据
        tempres = change(temp)
        for j in range(4):
            grids[j][i] = tempres[j]
        if temp != tempres:  # 判断与原来的数据有没有改动,从而破定是不是移动过
            ischanged = True
    return ischanged

# 下移


def move_down(grids):
    ''' 函数说明 '''
    # 功能: 响应下移操作
    # 参数: 游戏列表
    # 返回值: 是否移动过

    ischanged = False  # 移动标识
    for i in range(4):
        temp = [grids[j][i] for j in range(4)]  # 保存原数据
        tempres = change(temp[::-1])[::-1]
        for j in range(4):
            grids[j][i] = tempres[j]
        if temp != tempres:  # 判断与原来的数据有没有改动,从而破定是不是移动过
            ischanged = True
    return ischanged

# 合并重排操作


def change(rows: list):
    '''函数说明'''
    # 将一行进行合并重排,返回重排后的结果
    # 参数: 要合并重排的列表
    # 返回值: 重排后的列表

    # 第一步,先去0
    new_rows = [x for x in rows if x != 0]  # 这里用了列表的推导式生成不含0的列表
    '''
    以上代码等价于:
    new_rows = []
    for x in rows:
        if x != 0
        new_rows.append(x)
    '''
    result = []  # 用来存放结果

    # 实现分析:
    '''
    如果只有最后一个数,直接返回
    如果当前的数a与后面的数b相同,则添加a*2到结果列表,并将索引指向b后一个数
    如果当前的数a与后面的数b不相同,则添加a到列表,并将索引指向b
    直到索引指向最后一个数为止
    '''
    i = 0
    while i < len(new_rows):
        if i == (len(new_rows) - 1):
            result.append(new_rows[i])
            i += 1
        elif new_rows[i] != new_rows[i + 1]:
            result.append(new_rows[i])
            i += 1
        else:
            result.append(new_rows[i] * 2)
            i += 2
    while len(result) < 4:
        result.append(0)
    return result

# 检测


def check_game(grids):
    for i in range(4):
        # 末填满 可移
        if 0 in grids[i]:
            return False
        # 左右方向可移, 可移
        if grids[i] != change(grids[i]) or grids[i] != change(grids[i][::-1])[::-1]:
            return False
        temp = [grids[j][i] for j in range(4)]
        if temp != change(temp) or temp != change(temp[::-1])[::-1]:
            return False
    return True


if __name__ == '__main__':
    main()

后记

一个简单的控件台小程序,被我们用朴素的方法完成了.
游戏还有很多可以优化与调整的地方
比如:

  • 加入分数的概念
  • 加入反悔的概念
  • 加入中途退出游戏的概念
  • 加入成就的概念
  • 加入2048游戏胜得的概念
    等等.
    创意是无限的.
    这里用一个最简单的示例,起一个抛砖引玉的功能.

编程的世界充满了奇思妙想.
今天是2048,也许,未来还会有其他有意思的游戏.发挥你无穷的想象力,创造属于自己的世界吧

本文地址:https://blog.csdn.net/weixin_41810846/article/details/111939107