这篇文章主要介绍了通过Python实现的简易的自动玩贪吃蛇游戏的小程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学一学

实现效果

先看看效果

这比我手动的快多了,而且是单机的,自动玩没惹骂我,哈哈 ,多人游戏整个自动玩会被骂死~

代码

没装软件的先安装一下软件,没装模块的安装一下pygame模块。

|

1

|

`pip install pygame`

|

导入模块

|

1

2

|

`import` `pygame,sys,time,random``from` `pygame.``locals` `import` `*`

|

定义颜色变量

|

`redColour` `=` `pygame.Color(``255``,``0``,``0``)``blackColour` `=` `pygame.Color(``0``,``0``,``0``)``whiteColour` `=` `pygame.Color(``255``,``255``,``255``)``greenColour` `=` `pygame.Color(``0``,``255``,``0``)``headColour` `=` `pygame.Color(``0``,``119``,``255``)`

|

在所有后续的除法中,为预防pygame输出出现偏差,必须取除数(//)而不是单纯除法(/)

程序界面

第0行,HEIGHT行,第0列,WIDTH列为围墙,所以实际大小是13*13

|

`IGHT` `=` `15``WIDTH` `=` `15``FIELD_SIZE` `=` `HEIGHT` `*` `WIDTH``# 蛇头位于snake数组的第一个元素``HEAD` `=` `0`

|

用数字代表不同的对象,因为运动时矩阵上每个格子会处理成到达食物的路径长度,因此这三个变量间需要有足够大的间隔(>HEIGHT*WIDTH)来互相区分,小写一般是坐标,大写代表常量。对于新手小白想更轻松的学好Python基础,Python爬虫,web开发、大数据,数据分析,人工智能等技术,这里给大家分享系统教学资源,架下我尉(同英): 2763177065 【教程/工具/方法/解疑】

|

`FOOD` `=` `0``UNDEFINED` `=` `(HEIGHT` `+` `1``)` `*` `(WIDTH` `+` `1``)``SNAKE` `=` `2` `*` `UNDEFINED`

|

snake是一维数组,对应元素直接加上以下值就表示向四个方向移动。

|

`LEFT` `=` `-``1``RIGHT` `=` `1``UP` `=` `-``WIDTH` `# 一维数组,所以需要整个宽度都加上才能表示上下移动。``DOWN` `=` `WIDTH`

|

错误码

|

1

|

`ERR` `=` `-``2333`

|

用一维数组来表示二维的东西,board表示蛇运动的矩形场地,初始化蛇头在(1,1)的地方,初始蛇长度为1。

|

`board` `=` `[``0``]` `*` `FIELD_SIZE` `#[0,0,0,……]``snake` `=` `[``0``]` `*` `(FIELD_SIZE``+``1``)``snake[HEAD]` `=` `1``*``WIDTH``+``1``snake_size` `=` `1`

|

与上面变量对应的临时变量,蛇试探性地移动时使用。

|

`tmpboard` `=` `[``0``]` `*` `FIELD_SIZE``tmpsnake` `=` `[``0``]` `*` `(FIELD_SIZE``+``1``)``tmpsnake[HEAD]` `=` `1``*``WIDTH``+``1``tmpsnake_size` `=` `1`

|

food:食物位置初始在(4, 7),best_move: 运动方向。

|

|

`food` `=` `4` `*` `WIDTH` `+` `7``best_move` `=` `ERR`

|

运动方向数组,游戏分数(蛇长)

|

|

`mov` `=` `[LEFT, RIGHT, UP, DOWN]                                          ``score` `=` `1`

|

检查一个cell有没有被蛇身覆盖,没有覆盖则为free,返回true 。

|

|

`def` `is_cell_free(idx, psize, psnake):``return` `not` `(idx` `in` `psnake[:psize])`

|

检查某个位置idx是否可向move方向运动

|

|

`def` `is_move_possible(idx, move):``flag` `=` `False``if` `move` `=``=` `LEFT:``#因为实际范围是13*13,[1,13]*[1,13],所以idx为1时不能往左跑,此时取余为1所以>1``flag` `=` `True` `if` `idx``%``WIDTH >` `1` `else` `False``elif` `move` `=``=` `RIGHT:``#这里的<WIDTH-2跟上面是一样的道理``flag` `=` `True` `if` `idx``%``WIDTH < (WIDTH``-``2``)` `else` `False``elif` `move` `=``=` `UP:``#这里向上的判断画图很好理解,因为在[1,13]*[1,13]的实际运动范围外,还有个``#大框是围墙,就是之前说的那几个行列,下面判断向下运动的条件也是类似的``flag` `=` `True` `if` `idx > (``2``*``WIDTH``-``1``)` `else` `False``elif` `move` `=``=` `DOWN:``flag` `=` `True` `if` `idx < (FIELD_SIZE``-``2``*``WIDTH)` `else` `False``return` `flag`

|

重置board

board_BFS后,UNDEFINED值都变为了到达食物的路径长度。

如需要还原,则要重置它。

|

`def` `board_reset(psnake, psize, pboard):``for` `i` `in` `range``(FIELD_SIZE):``if` `i` `=``=` `food:``pboard[i]` `=` `FOOD``elif` `is_cell_free(i, psize, psnake):` `# 该位置为空``pboard[i]` `=` `UNDEFINED``else``:` `# 该位置为蛇身``pboard[i]` `=` `SNAKE`

|

广度优先搜索遍历整个board,计算出board中每个非SNAKE元素到达食物的路径长度。

|

`def` `board_BFS(pfood, psnake, pboard):``queue` `=` `[]``queue.append(pfood)``inqueue` `=` `[``0``]` `*` `FIELD_SIZE``found` `=` `False``# while循环结束后,除了蛇的身体,``# 其它每个方格中的数字为从它到食物的曼哈顿间距``while` `len``(queue)!``=``0``:``idx` `=` `queue.pop(``0``)``#初始时idx是食物的坐标``if` `inqueue[idx]` `=``=` `1``:` `continue``inqueue[idx]` `=` `1``for` `i` `in` `range``(``4``):``#左右上下``if` `is_move_possible(idx, mov[i]):``if` `idx` `+` `mov[i]` `=``=` `psnake[HEAD]:``found` `=` `True``if` `pboard[idx``+``mov[i]] < SNAKE:` `# 如果该点不是蛇的身体``if` `pboard[idx``+``mov[i]] > pboard[idx]``+``1``:``#小于的时候不管,不然会覆盖已有的路径数据。``pboard[idx``+``mov[i]]` `=` `pboard[idx]` `+` `1``if` `inqueue[idx``+``mov[i]]` `=``=` `0``:``queue.append(idx``+``mov[i])``return` `found`

|

从蛇头开始,根据board中元素值,从蛇头周围4个领域点中选择最短路径。

|

`def` `choose_shortest_safe_move(psnake, pboard):``best_move` `=` `ERR``min` `=` `SNAKE``for` `i` `in` `range``(``4``):``if` `is_move_possible(psnake[HEAD], mov[i])` `and` `pboard[psnake[HEAD]``+``mov[i]]<``min``:``#这里判断最小和下面的函数判断最大,都是先赋值,再循环互相比较``min` `=` `pboard[psnake[HEAD]``+``mov[i]]``best_move` `=` `mov[i]``return` `best_move`

|

检查是否可以追着蛇尾运动,即蛇头和蛇尾间是有路径的,为的是避免蛇头陷入死路。虚拟操作,在tmpboard,tmpsnake中进行。

|

`def` `is_tail_inside():``global` `tmpboard, tmpsnake, food, tmpsnake_size``tmpboard[tmpsnake[tmpsnake_size``-``1``]]` `=` `0` `# 虚拟地将蛇尾变为食物(因为是虚拟的,所以在tmpsnake,tmpboard中进行)``tmpboard[food]` `=` `SNAKE` `# 放置食物的地方,看成蛇身``result` `=` `board_BFS(tmpsnake[tmpsnake_size``-``1``], tmpsnake, tmpboard)` `# 求得每个位置到蛇尾的路径长度``for` `i` `in` `range``(``4``):` `# 如果蛇头和蛇尾紧挨着,则返回False。即不能follow_tail,追着蛇尾运动了``if` `is_move_possible(tmpsnake[HEAD], mov[i])` `and` `tmpsnake[HEAD]``+``mov[i]``=``=``tmpsnake[tmpsnake_size``-``1``]` `and` `tmpsnake_size>``3``:``result` `=` `False``return` `result`

|

让蛇头朝着蛇尾运行一步,不管蛇身阻挡,朝蛇尾方向运行。

|

`def` `follow_tail():``global` `tmpboard, tmpsnake, food, tmpsnake_size``tmpsnake_size` `=` `snake_size``tmpsnake` `=` `snake[:]``board_reset(tmpsnake, tmpsnake_size, tmpboard)` `# 重置虚拟board``tmpboard[tmpsnake[tmpsnake_size``-``1``]]` `=` `FOOD` `# 让蛇尾成为食物``tmpboard[food]` `=` `SNAKE` `# 让食物的地方变成蛇身``board_BFS(tmpsnake[tmpsnake_size``-``1``], tmpsnake, tmpboard)` `# 求得各个位置到达蛇尾的路径长度``tmpboard[tmpsnake[tmpsnake_size``-``1``]]` `=` `SNAKE` `# 还原蛇尾``return` `choose_longest_safe_move(tmpsnake, tmpboard)` `# 返回运行方向(让蛇头运动1步)`

|

在各种方案都不行时,随便找一个可行的方向来走(1步)

`def` `any_possible_move():``global` `food , snake, snake_size, board``best_move` `=` `ERR``board_reset(snake, snake_size, board)``board_BFS(food, snake, board)``min` `=` `SNAKE``for` `i` `in` `range``(``4``):``if` `is_move_possible(snake[HEAD], mov[i])` `and` `board[snake[HEAD]``+``mov[i]]<``min``:``min` `=` `board[snake[HEAD]``+``mov[i]]``best_move` `=` `mov[i]``return` `best_move`

|

转换数组函数

|

`def` `shift_array(arr, size):``for` `i` `in` `range``(size,` `0``,` `-``1``):``arr[i]` `=` `arr[i``-``1``]``def` `new_food():``#随机函数生成新的食物``global` `food, snake_size``cell_free` `=` `False``while` `not` `cell_free:``w` `=` `random.randint(``1``, WIDTH``-``2``)``h` `=` `random.randint(``1``, HEIGHT``-``2``)``food` `=` `WIDTH``*``h` `+` `w``cell_free` `=` `is_cell_free(food, snake_size, snake)``pygame.draw.rect(playSurface,redColour,Rect(``18``*``(food``/``/``WIDTH),` `18``*``(food``%``WIDTH),``18``,``18``))`

|

真正的蛇在这个函数中,朝pbest_move走1步。

|

`def` `make_move(pbest_move):``global` `snake, board, snake_size, score``shift_array(snake, snake_size)``snake[HEAD]` `+``=` `pbest_move``p` `=` `snake[HEAD]``for` `body` `in` `snake:``#画蛇,身体,头,尾``pygame.draw.rect(playSurface,whiteColour,Rect(``18``*``(body``/``/``WIDTH),` `18``*``(body``%``WIDTH),``18``,``18``))``pygame.draw.rect(playSurface,greenColour,Rect(``18``*``(snake[snake_size``-``1``]``/``/``WIDTH),``18``*``(snake[snake_size``-``1``]``%``WIDTH),``18``,``18``))``pygame.draw.rect(playSurface,headColour,Rect(``18``*``(p``/``/``WIDTH),` `18``*``(p``%``WIDTH),``18``,``18``))``#下面一行是把初始情况会出现的第一个白块bug填掉``pygame.draw.rect(playSurface,(``255``,``255``,``0``),Rect(``0``,``0``,``18``,``18``))``# 刷新pygame显示层``pygame.display.flip()``# 如果新加入的蛇头就是食物的位置``# 蛇长加1,产生新的食物,重置board(因为原来那些路径长度已经用不上了)``if` `snake[HEAD]` `=``=` `food:``board[snake[HEAD]]` `=` `SNAKE` `# 新的蛇头``snake_size` `+``=` `1``score` `+``=` `1``if` `snake_size < FIELD_SIZE: new_food()``else``:` `# 如果新加入的蛇头不是食物的位置``board[snake[HEAD]]` `=` `SNAKE` `# 新的蛇头``board[snake[snake_size]]` `=` `UNDEFINED` `# 蛇尾变为UNDEFINED,黑色``pygame.draw.rect(playSurface,blackColour,Rect(``18``*``(snake[snake_size]``/``/``WIDTH),``18``*``(snake[snake_size]``%``WIDTH),``18``,``18``))``# 刷新pygame显示层``pygame.display.flip()`

|

虚拟地运行一次,然后在调用处检查这次运行可否可行,可行才真实运行。对于新手小白想更轻松的学好Python基础,Python爬虫,web开发、大数据,数据分析,人工智能等技术,这里给大家分享系统教学资源,架下我尉(同英): 2763177065 【教程/工具/方法/解疑】

虚拟运行吃到食物后,得到虚拟下蛇在board的位置。

|

`def` `virtual_shortest_move():``global` `snake, board, snake_size, tmpsnake, tmpboard, tmpsnake_size, food``tmpsnake_size` `=` `snake_size``tmpsnake` `=` `snake[:]` `# 如果直接tmpsnake=snake,则两者指向同一处内存``tmpboard` `=` `board[:]` `# board中已经是各位置到达食物的路径长度了,不用再计算``board_reset(tmpsnake, tmpsnake_size, tmpboard)``food_eated` `=` `False``while` `not` `food_eated:``board_BFS(food, tmpsnake, tmpboard)   ``move` `=` `choose_shortest_safe_move(tmpsnake, tmpboard)``shift_array(tmpsnake, tmpsnake_size)``tmpsnake[HEAD]` `+``=` `move` `# 在蛇头前加入一个新的位置``# 如果新加入的蛇头的位置正好是食物的位置``# 则长度加1,重置board,食物那个位置变为蛇的一部分(SNAKE)``if` `tmpsnake[HEAD]` `=``=` `food:``tmpsnake_size` `+``=` `1``board_reset(tmpsnake, tmpsnake_size, tmpboard)` `# 虚拟运行后,蛇在board的位置``tmpboard[food]` `=` `SNAKE``food_eated` `=` `True``else``:` `# 如果蛇头不是食物的位置,则新加入的位置为蛇头,最后一个变为空格``tmpboard[tmpsnake[HEAD]]` `=` `SNAKE``tmpboard[tmpsnake[tmpsnake_size]]` `=` `UNDEFINED`

|

如果蛇与食物间有路径,则调用本函数。

|

`def` `find_safe_way():``global` `snake, board``safe_move` `=` `ERR``# 虚拟地运行一次,因为已经确保蛇与食物间有路径,所以执行有效``# 运行后得到虚拟下蛇在board中的位置,即tmpboard``virtual_shortest_move()` `# 该函数唯一调用处``if` `is_tail_inside():` `# 如果虚拟运行后,蛇头蛇尾间有通路,则选最短路运行(1步)``return` `choose_shortest_safe_move(snake, board)``safe_move` `=` `follow_tail()` `# 否则虚拟地follow_tail 1步,如果可以做到,返回true``return` `safe_move`

|

初始化pygame 模块

|

1

|

`pygame.init()`

|

定义一个变量用来控制游戏速度

|

1

|

`fpsClock` `=` `pygame.time.Clock()`

|

创建pygame显示层

|

1

2

|

`playSurface` `=` `pygame.display.set_mode((``270``,``270``))``pygame.display.set_caption(``'贪吃蛇'``)`

|

绘制pygame显示层

|

1

|

`playSurface.fill(blackColour)`

|

初始化食物

|

`pygame.draw.rect(playSurface,redColour,Rect(``18``*``(food``/``/``WIDTH),` `18``*``(food``%``WIDTH),``18``,``18``))``while` `True``:``for` `event` `in` `pygame.event.get():``#循环监听键盘和退出事件``if` `event.``type` `=``=` `QUIT:``#如果点了关闭``print``(score)``#游戏结束后打印分数``pygame.quit()``sys.exit()``elif` `event.``type` `=``=` `KEYDOWN:``#如果esc键被按下``if` `event.key``=``=``K_ESCAPE:``print``(score)``#游戏结束后打印分数``pygame.quit()``sys.exit()``# 刷新pygame显示层``pygame.display.flip() ``#画围墙,255,255,0是黄色,边框是36是因为,pygame矩形是以边为初始,向四周填充边框``pygame.draw.rect(playSurface,(``255``,``255``,``0``),Rect(``0``,``0``,``270``,``270``),``36``)``# 重置距离``board_reset(snake, snake_size, board)``# 如果蛇可以吃到食物,board_BFS返回true``# 并且board中除了蛇身(=SNAKE),其它的元素值表示从该点运动到食物的最短路径长``if` `board_BFS(food, snake, board):``best_move` `=` `find_safe_way()` `# find_safe_way的唯一调用处``else``:``best_move` `=` `follow_tail()``if` `best_move` `=``=` `ERR:``best_move` `=` `any_possible_move()``# 上面一次思考,只得出一个方向,运行一步``if` `best_move !``=` `ERR: make_move(best_move)``else``:``print``(score)``#游戏结束后打印分数``break``# 控制游戏速度``fpsClock.tick(``20``)``#20看上去速度正好`|

以上就是Python实现自动玩贪吃蛇程序的详细内容,更多关于Python自动玩贪吃蛇的资料请关注python教程入门学习其它相关文章!

【python教程入门学习】Python实现自动玩贪吃蛇程序相关推荐

  1. 代码全解:Python实现自动玩贪吃蛇程序

    录 实现效果 代码 实现效果 先看看效果 这比我手动的快多了,而且是单机的,自动玩没惹骂我,哈哈 ,多人游戏整个自动玩会被骂死~ 代码 没装软件的先安装一下软件,没装模块的安装一下pygame模块. ...

  2. [python教程入门学习]Python是什么?

    Python 是一种高级计算机编程语言,作者是荷兰人吉多·范罗苏姆.在 1989 年圣诞节期间,吉多打算开发一种新的脚本语言,用来取代 ABC 语言,就这样,一门新的编程语言 Python 诞生了. ...

  3. [python教程入门学习]Python标准库映射类型与可散列数据类型的关系

    本文章向大家介绍Python标准库映射类型与可散列数据类型的关系,主要包括Python标准库映射类型与可散列数据类型的关系使用实例.应用技巧.基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋 ...

  4. [python教程入门学习]python学习笔记(CMD执行文件并传入参数)

    本文章向大家介绍python学习笔记(CMD执行文件并传入参数),主要包括python学习笔记(CMD执行文件并传入参数)使用实例.应用技巧.基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋 ...

  5. 【python教程入门学习】普通人学python有意义吗

    普通人学python有意义吗?普通人能不能学习python语言,难不难,是否容易上手,学了python能做那些事情,能挣多少钱?这些问题是很多同学关心的问题,今天python教程入门学习就从小白同学的 ...

  6. 【python教程入门学习】第一个Pygame程序

    Pygame 作为一个入门级的游戏开发库,其实并不难学,只要掌握 Python 编程的相关知识就能很轻松地掌握它. Pygame 语法简单.明了,秉持了 Python 语言一贯的风格.同时,它作为一个 ...

  7. 【python教程入门学习】Python扑克牌21点游戏实例代码

    大家好,本篇文章主要讲的是Python扑克牌21点游戏实例代码,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览 废话还是说太多了 直接上代码 | `import` `random ...

  8. 【python教程入门学习】学python要多久,0基础学python有多难

    学python要多久,0基础学python有多难,这是很多想学习python语言同学绕不开的问题,都害怕花完钱最终没有应有的回报!对于毫无经验0基础的同学来说学习python什么最重要,方向选对坚持下 ...

  9. 【python教程入门学习】Python新年炫酷烟花秀代码

    先介绍下 Pygame 绘制烟花的基本原理,烟花从发射到绽放一共分为三个阶段: 1,发射阶段:在这一阶段烟花的形状是线性向上,通过设定一组大小不同.颜色不同的点来模拟"向上发射" ...

最新文章

  1. 微信小程序直播自己的服务器,使用微信小程序和腾讯云实现直播功能
  2. C++什么是内存泄漏
  3. Git安装及配置5分钟快速教程
  4. java 开发人员工具_Java开发人员的5种工具
  5. 第十五章 Python和Web
  6. 不想帮人家写一辈子程序就要看的一本书
  7. Transfer Execute Redirect重定向方法介绍
  8. SqlServer规则
  9. java反射用法示例_Java反射示例教程
  10. 阿里云 Code Pipeline 体验
  11. 【VRP】基于matlab蚁群算法求解多中心的车辆路径规划问题【含Matlab源码 111期】
  12. HTML5期末大作业:我的家乡网站设计——我的家乡-杭州(7页) HTML+CSS+JavaScript 大学生家乡网页作品 老家网页设计作业模板 学生网页制作源代码下载
  13. 【第8题】求 s=a+aa+aaa+aaaa+aa...a 的值
  14. 计算机房图怎么画,机房CAD图纸的画法教程
  15. 禁止复制服务器文件夹,远程桌面服务器 禁止复制文件夹
  16. adb模拟三指划动,GKUI19+WHUD,全新智能三屏交互体验
  17. Sun Java 国际认证考试流程表
  18. 图的基本操作(C语言)
  19. 1016: 幼儿园小朋友们的难题
  20. 关于语音识别技术的初探

热门文章

  1. 清华南开出品最新视觉注意力机制Attention综述
  2. 北理工硕士生「一字不差」抄袭顶会投稿,网友:买论文被忽悠了?
  3. 清华《摸鱼学导论》开班啦!1000多学子在线摸鱼,无期末考试
  4. 清华博士宅家太无聊,给猫咪讲函数
  5. 用Python分析了582个专业,1281个本科院校,告诉你怎么选择?
  6. 科学家都解决不了的5个“简单”算法,你不来看看?
  7. 自然语言处理(NLP)之从文本中提取时间
  8. 自然语言处理(NLP)之gensim中的TF-IDF的计算方法
  9. python之互斥锁
  10. PyTorch 手把手搭建(MNIST)神经网络