Имея переменную изменения функции в Python 3.4?

Я работаю над простой текстовой игрой и наткнулся на то, что не знаю, как это сделать. В моей игре вы получаете здоровье, силу, защиту, опыт и уровни по мере прохождения игры. Я сделал так, что всякий раз, когда происходит битва, мне не нужно переписывать все это в код, создав функцию специально для битвы. Поэтому, когда я хочу, чтобы произошла битва, я просто набираю battle1(), чтобы произошла последовательность битв. Единственная проблема заключается в том, что переменные статистики меняются так часто, и в коде, который я установил, поэтому, если вы используете зелье и подвергаетесь нападению, а ваше здоровье превысит максимальное здоровье вашего персонажа (которое варьируется от уровня к уровню), он будет быть установлен на максимальное здоровье, которое вы можете иметь (например, игрок использует зелье, когда у него 15 единиц здоровья, а максимальное здоровье равно 15, оно просто останется на уровне 15 единиц здоровья, а не увеличится до 17). Вот мой код:

class player:
    def __init__ (self, name, health, strength, defense):
        self.__health = health
        self.__strength = strength
        self.__defense = defense
        self.__name = name
    def getName(self):
        return self.__name

    def getHealth(self):
        return self.__health

    def getStrength(self):
        return self.__strength

    def getDefense(self):
        return self.__defense

    def getPotion(self):
        return self.__potion

    def subHealth(self, num):
        self.__health -= num
        return self.__health

    def setHealth(self, h):
        self.__health = h


def main():

    name1 = input("What would you like your name to be?")
    print("Hello,", name1, "you are on a quest to save otis from the evil Dongus. You must slay him, or Otis will poop.")
    player1 = player(name1, 10, 2, 1)
    enemy = player("Rat", 15, 0, 0)
    print("Your stats are, health:", player1.getHealth(), "strength:", player1.getStrength(), "and defense:", player1.getDefense())
    print("Fight.")
    attack =input("Type 1 to attack.")

    if attack == "1":

        enemy.subHealth(player1.getStrength()-enemy.getDefense())
        **if enemy.getHealth()>15:
            enemy.setHealth(15)**
        print(enemy.getName()+"'s health is",enemy.getHealth())
        player1.subHealth(enemy.getStrength()-player1.getDefense())
        **if player1.getHealth()>10:
            player1.setHealth(10)**

main()

Части, выделенные жирным шрифтом, — это части кода, о которых я говорю. Итак, есть ли способ сделать так, например, когда вы на 5 уровне, ваше максимальное здоровье установлено на 15, а не на десять? Имейте в виду, что во время битвы ваши враги наносят вам урон, поэтому вы не можете просто сделать player1.getHealth(). Спасибо!


person Robbie    schedule 10.08.2014    source источник
comment
не ответ, но вам не нужны эти методы получения и установки, вы можете напрямую обращаться к атрибутам.   -  person Padraic Cunningham    schedule 10.08.2014
comment
@Robbie: Просто используйте переменные напрямую. Назовите его health вместо __health, затем используйте player1.health вместо player1.getHealth() и player1.health = foo вместо player1.setHealth(foo).   -  person abarnert    schedule 10.08.2014
comment
@Robbie: Кроме того, даже если вам нужны частные переменные (которых в данном случае нет), вы не хотите использовать двойные символы подчеркивания. Двойное подчеркивание предназначено только для методов, которые вам нужно скрыть от подклассов (чтобы они могли определить метод с тем же именем, не переопределяя случайно ваш). Вы можете прочитать PEP 8, руководство по стилю Python, в котором объясняется все это и многое другое.   -  person abarnert    schedule 10.08.2014
comment
Хорошо, логично, извините, я случайно удалил свой комментарий ..   -  person Robbie    schedule 10.08.2014
comment
Кстати, я не уверен, почему кто-то проголосовал за вас, потому что я думаю, что это разумный вопрос (то, что вы новичок, не делает вас глупым или ленивым, это просто делает вас новичком). Но вы определенно можете улучшить его, удалив весь ненужный код (см. MCVE) и дав более конкретное представление о том, какая часть на этом ты застрял.   -  person abarnert    schedule 10.08.2014
comment
О, ха-ха, извините, я присоединился к другому форуму, и они говорят хранить весь код, каким бы неважным он ни был, и я думаю, что я неправильно прочитал MCVE ›.‹. Я сделаю это, как только вернусь с ужина.   -  person Robbie    schedule 11.08.2014
comment
@Robbie: StackOverflow стремится создать полезный репозиторий ответов — таким образом, эти ответы могут быть лучшими результатами Google в случаях с удобным поиском, и, по крайней мере, кто-то может указать, что это дубликат в случаях, когда поиск не помогает. Выяснение того, какой код не имеет значения (и проверка того, что вы правы и все еще можете продемонстрировать проблему) — это то, как вы делаете свою часть работы; запуск кода и проверка того, что их ответы действительно работают, — это то, как другие выполняют свою часть работы.   -  person abarnert    schedule 11.08.2014


Ответы (2)


Итак, есть ли способ сделать так, например, когда вы на 5 уровне, ваше максимальное здоровье установлено на 15, а не на десять?

Да. Вам нужно сохранить «максимальное здоровье» для игрока в дополнение к его «текущему здоровью»:

if player1.getHealth() > player.getMaxHealth()
    player1.setHealth(player.getMaxHealth())

Как объясняет Падраик в комментарии, вам не нужны геттеры и сеттеры, подобные этому, в Python, и это обычно считается плохим стилем. Так что лучше было бы написать так:

if player1.health > player1.max_health:
    player1.health = player1.max_health

Вы можете написать это немного короче, используя min:

player1.health = min(player1.health, player1.max_health)

Кроме того, если максимальное здоровье — это то, что вы можете вычислить на лету (может быть, 10 + level?), вы можете написать для этого функцию и вызывать эту функцию всякий раз, когда вам это нужно, вместо того, чтобы сохранять ее как дополнительный атрибут.

Одна из замечательных особенностей Python заключается в том, что вы можете начать с атрибута и изменить его на вычисляемое значение, не превращая его в функцию, с помощью @property:

@property
def max_health(self):
    return 10 + self.level
person abarnert    schedule 10.08.2014
comment
Хорошо, почти все это имеет смысл. Разве функция min() не выбирает наименьшее из двух значений? Что происходит, когда значения совпадают? - person Robbie; 10.08.2014
comment
Возвращает минимальное значение. Не имеет значения, если существует более одного минимума. - person joel goldstick; 10.08.2014
comment
@Robbie: Это действительно то, что вы можете проверить на себе быстрее, чем вы можете спросить. Просто откройте интерпретатор и введите print(min(2, 2)) и посмотрите, что получится. - person abarnert; 10.08.2014
comment
@Abarnert Я попробовал, просто не понял, почему это сработало. - person Robbie; 11.08.2014
comment
Также я получаю сообщение об ошибке следующего вида: Basics/Game.py, строка 100, в бою1 вражеский.Здоровье = мин(враг.Здоровье(), вражеский.вражескиймаксЗдоровье()) Ошибка типа: объект 'int' не может быть вызван. Любые идеи? - person Robbie; 11.08.2014
comment
@Robbie: если вы замените функцию получения простым атрибутом, вы не будете вызывать этот атрибут, а просто используете его как значение. Посмотрите еще раз на мой пример. - person abarnert; 11.08.2014
comment
@abarnert, но всякий раз, когда я это делаю, я получаю сообщение об ошибке: in battle1 вражеский.subHealth = num+player1.Strength-enemy.Defense TypeError: неподдерживаемые типы операндов для +: 'int' и 'method'. - person Robbie; 11.08.2014
comment
@Robbie: Не видя вашего кода, трудно точно понять, что вы делаете неправильно, но похоже, что Strength — это обычный атрибут, а Defense — это метод. Вы должны вызывать методы, а не члены — или упростить задачу, сделав их всеми членами, чтобы вам не нужно было беспокоиться об их прямолинейности. - person abarnert; 11.08.2014
comment
@abarnert Меня смущает, когда что-то является атрибутом, а когда - методом. Как вы устанавливаете, является ли что-то атрибутом или методом? По какой-то причине я избавился от всех геттеров и сеттеров в коде, и по какой-то причине большинство функций, которые я определил в классе player: требуют вызова. Это пример того, как я изменил функции: def Strength(self): return self.__strength (простите, я не могу отформатировать это в комментариях :/). Тем не менее, по какой-то причине, когда я делаю player1.strength, мне нужно вызвать его. - person Robbie; 12.08.2014
comment
@Robbie: я думаю, вам нужно прочитать руководство по классам. Но кратко (и в общих чертах): метод — это атрибут, который определяется и вызывается как функция. Когда вы def spam(self):, это делает spam методом каждого экземпляра вашего класса. Когда вы делаете self.eggs = 0 в своем методе __init__, это делает eggs обычным атрибутом каждого экземпляра вашего класса. - person abarnert; 12.08.2014
comment
@abarnert Я думаю, мне нужно пройти еще один курс по Python. Как мне изменить все методы на простые атрибуты в моем коде? Я запутался, так как в моем коде у меня есть def Health(self): всегда, и я никогда не делал def Health(self) = self.Health. Если я ошибаюсь, не должно ли это означать, что мне всегда придется вызывать метод с помощью ()? Только иногда в моем коде это нужно. Я не очень хорошо понимаю статью, я постараюсь прочитать ее, когда я меньше устану, я полагаю. - person Robbie; 12.08.2014
comment
@Robbie: Просто полностью избавьтесь от метода def Health(self): и измените код, выполняющий self.__health = health, на self.health = health. Тогда у вас есть атрибут health. К которому вы можете получить доступ внутри как self.health или снаружи как player1.health. Имеет ли это смысл? - person abarnert; 12.08.2014
comment
@abarnert Это имеет смысл. В коде все выглядит намного проще :). Сейчас почти все работает нормально, но я спрошу об этом в другом вопросе. - person Robbie; 12.08.2014

Просто переложите ответственность на игрока, например:

def changeHealth (self, delta):
    self.__health += delta

    maxHealth = 10 if self.__level < 5 else 15
    if self.__health > maxHealth:
        self.__health = maxHealth
    elif self.__health < 0
        self.__health = 0
person poke    schedule 10.08.2014