Загрузка данных


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import random, time, math

class Player:
    def __init__(self, name):
        self.name = name
        self.max_hp = 100
        self.hp = self.max_hp
        self.atk = 15
        self.defense = 5
        self.room = 0
        self.inv = []

    def alive(self):
        return self.hp > 0

    def heal(self, n):
        old = self.hp
        self.hp = min(self.max_hp, self.hp + n)
        print('Восстанавливается ' + str(self.hp - old) + ' HP (HP: ' + str(self.hp) + '/' + str(self.max_hp) + ')')

    def dmg(self, n):
        dmg = max(0, n - self.defense)
        self.hp -= dmg
        print(self.name + ' получает ' + str(dmg) + ' урона (HP: ' + str(self.hp) + '/' + str(self.max_hp) + ')')
        if self.hp <= 0:
            print(self.name + ' пал(а) в подземелье…')

    def attack(self, enemy):
        print(self.name + ' атакует ' + enemy.name + '!')
        enemy.dmg(self.atk)

    def use_potion(self):
        pots = [i for i in self.inv if isinstance(i, HealingPotion)]
        if not pots:
            print('Зелий нет.')
            return
        print('Зелья:')
        for i, p in enumerate(pots, 1):
            print(' ' + str(i) + '. ' + str(p))
        ch = input('Номер (Enter – отмена): ')
        if ch.isdigit() and 1 <= int(ch) <= len(pots):
            pot = pots[int(ch) - 1]
            pot.apply(self)
            self.inv.remove(pot)

    def status(self):
        inv = ', '.join(map(str, self.inv)) if self.inv else 'пусто'
        print('\n--- ' + self.name + ' ---')
        print('HP: ' + str(self.hp) + '/' + str(self.max_hp) + '  Atk: ' + str(self.atk) + '  Def: ' + str(self.defense))
        print('Комната: ' + str(self.room))
        print('Инвентарь: ' + inv)
        print('-------------------\n')

class Enemy:
    def __init__(self, name, hp, atk, df):
        self.name = name
        self.max_hp = hp
        self.hp = hp
        self.atk = atk
        self.defense = df

    def alive(self):
        return self.hp > 0

    def dmg(self, n):
        dmg = max(0, n - self.defense)
        self.hp -= dmg
        print(self.name + ' получает ' + str(dmg) + ' урона (HP: ' + str(self.hp) + '/' + str(self.max_hp) + ')')
        if self.hp <= 0:
            print(self.name + ' повержен!')

    def attack(self, player):
        print(self.name + ' атакует ' + player.name + '!')
        player.dmg(self.atk)

    def __str__(self):
        return self.name + ' (HP:' + str(self.hp) + '/' + str(self.max_hp) + ')'

class HealingPotion:
    def __init__(self, amount=30):
        self.amount = amount

    def apply(self, p):
        p.heal(self.amount)

    def __repr__(self):
        return 'Зелье(+' + str(self.amount) + 'HP)'

class Game:
    def __init__(self):
        n = input('Имя героя: ').strip()
        if not n:
            n = 'Аноним'
        self.p = Player(n)
        self.rooms = 10

    def gen_enemy(self):
        lvl = self.p.room + 1
        hp = random.randint(20, 30) + lvl * 5
        atk = random.randint(5, 10) + lvl * 2
        df = random.randint(2, 5) + lvl
        return Enemy(random.choice(['Гоблин', 'Скелет', 'Тролль', 'Паук']), hp, atk, df)

    def maybe_potion(self):
        if random.random() < 0.3:
            pot = HealingPotion(random.choice([20, 30, 40]))
            self.p.inv.append(pot)
            print('Вы нашли ' + str(pot) + '!')

    def combat(self, e):
        while e.alive() and self.p.alive():
            print('\nХод игрока:')
            print(' 1 – Атака')
            print(' 2 – Зелье')
            print(' 3 – Бежать (50%)')
            c = input('> ').strip()
            if c == '1':
                self.p.attack(e)
            elif c == '2':
                self.p.use_potion()
                continue
            elif c == '3':
                if random.random() < 0.5:
                    print('Вы успели уйти!')
                    return
                else:
                    print('Не удалось уйти!')
            else:
                print('Неизвестно, пропуск хода.')

            if e.alive():
                time.sleep(0.4)
                e.attack(self.p)

        if not self.p.alive():
            print('\n*** ИГРА ОКОНЧЕНА ***')
            exit()
        print('\nВы победили ' + e.name + '!')
        self.maybe_potion()

    def explore(self):
        while self.p.room < self.rooms:
            self.p.status()
            input('Enter – идти дальше...')
            self.p.room += 1
            print('\n=== Комната ' + str(self.p.room) + ' ===')
            time.sleep(0.3)

            if random.random() < 0.6:
                enemy = self.gen_enemy()
                print('Враг: ' + str(enemy))
                self.combat(enemy)
            else:
                print('Комната пуста.')
                self.maybe_potion()

        print('\n*** Вы вышли из подземелья! ***')
        self.p.status()

    def start(self):
        print('\n--- Добро пожаловать в Подземелье! ---')
        self.explore()

if __name__ == '__main__':
    Game().start()