我在Python中的状态机遇到无限循环

时间:2012-09-27 07:01:08

标签: python state-machine

我是python的新手。我的代码进入无限循环,不断添加&打印numberCycles。我在C ++中的逻辑很好。 你能帮忙找出原因吗?

  • 第一行输入是模拟次数。
  • 下一行是单个生殖周期的分钟数。
  • 下一行是行数(x),后跟一个空格,后跟列数(y)。
  • 下一组y行将有x个字符数,其中一个句点(.)代表一个空格,一个国会大厦B代表一个起始的Bunny尝试重现为uprightdownleft方向。如果有一个现有的兔子,那就进入睡眠状态。

INPUT.TXT

2     # 2 simulations
5     # 5 minutes/cycle
3 3   # 3*3 map
...
.B.
...
1
4 4
B.BB
..B.
...
B.B

Spot.py

#!/usr/bin/env python

class Spot(object):
    isBunny = bool()
    nextCycle = 0
    UP = 0
    RIGHT = 1
    DOWN = 2
    LEFT = 3
    SLEEP = 4

    def __init__(self, newIsBunny):
        self.isBunny = newIsBunny
        self.nextCycle = self.UP

    def setNextCycle(self):
        if (self.nextCycle != self.SLEEP):
            self.nextCycle += 1

    def getNextCycle(self):
        return self.nextCycle

    def getIsBunny(self):
        return self.isBunny

    def makeBunny(self):
        if not self.isBunny:
            self.nextCycle = self.UP
        self.isBunny = True

Bunny.py

#!/usr/bin/env python
from Spot import Spot
import os

class Bunny(object):    
    @classmethod
    def main(cls, args):
        with open(os.path.expanduser('~/Desktop/input.txt')) as f: 
            numSims = int(f.readline()) 
            myMap = []  
            print numSims
            minPerCycle= int(f.readline()) 
            print minPerCycle
            for k in xrange(numSims): 
                xyLine= f.readline()
                row = int(xyLine.split()[0]) 
                col = int(xyLine.split()[1])  
                print row,col
                for i in range(0,row): 
                    myLine = f.readline() 
                    myMap.append([]) 
                    for j in range(0,col): 
                        myMap[i].append(Spot(myLine[j] == 'B')) 

                numCycles = 1

                if cls.isFilled(row,col,myMap):
                    numCycles = 0

                while not cls.isFilled(row,col,myMap):
                    numCycles += 1
                    print numCycles
                    for m in range(0,row): 
                        for n in range(0,col): 
                            if myMap[m][n].getIsBunny():
                                if myMap[m][n].getNextCycle() == Spot.UP:
                                    if m>0:
                                        myMap[m-1][n].makeBunny()
                                    break
                                elif myMap[m][n].getNextCycle() == Spot.RIGHT:
                                    if n<col-1:
                                        myMap[m][n+1].makeBunny()
                                    break
                                elif myMap[m][n].getNextCycle() == Spot.DOWN:
                                    if m<row-1:
                                        myMap[m+ 1][n].makeBunny()
                                    break
                                elif myMap[m][n].getNextCycle() == Spot.SLEEP:
                                    if n>0:
                                        myMap[m][n- 1].makeBunny()
                                    break
                            myMap[m][n].setNextCycle() 
                time = numCycles * minPerCycle
                print "It took " , time , " minutes for the bunnies to take over the world!\n"
                del myMap[:]
            f.close()

    @classmethod
    def isFilled(cls,row,col,myMap):
        for a in range(0,row): 
            for b in range(0,col): 
                if not myMap[a][b].getIsBunny():
                    return False
        return True


if __name__ == '__main__':
    import sys
    Bunny.main(sys.argv)

1 个答案:

答案 0 :(得分:1)

它永远不会向左转。此外,您为内循环设置了一个中断,因此永远不会调用myMap[m][n].setNextCycle()。我刚刚看到your C++ code,您将其翻译为Python但有错误(使用Spot.SLEEP代替Spot.LEFT)。

{C}中的break语句是有意义的,因为你想打破switch。在这里,您使用的是if..else

应该是这样的:

while not cls.isFilled(row, col, myMap):
    numCycles += 1
    print numCycles
    for m in range(0,row): 
        for n in range(0,col): 
            if myMap[m][n].getIsBunny():
                if myMap[m][n].getNextCycle() == Spot.UP:
                    if m>0:
                        myMap[m-1][n].makeBunny()
                elif myMap[m][n].getNextCycle() == Spot.RIGHT:
                    if n<col-1:
                        myMap[m][n+1].makeBunny()
                elif myMap[m][n].getNextCycle() == Spot.DOWN:
                    if m<row-1:
                        myMap[m+ 1][n].makeBunny()
                elif myMap[m][n].getNextCycle() == Spot.LEFT:
                    if n>0:
                        myMap[m][n-1].makeBunny()

            myMap[m][n].setNextCycle()