Почему переопределение функции внутри другой функции не работает? (Python Черепаха) - PullRequest
0 голосов
/ 17 марта 2020

Я программирую игру, в которой вражеские черепахи (в программе это называется бадтурт) преследуют черепаху пользователя. Пользователь может заставить свою черепаху атаковать вражеских черепах, отправив атаку (еще одну черепаху).

На 2-м уровне есть две вражеские черепахи, преследующие черепаху пользователя. Чтобы одна вражеская черепаха перестала двигаться (после того, как на нее напали / ударили), я попытался переопределить функцию, которая заставляет двигаться вражескую черепаху, что было сделано внутри другой функции. (Я переопределил его как None)

attack = turtle.Turtle()
#...attributes

def turtleattack():
    global lvl
    global q
    global w
    global e
    #... positioning attack
    for i in range(75):
        attack.forward(10)
        if lvl == 1:
            Chase(badturt)
        if lvl == 2:
            Chase(badturt)
            Chase(badturt2)
        if lvl == 3:
            Chase(badturt)
            Chase(badturt2)
            Chase(badturt3)
        IfAttackHit()
bg.onkeypress(turtleattack, 'z')
bg.listen()


def Chase(bt): #makes bad turt (bt) chase turt
    bt.setheading(bt.towards(turt))
    bt.forward(11)

def StopChase(bt):
    global lvl
    global win
    #global Chase <---------------- program stops running if I write it in
    if lvl == 1:
        #...
    if lvl == 2:
        def Chase(bt):
            None
        if q == 2 and w == 2:
            lvl = 3
            writeinfo()
    if lvl == 3:
        def Chase(bt):
            None
        if q == 3 and w == 3 and e == 3:
            #... (winning the game)

def ChaseAgain(bt): #makes badturt chase again when it moves onto next lvl
    def Chase(bt):
        bt.setheading(badturt.towards(turt))
        bt.forward(11)
    Chase(bt)


def IfAttackHit():
    global win
    global lvl
    global q
    global w
    global e
    if lvl == 1:
        if badturt.distance(attack) < 20:
            badturt.hideturtle()
            attack.hideturtle()
            badturt.goto(300,350)
            q = 1
            StopChase(badturt) #<---- doesn't work
    if lvl == 2:
        if badturt.distance(attack) < 20:
            badturt.hideturtle()
            attack.hideturtle()
            badturt.goto(300,350)
            q = 2
            StopChase(badturt)
        if badturt2.distance(attack) < 20:
            badturt2.hideturtle()
            badturt2.goto(-300,350)
            attack.hideturtle()
            w = 2
            StopChase(badturt2)
    if lvl == 3:
        #same format as lvl 2 but with addition of badturt3


while True:
    if lvl == 1:
         while True:
            CheckDamage()
            if turthealth == 0:
                LOSE()
                break
            IfAttackHit()
            Chase(badturt)
            if q == 1:
                break
    break
    if lvl == 2:
        ChaseAgain(badturt) #make it move again
        ChaseAgain(badturt2)
        badturt.goto(300,350)
        badturt.showturtle()
        badturt2.showturtle()
        while True:
            CheckDamage()
            if turthealth == 0:
                LOSE()
                break
            IfAttackHit()
            Chase(badturt)
            Chase(badturt2)
    break
    if lvl == 3:
        #same format as lvl 2 but with addition of badturt3
        break

Это не сработало. Было ли это потому, что он был вложен в другую функцию? StopChase () никогда не вызывался? Была ли функция снова переопределена, чтобы вражеская черепаха снова начала двигаться?

Кроме того, мой учитель сказал мне, что мне нужно написать «глобальное преследование», чтобы переопределить его в другой функции, но когда я это сделаю, программа останавливается в этой точке - когда я перемещаю курсор по экрану черепахи, он просто показывает курсор загрузки, и ничего не происходит на экране / он зависает. (Было ли это неправильно, или это проблема с программой python на моем ноутбуке?)

Я также попытался переопределить Chase (), чтобы badturt двигался только вперед 0 (по сути, заставляя это делать) ничего), но это тоже не сработало.

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

Ответы [ 2 ]

2 голосов
/ 17 марта 2020

Когда вы переопределяете неклассный метод, переопределение является постоянным, то есть оно применяется ко всему. Вы, вероятно, не хотите этого.

Что говорит против написания условия в вашем методе Чейза?


В вашем коде есть различные плохие методы кодирования:

  • Обычно вам следует воздерживаться от использования global. Вы должны создавать классы и экземпляры классов, которые имеют атрибуты и передавать эти экземпляры.
  • Методы не пишутся с заглавной буквы. Классы пишутся с заглавной буквы.
  • У вас есть некоторый недоступный код из-за break
  • Используйте pass вместо None, когда ничего не должно происходить
0 голосов
/ 17 марта 2020

Тин Нгуен абсолютно прав, и вы обязательно должны следовать его советам. Я просто хотел бы уточнить ваш первый вопрос. Даже если это может быть плохо, переопределение вашей функции с помощью global должно работать. Вот что я попробовал в качестве минимального примера:

def f():
    print("f")

def g():
    global f
    def f():
        print("f_prime")

f()
g()
f()

При вызове я получаю:

f
f_prime

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

...