Python: If-elses внутри класса "init";Это работает? - PullRequest
4 голосов
/ 11 августа 2011

Я еще один новичок в программировании, проходящий через "Изучение Python трудным путем", и столкнулся с чем-то, что я не до конца понимаю.

Я предвосхищу это, сказав, что, хотя я действительно наслаждаюсь его планом урока, одним неприятным побочным эффектом, по-видимому, является то, что я не понимаю многих технических разговоров, связанных с миром программирования. Мне потребовалось два дня, чтобы понять, что такое «инстанцирование», и даже сейчас я только думаю, что понял, хе. Поэтому, надеюсь, ответ на мой запрос еще не был задан более технически наглядным способом, если мне жаль, что я был излишним.

В любом случае, я пытаюсь завершить текстовое приключение, используя классы для описания каждой комнаты. Что я на самом деле делаю, так это импортирую мою старую работу в этот более новый, более «ООП» -й способ - преобразование программы, которая по сути состоит из 980 строк вызовов функций.

Итак, ранее у меня были «комнаты» внутри каждой функции, которые проверяли, достигли ли вы определенных игровых целей, чтобы описать эту комнату для вас. Пример:

def room_one():
    if "flashlight" in pack:
        print "You see an exit to the NORTH and a bear to the EAST."
    elif "flashlight" not in pack:
        print "It's too dark to see."

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

class Runner(object):
    def __init___(self):
        self.goals = [] #an array for game achievements (talked_to_king, etc)
        self.pack = [] #an array for game items (flask, key, etc)

    def play(self, currentroom, gamestate):

        while True:

            print "\n--------"
            print currentroom.desc #this line prints the room description, could
            cmd = raw_input("> ")  #it also be part of the problem?
            gamestate.state = currentroom.actions(cmd)

            if gamestate.state != "SAME":
                currentroom = gamestate.state

            else:
                pass

class Room(object):
    def __init__(self):
        self.desc = "null" #short room description
        self.lookdesc = "super null" #longer room description for the LOOK command


    def actions(self, cmd):
        if 'help' in cmd:
            print """
            'look' -- see your surroundings, including exits.
            'get' -- to pick up an item (if it can be picked up).
            'inventory' -- displays your collected items
            'throw' -- some objects can be thrown
            'talk' -- speak to someone
            Other commands, or objects to interact with, will tend to
            show up IN UPPERCASE. (but still type them in lowercase!)
            Cardinal directions (north, south, east, west) for movement.
            """
            return "SAME"
        elif 'inv' in cmd:
            print "--Inventory--\n"
            for items in game.pack:
                print items
            print "-------------\n"
            return "SAME"
        elif 'look' in cmd:
            print self.lookdesc
            return "SAME"
        elif 'goals' in cmd:
            for goal in game.goals:
                print goal
            return "SAME"
        else:
            print "That won't work here."
            return "SAME"


class Office(Room):

    def __init__(self):

        super(Office, self).__init__()
        # here's the part that doesn't work
        if 'principal' in game.goals:
            self.desc = "You're in the principal's office, and there's a zombie in here!"
        else:
            self.desc = "You're in the principal's office."

        self.lookdesc = "The walls in here are dingy from decades of smoking.\nA door to the WEST leads back to the foyer."



    def actions(self, cmd):

        if "west" in cmd and not "principal" in game.goals:

            print "Buck up and talk to the old prune."

            return "SAME"

        elif "talk" in cmd:

            print "You call to the principal."
            game.goals.append('principal')
            next = raw_input("--Mr. Friiiiinkseseeees...--")
            print "But OH MY DAMN he's actually a zombie now."
            next = raw_input("--Aww weak--")
            return "SAME"

        return super(Office, self).actions(cmd)

Чтобы проверить, добавляется ли массив «целей», я поместил простую функцию проверки целей в родительский класс Room и, конечно же, добавил game.goals. Но моё утверждение if-else, похоже, на самом деле ничего не делает; независимо от того, что находится в массиве целей, я всегда получаю отчёт else, когда возвращаюсь в комнату.

Справедливости ради, если поместить if-else в комнату init так, как будто это был какой-то выстрел в темноте, на самом деле я был удивлен, что мне не пришло сообщение об ошибке, говорящее мне, что это не то, что нужно! Но тот факт, что он не заботится о содержимом массива game.goals, говорит мне, что это не лучший способ сделать это. Как мне это реализовать?

В качестве подзапроса - если в такой программе, как эта, если состояние игры изменяется настолько, что содержимое комнаты резко изменяется, считается ли лучше просто иметь целый другой класс для измененной комнаты? Разве важнее сохранить «карту» и сказать, что RoomThree (Комната) всегда является RoomThree, независимо от того, какие изменения в игровом состоянии произошли, или если к тому времени, когда игра вернется в RoomThree, место будет уничтожено, разграблено, в огне, полный вампиров и запахов салата, это должна быть просто другая комната? Я надеюсь, что не , потому что кажется более разумным, чтобы каждая комната просто "была той комнатой" и позволяла содержимому таких вещей, как game.goals и game.pack, изменять экземпляр класса вместо просто создаю новый класс, когда выполняются определенные условия.

Во всяком случае, это было давно. tl; dr - я делаю это странно ??

ВНОВЬ РЕДАКТИРОВАТЬ: Очистил код основного вопроса, чтобы он соответствовал новому коду, предложенному людьми здесь, а также добавил родительский класс «Комната», чтобы проверить, не является ли это частью проблемы. По-прежнему нет решения, но я верю, что качество кода улучшилось :) whee

ЗАКЛЮЧИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ (я надеюсь): Ага, ответ Стоуна был снова самым полезным. Поскольку я возвращал «то же самое» своему бегуну, он использовал старый экземпляр Office. Мне нужно было создать совершенно новый экземпляр, чтобы он смог распознать изменения; вернув «Office ()» вместо «ЖЕ», я достиг этого. Спасибо всем за помощь не только в решении данной проблемы, но и в облегчении чтения кода, а также в том, чтобы помочь мне изменить свое мышление относительно моих многословных операторов if-else. МВА: Д

Ответы [ 2 ]

1 голос
/ 11 августа 2011

Что происходит, когда у вас 100 комнат? Будет ли ваша игровая функция иметь 100 операторов if, просто чтобы установить комнату, в которой вы находитесь? (установите это снова, в основном)

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

edit: Я просто перечитал то, что у вас есть, и теперь проблема кажется очевидной, если вы не оставили жизненно важный код.

Единственный раз, когда вы добавляете принципала к целям, находится внутри функции-члена класса Office. Следовательно, к тому моменту, когда вы приступите к добавлению принципала к целям, будет слишком поздно, Office уже инициализирован и не будет повторно инициализирован, если вы не создадите новый экземпляр Office. Вам нужно будет обновить описание комнаты после добавления этой цели.

0 голосов
/ 11 августа 2011

Полагаю по этому:

    if not 'principal' in game.goals:

Вы имели в виду это:

    if 'principal' not in game.goals:

или это:

    if not ('principal' in game.goals):

not 'somestring' - это False, потому что непустая строка всегда True, и у вас нет False в ваших целях, поэтому она всегда оценивается как False.


Где создаются объекты Office? Поскольку вы проверяете только условие создания объекта, и после этого к цели добавляется принципал, поэтому при повторном использовании того же объекта описание не изменится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...