讲师中心 微信公众号
AI工具推荐 视频效率加速

Python Curses贪吃蛇:食物生成与蛇身增长机制优化指南

夏宇大大_6402

夏宇大大_6402

发布时间:2025-12-08 21:01:54

|

902人浏览过

|

来源于php中文网

原创

Python Curses贪吃蛇:食物生成与蛇身增长机制优化指南

本教程旨在解决python `curses`贪吃蛇游戏中,蛇吃掉食物后未能正确增长,并导致`typeerror`的问题。核心在于当蛇头与食物位置重合时,应立即重新生成新的食物,而非简单地将食物变量设为`none`。通过修正食物生成逻辑,确保游戏能够持续进行,并使蛇身在每次成功进食后正确增长。

引言

在开发基于curses库的Python贪吃蛇游戏时,一个常见的挑战是确保游戏逻辑的正确性,特别是关于食物的生成、蛇的进食以及蛇身的增长。本文将深入探讨一个特定问题:当蛇吃到食物后,蛇身未能增长,反而可能导致程序崩溃,并提供详细的解决方案和优化建议。

问题分析

原始代码中,当蛇头与食物位置重合时,食物的处理逻辑如下:

        if head == food:
            food = None
        else:
            tail = snake.pop()

这段代码的意图是,如果蛇吃到了食物,就将food变量设为None,表示食物已被移除。然而,问题出在随后的渲染阶段:

        w.addch(food[0], food[1], curses.ACS_PI)

当food被设为None后,尝试访问food[0]和food[1]会导致TypeError: 'NoneType' object is not subscriptable。这意味着程序在吃掉食物后,试图在一个空值上执行索引操作而崩溃。

立即学习“Python免费学习笔记(深入)”;

提示词大师-python版
提示词大师-python版

图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍

下载

此外,将food设为None也未能实现食物的重新生成,导致游戏无法继续提供新的食物供蛇食用,从而无法实现蛇身的增长。蛇身增长的逻辑依赖于在吃到食物时 不 移除蛇尾,而当前代码在food == None时,既没有重新生成食物,也没有跳过snake.pop()(虽然这是在else块中,但food=None本身就是问题)。

解决方案

解决此问题的关键在于,当蛇头吃到食物后,不应将food设为None,而应该立即调用create_food函数来生成一个新的食物。这样既避免了TypeError,又确保了游戏能够持续进行,并允许蛇身通过不移除尾部来增长。

将原始代码中的食物处理逻辑修改为:

        if head == food:
            food = create_food(snake, box) # 吃到食物后,立即生成新食物
        else:
            tail = snake.pop() # 未吃到食物,移除蛇尾
            w.addch(tail[0], tail[1], ' ') # 清除旧蛇尾的显示

注意: 原始代码中清除蛇尾的w.addch(tail[0], tail[1], ' ')语句位于w.addch(food[0], food[1], curses.ACS_PI)之后,并且在else块之外,这意味着即使蛇吃到了食物,tail变量也可能未定义,或者在food = None之后,tail的清除也可能出错。更合理的做法是,只有在蛇未吃到食物时,才移除蛇尾并清除其显示。

完整代码示例与优化

以下是修正后的main函数核心游戏循环部分,包含了食物生成与蛇身增长的正确逻辑:

import curses
from random import randint

def create_food(snake, box):
    """
    在指定边界内生成一个不在蛇身位置的食物。
    """
    food = None
    while food is None:
        # 确保食物生成在边界内
        food = [randint(box[0] + 1, box[1] - 1), randint(box[2] + 1, box[3] - 1)]
        # 确保食物不生成在蛇身上
        if food in snake:
            food = None
    return food

def main(stdscr):
    curses.curs_set(0) # 隐藏光标
    stdscr.timeout(100) # 设置刷新间隔(毫秒),控制游戏速度

    sh, sw = stdscr.getmaxyx() # 获取屏幕高度和宽度
    w = curses.newwin(sh, sw, 0, 0) # 创建一个新的窗口
    w.keypad(1) # 启用特殊按键输入(如方向键)

    # 定义游戏区域的边界 [y_min, y_max, x_min, x_max]
    box = [3, sh - 3, 3, sw - 3]
    # 初始化蛇身,由多个坐标组成
    snake = [
        [sh // 2, sw // 2],
        [sh // 2, sw // 2 - 1],
        [sh // 2, sw // 2 - 2]
    ]

    food = create_food(snake, box) # 初始生成食物

    key = curses.KEY_RIGHT # 初始方向向右

    while True:
        # 绘制边界和分数(每次循环都重新绘制,因为curses会清屏)
        w.border(0)
        w.addstr(0, 5, f" Score: {len(snake) - 3} ") # 显示分数

        next_key = w.getch() # 获取用户输入
        # 如果没有新输入,保持当前方向
        key = key if next_key == -1 else next_key

        # 计算新蛇头的位置
        head = [snake[0][0], snake[0][1]]

        if key == curses.KEY_DOWN:
            head[0] += 1
        elif key == curses.KEY_UP:
            head[0] -= 1
        elif key == curses.KEY_LEFT:
            head[1] -= 1
        elif key == curses.KEY_RIGHT:
            head[1] += 1

        snake.insert(0, head) # 将新蛇头插入蛇身列表的开头

        # 检查蛇头是否与食物重合
        if head == food:
            food = create_food(snake, box) # 吃到食物,生成新食物
        else:
            # 未吃到食物,移除蛇尾并清除其显示
            tail = snake.pop()
            w.addch(tail[0], tail[1], ' ')

        # 绘制食物
        # create_food函数保证了food在绘制前不会是None
        w.addch(food[0], food[1], curses.ACS_PI)

        # 绘制新蛇头
        w.addch(snake[0][0], snake[0][1], '*')

        # 游戏结束条件:撞墙或撞到自己
        if (
            snake[0][0] in [box[0], box[1]] or # 撞到上下墙
            snake[0][1] in [box[2], box[3]] or # 撞到左右墙
            snake[0] in snake[1:] # 撞到自己
        ):
            break # 退出游戏循环

        w.refresh() # 刷新屏幕显示

    # 游戏结束,显示"Game Over"
    w.addstr(sh // 2, sw // 2 - 5, "GAME OVER!")
    w.refresh()
    w.getch() # 等待用户按键后退出

curses.wrapper(main)

代码解析

  1. create_food(snake, box) 函数: 此函数负责在游戏区域box内随机生成食物的坐标,并确保新生成的食物不会出现在蛇身的任何部分上,避免食物被立即“吃掉”或生成在不可达位置。
  2. 游戏循环 (while True):
    • 边界与分数绘制: 每次循环开始时,重新绘制游戏边界和当前分数。这是curses应用的常见做法,以确保屏幕内容正确更新。
    • 输入处理: w.getch() 获取用户按键,控制蛇的移动方向。key = key if next_key == -1 else next_key 确保在没有新输入时,蛇继续沿当前方向移动。
    • 蛇头移动: 根据当前方向更新蛇头head的坐标。
    • 插入新蛇头: snake.insert(0, head) 将新蛇头添加到蛇身列表的最前端。
    • 食物交互逻辑:
      • if head == food::如果蛇头位置与食物位置相同,说明蛇吃到了食物。此时,调用create_food(snake, box)生成新的食物,并且 不执行 snake.pop()操作,从而使蛇身增长一个单位。
      • else::如果蛇没有吃到食物,则执行snake.pop()移除蛇身列表的最后一个元素(即蛇尾),并在屏幕上清除其显示,模拟蛇的移动。
    • 绘制: 分别绘制食物(curses.ACS_PI代表一个π符号)和新蛇头(*)。
    • 游戏结束条件: 检查蛇头是否撞到边界或撞到自身(snake[0] in snake[1:]),如果满足条件则跳出循环,游戏结束。
    • 刷新屏幕: w.refresh() 更新屏幕显示所有绘制的元素。

注意事项

  • curses环境: 在不同操作系统上,`

热门AI工具

更多
墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

相关专题

更多
while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

334

2023.09.25

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

80

2026.09.23

Buffalo框架路由与请求处理实操指南
Buffalo框架路由与请求处理实操指南

本专题讲解Buffalo框架路由与请求处理机制,涵盖路由注册与分组、资源路由、Handler编写规范、Context上下文方法、参数绑定、中间件编写挂载、Session与Cookie读写、Flash消息及错误页面定制方法。

40

2026.09.23

Buffalo框架零基础入门教程
Buffalo框架零基础入门教程

本专题整理Buffalo框架入门内容,涵盖Go环境准备、buffalo CLI安装、新项目生成、目录结构说明、dev热加载启动、数据库连接配置与常见报错排查,帮助新手按约定优于配置的思路跑通第一个Buffalo框架应用。

20

2026.09.23

Conan创建软件包配方指南
Conan创建软件包配方指南

本专题介绍通过conanfile.py创建软件包的方法,讲解包名、版本、依赖和构建设置等基础信息,以及source、build、package、package_info等常用方法的作用及编写思路。

20

2026.09.22

Conan二进制包配置指南
Conan二进制包配置指南

本专题介绍Conan根据操作系统、编译器、架构和构建类型生成二进制包的方法,讲解Profile、Settings、Options及Package ID的作用,帮助管理不同平台和编译环境下的包版本。

40

2026.09.22

Conan私有仓库搭建教程
Conan私有仓库搭建教程

本专题系统的讲解Conan私有仓库的搭建流程,涵盖仓库服务部署、存储目录配置、用户认证、权限划分和远程地址添加,并介绍内部C++依赖包的上传、下载及版本维护方法。

40

2026.09.22

loomy官网入口地址合集
loomy官网入口地址合集

本专题汇总了 Loomy 桌面 AI 助理的官方入口地址合集及使用指南。提供 macOS 与 Windows 客户端下载 。Loomy 是讯飞推出的桌面级 AI 工作搭子,支持文件整理、数据分析、网页操作及通过飞书/钉钉远程操控电脑,助你高效完成本地办公任务 。

40

2026.09.22

NumPy常见函数使用方法
NumPy常见函数使用方法

本专题整理 NumPy 常见函数使用方法相关教程,覆盖函数大全、参数用法、数组运算、统计聚合、排序处理、where 条件筛选、linspace 创建数列等常用场景,帮助读者快速掌握 NumPy 函数调用思路和实际数据处理技巧。

60

2026.09.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn