如何用 Python 写出简单的 2048 小遊戏

如何用 Python 写出简单的 2048 小遊戏

大家好,我是一个喜欢研究算法、机械学习和生物计算的小青年,我的CSDN博客是:一骑代码走天涯
如果您喜欢我的笔记,那么请点一下关注、点赞和收藏。如果内容有错或者有改进的空间,也可以在评论让我知道。😄


平时工作太忙,为了舒缓下身心,有空的时候我就会写些杂七杂八的东西😂一方面可以放空下自己的,另一方面顺便训练下自己的写代码能力👨🏻‍💻。

下面是我之前自己用 Python3 复现了一个之前挺火的小游戏 — 2048。因为只是纯粹觉得有趣才写,没有考虑复杂度的问题,也没有用多余的 Python packages来辅助 (只用了Python3 自己的 built-in packages),所以美观和算法上不怎麽好,勿见怪。

接下来,介绍一下这个程序的整个构成:

1. 大纲

整个程序其实就是一个 Class 物件,不需要其它参数,只需要定义Class方法就能运行。

整个程序的大纲如下 (细节后面会讲):

class Playboard2048:
    # 初始化2048遊戏数格
    def __init__(self):
        self.row = 4  # 设定数格为4列
        self.col = 4  # 设定数格为4栏
        self.field = [[0 for c in range(self.col)] for r in range(self.row)]  # 初始所有格子为数字"0"
        
    def __generate_number(self) # 隨机生成一个数字
    def __check_stuck(self)     # 检查是否死局 
    def get_maximum(self)       # 找出现时最大数字
    def show(self)              # 展示遊戏数格
    def move_left(self)         # 把数字往左移动
    def move_up(self)           # 把数字往上移动
    def move_right(self)        # 把数字往右移动
    def move_down(self)         # 把数字往下移动
    def play(self)              # 开始遊戏
    
game = Playboard2048()
game.play()

2. 准备遊戏

代码里有两个物件方法直接与遊戏运行相关,分別是show(self)play(self)

show(self)是用来显示2048的遊戏数格,把数格里面的 "0"换成空格,以便辨认哪儿是可以移动的方向。

def show(self):
    for r in range(self.row):
        temp = self.field[r].copy()
        for i in range(len(temp)):
            if temp[i] == 0:
                temp[i] = " "
        print(temp)

play(self)用是用来初始化遊戏管理遊戏进行时的控制

def play(self):
    exit_ = False  # 检查是否登出遊戏
    stuck_ = False # 检查是否死局
    step = ""      # 玩家的方向选择
    print("Generating a playboard...")  #开始遊戏
    while not exit_ and not stuck_:
        step = ""
        stuck_ = self.__check_stuck()
        if stuck_:   # 判断为死局
            self.show()
            print("Game over! You are stuck.")
            return
        self.__generate_number()
        self.show()
        while step == "":  # 开局,玩家输入方向
            step = input("Your step (Up/Down/Left/Right/Exit): ")
            step = step.lower()
            if step == "exit": # 登出遊戏
                print("Thanks for playing, now ending...")
                return
            print(step)
            if step != "up" and step != "down" and step != "left" and step != "right":
                step = ""
                print("Only Up/Down/Left/Right/Exit is accepted... please re-input: ")
        if step == "left":
            self.move_left()  #左移
        elif step == "right":
            self.move_right() #右移
        elif step == "up":
            self.move_up()    #上移
        elif step == "down":
            self.move_down()  #下移
        max_ = self.get_maximum()  # 找出当前最大数字
        if max_ == 2048: # 当出现2048,判断玩家胜利
            self.show()
            print("You win!!!")
            return

3. 移动数字

在平时我们玩的 2048 遊戏中,每个回合玩家都可以选择把数字往上、下、左、右四个方向其中一个推。只要该方向还有空位,数字就可以往该方向。

下面用 往左移动做一個例子,另外三个写法大同小异:

def move_left(self):
    for r in range(self.row): 
        diff = 0
        for c in range(self.col):
            if self.field[r][c] == 0:
                diff += 1
            elif self.field[r][c] != 0 and diff > 0:
                self.field[r][c - diff] = self.field[r][c]
                self.field[r][c] = 0
    for r in range(self.row):
        for c in range(1, self.col):
            if self.field[r][c] == self.field[r][c - 1] and c != 0:
                self.field[r][c - 1] += self.field[r][c]
                self.field[r][c] = 0
            if self.field[r][c - 1] == 0:
                self.field[r][c - 1] = self.field[r][c]
                self.field[r][c] = 0

4. 数字生成 & 系统检查

这段代码远用了randommath的built-in packages,可以让系统在任意空格中隨机生成数字

p.s.: 生成数字的计算方法是我自己想出来的,效果未必很好。

def __generate_number(self):
    import random
    import math
    empty = []
    for r in range(self.row):
        for c in range(self.col):
            if self.field[r][c] == 0:
                empty.append([r, c])
    [picked_r, picked_c] = random.choice(empty)
    max_ = 0
    for r in range(self.row):
        if max_ <= max(self.field[r]):
            max_ = max(self.field[r])
    self.field[picked_r][picked_c] = 2**(max(0, int(math.log(max_ + 0.00000001, 2)) - 1))  #生成数字的计算方法

当然,这遊戏是有机会死局的,所以每个回合都要检查数格上还有没有空格子给玩家移动。如果四个方向没有,那就返回 stuck = True

def __check_stuck(self):
    stuck = True
    for r in range(self.row):
        for c in range(self.col):
            current = self.field[r][c]
            if 0 <= r < self.row - 1:
                if current == self.field[r + 1][c]:
                    stuck = False
            if 0 < r <= self.row - 1:
                if current == self.field[r - 1][c]:
                    stuck = False
            if 0 <= c < self.col - 1:
                if current == self.field[r][c + 1]:
                    stuck = False
            if 0 < c <= self.col - 1:
                if current == self.field[r][c - 1]:
                    stuck = False
    return stuck

5. 玩遊戏

最后,所有代码都写好的话,保存成Python 文件 (.py)。如果在 Linux,可以直接用 python3 -i 這类工具在terminal运行;在Windows也很简单 只要系统里有Python,双击2048.py文件就能进入遊戏
2048只是一个Python文件
2048遊戏介面

源代码可Github上下载/参考:https://github.com/6x16/Little-games

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 20
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值