ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

如何用python写一个2048?

2022-02-08 19:30:32  阅读:203  来源: 互联网

标签:direction python 2048 如何 range score row png vList


用python写一个2048?你也可以!

这是我今天的学习过程中看到的
代码来源:《Python游戏设计案例实战》
过程很复杂啦,我把源码放在这,具体程序放在GitHub上,想要的点击这里

from msilib.schema import Directory
from tkinter import *
from tkinter import messagebox as msgbox
import random
from tkinter import scrolledtext
from turtle import left
from unittest import result
v = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
def init(v):
    for i in range(4):
        v[i] = [random.choice([0,0,0,2,2,4])for x in v[i]]
def align(vList,direction):
    '''
    对齐非零的数字
    direction == 'left':向左对齐,如[8,0,0,2]左对齐后成为[8,2,0,0]
    direction == 'right':向右对齐,如[8,0,0,2]左对齐后成为[0,0,8,2]
    '''
    #移除列表中的0元素
    for i in range(vList.count(0)):
        vList.remove(0)
    #被移除的0元素
    zeros = [0 for x in range(4 - len(vList))]
    if direction == 'left':
        #在右侧补0元素
        vList.extend(zeros)
    else:
        #在左侧补0元素
        vList[:0] = zeros
def addSame(vList,direction):
    #将相同的元素相加,返回新增积分
    score = 0
    if direction == 'left':
        for i in [0,1,2]:
            if vList[i] == vList[i+1] != 0:
                vList[i] *= 2
                vList[i+1] = 0
                score += vList[i]
                return {'bool':True,'score':score}
    else:
        for i in [3,2,1]:
            if vList[i] == vList[i-1] != 0:
                vList[i] *= 2
                vList[i-1] = 0
                score += vList[i]
                return{'bool':True,'score':score}
    return{'bool':False,'score':score}
def handle(vList,direction):
    '''
    处理一行(列)中的数据,得到最终的该行(列)的数字状态值,返回得分
    vList:列表结构,存储了一行(列)中的数据
    direction:移动放向,向上和向左都使用方向'left',向右和向下都使用'right'
    '''
    increment = 0
    align(vList,direction)
    result = addSame(vList,direction)
    #合并的得分
    increment += result['score']
    align(vList,direction)
    return increment
def operation(v,op):
    totalScore = 0
    #计算本次得分
    gameOver = False
    direction = 'left'
    print(op)
    if op == 'Left':
        #向左移动
        direction = 'left'
        for row in range(4):
            totalScore += handle(v[row],direction)
    elif op == 'Right':
        #向右移动
        direction = 'right'
        for row in range(4):
            totalScore += handle(v[row],direction)
    elif op == 'Up':
        #向上移动
        direction = 'left'
        for col in range(4):
            #将矩阵中一列复制到一个列表中然后处理
            vList = [v[row][col]for row in range(4)]
            totalScore += handle(vList,direction)
            #将处理后的列表中的数字覆盖原来矩阵中的值
            for row in range(4):
                v[row][col] = vList[row]
    elif op == 'Down':
        #向下移动
        direction = 'right'
        for col in range(4):
            #将矩阵中一列复制到一个列表中然后处理
            vList = [v[row][col]for row in range(4)]
            totalScore += handle(vList,direction)
            #将处理后的列表中的数字覆盖原来矩阵中的值
            for row in range(4):
                v[row][col] = vList[row]
    #以下是在空白区域随机产生的新的数字
    N = 0
    for q in v:
        #统计0的个数
        N += q.count(0)
        #统计空白区域数目N
        #存在剩余的空白区域时,产生随机数2和4
        if N != 0:
            addElement(N)
        #判断游戏是否真正结束
        if isOver():
            gameOver = True
        return {'gameOver':gameOver,'score':totalScore}
def addElement(N):
    #按照数字2和数字4出现的比率为3:1来产生随机数2和4
    num = random.choice([2,2,2,4])
    #产生随机数K,上一步产生的2或4将被填到第k个空白区域
    k = random.randrange(1,N+1)
    n = 0
    for i in range(4):
        for j in range(4):
            if v[i][j] == 0:
                n += 1
                if n == k:
                    v[i][j] = num
                    break
def isOver():
    N = 0
    for q in v:
        #统计0的个数
        N += q.count(0)
    if N != 0:
        return False
    else:
        for row in range(4):
            #按行判断是否有相同元素
            flag = isListOver(v[row])
            if flag ==False:
                return False
        for col in range(4):
            #按列判断是否有相同元素
            #将矩阵中的一列复制到一个列表中然后处理
            vList = [v[row][col] for row in range(4)]
            flag = isListOver(vList)
            if flag == False:
                return False
    return True
def isListOver(vList):
    for i in [0,1,2]:
        if vList[i] == vList[i+1] and vList[i+1] != 0:
            return False
    return True
def drawGameImage():
    global x,y 
    for i in range(0,4):
        for j in range(0,4):
            #计算对应的图像索引号
            m = v[i][j]
            #二维列表中存储的是2,4,8,需要将其转换成图像索引号
            #print('m',m)
            n = 0
            while m > 1:
                n = n + 1
                m = m / 2
            #print('n',n)
            img1 = imgs[n]
            #从imgs列表获取对应的图像
            cv.create_image((j*120+70,i*120+70),image = img1)
            #显示到Canvas上
            cv.pack()
def callback(event):
    #按键处理
    global score 
    print('按下键:',event.char)
    KeyCode = event.keysym
    #获取用户按下的方向键
    result = operation(v,KeyCode)
    #根据移动方向重新计算矩阵值
    drawGameImage()
    #绘制游戏界面
    score += result['score']
    #从字典中获取'score'键值
    root.title('得分:'+str(score))
    if result['gameOver'] == True:
        #游戏结束
        print('Game Over, You failed!')
        msgbox.showinfo('Game Over','Your total score:'+str(score))
    else:
        if score >= 20480:
            print('Game Over, You win!!!')
            msgbox.showinfo('Game Over','You Win!!!')
init(v)
score = 0
root = Tk()
root.title('2048')
imgs = [PhotoImage(file=x) for x in ['0.png','2.png','4.png','8.png','16.png','32.png','64.png','128.png','256.png','512.png','1024.png','2048.png','4096.png']]
cv = Canvas(root,bg='green',width = 500,height = 500)
drawGameImage()
cv.bind('<KeyPress>',callback)
cv.pack()
cv.focus_set()
#将焦点设置到cv上
root.mainloop()

如果你觉得我的分享有点意思,或者能给你带来一些收获,那么给我点个赞叭!

标签:direction,python,2048,如何,range,score,row,png,vList
来源: https://blog.csdn.net/weixin_45386315/article/details/122829726

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有