在Python中循环提前结束?

2024-10-16 20:39:27 发布

您现在位置:Python中文网/ 问答频道 /正文

由于某种原因,我的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!"

Tags: numberiffooddefrandomlisthasprint
3条回答

您使Ant.health成为一个类变量(在所有Ant实例之间共享)。在

一旦一只蚂蚁的健康值变为0,它们就会全部死亡。在

这是一个改进版。下面的代码是python2和python3兼容的,我认为修复了所有错误!在

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()
  1. 您没有构造函数(__init__(self, ...)),也没有初始化对象的属性
  2. 在方法中调用此对象属性自身属性,不是通过类名.属性;在python中,您显式地将实例或类对象传递给方法,按照惯例,它们应该是“self”(实例)或“cls”(类)。在
  3. 如果要在Ant对象中使用任何殖民地属性,反之亦然,则需要显式传递引用,并将其存储为属性。最明智的做法是通过调用ants.append(Ant(self))从Colony创建Ant;Ant的构造函数应具有签名“definit(self,Colony):”

好吧,这是因为def purge(self)中的以下一行:

    Colony.list = Colony.temp

第一次运行purge(),它使Colony.list和{}都指向内存中的同一个数组。所以第二次运行purge(),你进入了一个无限循环,在这个循环中,for number in Colony.list:执行Colony.temp.append("ant"),这实际上也增加了{},循环永远不会退出,因为它总是有一个新成员。在

在python中,for循环为给定对象创建迭代器(如果它还不是迭代器)。在每次迭代中,python都会调用迭代器的next()方法(在本例中为list)。如果next()不能产生一个新的值进行迭代,它将引发StopIteration,循环退出。别担心,这个异常是由for语句自动处理的。在您的例子中,Colony.list.next()总是会找到一个新值(因为您刚刚附加了它),并且永远不会到达末尾。在

要修复代码,请尝试切片。这意味着复制数组,而不是将两个名称指向同一个数组:

^{pr2}$

相关问题 更多 >