Python贪吃蛇游戏知识点
创始人
2024-10-28 07:03:56
0

一、Python游戏开发,Python实现贪吃蛇小游戏与吃豆豆 附带源码

Python版本: 3.6.4

相关模块:

pygame模块;

以及一些Python自带的模块。

安装Python并添加到环境变量,pip安装需要的相关模块即可。

贪吃蛇的游戏规则应该不需要我多做介绍了吧T_T。写个贪吃蛇游戏其实还是很简单的。首先,我们进行一下游戏初始化:

然后定义一个贪吃蛇类:

其中head_coord用来记录蛇头所在位置,而tail_coords是一个二维数组,用来记录所有蛇身的位置。一开始,贪吃蛇长为3,并且位置是随机生成的。用户通过键来控制贪吃蛇的行动:

需要注意的是,贪吃蛇不能180大拐弯,只能90地拐弯。例如正在向左行动的贪吃蛇不能瞬间变成向右行动。具体而言,代码实现如下:

然后,我们需要随机生成一个食物,且需要保证该食物的位置不与贪吃蛇的位置相同:

在更新贪吃蛇的时候,如果它吃到了食物,则蛇身长加一,否则只是简单的按照给定的方向行动而不改变蛇身长度:

同时,当贪吃蛇吃到食物时,需要重新生成一个新的食物:

最后,当贪吃蛇碰到墙壁或者蛇头碰到蛇身时,游戏结束:

并显示一下游戏结束界面:

玩家通过键控制游戏的主角吃豆人吃掉藏在迷宫内的所有豆子,并且不能被鬼魂抓到。

若能顺利吃完迷宫内的所有豆子并且不被鬼魂抓到,则游戏胜利,否则游戏失败。

逐步实现:

Step1:定义游戏精灵类

首先,让我们先来明确一下该游戏需要哪些游戏精灵类。

①墙类

②食物类(即豆豆)

③角色类

角色类包括吃豆人和鬼魂,鬼魂由电脑控制其运动轨迹,吃豆人由玩家控制其运动轨迹。

显然,其均需具备更新角色位置和改变角色运动方向的能力,其源代码如下:

Step2:设计游戏地图

利用Step1中定义的游戏精灵类,我们就可以开始设计游戏地图了。由于时间有限,我只写了一个关卡的游戏地图,有兴趣的小伙伴可以在此基础上进行扩展(在我的源代码基础上进行扩展是很方便滴~)。游戏地图的设计包括以下四方面内容:

①创建墙

②创建门(一开始关幽灵用的)

image.gif

③创建角色

④创建食物

因为食物不能和墙、门以及角色的位置重叠,所以为了方便设计游戏地图,要先创建完墙、门以及角色后再创建食物:

Step3:设计游戏主循环

接下来开始设计游戏主循环。首先是初始化:

然后定义主函数:

其中startLevelGame函数用于开始某一关游戏,其源代码如下:

showText函数用于在游戏结束或关卡切换时在游戏界面中显示提示性文字,其源代码如下:

二、为什么python贪吃蛇运行错误

'float' object cannot be interpreted as an integer的意思是:float类型不能解释为int类型。

代码错误处应该发生在图中红框内的代码语句中。

因为使用的是Python3所以在所框语句中应该使用//去代替/。

扩展资料:

Python贪吃蛇代码:

import pygame,sys,random,time

from pygame.locals import*#从pygame模块导入常用的函数和常量

#定义颜色变量

black_colour= pygame.Color(0,0,0)

white_colour= pygame.Color(255,255,255)

red_colour= pygame.Color(255,0,0)

grey_colour= pygame.Color(150,150,150)

#定义游戏结束函数

def GameOver(gamesurface):

#设置提示字体的格式

GameOver_font= pygame.font.SysFont("MicrosoftYaHei", 16)

#设置提示字体的颜色

GameOver_colour= GameOver_font.render('Game Over',True,grey_colour)

#设置提示位置

GameOver_location= GameOver_colour.get_rect()

GameOver_location.midtop=(320,10)

#绑定以上设置到句柄

gamesurface.blit(GameOver_colour,GameOver_location)

#提示运行信息

pygame.display.flip()

#休眠5秒

time.sleep(5)

#退出游戏

pygame.quit()

#退出程序

sys.exit()

#定义主函数

def main():

#初始化pygame,为使用硬件做准备

pygame.init()

pygame.time.Clock()

ftpsClock= pygame.time.Clock()

#创建一个窗口

gamesurface= pygame.display.set_mode((640,480))

#设置窗口的标题

pygame.display.set_caption('tanchishe snake')

#初始化变量

#初始化贪吃蛇的起始位置

snakeposition= [100,100]

#初始化贪吃蛇的长度

snakelength= [[100,100],[80,100],[60,100]]

#初始化目标方块的位置

square_purpose= [300,300]

#初始化一个数来判断目标方块是否存在

square_position= 1

#初始化方向,用来使贪吃蛇移动

derection="right"

change_derection= derection

#进行游戏主循环

while True:

#检测按键等pygame事件

for event in pygame.event.get():

if event.type==QUIT:

#接收到退出事件后,退出程序

pygame.quit()

sys.exit()

elif event.type==KEYDOWN:

#判断键盘事件,用w,s,a,d来表示上下左右

if event.key==K_RIGHT or event.key==ord('d'):

change_derection="right"

if event.key==K_LEFT or event.key==ord('a'):

change_derection="left"

if event.key==K_UP or event.key==ord('w'):

change_derection="up"

if event.key==K_DOWN or event.key==ord('s'):

change_derection="down"

if event.key==K_ESCAPE:

pygame.event.post(pygame.event.Event(QUIT))

#判断移动的方向是否相反

if change_derection=='left'and not derection=='right':

derection= change_derection

if change_derection=='right'and not derection=='left':

derection= change_derection

if change_derection=='up' and not derection=='down':

derection= change_derection

if change_derection=='down' and not derection=='up':

derection= change_derection

#根据方向,改变坐标

if derection=='left':

snakeposition[0]-= 20

if derection=='right':

snakeposition[0]+= 20

if derection=='up':

snakeposition[1]-= 20

if derection=='down':

snakeposition[1]+= 20

#增加蛇的长度

snakelength.insert(0,list(snakeposition))

#判断是否吃掉目标方块

if snakeposition[0]==square_purpose[0] and snakeposition[1]==square_purpose[1]:

square_position= 0

else:

snakelength.pop()

#重新生成目标方块

if square_position==0:

#随机生成x,y,扩大二十倍,在窗口范围内

x= random.randrange(1,32)

y= random.randrange(1,24)

square_purpose= [int(x*20),int(y*20)]

square_position= 1

#绘制pygame显示层

gamesurface.fill(black_colour)

for position in snakelength:

pygame.draw.rect(gamesurface,white_colour,Rect(position[0],position[1],20,20))

pygame.draw.rect(gamesurface,red_colour,Rect(square_purpose[0],square_purpose[1],20,20))

#刷新pygame显示层

pygame.display.flip()

#判断是否死亡

if snakeposition[0]<0 or snakeposition[0]>620:

GameOver(gamesurface)

if snakeposition[1]<0 or snakeposition[1]>460:

GameOver(gamesurface)

for snakebody in snakelength[1:]:

if snakeposition[0]==snakebody[0] and snakeposition[1]==snakebody[1]:

GameOver(gamesurface)

#控制游戏速度

ftpsClock.tick(5)

if __name__=="__main__":

main()

三、如何用Python写一个贪吃蛇AI

首先,让我们罗列一些问题:(像头脑风暴那样,想到什么就写下来即可)

蛇和食物间有路径直接就去吃,不可取。那该怎么办?

如果蛇去吃食物后,布局是安全的,是否就直接去吃?(这样最优吗?)

怎样定义布局是否安全?

蛇和食物之间如果没有路径,怎么办?

最短路径是否最优?(这个明显不是了)

那么,如果布局安全的情况下,最短路径是否最优?

除了最短路径,我们还可以怎么走?S形?最长?

怎么应对蛇身越来越长这个问题?

食物是随机出现的,有没可能出现无解的布局?

暴力法(brute force)能否得到最优序列?(让贪吃蛇尽可能地多吃食物)

只要去想,问题还挺多的。这时让我们以面向过程的思想,带着上面的问题,

把思路理一理。一开始,蛇很短(初始化长度为1),它看到了一个食物,使用 BFS得到矩形中每个位置到达食物的最短路径长度。在没有蛇身阻挡下,

就是曼哈顿距离。然后,我要先判断一下,贪吃蛇这一去是否安全。所以我需要一条虚拟的蛇,它每次负责去探路。如果安全,才让真正的蛇去跑。

当然,虚拟的蛇是不会绘制出来的,它只负责模拟探路。那么,怎么定义一个布局是安全的呢?如果你把文章开头那张动态图片中蛇的销魂走位好好的看一下,

会发现即使到最后蛇身已经很长了,它仍然没事一般地走出了一条路。而且,是跟着蛇尾走的!嗯,这个其实不难解释,蛇在运动的过程中,消耗蛇身,

蛇尾后面总是不断地出现新的空间。蛇短的时候还无所谓,当蛇一长,就会发现,要想活下来,基本就只能追着蛇尾跑了。在追着蛇尾跑的过程中,

再去考虑能否安全地吃到食物。(下图是某次 BFS后,得到的一个布局, 0代表食物,数字代表该位置到达食物的距离,+号代表蛇头,*号代表蛇身,

-号代表蛇尾,#号代表空格,外面的一圈#号代表围墙)

#######

# 0 1 2 3 4#

# 1 2 3# 5#

# 2 3 4- 6#

# 3+** 7#

# 4 5 6 7 8#

#######

经过上面的分析,我们可以将布局是否安全定义为蛇是否可以跟着蛇尾运动,也就是蛇吃完食物后,蛇头和蛇尾间是否存在路径,如果存在,我就认为是安全的。

OK,继续。真蛇派出虚拟蛇去探路后,发现吃完食物后的布局是安全的。那么,

真蛇就直奔食物了。等等,这样的策略好吗?未必。因为蛇每运动一步,布局就变化一次。布局一变就意味着可能存在更优解。比如因为蛇尾的消耗,

原本需要绕路才能吃到的食物,突然就出现在蛇眼前了。所以,真蛇走一步后,更好的做法是,重新做 BFS。然后和上面一样进行安全判断,然后再走。

接下来我们来考虑一下,如果蛇和食物之间不存在路径怎么办?上文其实已经提到了做法了,跟着蛇尾走。只要蛇和食物间不存在路径,蛇就一直跟着蛇尾走。同样的,由于每走一步布局就会改变,所以每走一步就重新做 BFS得到最新布局。

好了,问题又来了。如果蛇和食物间不存在路径且蛇和蛇尾间也不存在路径,

怎么办?这个我是没办法了,选一步可行的路径来走就是了。还是一个道理,每次只走一步,更新布局,然后再判断蛇和食物间是否有安全路径;

没有的话,蛇头和蛇尾间是否存在路径;还没有,再挑一步可行的来走。

上面列的好几个问题里都涉及到蛇的行走策略,一般而言,我们会让蛇每次都走最短路径。这是针对蛇去吃食物的时候,

可是蛇在追自己的尾巴的时候就不能这么考虑了。我们希望的是蛇头在追蛇尾的过程中,

尽可能地慢。这样蛇头和蛇尾间才能腾出更多的空间,空间多才有得发展。所以蛇的行走策略主要分为两种:

1.目标是食物时,走最短路径

2.目标是蛇尾时,走最长路径

那第三种情况呢?与食物和蛇尾都没路径存在的情况下,这个时候本来就只是挑一步可行的步子来走,最短最长关系都不大了。

至于人为地让蛇走S形,我觉得这不是什么好策略,最初版本中已经分析过它的问题了。(当然,除非你想使用最最无懈可击的那个版本,就是完全不管食物,

让蛇一直走S,然后在墙边留下一条过道即可。这样一来,蛇总是可以完美地把所有食物吃完,然后占满整个空间,可是就很 boring了。

没有任何的意思)

上面还提到一个问题:因为食物是随机出现的,有没可能出现无解的局面?答案是:有。我运行了程序,然后把每一次布局都输出到 log,发现会有这样的情况:

#######

#*****#

#**- 0*#

#**#+*#

#*****#

#*****#

#######

其中,+号是蛇头,-号是蛇尾,*号是蛇身,0是食物,#号代表空格,外面一圈#号代表墙。这个布局上,食物已经在蛇头面前了,可是它能吃吗?不能!因为它吃完食物后,长度加1,蛇头就会把 0的位置填上,布局就变成:

#######

#*****#

#**-+*#

#**#**#

#*****#

#*****#

#######

此时,由于蛇的长度加1,蛇尾没有动,而蛇头被自己围着,挂掉了。可是,我们却还有一个空白的格子#没有填充。按照我们之前教给蛇的策略,

面对这种情况,蛇头就只会一直追着蛇尾跑,每当它和食物有路径时,它让虚拟的蛇跑一遍发现,得到的新布局是不安全的,所以不会去吃食物,

而是选择继续追着蛇尾跑。然后它就这样一直跑,一直跑。死循环,直到你按 ESC键为止。

由于食物是随机出现的,所以有可能出现上面这种无解的布局。当然了,你也可以得到完满的结局,贪吃蛇把整个矩形都填充满。

上面的最后一个问题,暴力法是否能得到最优序列。从上面的分析看来,可以得到,但不能保证一定得到。

最后,看看高瞻远瞩的蛇是怎么跑的吧:

相关内容

热门资讯

猜歌猜知识的游戏规则 一、猜歌名游戏规则有哪些1、本轮游戏共需20人参加,分成两组,每组十人。2、当主持人放出音乐后,猜到...
cf游戏安全知识答题全部正确答... 一、cf生化大赏答案大全2023cf生化奖励活动的答案是什么?2023年最新答题活动已经开始。玩家可...
超级玛丽三代游戏知识讲解 一、网络单机游戏超级玛丽,为什么通关时必须要摘下旗子我相信小时候大家都有玩过或者是听过这款非常经典的...
dnf腾讯游戏安全知识答题答案 一、2021腾讯游戏安全知识答题答案A、都是一起玩游戏的,借给他玩玩呗B、账号密码,不要告知其他人。...
设计一款游戏需要什么知识 一、游戏设计需要什么基础游戏设计需要的基础:1、知识基础:游戏设计原理、用户体验设计程序与方法、二维...
三年级测量知识的游戏题目 一、三年级测量周长的三种方法三年级测量周长的三种方法包括直接测量、使用长度单位和利用比例关系。1、直...
奇怪的冷知识游戏下载中文 一、你知道哪些关于游戏中的奇怪冷知识许多网友们在玩游戏的时候都会总结一些游戏当中的冷知识,将这些知识...
能源利用的理论知识游戏 一、飞船太空采集能源的游戏下载地址:类型:安卓游戏-冒险解谜版本:v0.1大小:61.41M语言:中...
能科普知识的小游戏下载 一、让你爱不释手的益智类小游戏有哪些游戏市场现如今可谓竞争激烈,每一款游戏也是极尽自己的能力,想打造...
扩大知识面游戏有哪些类型 一、工作之余,有哪些能够很好地拓展知识面的手机小游戏在现在这个游戏横生的时代,游戏从一开始简单的单机...