I've tried running the following code through Spyder and an online IDE, but neither one fully completes the program. It either times out or just refuses to run.

import random
from pprint import pprint

petri_dish = []

class Species:
    def __init__(self,total,name,life,attack,defense,move,location):
        area = 1000
        self.total = 100
        self.name = name
        self.life = self.total - (random.randint(1,100))
        self.attack = self.total - (random.randint(1,100))
        self.defense = self.total - (random.randint(1,100))
        self.move = self.total - (random.randint(1,100))
        self.location = [random.randint(1,area),random.randint(1,area)]
    def relocate(self):
        x_move_add = random.randint(self.location[0], self.location[0] + self.move)
        x_move_minus = random.randint(self.location[0] - self.move,self.location[0])
        y_move_add = random.randint(self.location[1], self.location[1] + self.move)
        y_move_minus = random.randint(self.location[1] - self.move,self.location[1])
        self.location = [random.randint(x_move_minus,x_move_add),random.randint(y_move_minus,y_move_add)]
        for n in range(2):
            if self.location[n] > 1000:
                self.location[n] = 1000
            elif self.location[n] < 0:
                self.location[n] = 0
    def fight(self,enemy):
        while self.life > 0 and enemy.life > 0:
            self.life = (self.life + self.defense) - enemy.attack
            enemy.life = (enemy.life + enemy.defense) - self.attack
        else:
            if self.life > enemy.life:
                print 'Species #' + str(enemy.name) + ' was eaten!'
                self.attack = self.attack + enemy.attack
                self.life = 100
                petri_dish.remove(enemy)
            else:
                print 'Species #' + str(self.name) + ' was eaten.'
                enemy.attack = enemy.attack + self.attack
                enemy.life = 100
                petri_dish.remove(self)
    def target(self):
        for z in petri_dish:
            if z.location != self.location:
                if (z.location[0] in range(self.location[0] - self.move, self.location[0] + self.move)) and (z.location[1] in range(self.location[1] - self.move, self.location[1] + self.move)):
                    self.fight(z)

for n in range(20):
    petri_dish.append(Species(0,n,0,0,0,0,0))

def show():
    for z in petri_dish:
        print z.location,z.move

def move_around():
    for x in petri_dish:
        x.relocate()
        x.target()

while len(petri_dish) > 1:
    move_around()

for x in petri_dish:
    pprint(vars(x))

Any idea as to what's going on? This was working earlier, but now it's broken. As you can probably tell, this program is a really, really simple petri dish simulator populated by some remarkably unintelligent cells.

Bonus Question: Are infinite loops bad for your computer? I've hit a few of them and I don't want to risk harming my machine in any way, shape, or form.

有帮助吗?

解决方案

mostly, it's because your algorithm can generate inputs which aren't constrained using the algorithm you chose.

first, random.randint(1,100) will produce a number between 1 and 100. you are really using 100 - randint(1,100) though, which will occasionally produce 0s. if you get two items with move=0, neither one can actually move to engage the other one, so your loop will never exit. maybe just use self.move = random.randint(1,100) instead etc. (same is true for life and other things).

there are other constraints which are also invalid - take these lines:

self.life = (self.life + self.defense) - enemy.attack
enemy.life = (enemy.life + enemy.defense) - self.attack

there are two issues with this. one, if x.defense > y.attack, you are actually adding life to the object. you probably want to saturate this at the initial value of self.life (or 100 if you really want healing).

second, even if you do that, you can have a case like this: self.attack = 20 self.defense = 30 enemy.attack = 20 enemy.defense = 30

which is basically a pillow fight :) since attack is always less than defense, neither life is actually ever going to go down, and this loop will run forever. you might want to introduce a random element here.

其他提示

You should be a bit more specific on what "refuses to run" and "times out" mean.

My understanding would be that "times out" means that you got an infinite loop. Your program runs the risk of executing forever, if cells don't encounter each other to have a fight().

I'd do several changes to the program:

  • move the target() as a normal function with one (or two) parameters. This way, the Species class won't depend on the global population array.
  • do a pprint after each iteration, not at the very end. If the above (cells randomly running around) holds, the pprint at the end won't get to be executed.
  • change the while condition to end either at len() == 1 or after a maximum number of iterations

HTH,

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top