马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 囧囧JOJO 于 2020-1-30 22:37 编辑
萌新嘛也不懂,感觉自己写的对了,但是运行结果看,几乎没有可能鱼全被吃掉。
先说说我的代码吧。
阅读我代码之前,我先解释一下几个难理解的变量命名具体代表什么。。
range_x表示场景范围的x坐标
range_y表示场景范围的y坐标(也即从(0,0)到(10,10)的121个位置。)
鱼类里面的Fx属性为fish x,就是鱼的x坐标,同理Fy表示鱼的y坐标
way表示4个数里面随机生成的一个数,用来说明朝哪个方向走(上下左右),后面也有说明。
乌龟类的HP属性表示乌龟的血量
同理乌龟类里面的属性TX,Ty分别表示Turtle x,Turtle y乌龟的x,y坐标。
fish=[]的这个列表用来储存鱼,初始列表10个值,也即10条鱼
step顾名思义,就是乌龟需要一次走几步(1或2步),但是为了循环方便,它的值为(0和1)
先把我写的代码整体复制过来:import random as r
#先生成场景范围(x,y)
range_x = 10
range_y = 10
class Fish:
def __init__(self):
self.Fx = r.randint(0,range_x)
self.Fy = r.randint(0,range_y)
def move(self):
way = r.randint(-2,2)#确定鱼怎么走(1上,-1下,-2左,2右)
while way == 0 :#生成的way只能是-2,-1,1,2,不能为0
way = r.randint(-2,2)
if(abs(way) == 1):#判断鱼为上下方向移动
if(way > 0):
self.Fy += 1
else:
self.Fy -= 1
if(self.Fy < 0):
self.Fy += 2
elif(self.Fy > range_y):
self.Fy -= 2
if(abs(way) == 2):#判断鱼为左右方向移动
if(way > 0):
self.Fx += 1
else:
self.Fx -= 1
if(self.Fx < 0):
self.Fx += 2
elif(self.Fx > range_x):
self.Fx -= 2
class Turtle:
def __init__(self):
self.HP = 100
self.Tx ,self.Ty= r.randint(0,range_x),r.randint(0,range_y)#生成初始乌龟的位置
def move(self):
way = r.randint(-2,2)#确定乌龟怎么走(1上,-1下,-2左,2右)
while way == 0 :#生成的way只能是-2,-1,1,2,不能为0
way = r.randint(-2,2)
if(abs(way) == 1):#判断乌龟为上下方向移动
if(way > 0):
self.Ty += 1
else:
self.Ty -= 1
if(self.Ty < 0):
self.Ty += 2
elif(self.Ty > range_y):
self.Ty -= 2
if(abs(way) == 2):#判断乌龟为左右方向移动
if(way > 0):
self.Tx += 1
else:
self.Tx -= 1
if(self.Tx < 0):
self.Tx += 2
elif(self.Tx > range_x):
self.Tx -= 2
'''
↑(-1)
←(-2) 0 →(2)
↓(1)
'''
t = Turtle()#初始化(血量,位置)乌龟
fish = []
for i in range(10):
fish.append(Fish())#创建10个鱼列表,
while True:
step = r.randint(0,1)
#乌龟一次走几步(1-2)
t.HP -= (step+1) #乌龟血量减去移动次数
for i in range(step):
t.move()
for i in range(len(fish))[::-1]:
fish[i].move()
if (fish[i].Fx == t.Tx and fish[i].Fy == t.Ty):
del fish[i]
print('有一条鱼儿被吃掉了...')
if (t.HP+20>100):
t.HP = 100
else:
t.HP += 20
if len(fish) == 0:
print('鱼儿都吃完了,游戏结束!')
break
if(t.HP <= 0):
print('乌龟体力耗尽,挂掉了!')
break
根据题意:假设游戏场景为范围(x, y)为0<=x<=10,0<=y<=10,我设置了地图的大小(x,y),即从(0,0)到(10,10),共121个位置。
import random as r
#先生成场景范围(x,y)
range_x = 10
range_y = 10
接着就是两个类(乌龟类 和 鱼类)
按照代码运行顺序看吧。首先是t = Turtle(),注释也写了,初始化乌龟的血量和初始位置,在乌龟类里面是这样的:class Turtle:
def __init__(self):
self.HP = 100
self.Tx ,self.Ty= r.randint(0,range_x),r.randint(0,range_y)#生成初始乌龟的位置
接下来,代码就创建了10条鱼,并且每条鱼都加入列表fish里面了,而创建鱼的代码在 鱼类 里面,如下:class Fish:
def __init__(self):
self.Fx = r.randint(0,range_x)
self.Fy = r.randint(0,range_y)
至此,准备工作已经完成了,现在就是正式move过程,我把move过程写进一个死循环,直到鱼死或者乌龟死,才跳出循环,具体如下:while True:
step = r.randint(0,1)
#乌龟一次走几步(1-2)
t.HP -= (step+1) #乌龟血量减去移动次数
for i in range(step):
t.move()
for i in range(len(fish))[::-1]:
fish[i].move()
if (fish[i].Fx == t.Tx and fish[i].Fy == t.Ty):
del fish[i]
print('有一条鱼儿被吃掉了...')
if (t.HP+20>100):
t.HP = 100
else:
t.HP += 20
if len(fish) == 0:
print('鱼儿都吃完了,游戏结束!')
break
if(t.HP <= 0):
print('乌龟体力耗尽,挂掉了!')
break
先确定乌龟一次走几步,然后把走路消耗的血扣掉,接着一个循环(一次移动两步或者一步),让乌龟完成一次的移动。
再接着,十只鱼(刚开始10只,后来死了就不是十只)要逐个移动,写进for循环里,因为循环里要把鱼跟乌龟同一个位置的鱼杀死,所以我倒序移动鱼(即第十条先移动,接着第九条... ...),for循环里的代码也简单,就是鱼移动,然后判断是不是跟乌龟同一个位置,是就删除fish列表中这条鱼,接着给乌龟加血20。
循环结束之后要确定与是不是都死了,或者乌龟是不是累死了,也就是两个if判断,很简单,我觉得我不需要解释了。。
接着就是两个类里面的方法,其实方法都是一样的,照搬照抄的,我只讲一个鱼的就行了。。def move(self):
way = r.randint(-2,2)#确定乌龟怎么走(1上,-1下,-2左,2右)
while way == 0 :#生成的way只能是-2,-1,1,2,不能为0
way = r.randint(-2,2)
if(abs(way) == 1):#判断鱼为上下方向移动
if(way > 0):
self.Fy += 1
else:
self.Fy -= 1
if(self.Fy < 0):
self.Fy += 2
elif(self.Fy > range_y):
self.Fy -= 2
if(abs(way) == 2):#判断鱼为左右方向移动
if(way > 0):
self.Fx += 1
else:
self.Fx -= 1
if(self.Fx < 0):
self.Fx += 2
elif(self.Fx > range_x):
self.Fx -= 2
判断上下左右哪个方向移动也就是生成(-2,-1,1,2)四个数字,-2表示向左,2表示向右,-1表示向上,1表示向下。
然后判断生成的这个数的绝对值是1还是2(abs(way)),如果是1表示上下方向移动,只用更改y坐标就行了,反之改x坐标。
我改坐标的方法是,先改,然后判断是否出界了,如果出界了就反方向再走两步就回来了(也就是题中说的当移动到场景边缘,自动向反方向移动),至此我代码也就写完了。问题就是几乎不可能让乌龟把鱼吃完。
我也尝试用小甲鱼答案里的方法运行,乌龟把鱼吃完的概率远远大于我写的。不清楚思路上有什么问题,下面附上小甲鱼写的参考答案(我也不能完全看懂,就直接贴出来吧。)import random as r
legal_x = [0, 10]
legal_y = [0, 10]
class Turtle:
def __init__(self):
# 初始体力
self.power = 100
# 初始位置随机
self.x = r.randint(legal_x[0], legal_x[1])
self.y = r.randint(legal_y[0], legal_y[1])
def move(self):
# 随机计算方向并移动到新的位置(x, y)
new_x = self.x + r.choice([1, 2, -1, -2])
new_y = self.y + r.choice([1, 2, -1, -2])
# 检查移动后是否超出场景x轴边界
if new_x < legal_x[0]:
self.x = legal_x[0] - (new_x - legal_x[0])
elif new_x > legal_x[1]:
self.x = legal_x[1] - (new_x - legal_x[1])
else:
self.x = new_x
# 检查移动后是否超出场景y轴边界
if new_y < legal_y[0]:
self.y = legal_y[0] - (new_y - legal_y[0])
elif new_y > legal_y[1]:
self.y = legal_y[1] - (new_y - legal_y[1])
else:
self.y = new_y
# 体力消耗
self.power -= 1
# 返回移动后的新位置
return (self.x, self.y)
def eat(self):
self.power += 20
if self.power > 100:
self.power = 100
class Fish:
def __init__(self):
self.x = r.randint(legal_x[0], legal_x[1])
self.y = r.randint(legal_y[0], legal_y[1])
def move(self):
# 随机计算方向并移动到新的位置(x, y)
new_x = self.x + r.choice([1, -1])
new_y = self.y + r.choice([1, -1])
# 检查移动后是否超出场景x轴边界
if new_x < legal_x[0]:
self.x = legal_x[0] - (new_x - legal_x[0])
elif new_x > legal_x[1]:
self.x = legal_x[1] - (new_x - legal_x[1])
else:
self.x = new_x
# 检查移动后是否超出场景y轴边界
if new_y < legal_y[0]:
self.y = legal_y[0] - (new_y - legal_y[0])
elif new_y > legal_y[1]:
self.y = legal_y[1] - (new_y - legal_y[1])
else:
self.y = new_y
# 返回移动后的新位置
return (self.x, self.y)
turtle = Turtle()
fish = []
for i in range(10):
new_fish = Fish()
fish.append(new_fish)
while True:
if not len(fish):
print("鱼儿都吃完了,游戏结束!")
break
if not turtle.power:
print("乌龟体力耗尽,挂掉了!")
break
pos = turtle.move()
# 在迭代器中删除列表元素是非常危险的,经常会出现意想不到的问题,因为迭代器是直接引用列表的数据进行引用
# 这里我们把列表拷贝给迭代器,然后对原列表进行删除操作就不会有问题了^_^
for each_fish in fish[:]:
if each_fish.move() == pos:
# 鱼儿被吃掉了
turtle.eat()
fish.remove(each_fish)
print("有一条鱼儿被吃掉了...")
小弟不才,只能这样解释了,望大佬帮忙指导,俺也想追随大佬的脚步啊!!
|