基于python做一个2048小游戏

 更新时间:2024年01月14日 08:53:38   作者:微小冷  
2048的逻辑无非是操作4*4的方格,每个方格中有一个数,这些数可以移动,如果两个相同的数字在移动时相撞了,就可以彼此合并,本文将给大家介绍如何基于python做一个2048小游戏,感兴趣的小伙伴跟着小编一起来看看吧

逻辑设计

2048的逻辑无非是操作4 × 4 的方格,每个方格中有一个数,这些数可以移动,如果两个相同的数字在移动时相撞了,就可以彼此合并。

而这个4 × 4的方格,无非是一个矩阵。只需设计好移动逻辑,再用PyGame将这个方格表现出来就算大功告成。

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

首先,对列表进行操作时,先排除0的影响,在排除0的影响之后,若相邻元素相等,即可合并。例如对于[ 0 , 2 , 2 , 0 ],如果向左合并则输出为[ 4 , 0 , 0 , 0 ]。

def mergeLst(lst):
    lst = [x for x in lst if x] # 删除lst中的0
    newLst = []
    N, i = len(lst), 0
    while i < N:
        if i<N-1 and lst[i] == lst[i+1]:
            newLst.append(lst[i]*2)
            i += 2
        else:
            newLst.append(lst[i])
            i += 1
    return newLst + (4-len(newLst))*[0]

测试如下

mergeLst([0,2,2,0]) # [4, 0, 0, 0]
mergeLst([2,2,2,2]) # [4, 4, 0, 0]
mergeLst([2,2,8,4]) # [4, 8, 4, 0]

相应地,对一个矩阵进行合并,只需针对每一行进行操作即可

[mergeLst(x) for x in mat]

对于上下左右不同按键的操作,可以先将矩阵旋转,然后再进行合并操作,合并之后再逆转回来。

def rotate(mat):
    newMat = [[[] for _ in mat] for b in mat[0]]
    for i,row in enumerate(mat, 1):
        for j,r in enumerate(row, 0):
            newMat[j][-i] = r
    return newMat

在实际操作中,左、下、右、上分别对应旋转0,1,2,3次,即

KEY_DCT = {
    pygame.K_LEFT:0,   pygame.K_DOWN:1,
    pygame.K_RIGHT:2,  pygame.K_UP:3
}

从而游戏的总挪动逻辑如下

def updateMat(mat, key):
    N = KEY_DCT[key]
    for _ in range(N):
        mat = rotate(mat)
    mat = [mergeLst(x) for x in mat]
    for _ in range(4-N):
        mat = rotate(mat)   # 旋转回来
    return mat

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

from itertools import product
from random import sample, randint
def addNew(mat):
    ijs = []
    for i,j in product(range(4), range(4)):
        if mat[i][j] == 0:
            ijs.appen((i,j))
    if len(ijs) == 0:
        return False
    i, j = sample(ijs, 1)[0]   # 挑选一个不为0的点
    x = randint(1,100)
    x = 7 - np.floor(np.log2(x))
    mat[i,j] = int(2**x)
    return True

绘图逻辑

这个游戏的绘图逻辑比较简单,只需为矩阵中每个元素赋予一个颜色即可。

GRAY = (205, 205, 205)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
SIZE = 80

def setColor(N):
    if N == 0:
        return (233, 233, 233)
    n = int(math.log2(N))
    delta = int(255/15)
    return (255-n*delta, n*delta, (128+n*delta)%255)


def draw(win, font, mat):
    for i,j in product(range(4), range(4)):
        ch = str(mat[i][j])
        rect = (j*SIZE, i*SIZE, SIZE, SIZE)
        c = setColor(mat[i][j])
        pygame.draw.rect(win, c, rect)
        pygame.draw.rect(win, GRAY, rect, 5)

        txt = font.render(ch, True, GREEN)
        offset =  (0.5 - len(ch)/10)*SIZE
        xy = (j*SIZE+offset, (i+0.3)*SIZE)
        win.blit(txt, xy)

主循环

最后,实现游戏的主循环如下

def gui():
    pygame.init()
    win = pygame.display.set_mode(
        (4 * SIZE, 4 * SIZE))
    pygame.display.set_caption("迷宫游戏")
    font.init()
    f = font.Font('C:\\WINDOWS\\Fonts\\ARLRDBD.TTF', 32)
    running = True

    mat = [[0]*4 for _ in range(4)]
    addNew(mat)
    while running:
        win.fill(WHITE)
        for evt in pygame.event.get():
            if evt.type == pygame.QUIT:
                return
            if evt.type == pygame.KEYDOWN and evt.key in KEY_DCT:
                newMat = updateMat(mat, evt.key)
                if newMat!=mat:
                    mat = newMat
                    running = addNew(mat)
        draw(win, f, mat)
        # 判断玩家是否到达出口
        if max([max(x) for x in mat])==2048:
            print("恭喜通关")
            running = False
        if min([min(x) for x in mat])>0:
            print("游戏失败")
            running = False

        pygame.display.update()

游戏效果如下

以上就是基于python做一个2048小游戏的详细内容,更多关于python 2048小游戏的资料请关注脚本之家其它相关文章!

相关文章

  • 使用Nibabel库对nii格式图像的读写操作

    使用Nibabel库对nii格式图像的读写操作

    这篇文章主要介绍了使用Nibabel库对nii格式图像的读写操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • 深入理解python中的ThreadLocal

    深入理解python中的ThreadLocal

    本文主要介绍了深入理解python中的ThreadLocal,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • Numpy之random.randint产生随机整数方式

    Numpy之random.randint产生随机整数方式

    这篇文章主要介绍了Numpy之random.randint产生随机整数方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • Python实现数据透视表详解

    Python实现数据透视表详解

    今天小编就为大家分享一篇用Python实现数据的透视表的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-10-10
  • pycharm创建django项目出现路径错误问题

    pycharm创建django项目出现路径错误问题

    在PyCharm中创建Django项目时,若使用之前项目的环境编译器,且已修改其根目录,则新建项目路径可能出错。解决办法是在设置中选择Project,通过齿轮图标进入Show All,选择编译器路径,点击笔形图修改Development configuration的Root path为/,以确保新项目能正确创建
    2024-09-09
  • 教你使用Python连接oracle

    教你使用Python连接oracle

    今天教各位小伙伴怎么用Python连接oracle,文中附带非常详细的图文示例,对正在学习的小伙伴们很有帮助哟,需要的朋友可以参考下
    2021-05-05
  • Pytorch之nn.Upsample()和nn.ConvTranspose2d()用法详解

    Pytorch之nn.Upsample()和nn.ConvTranspose2d()用法详解

    nn.Upsample和nn.ConvTranspose2d是PyTorch中用于上采样的两种主要方法,nn.Upsample通过不同的插值方法(如nearest、bilinear)执行上采样,没有可学习的参数,适合快速简单的尺寸增加,而nn.ConvTranspose2d通过可学习的转置卷积核进行上采样
    2024-10-10
  • Pytorch中accuracy和loss的计算知识点总结

    Pytorch中accuracy和loss的计算知识点总结

    在本片文章里小编给大家整理的是关于Pytorch中accuracy和loss的计算相关知识点内容,有需要的朋友们可以学习下。
    2019-09-09
  • Python多线程、异步+多进程爬虫实现代码

    Python多线程、异步+多进程爬虫实现代码

    这篇文章主要介绍了Python多线程、异步+多进程爬虫实现代码,需要的朋友可以参考下
    2016-02-02
  • python使用PIL和matplotlib获取图片像素点并合并解析

    python使用PIL和matplotlib获取图片像素点并合并解析

    这篇文章主要介绍了python使用PIL和matplotlib获取图片像素点并合并解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09

最新评论