栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python命令行版2048小游戏

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python命令行版2048小游戏

本文是1小时入门Python的“课后习题”。

完整代码请移步Python实现命令行版2048。

按理说看到这里,并写到这里,就应该算是完成了入门,那么接下来就要用入门学会的知识,写一个命令行版的2048小游戏。

2048的逻辑无非是操作4x4的方格,每个方格中有一个数,我们可以操作这些数字进行移动,如果两个相同的数字在我们的操作下相撞了,那么它们就可以合并了。

而这个4x4的方格,无非是一个矩阵。

我们的操作可以理解为输入字符,用wsad代表上下左右,y代表确定,n代表取消。

python接收字符的函数是input,例如

>>> x = input("input a number")
input a number5
>>> x
'5'

而创建矩阵,可以用np.zeros([4,4]).astype(int),表示创建一个 4 × 4 4times4 4×4的全0矩阵,并化为整形。

矩阵中只有16个元素,尽管循环效率低下,但足以满足人的操作速度了。

操作逻辑

2048只有四个手势动作,即上下左右,这四个动作所引发的结果都可以归结为对单行或者单列的操作,进而归结为对一个列表的操作。

例如对于[0,2,2,0],如果向右合并,则输出为[0,0,0,4],向左合并则输出为[4,0,0,0]。

其实现方法如下

def addZeros(lst:list,flag:bool=True):
    zeros = [0]*(4-len(lst))
    return zeros+lst if flag else lst+zeros

# flat为Ture时把0补在左边;否则补右边
def rmZero(lst, flag=True):
    lst = [x for x in lst if x]
    end = len(lst)-1
    if end < 1:
        return addZeros(lst,flag)
    index = range(end) if flag else range(end,-1,-1)
    iter = 1 if flag else -1
    for i in index:
        if lst[i] == lst[i+iter]:
            lst[i] *= 2
            lst[i+iter] = 0
    lst = [x for x in lst if x]
    return addZeros(lst,flag)

然后,针对行和列均需遍历执行rmZero。其中,wsad分别表示上下左右

# w,s,a,d分别为上下左右
def updateMat(mat,op):
    flag = op in "sd"
    if op in "ws":
        for i in range(4):
            mat[:,i] = rmZero(mat[:,i],flag)
    else:
        for i  in range(4):
            mat[i,:] = rmZero(mat[i,:],flag)
    return mat

这三个函数已经完成了2048的交互逻辑,接下来就是将updateMat这个函数嵌入到游戏的流程之中。

初始化

2048游戏在开始之前,需要初始化一个4x4的矩阵,然后每次操作之前,需要在矩阵中为0的位置随机生成一个数。随机生成的数的取值范围决定了游戏的难度,所以生成方式也比较灵活,下面给出一种普通的生成方法

def addNew(mat):
    i,j = randint(4),randint(4)
    while(mat[i,j]!=0):
        i,j = randint(4),randint(4)
    else:
        x = randint(1,100)
        x = 7 - np.floor(np.log2(x))
        mat[i,j] = int(2**x)
    print(mat)

交互操作

然后是交互操作,asdw表示操作,q表示退出。

def InputNew(mat):
    op = input("input operator:")
    if op in "asdw":
        newMat = updateMat(mat*1,op)
        if np.max(np.abs(mat-newMat))==0:
            print("Invalid operation")
            return mat,"Error"
        else:
            return newMat,"True"
    if op == 'q':
        return mat, "Exit"
    print("Invalid Input")
    return mat, "Error"

main

if __name__ == "__main__":
    while(1):
        addNew(mat)
        newMat,flag = InputNew(mat)
        while flag=="Error":
            newMat,flag = InputNew(mat)
        if flag == "Exit":
            break
        mat = newMat
        print(mat)
        print('-'*30)

        if np.max(mat)==2048: flag == "win"
        if np.min(mat)!=0: flag == "lose"
        if flag in ["win","lose"]:
            if input(f"you {flag}, play again? ")=="y":
                mat *= 0
            else: break
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/503513.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号