详解200行Python代码实现控制台版2048【总有一款坑适合你】【超详细】

这篇博客介绍了如何使用Python的curses库在Windows系统上实现2048游戏。内容包括安装curses库的解决方法、游戏逻辑框架、用户输入处理、棋盘创建与核心操作,以及绘制游戏界面。文章详细记录了作者在学习过程中遇到的问题及解决方案,并提供了完整代码。
摘要由CSDN通过智能技术生成

跟着实验楼学习了2048的Python实现,先丢个地址 200行Python代码实现2048

我接触Python时间不长,只了解一些基本的语法和容器,在学习的过程中遇到不少问题,这里做一个记录。


curses库(windows系统)

本来想着在搞明白之前先运行代码看看效果,结果光这里的报错就折腾了我好半天。查了下才知道curses库不支持windows系统,需要使用一个 unofficial curses来代替Python自带的curses库,也就是whl包。unofficial curses ←这里下载,如果显示404,换谷歌浏览器!!!我当时用的是qq浏览器,404到怀疑人生= = 下载完以后,在Terminal中先用cd进入到刚下载的位置(最好改下默认保存路径,把它下载到2048的项目文件夹),输入pip install+带后缀的文件名,回车,大部分人到这一步就完事了。

但我可不是一般人,我是踩雷大师。

说一说不同报错的解决方案吧。

1.not a supported wheel on this platform

多半是版本下错了。链接中有好多版本,可以根据自己Python的版本和系统来确定。如果还是报错的话,开一个Python文件运行这段话检查下信息。

import pip 
print(pip.pep425tags.get_supported())

如果显示 module 'pip' has no attribute 'pep425tags',改成这个

import pip._internal
print(pip._internal.pep425tags.get_supported())

以下是我的输出。现在可以根据元组组合挑选对应版本了。比如说我就应该下载 curses-2.2+utf8-cp36-cp36m-win_amd64.whl

[('cp36', 'cp36m', 'win_amd64'), ('cp36', 'none', 'win_amd64'), ('py3', 'none', 'win_amd64'), ('cp36', 'none', 'any'), ('cp3', 'none', 'any'), ('py36', 'none', 'any'), ('py3', 'none', 'any'), ('py35', 'none', 'any'), ('py34', 'none', 'any'), ('py33', 'none', 'any'), ('py32', 'none', 'any'), ('py31', 'none', 'any'), ('py30', 'none', 'any')]

2. You should consider upgrading via the 'python -m pip install --upgrade pip' command.

pip的时候可能会遇到的错误,提示你升级pip。直接按它说的,输入python-m pip install --upgrade pip回车就好了。

回车后如果显示Requirement already up-to-date: (一段路径),那就根据提供的路径找到这个文件删除后再升级。

到这,终于可以开始进入正题了!!!


导入需要的包

import curses
from random import randrange, choice
from collections import defaultdict

对引入的包做一个简单的了解吧~

curses是一个图形函数库,用于实现终端无关的控制台输出以及输入处理,可以在终端内绘制简单的图形用户界面。

randrange()函数,从给定的范围返回随机项。

choice()函数,返回一个列表,元组或字符串的随机项。

# 如果直接import random使用时就需要写成random.choice/randrange
from random import randrange, choice
# 输出[0,100)之间的随机数
print(randrange(0,100))
# 随机输出1,2,3,4的其中一项,同理qwerty
print(choice([1,2,3,4]),choice('qwerty'))

defaultdict,dict的一个子类,重写了部分方法,使得查询错误时会调用工厂函数产生对应工厂类的对象。也就是有一个默认值保证查询出错时程序不会报错(不严谨解释)

from collections import defaultdict
test = [('x',5),('y',4),('z',6),('x',6)]
testDict = defaultdict(list)
for x,y in test:
    testDict[x].append(y)
print(list(testDict.items()))
# 输出[('x', [5, 6]), ('y', [4]), ('z', [6])]
print(testDict['w'])
# 没有报错,而是输出了[]

主逻辑

借用下实验楼的图。

经过分析,会发现其实就两种状态。游戏中和不在游戏中。其中,不在游戏中包括赢和输两个分支。按功能来看,需要初始化(赢/输/开始新的一局)和退出游戏。由此可以先得出以下的框架(具体内容等会儿填充):

def main(stdscr):

    def init():
        # 重置游戏棋盘
        return 'Game'

    def not_game(state):
        # 画出 GameOver 或者 Win 的界面
        # 读取用户输入得到action,判断是重启游戏还是结束游戏
        responses = defaultdict(lambda: state) # 默认是当前状态,没有行为就会一直在当前界面循环
        responses['Restart'], responses['Exit'] = 'Init', 'Exit' # 对应不同的行为转换到不同的状态
        return responses[action]

    def game():
        # 画出当前棋盘状态
        # 读取用户输入得到action
        if action == 'Restart':
            return 'Init'
        if action == 'Exit':
            return 'Exit'
        # if 成功移动了一步:
            if 游戏胜利了:
                return 'Win'
            if 游戏失败了:
                return 'Gameover'
        return 'Game'


    state_actions = {
            'Init': init,
            'Win': lambda: not_game('Win'),
            'Gameover': lambda: not_game('Gameover'),
            'Game': game
        }

    state = 'Init'

    # 状态机开始循环
    while state != 'Exit':
        # 末尾的():state_actions中以函数名作为字典值
        state = state_actions[state]() 

两个点。

1.def main(stdscr)里的stdscr

curses使用两个数据结构映射终端屏幕,stdscr和curscr。stdscr是“标准屏幕”(逻辑屏幕),在curses函数库产生输出时就刷新,是默认输出窗口(用户不会看到该内容)。curscr是“当前屏幕”(物理屏幕),在调用refresh函数是,函数库会将curscr刷新为stdscr的样子。

2.lambda函数和state = state_actions[state]() 末尾的括号

匿名函数。创建语法是:lambda parameters:ex

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值