mooseman55 Ответов: 1

Игра "Жизнь" Джона Конвея на языке Python дает неправильный выход


Я пытаюсь сделать быструю демонстрацию игры Конвея в жизнь с использованием python. Когда я запускаю код, который я написал ниже, он, кажется, работает, но при использовании в конкретных случаях, например, с осциллятором, все разваливается.

(У меня есть примеры выходных данных ниже)

Что я уже пробовал:

import time
import os

def main():
    oldRows=[["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","+","-","-","-","-","-"],
             ["-","-","-","-","+","-","-","-","-","-"],
             ["-","-","-","-","+","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"]]

    newRows=[["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"],
             ["-","-","-","-","-","-","-","-","-","-"]]

    printBoard(oldRows)
    for i in range(5):
        cycle(oldRows, newRows)
        oldRows=newRows
        time.sleep(.2)
        os.system('clear')
    cycle(oldRows, newRows)


def printBoard(rows):
    print("______________________________")
    for r in range(len(rows)):
        for i in range(len(rows)):
            print(" " + rows[r][i] + " ", end="")
        print("")
    print("______________________________")


def checkPop(oldRows, r, i):
    popCount = 0

    # check the top row
    if (r != 0):
        if (i != 0):
            if (oldRows[r-1][i-1] == "+"):
                popCount+=1
        if (oldRows[r-1][i] == "+"):
                popCount+=1
        if (i != len(oldRows)-1):
            if (oldRows[r-1][i+1] == "+"):
                popCount+=1

    # check the middle row minus the center
    if (i != 0):
        if (oldRows[r][i-1] == "+"):
            popCount+=1
    if (i != len(oldRows)-1):
        if (oldRows[r][i+1] == "+"):
            popCount+=1

    # check bottom row
    if (r != len(oldRows)-1):
        if (i != 0):
            if (oldRows[r+1][i-1] == "+"):
                popCount+=1
        if (oldRows[r+1][i] == "+"):
            popCount+=1
        if (i != len(oldRows)-1):
            if (oldRows[r+1][i+1] == "+"):
                popCount+=1
    #print("(" + str(r) + "," + str(i) + ") p = " + str(popCount))
    return popCount


def checkBirth(oldRows, r, i):
    if (checkPop(oldRows, r, i) == 3):
        return True
    else:
        return False


def cycle(oldRows, newRows):
    for r in range(len(oldRows)):
        for i in range(len(oldRows)):

            # if the cell starts already dead
            if (oldRows[r][i] == "-"):
                # see if there are 3 live cells around it to bring it to life
                if checkBirth(oldRows, r, i):
                    newRows[r][i] = "+"
                else:
                    newRows[r][i] = "-"
            else:
                # kill if lack of population
                if (checkPop(oldRows, r, i) < 2):
                    newRows[r][i] = "-"

                # kill due to over crowding
                elif (checkPop(oldRows, r, i) > 3):
                    newRows[r][i] = "-"

                # live
                else:
                    newRows[r][i] = "+"
    printBoard(newRows)


if __name__ == "__main__":
    main()


Вот что происходит, когда я запускаю его ("- "- это мертвая клетка, а " + " - живая клетка):

** Ожидаемый Результат:**

Gen 1:

...- - + - - ...
...- - + - - ...
...- - + - - ...

Gen 2:

...- - - - -...
...- + + + -...
...- - - - -...

Быт 3:

...- - + - - ...
...- - + - - ...
...- - + - - ...

и т.д....


**фактическая производительность:**

Gen 1:

...- - + - - ...
...- - + - - ...
...- - + - - ...

Gen 2:

...- - - - -...
...- + + + -...
...- - - - -...

Быт 3:

...- - + + - ...
...- + - + - ...
...- - - - - ...

Быт 4:

...- - + + - ...
...- - + + - ...
...- - - - - ...

1 Ответов

Рейтинг:
0

Patrice T

Я думаю, что проблема здесь:

oldRows=newRows

Вам нужно поменять местами обе доски.

Совет:
- вы можете упростить код тура, сделав доску больше, чем отображаемая часть (1 строка и столбец вокруг), таким образом, вам не придется обрабатывать бордеры.
- Если вы хотите серьезно относиться к игре жизни, вам нужно хранить исходные паттерны в более эффективном формате. RLE-это широко используемый формат.
Кодировка длины пробега - Википедия[^]
Примеры (с другого языка: HP Prime):
RLEMap (1, 1, "3o!"); // Blinker
RLEMap (13, 5, "bo$3o$obo$3o$bo!"); // Pulsar
RLEMap (1, 6, "b3o$3o!"); // Toad
RLEMap (30, 5, "bo$3o$obo$3o$bo!"); // Pulsar
RLEMap (1, 17, "24bo11b$22bobo11b$12b2o6b2o12b2o$11bo3bo4b2o12b2o$2o8bo5bo3b2o14b$2o8bo3bob2o4bobo11b$10bo5bo7bo11b$11bo3bo20b$12b2o!"); // Glider Canon


Вы должны научиться использовать отладчик как можно скорее. Вместо того чтобы гадать, что делает ваш код, пришло время увидеть, как он выполняется, и убедиться, что он делает то, что вы ожидаете.

Отладчик позволяет вам следить за выполнением строка за строкой, проверять переменные, и вы увидите, что есть точка, в которой он перестает делать то, что вы ожидаете.
Отладчик-Википедия, свободная энциклопедия[^]

Отладчик здесь для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.
Когда код не делает того, что ожидается, вы близки к ошибке.