Лучший способ запустить код один раз в циклах while? - PullRequest
0 голосов
/ 12 ноября 2018

Я пишу текстовую RPG для класса и застрял в затруднительном положении кода ...

from tkinter import *
...
runOnce = False
nextRun = False
"""Main Loop"""

while True:
    #New Game initialize
    if you.rName == None and runOnce == False:
        log("What is your name, adventurer?", eventLog)
        runOnce = True
    if you.rName != None and nextRun == False:
        log(f'What is your profession, {you.rName}?', eventLog)
        nextRun = True

#keypresses
playerInput.bind("<Return>", keyPress)
playerInput.bind("<FocusIn>", focusIn) 

top.update()
top.update_idletasks()

То, что у меня есть в настоящее время, работает, но есть гораздо больше ситуаций типа оператора if, которые требуют ответов, прежде чем перейти к следующему оператору. Цикл должен постоянно обновлять графический интерфейс по мере запуска игры.

Как я могу эффективно кодировать то, что требует ответа один раз в цикле while?

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

Видя разъяснения, я согласен с комментариями, что эти типы действий не должны входить в цикл.Это должны быть все данные, которые собираются до основного игрового цикла.

Если вы просматриваете их для проверки входных данных, вы можете использовать вместо них отдельные циклы:

while not you.name:
   you.name = input('Enter name: ')
   # some additional validation text if necessary...

while not you.job:
   you.job = input('Enter job: ')
   # some additional validation text if necessary...    
while True:
   # main game loop requiring you.name, you.job

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

class RunOnce(object):
    def __init__(self, func):
        self.func = func
        self.ran = False

    def __call__(self):
        if not self.ran:
            self.func()
            self.ran = True
    # once the function has been called, 
    # flip self.ran so it won't fire again.

# Decorate your functions with this special class
@RunOnce
def get_name():
    you.name = input('Enter Name: ')

@RunOnce
def get_job():
    you.job = input('Enter Job: ')

А затем, когда вы находитесь в основном игровом цикле:

while True:
    get_name()    # this will run once
    get_job()     # this too will run once
    get_name()    # this won't run anymore
    get_job()     # this neither.

Преимущество этого подхода заключается в том, что он дает вам возможность перезапускать функцию при необходимости:

get_name()             # get_name.ran becomes True
get_name.ran = False   # reset the flag
get_name()             # this will run again.

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

0 голосов
/ 12 ноября 2018

Попробуйте проверить ваши параметры на ноль, прежде чем их использовать. Если вы ищете ввод пользователя, вы можете сделать это:

userInput = None
while True:     
    userInput = input("Do the thing only once") if userInput is None else userInput
    ...
...