出于某种原因,我的while循环在两次尝试后停止,我无法弄清楚出了什么问题...... 它应该是一个蚂蚁农场,你可以选择繁殖和制作新的蚂蚁等。 我只是不明白为什么它会停止...... 这是我的代码:
import random
class Colony(object):
workerAnts = 0
list = []
temp = []
foodAmount = 10
def breedWorker(self):
if Colony.foodAmount < 5:
print "Sorry! You do not have enough food to create a new worker ant!"
else:
Colony.foodAmount -= 5
Colony.workerAnts += 1
Colony.list.append("ant")
def step(self):
number = 'ant'
for number in Colony.list:
a = Ant()
a.forage()
if Colony.foodAmount > 0:
Colony.foodAmount -= 1
if Colony.foodAmount < len(Colony.list):
for number in Colony.list[Colony.foodAmount+1:]:
Ant.health -= 1
def purge(self):
number = 'ant'
for number in Colony.list:
if Ant.health > 0:
Colony.temp.append("ant")
Colony.list = Colony.temp
class Ant(object):
health = 10
def forage(self):
if Ant.health == 0:
Colony.workerAnts -= 1
if random.randint(0,100) > 95:
Ant.health = 0
print "Ant has died from a horrible accident!"
Colony.workerAnts -= 1
elif random.randint(0,100) < 40:
newFood = random.randint(1,5)
print "Ant has found %s food!!" % newFood
Colony.foodAmount += newFood
elif random.randint(0,100) < 5:
Ant.health = 10
Colony.foodAmount += 10
print "You've found sweet nectar! Your ant has returned to full health and has brought 10 food back to the colony!"
else:
print "Ant returned empty-handed!"
def main():
queen = Colony()
queen2 = Ant()
while queen.workerAnts > 0 or queen.foodAmount >= 5:
print "========================================================"
print """
Your colony has %s ants and %s food, Your Majesty.\nWhat would you like to do?\n0: Do nothing.\n1: Breed worker. (Costs 5 food.)""" % (queen.workerAnts, queen.foodAmount)
answer = int(raw_input(">"))
if answer != 1 and answer != 0:
print "Sorry, invalid input!"
if answer == 0:
queen.step()
queen.purge()
if answer == 1:
print "Breeding Worker..."
queen.breedWorker()
queen.step()
queen.purge()
if queen.workerAnts <= 0 and queen.foodAmount < 5:
print "I'm sorry! Your colony has died out!"
答案 0 :(得分:1)
__init__(self, ...)
)并且没有初始化对象的属性ants.append(Ant(self))
来创建来自Colony的Ant; Ant的构造函数应该有签名`def init (self,colony):'答案 1 :(得分:0)
您使Ant.health
成为一个类变量(在所有Ant实例之间共享)。
一旦蚂蚁的健康状况变为0,他们就会死亡。
这是一个改进版本。以下代码兼容Python 2和3,我认为修复了所有错误!
import random
import sys
if sys.hexversion < 0x3000000:
# Python 2.x
inp = raw_input
rng = xrange
else:
# Python 3.x
inp = input
rng = range
def get_int(prompt, lo=None, hi=None):
"""
Prompt until an integer value in [lo..hi] is entered, then return it
"""
while True:
try:
val = int(inp(prompt))
if (lo is None or lo <= val) and (hi is None or val <= hi):
return val
except ValueError:
pass
class InsufficientFoodError(Exception):
pass
class Colony:
def __init__(self, workers=0, food=10):
self.food = food + Ant.cost * workers
self.ants = []
for i in rng(workers):
self.add_ant()
def add_ant(self):
try:
self.ants.append(Ant(self))
except InsufficientFoodError as e:
print(e)
def step(self):
# all ants eat, then all ants forage:
for ant in self.ants:
ant.eat()
for ant in self.ants:
ant.forage()
# bring out yer dead!
self.ants = [ant for ant in self.ants if ant.is_alive()]
def add_food(self, amount):
self.food += amount
def take_food(self, amount):
amt = min(amount, self.food)
self.food -= amt
return amt
def num_ants(self):
return len(self.ants)
class Ant:
cost = 5
max_health = 10
def __init__(self, colony):
# try to get enough food to produce an ant
food = colony.take_food(Ant.cost)
if food < Ant.cost:
# Failed! return any taken food and throw an error
colony.add_food(food)
raise InsufficientFoodError('The colony does not have enough food to make a new Ant')
else:
# Success!
self.colony = colony
self.health = Ant.max_health
def eat(self):
if self.health > 0:
self.health -= 1 - self.colony.take_food(1)
if self.health == 0:
print("An ant starved to death.")
def forage(self):
if self.is_alive():
dice = random.randint(0, 100)
if dice <= 5:
self.health = Ant.max_health
self.colony.add_food(10)
print("You've found sweet nectar! Your ant has returned to full health and has brought 10 food back to the colony!")
elif dice <= 40:
found_food = random.randint(1, 5)
self.colony.add_food(found_food)
print("Ant has found {} food!".format(found_food))
elif dice <= 95:
print("Ant returned empty-handed!")
else:
self.health = 0
print("Ant has died from a horrible accident!")
def is_alive(self):
return self.health > 0
def main():
colony = Colony()
while True:
print(
"========================================================\n"
"\n"
"Your colony has {ants} ants and {food} food, Your Majesty.\n"
"What would you like to do?\n"
" 1: Do nothing\n"
" 2: Breed worker (costs {cost} food)"
.format(ants=colony.num_ants(), cost=Ant.cost, food=colony.food)
)
opt = get_int("> ", 1, 2)
if opt == 2:
print("Breeding Worker...")
colony.add_ant()
colony.step()
if colony.num_ants() == 0 and colony.food < Ant.cost:
print("I'm sorry! Your colony has died out!")
break
if __name__=="__main__":
main()
答案 2 :(得分:0)
嗯,这是因为def purge(self)
中的以下行:
Colony.list = Colony.temp
第一次运行purge()
时,它会使Colony.list
和Colony.temp
指向内存中的同一个数组。因此,当您第二次运行purge()
时,您会进入一个无限循环,for number in Colony.list:
执行Colony.temp.append("ant")
,这实际上会增加Colony.list
,并且循环永不退出,因为它总会有一个新成员。
在python中,for
循环为给定对象创建迭代器(如果它还不是迭代器)。在每次迭代中,python都会调用迭代器的next()
方法(在本例中为列表)。如果next()
无法产生新值来迭代,则会引发StopIteration
,并且循环退出。不用担心,for
语句会自动为您处理此异常。在您的情况下,Colony.list.next()
始终会找到一个新值(因为您刚刚附加到它上面),并且永远不会到达终点。
要修复代码,请尝试切片。这意味着复制了数组,而不是将两个名称指向同一个数组:
Colony.list = Colony.temp[:]
答案 3 :(得分:0)
这个答案有点偏,但似乎它将是一个有价值的知识。 这里的一个大问题是你的课程以不合需要的方式使用。
类的主要优点是保存变量/函数的实例,这样您就可以对它们进行多次独立分组。
通过调用Colony.<var>
,您正在更改基类(或超级)类变量的var
。如果你只想拥有一个殖民地,这是有效的......但是如果你想要两个,那该怎么办?还是三个!还是一百万!!?
注意当您没有输入self
作为类函数的第一个参数时,如何收到错误?您需要意识到的是,您正在将类的实例作为第一个参数传递。这就是类如何知道要使用的变量分组。
说我们有一个班级Antzilla
class Antzilla:
antvar = "antzilla var"
def PrintSuperAntvar(self):
print Antzilla.antvar
def PrintInstanceOfAntvar(self):
print self.antvar
请注意PrintSuperAntvar
调用基本var并且PrintInstanceOfAntvar
打印Antzilla
的实例
如果我az1
并更改az1.antvar
,则不会更改Antzilla.antvar
值。
az1 = Antzilla()
az1.antvar = "new var"
az1.PrintSuperAntvar()
>>> antzilla var
az1.PrintInstanceOfAntvar()
>>> new var
我现在可以创建一个具有原始起始值的新Antzilla
实例,因为我从未更改过基类值
az2 = Antzilla()
az2.PrintSuperAntvar()
>>> antzilla var
az2.PrintInstanceOfAntvar()
>>> antzilla var
但是,如果您要更改此超级值,则会看到新的Antzilla
以此新值开头,但已更改的Antzilla
仍保持不变。
Antzilla.antvar = "newest var"
az3 = Antzilla()
az3.PrintSuperAntvar()
>>> newest var
az3.PrintInstanceOfAntvar()
>>> newest var
az1.PrintSuperAntvar()
>>> new var
观看!!! 注意我们致电az2
时会发生什么!
az2.PrintSuperAntvar()
>>> newest var
az2
永远不会从超级变量中更改,因此当我们将Antzilla.antvar
从"antzilla var"
更改为"newest var"
时,az2
将继续坚持超级值。
我们如何避免这种冲突!?它很简单!
只需在您的类中添加构造函数即复制超值,或将新值添加到自己的变量中。
如果存在,则在您创建新的__init__
实例
Antzilla
函数
class Antzilla:
antvar = "antzilla var"
def __init__(self):
self.antvar = Antzilla.antvar
...
您还可以将var作为要求添加到构造函数中,以使每个实例都是唯一的。
class Antzilla:
antvar = "antzilla var"
def __init__(self, antvar ):
self.antvar = antvar
...
az1 = Antzilla("antzilla unique swag")
重要的是要注意,在处理列表等变量时,您需要专门为每个实例创建一个新列表。幸运的是,最好的地方也是构造函数。
现在回到你的问题,..对于你的两个类,我会添加像这样的构造函数
对于殖民地:
class Colony(object):
workerAnts = 0
list = []
temp = []
foodAmount = 10
def __init__(self):
self.workerAnts = 0
self.list = []
self.temp = []
self.foodAmount = 10
....
对于Ant
class Ant(object):
health = 10
def __init__(self):
self.health = 10
....
最后,在进入数学或逻辑错误之前,您需要做的是用self
或给定范围内的变量名称替换您调用基本或超级变量的所有位置。
即:
Colony.foodAmount -= 5
更改为:
self.foodAmount -= 5
=============================================== =============================
PS那个你写的地方:
Colony.temp.append("ant")
实际上是将字符串附加到 base 列表中。您可能希望将其更改为Ant
的构造函数..它返回Ant
类的新实例,并使其将变量添加到colony
的实例而不是基础colony
self.temp.append(Ant())
=============================================== =============================
希望这会有所帮助!!
干杯,
校准