python 实现 2048游戏

Python 实现2048游戏

完整代码下载地址:https://download.csdn.net/download/qq_41676952/14939740

效果图:

说明

  • 通过控制方向键实现上下左右的移动
  • 按下u键回退到上一步,仅支持回退一步
  • 按下r键重新开始
  • 按下q键出退出游戏

思路:

1.导入必要的依赖包

import os
import keyboard   #用于监听键盘按键事件
import random

2.创建地图:

# 创建数组
field = [[random.choice([0, 2, 4]) for j in range(4)] for i in range(4)]
print_field(field)

3.监听键盘事件

# 监测按键
keyboard.hook(fun)  # 当有键盘按键事件触发时会调用fun函数
keyboard.wait()

4.处理键盘按键事件

  • r 重新开始
  • u 撤销上一步
  • q 退出
  • 方向键控制游戏操作

:对应的按键可以自定义,在以下代码的对应 出修改即可

def fun(key):
    """ 检测按键事件 up down left right """
    # print(key.name)
    if key.event_type == 'down': 
        if key.name == 'q':# q退出
            raise('退出游戏!')

        elif key.name == 'r':# r重新开始
            for i in range(4):
                for j in range(4):
                    field[i][j] = random.choice([0, 0, 0, 2, 2, 4])

            print_field(field) # 更新显示
 
        elif key.name == 'u':# u撤销上一步操作
            for i in range(4):
                for j in range(4):
                    field[i][j] = field_1[i][j]
            
            print_field(field)# 更新输出显示

        elif key.name in ['left', 'right', 'up', 'down']:  # 方向键
            for i in range(4):
                for j in range(4):
                    field_1[i][j] = field[i][j]

            # 按下方向键之后计算新的矩阵
            process(key.name)

            # 产生一个随机数字加入field
            create_new()

            # 输出显示
            print_field(field)

5.按下方向键后计算新的矩阵

  • 先进行去零操作,
  • 再进行移动计算

以左移为例:矩阵的每一行先进行去零操作,再进行左移动计算,
[2,0,2,4] -> [2,2,4,0] -> [4,4,0,0]
[2,0,0,2] -> [2,2,0,0] -> [4,0,0,0]
[0,0,2,2] -> [2,2,0,0] -> [4,0,0,0]
[2,2,2,2] -> [2,2,2,2] -> [4,4,0,0]

右移、上移、下移 其本质和左移是相同的,在调用 f1(dat) 函数时,对调用数据的方向进行调整一下就可以了

注意 f1(dat) 函数调用时数据的顺序


def zero_filter(dat):
    """去除零元素"""
    temp_dat = [0, 0, 0, 0]
    k = 0
    for i in range(4):
        if dat[i]:
            temp_dat[k] = dat[i]
            k = k + 1

    return temp_dat


def f1(dat):
    """
    计算每一行(列)移动后的元素
    """

    dat = zero_filter(dat)

    if dat[0] == dat[1]:
        dat[0] = dat[0] + dat[1]

        if dat[2] == dat[3]:
            dat[1] = dat[2] + dat[3]
            dat[2] = 0
            dat[3] = 0
        else:
            dat[1] = dat[2]
            dat[2] = dat[3]
            dat[3] = 0
    else:
        if dat[1] == dat[2]:
            dat[1] = dat[1] + dat[2]
            dat[2] = dat[3]
            dat[3] = 0
        else:
            if dat[2] == dat[3]:
                dat[2] = dat[2] + dat[3]
                dat[3] = 0
            else:
                pass
    return dat


def process(key_name):
    # 计算移动后的矩阵
    if key_name == 'left':
        for i in range(4):
            temp_dat = f1(field[i])
            for j in range(4):
                field[i][j] = temp_dat[j]

    elif key_name == 'right':
        for i in range(4):
            temp_dat = f1(field[i][::-1])
            for j in range(4):
                field[i][j] = temp_dat[::-1][j]

    elif key_name == 'up':
        for j in range(4):
            temp_dat = []
            for i in range(4):
                temp_dat.append(field[i][j])
            temp_dat = f1(temp_dat)

            for i in range(4):
                field[i][j] = temp_dat[i]

    else:
        for j in range(4):
            temp_dat = []
            for i in range(4):
                temp_dat.append(field[i][j])
            temp_dat = f1(temp_dat[::-1])

            for i in range(4):
                field[i][j] = temp_dat[::-1][i]

6.产生新的数据
每次移动后都需要在空白的位置产生一个新的数据

def create_new():
    """
    产生一个新的数字 2 或 4 
    """
    field_zero = []

    # 找出field中数字为0的位置
    for i in range(4):
        for j in range(4):
            if field[i][j] == 0:
                field_zero.append((i, j))

    if field_zero:
        index_zero = random.choice(field_zero)
        field[index_zero[0]][index_zero[1]] = random.choice([2, 4])

7.输出显示

  • 控制输出的格式,通过对print函数的参数进行设置,修改终端默认显示的颜色,
  • 可通过设置color_dict 设置不同数字的前景色和背景色

color_dict = {0: [30, 40],  # 白字 黑底
              2: [31, 47],  # 黑字 白底
              4: [30, 42],  # 黑字 绿底
              8: [30, 46],    # 黑字 青蓝色底
              16: [37, 44],   # 黑字 蓝底
              32: [37, 41],   # 白字 红底
              64: [37, 45],   # 白字 紫红色底
              128: [30, 43],  # 白字 黄底
              256: [30, 42],  # 白字 青蓝色
              512: [30, 44],  # 黑字 蓝底
              1024: [37, 45],  # 黑字 紫红色
              2048: [37, 40],  # 白字 黑底
              4096: [37, 40],     # 白字 黑底
              8192: [37, 40]}     # 白字 黑底


def print_field(dat):
    """在控制台打印输出"""
    os.system('cls')
    print('\n********* 2048 *********\n')
    for i in range(4):
        for j in range(4):
            # 控制不同数字的颜色
            color_set = '\033[1;{};{}m'.format(color_dict[dat[i][j]][0], color_dict[dat[i][j]][1])  
            print(color_set, str(dat[i][j]).center(4), end='')
        color_set = '\033[1;37;40m'
        print(color_set)

完整代码下载地址:https://download.csdn.net/download/qq_41676952/14939740

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值