ICode9

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

“2048”~~~~益智小游戏的python实现

2020-06-12 18:03:00  阅读:263  来源: 互联网

标签:matrix width python self 2048 ss range 小游戏 grid


      2048是一款非常有趣的益智游戏,是需要你控制方向键来控制所有方块向一个方向移动,两个相同数字的方块撞在一起后会合并成为他们的和,每次移动操作后会在空白的方格处随机生成一个2或者4,最后你只要得到一个“2048”的方块就胜利了。如果16个格子全满了并且相邻的格子都没有相同的数字可以消除的话,那么恭喜你本局游戏结束了。

     2048的作者Gabriele Cirulli最初把把它以开源的形式发布在GitHub上,后来意外地风靡全球,各种版本衍生层出不穷。顺表吐槽一句:这位作者也仅仅只有20岁左右啊!!!而且是利用周末时间完成的,而我们的20岁。。。。。(各种短视频,游戏~~)

    当你读完游戏规则时你可能会觉得这是个小学生游戏,额............这个游戏确实是可以不费太多精力完成的(手动滑稽),但你要想不费一点功夫就成功拼出2048来也确实不太可能,毕竟我也是费了九牛二虎之力也没有完成的人。(拼到512实在觉得烦了就放弃了)。尽管如此也不缺大神的存在,下图是我在某博主的主页看到他拼到16384的场景。(说实话真的佩服他的耐心,要是我的话早就逐渐暴躁了起来...)

     然后呢,给大家免费附上2048的源码大约200多行(python实现),我查看了好多语言的版本,好像都不如python简洁。

#coding=UTF-8
from tkinter import *
from random import randint
from random import choice
import tkinter.messagebox
"""
When you use python 3.X,you need to use the following header file.
from tkinter import *
from random import randint
from random import choice
import tkinter.messagebox
Author:Jeremy Wang
"""

class Grid(object):
    def __init__(self, master=None, height=4, width=4, offset=10, grid_width=200, bg="#696969"):
        self.height = height
        self.width = width
        self.offset = offset
        self.grid_width = grid_width
        self.bg = bg
        self.canvas = Canvas(master, width=self.width*self.grid_width + 2*self.offset,height=self.height*self.grid_width+2*self.offset, bg=self.bg)
        self.initial()

    def initial(self):
        for i in range(0,4):
            for j in range(0,4):
                x = i * self.grid_width + self.offset
                y = j * self.grid_width + self.offset
                self.canvas.create_rectangle(x+10, y+10, x + self.grid_width-10, y + self.grid_width-10, fill="#808080",outline=self.bg)
        self.canvas.pack(side=RIGHT, fill=Y)

    def draw(self, pos, color, text):
        x = pos[0] * self.grid_width + self.offset
        y = pos[1] * self.grid_width + self.offset
        # outline属性要与网格的背景色(self.bg)相同,要不然会很丑
        self.canvas.create_rectangle(x+10, y+10, x + self.grid_width-10, y + self.grid_width-10, fill=color, outline=self.bg)
        ft1 = ('Comic Sans MS', 50, "bold")
        self.canvas.create_text(pos[0] * 200 + 110, pos[1] * 200 + 110, text=text, font=ft1)


class Matrix(object):
    def __init__(self, grid):
        self.grid = grid
        self.matrix = [[0 for i in range(4)] for i in range(4)]
        self.matrix_o = [[0 for i in range(4)] for i in range(4)]
        self.vacancy = []
        self.gamewin = False

        #使用一个字典将数字与其对应的颜色存放起来
        self.color ={0:"#808080", 2:"#FFFACD", 4:"#F5DEB3", 8:"#F0E68C", 16:"#FFFF00", 32:"#FFD700", 64:"#FFA500", 128:"#FF8C00",
                     256:"#CD5C5C", 512:"#FF6347", 1024:"#FF0000", 2048:"#00FFFF"}

    def initial(self):
        self.matrix = [[0 for i in range(4)] for i in range(4)]
        self.void()
        self.generate()
        self.generate()
        self.draw()

        for i in range(0, 4):
            for j in range(0, 4):
                self.matrix_o[i][j] = self.matrix[i][j]



    def draw(self):
        for i in range (0, 4):
            for j in range (0, 4):
                pos = (i, j)
                text = str(self.matrix[i][j])
                color = self.color[self.matrix[i][j]]
                self.grid.draw(pos, color, text)

    #计算空位
    def void(self):
        self.vacancy = []
        for x in range(0,4):
            for y in range(0,4):
                if self.matrix[x][y] == 0:
                    self.vacancy.append((x,y))
        return len(self.vacancy)

    #在空位中,随机生成2或4
    def generate(self):
        pos=choice(self.vacancy)
        if randint(0,5)==4:
            self.matrix[pos[0]][pos[1]] = 4
        else:
            self.matrix[pos[0]][pos[1]] = 2
        del self.vacancy[self.vacancy.index((pos[0], pos[1]))]

    #矩阵左移
    def up(self):
        ss = 0
        for i in range(0, 4):
            for j in range(0, 3):
                s = 0
                if not self.matrix[i][j] == 0:
                    for k in range(j + 1, 4):
                        if not self.matrix[i][k] == 0:
                            if self.matrix[i][j] == self.matrix[i][k]:
                                ss = ss + self.matrix[i][k]
                                self.matrix[i][j] = self.matrix[i][j] * 2
                                if self.matrix[i][j] == 2048:
                                    self.gamewin = True
                                self.matrix[i][k] = 0
                                s = 1
                                break
                            else:
                                break
                    if s == 1:
                        break
        for i in range(0, 4):
            s = 0
            for j in range(0, 3):
                if self.matrix[i][j - s] == 0:
                    self.matrix[i].pop(j - s)
                    self.matrix[i].append(0)
                    s = s + 1
        return ss

    #矩阵右移
    def down(self):
        for i in range(0, 4):
            self.matrix[i].reverse()
        ss = self.up()
        for i in range(0, 4):
            self.matrix[i].reverse()
        return ss

    #矩阵上移
    def left(self):
        ss = 0
        for i in range(0, 4):
            for j in range(0, 3):
                s = 0
                if not self.matrix[j][i] == 0:
                    for k in range(j + 1, 4):
                        if not self.matrix[k][i] == 0:
                            if self.matrix[j][i] == self.matrix[k][i]:
                                ss = ss + self.matrix[k][i]
                                self.matrix[j][i] = self.matrix[j][i] * 2
                                if self.matrix[j][i] == 2048:
                                    self.gamewin = True
                                self.matrix[k][i] = 0
                                s = 1
                                break
                            else:
                                break
                    if s == 1:
                        break
        for i in range(0, 4):
            s = 0
            for j in range(0, 3):
                if self.matrix[j-s][i] == 0:
                    for k in range(j-s, 3):
                        self.matrix[k][i] = self.matrix[k+1][i]
                    self.matrix[3][i] = 0
                    s = s+1
        return ss

    #矩阵下移
    def right(self):
        ss = 0
        for i in range(0, 4):
            for j in range(0, 3):
                s = 0
                if not self.matrix[3-j][i] == 0:
                    k = 3-j-1
                    while k >= 0:
                        if not self.matrix[k][i] == 0:
                            if self.matrix[3-j][i] == self.matrix[k][i]:
                                ss = ss +  self.matrix[k][i]
                                self.matrix[3-j][i] = self.matrix[3-j][i] * 2
                                if self.matrix[3-j][i] == 2048:
                                    self.gamewin = True
                                self.matrix[k][i] = 0
                                s = s+1
                                break
                            else:
                                break
                        k = k -1
                if s == 1:
                        break
        for i in range(0, 4):
            s = 0
            for j in range(0, 3):
                if self.matrix[3-j+s][i] == 0:
                    k = 3-j+s
                    while k > 0:
                        self.matrix[k][i] = self.matrix[k-1][i]
                        k = k-1
                    self.matrix[0][i] = 0
                    s = s+1
        return ss

class Game(Frame):
    def __init__(self, master):
        Frame.__init__(self, master)
        self.grid = Grid(master)
        self.matrix = Matrix(self.grid)
        self.score = 0
        self.status = ['run', 'stop']
        self.grid.canvas.bind_all("<KeyRelease>", self.key_release)

        #界面左侧显示分数
        self.m = StringVar()
        self.ft1 = ('Times New Roman', 40, "bold")
        self.m1 = Message(master, textvariable=self.m, aspect=5000, font=self.ft1, bg="#696969")
        self.m1.pack(side=LEFT, fill=Y)
        self.m.set("Score:"+str(self.score))

        self.initial()

    #这个方法用于游戏重新开始时初始化游戏
    def initial(self):
        self.score = 0
        self.m.set("Score:"+str(self.score))
        self.matrix.initial()

    def key_release(self, event):
        key = event.keysym
        if key == "Up":
            ss = self.matrix.up()
            self.run(ss)
        elif key == "Down":
            ss = self.matrix.down()
            self.run(ss)
        elif key == "Left":
            ss = self.matrix.left()
            self.run(ss)
        elif key == "Right":
            ss = self.matrix.right()
            self.run(ss)

    def run(self, ss):
        if not self.matrix.matrix == self.matrix.matrix_o:
            self.score = self.score + int(ss)
            self.m.set("Score:" + str(self.score))
            if self.matrix.gamewin == True:
                self.matrix.draw()
                message = tkMessageBox.showinfo("大吉大利,今晚吃鸡!", "你的分数: %d" % self.score)
                if message == 'ok':
                    self.initial()
            else:
                self.matrix.void()
                self.matrix.generate()
                for i in range(0, 4):
                    for j in range(0, 4):
                        self.matrix.matrix_o[i][j] = self.matrix.matrix[i][j]
                self.matrix.draw()
        else:
            v = self.matrix.void()
            if v < 1:
                message = tkMessageBox.showinfo("你输了/(ㄒoㄒ)/~~", "你的分数: %d" % self.score)
                if message == 'ok':
                    self.initial()



if __name__ == '__main__':
    root = Tk()
    game = Game(root)
    game.mainloop()

       tips:这个程序的实现是需要用到tkinter库的,tkinter库是python自带的标准库是无需下载的,直接import即可。(温馨提示小白:并不是所有的库都不用下载,有些是需要自己安装的。)

运行之后的界面是这样的,唯一的缺点是当你game over 时页面不会关闭,需要你自己关闭。

最后呢,我也是通过这个游戏悟出了几点人生道理:

1.掌握方法会让你事半功倍。

2.人生走错一步可能就永远弥补不回来了,

3.不以跬步,无以至千里(人生贵在坚持)。

标签:matrix,width,python,self,2048,ss,range,小游戏,grid
来源: https://blog.csdn.net/Huamanlou0907/article/details/106654666

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

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

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

ICode9版权所有