Форум программистов, компьютерный форум, киберфорум
Python: Решение задач
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/92: Рейтинг темы: голосов - 92, средняя оценка - 4.86
3 / 3 / 0
Регистрация: 25.03.2023
Сообщений: 4

Нужно исправить код задания про РПГ-игру

27.03.2023, 19:23. Показов 22191. Ответов 8

Студворк — интернет-сервис помощи студентам
Вася решил заняться разработкой компьютерных игр (Python применяется даже в геймдеве!). Ему поручили разрабатывать искусственный интеллект для союзников, которые сражаются бок о бок с реальными игроками. Но так как Вася пока не силён в теме машинного обучения и нейросетей, ему предстоит заменить эти знания смекалкой и набором if/else-условий.

Вася уже написал код, описывающий монстров (файл monsters.py), этот код изменять нельзя.

В файле heroes.py вы найдёте заготовки системы классов:

базовый класс hero, который нельзя изменять;
наследники класса tank/healer/attacker — их надо изменять.
Помимо этого, в main.py есть код, который:

запускает один год сражений — изменять нельзя;
создаёт команду для сражения с монстрами — изменять можно, но с условиями;
запускает 20 раз один год сражений и подсчитывает количество побед — изменять нельзя.
Ваша задача:

Дописать код в классы tank/healer/attacker в файле heroes.py.
Сформировать команду в main.py.
Проверить, что с выбранной вами стратегией герои побеждают монстров как минимум в половине случаев (>= 10 побед из 20).
Цель: из 20 сражений нужно побеждать как минимум в 10. В сражениях много случайностей, поэтому убедитесь, что в нескольких разных запусках ваша команда набирает нужное количество очков.

Мой вариант решения:

Файл main.py:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import random
from monsters import MonsterBerserk, MonsterHunter
from heroes import Tank, Healer, Attacker
 
 
def one_year_of_war():
    # Ниже приведен пример составления команды
    # Вы можете изменять состав команды, НО размер команды не должен быть более 5.
 
    tank = Tank("Танк Пётр")
    attacker = Attacker("Убийца Ольга")
    second_attacker = Attacker("Убийца Траур")
    healer = Healer("Монах Игнат")
    second_healer = Healer("Монах Ирэна")
    good_team = [tank, attacker, second_attacker, second_healer, healer]
 
    # Код ниже изменять нельзя!
 
    # Функция запускает симуляцию одного года сражений.
    # В цикле запускается 365 итераций (1 итерация = 1 день)
    # Каждый день каждый герой и монстр выбирают и совершают ОДНО действие.
    # Если монстры умирают - они пропадают из списка
    # Если умирают герои - цикл завершается - битва считается проигранной (возвращается 0)
    # Если герои выживают - битва считается выигранной (возвращается 1)
    if sum([isinstance(hero, (MonsterHunter, MonsterBerserk)) for hero in good_team]) > 1:
        print("В команде героев может быть только 1 монстр!")
        return 0
 
    evil_names = ["Абвыргл", "Мефисто", "Драник", "Диабло", "Пусечка", "Стаут"]
    mob_warrior = MonsterBerserk("Берсерк " + random.choice(evil_names))
    mob_ranger = MonsterHunter("Рейнджер " + random.choice(evil_names))
    evil_team = [mob_warrior, mob_ranger]
 
    for day in range(1, 366):
        print("=" * 50 + "\nНачало дня №" + str(day) + "\n" + "=" * 50)
 
        # В циклах у героев и монстров вызывается метод make_a_move, который должен выбирать и совершать одно действие
        # Для наглядности вы можете добавлять в каждое действие принты с подробностями (чтобы знать кто когда и что совершает)
        # При помощи этой информации вы сможете искать проблемы и ошибки в вашем коде и в конечном итоге это поможет вам улучшить стратегию
        print("\nКоманда добра:\n" + '-' * 50)
        for hero in good_team:
            hero.make_a_move(good_team, evil_team)
 
        print("\nКоманда зла:\n" + '-' * 50)
        for mob in evil_team:
            mob.make_a_move(evil_team, good_team)
 
        print(f"Итоги дня сражений №{day}")
 
        # В итогах дня у каждого героя и каждого монстра вызывается метод __str__ который должен описывать их текущее состояние
        print("\nКоманда добра:\n" + '-' * 50)
 
        def __str__(self):
            return str(self.value)
 
        print("\nКоманда зла:\n" + '-' * 50)
        for mob in evil_team:
            print(mob)
 
        # Мёртвые монстры удаляются из списка
        evil_team = [mob for mob in evil_team if mob.is_alive()]
        # Новые монстры в чётные дни добавляются в список (но их не может быть больше 4)
        if day % 2 == 0 and len(evil_team) < 4:
            newborn_evils = [MonsterBerserk("Берсерк " + random.choice(evil_names)), MonsterHunter("Рейнджер " + random.choice(evil_names))]
            evil_team.append(random.choice(newborn_evils))
 
        if any([not hero.is_alive() for hero in good_team]):
            print("Вы проиграли!")
            return 0
        else:
            print("Сражение продолжается!")
 
    else:
        print("Вы одержали победу!")
        return 1
 
 
# Код ниже не подлежит изменению
# Он запускает 20 симуляций. Для зачёта по заданию вам надо стабильно набирать 10 или более побед.
count_of_wins = 0
for year in range(1, 21):
    count_of_wins += one_year_of_war()
 
print("Из 20 раз команда героев одержала", count_of_wins, "побед")
if count_of_wins < 10:
    print("Героям нужна другая тактика, попробуйте ещё!")
else:
    print("Герои готовы к реальному сражению, задание выполнено!")
Файл monsters.py:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import random
 
 
class Monster:
 
    max_hp = 150
    start_power = 10
 
    def __init__(self, name):
        self.name = name
        self.__hp = self.max_hp
        self.__power = self.start_power
        self.__is_alive = True
 
    def get_hp(self):
        return self.__hp
 
    def set_hp(self, new_value):
        self.__hp = max(new_value, 0)
 
    def get_power(self):
        return self.__power
 
    def set_power(self, new_power):
        self.__power = new_power
 
    def attack(self, target):
        pass
 
    def is_alive(self):
        return self.__is_alive
 
    def take_damage(self, damage):
        print("\t", self.name, "Получил удар с силой равной = ", round(damage), ". Осталось здоровья - ", round(self.get_hp()))
        if self.get_hp() <= 0:
            self.__is_alive = False
 
    def make_a_move(self, friends, enemies):
        pass
 
    def __str__(self):
        return 'Name: {0} | HP: {1}'.format(self.name, self.get_hp())
 
 
class MonsterBerserk(Monster):
 
    def __init__(self, name):
        super().__init__(name)
        self.madness = 1
 
    def attack(self, target):
        target.take_damage(self.get_power() * self.madness)
        self.madness += 0.1
 
    def take_damage(self, power):
        self.set_hp(self.get_hp() - power * (self.madness / 2))
        if self.get_hp() < 50:
            self.madness *= 2
        super().take_damage(power)
 
    def make_a_move(self, friends, enemies):
        print(self.name, end=' ')
        self.madness = min(self.madness, 4)
        if not enemies:
            return
        if self.madness < 3:
            print("Атакую того, кто стоит ближе -", enemies[0].name)
            self.attack(enemies[0])
        else:
            target = random.choice(enemies)
            print("BERSERK MODE!!! Уровень безумия - " + str(self.madness) + " Случайно атакую -", target.name)
            print()
            self.attack(target)
        print('\n')
 
 
class MonsterHunter(Monster):
 
    def __init__(self, name):
        super().__init__(name)
        self.potions = 10
 
    def attack(self, target):
        target.take_damage(self.get_power() + (10 - self.potions))
 
    def take_damage(self, power):
        self.set_hp(self.get_hp() - power)
        if random.randint(1, 10) == 1:
            self.potions -= 1
        super().take_damage(power)
 
    def give_a_potion(self, target):
        self.potions -= 1
        target.set_hp(target.get_hp() + self.get_power())
 
    def make_a_move(self, friends, enemies):
        print(self.name, end=' ')
        target_of_potion = friends[0]
        min_health = target_of_potion.get_hp()
        for friend in friends:
            if friend.get_hp() < min_health:
                target_of_potion = friend
                min_health = target_of_potion.get_hp()
 
        if min_health < 60 and self.potions > 0:
            print("Исцеляю", target_of_potion.name)
            self.give_a_potion(target_of_potion)
        else:
            if not enemies:
                return
            print("Атакую ближнего -", enemies[0].name)
            self.attack(enemies[0])
        print('\n')
Файл heroes.py:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
import random
 
 
class Hero:
    # Базовый класс, который не подлежит изменению
    # У каждого наследника будут атрибуты:
    # - Имя
    # - Здоровье
    # - Сила
    # - Жив ли объект
    # Каждый наследник будет уметь:
    # - Атаковать
    # - Получать урон
    # - Выбирать действие для выполнения
    # - Описывать своё состояние
 
    max_hp = 150
    start_power = 10
 
    def __init__(self, name):
        self.name = name
        self.__hp = self.max_hp
        self.__power = self.start_power
        self.__is_alive = True
 
    def get_hp(self):
        return self.__hp
 
    def set_hp(self, new_value):
        self.__hp = max(new_value, 0)
 
    def get_power(self):
        return self.__power
 
    def set_power(self, new_power):
        self.__power = new_power
 
    def is_alive(self):
        return self.__is_alive
 
    # Все наследники должны будут переопределять каждый метод базового класса (кроме геттеров/сеттеров)
    # Переопределенные методы должны вызывать методы базового класса (при помощи super).
    # Методы attack и __str__ базового класса можно не вызывать (т.к. в них нету кода).
    # Они нужны исключительно для наглядности.
    # Метод make_a_move базового класса могут вызывать только герои, не монстры.
    def attack(self, target):
        # Каждый наследник будет наносить урон согласно правилам своего класса
        pass
 
    def take_damage(self, damage):
        # Каждый наследник будет получать урон согласно правилам своего класса
        # При этом у всех наследников есть общая логика, которая определяет жив ли объект.
        print("\t", self.name, "Получил удар с силой равной = ", round(damage), ". Осталось здоровья - ", round(self.get_hp()))
        # Дополнительные принты помогут вам внимательнее следить за боем и изменять стратегию, чтобы улучшить выживаемость героев
        if self.get_hp() <= 0:
            self.__is_alive = False
 
    def make_a_move(self, friends, enemies):
        # С каждым днём герои становятся всё сильнее.
        self.set_power(self.get_power() + 0.1)
 
    def __str__(self):
        pass
 
 
class Healer(Hero):
    class Healer(Hero):
        def init(self, name, max_health, max_power):
            super().init(name, max_health, max_power)
            self.__mag_power = self.__power * 3
 
            def attack(self, enemy):
                enemy.receive_damage(self.__power / 2)
 
            def receive_damage(self, damage):
                super().receive_damage(damage * 1.2)
 
            def heal(self, target):
                target.receive_healing(self.__mag_power)
 
            def choose_action(self, allies, enemies):
                if self.__health <= 0:
                    return
                target = self.__find_weakest_ally(allies)
                if target:
                    self.heal(target)
                else:
                    target = self.__find_strongest_enemy(enemies)
                    if target:
                        self.attack(target)
 
    # Целитель:
    # Атрибуты:
    # - магическая сила - равна значению НАЧАЛЬНОГО показателя силы умноженному на 3 (self.__power * 3)
    # Методы:
    # - атака - может атаковать врага, но атакует только в половину силы self.__power
    # - получение урона - т.к. защита целителя слаба - он получает на 20% больше урона (1.2 * damage)
    # - исцеление - увеличивает здоровье цели на величину равную своей магической силе
    # - выбор действия - получает на вход всех союзников и всех врагов и на основе своей стратегии выполняет ОДНО из действий (атака,
    # исцеление) на выбранную им цель
 
 
class Tank(Hero):
    def init(self, name, max_health, max_power):
        super().init(name, max_health, max_power)
        self.__defense = 1
        self.__is_shield_up = False
 
        def attack(self, enemy):
            damage = self.__power / 2
            enemy.receive_damage(damage)
 
        def receive_damage(self, damage):
            damage /= self.__defense
            super().receive_damage(damage)
 
        def raise_shield(self):
            if not self.__is_shield_up:
                self.__is_shield_up = True
                self.__power /= 2
                self.__defense *= 2
 
        def lower_shield(self):
            if self.__is_shield_up:
                self.__is_shield_up = False
                self.__power *= 2
                self.__defense /= 2
 
        def choose_action(self, allies, enemies):
            if self.__health <= 0:
                return
            if self.__is_shield_up:
                self.lower_shield()
            else:
                target = self.__find_closest_enemy(enemies)
                if target:
                    self.attack(target)
                else:
                    self.raise_shield()
 
    # Танк:
    # Атрибуты:
    # - показатель защиты - изначально равен 1, может увеличиваться и уменьшаться
    # - поднят ли щит - танк может поднимать щит, этот атрибут должен показывать поднят ли щит в данный момент
    # Методы:
    # - атака - атакует, но т.к. доспехи очень тяжелые - наносит половину урона (self.__power)
    # - получение урона - весь входящий урон делится на показатель защиты (damage/self.defense) и только потом отнимается от здоровья
    # - поднять щит - если щит не поднят - поднимает щит. Это увеличивает показатель брони в 2 раза, но уменьшает показатель силы в 2 раза.
    # - опустить щит - если щит поднят - опускает щит. Это уменьшает показатель брони в 2 раза, но увеличивает показатель силы в 2 раза.
    # - выбор действия - получает на вход всех союзников и всех врагов и на основе своей стратегии выполняет ОДНО из действий (атака,
    # поднять щит/опустить щит) на выбранную им цель
 
class Attacker(Hero):
    def init(self, name, max_health, max_power):
        super().init(name, max_health, max_power)
 
        self.__power_multiply = 2
 
        def attack(self, enemy):
            damage = self.__power * self.__power_multiply
            enemy.receive_damage(damage)
            self.power_down()
 
        def receive_damage(self, damage):
            damage *= self.__power_multiply / 2
            super().receive_damage(damage)
 
        def power_up(self):
            self.__power_multiply *= 2
 
        def power_down(self):
            self.__power_multiply /= 2
 
        def choose_action(self, allies, enemies):
            if self.__health <= 0:
                return
            target = self.__find_weakest_enemy(enemies)
            if target:
                self.attack(target)
            else:
                target = self.__find_most_damaged_ally(allies)
                if target:
                    self.power_up()
                    self.heal(target)
                    self.power_down()
 
    # Убийца:
    # Атрибуты:
    # - коэффициент усиления урона (входящего и исходящего)
    # Методы:
    # - атака - наносит урон равный показателю силы (self.__power) умноженному на коэффициент усиления урона (self.power_multiply)
    # после нанесения урона - вызывается метод ослабления power_down.
    # - получение урона - получает урон равный входящему урона умноженному на половину коэффициента усиления урона - damage * (
    # self.power_multiply / 2)
    # - усиление (power_up) - увеличивает коэффициента усиления урона в 2 раза
    # - ослабление (power_down) - уменьшает коэффициента усиления урона в 2 раза
    # - выбор действия - получает на вход всех союзников и всех врагов и на основе своей стратегии выполняет ОДНО из действий (атака,
    # усиление, ослабление) на выбранную им цель
Комментарий преподавателя:

Вложенности быть не должно

Метод должен называться __init__

Внутри метода не должны быть никаких других методов

__str__ всегда должен возвращать строку, а у вас None

Помогите доработать код
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
27.03.2023, 19:23
Ответы с готовыми решениями:

Нужно отредактировать с учетом полученного задания, не понимаю как исправить код
С Делфи раньше никогда не работал и знаком буквально пару недель, а курсовая ждать не будет :( Код примера: unit Unit1; ...

Подскажите игру (стратегию или РПГ)
Помогите найти игру: экономическая стратегия в реальном времени (21 век) Не сильно боевая, экономически продвинутая игра. Играл в...

Нужно немного исправить игру
Здравствуйте! Я сделала игру, только есть проблемы: очки не начисляются при выстреле в картинку и не исчезает надпись &quot;Вы...

8
Эксперт PythonЭксперт Java
19530 / 11067 / 2931
Регистрация: 21.10.2017
Сообщений: 23,294
27.03.2023, 20:52
Цитата Сообщение от llkl12g Посмотреть сообщение
__str__ всегда должен возвращать строку, а у вас None
Цитата Сообщение от llkl12g Посмотреть сообщение
def __str__(self):
        pass
Удивительно!

Добавлено через 3 минуты
Цитата Сообщение от llkl12g Посмотреть сообщение
Вложенности быть не должно
Когда копипастил, с отступами промахнулся.

Добавлено через 50 секунд

Не по теме:

Все-таки даже с чатжпт надо держать ухо востро...

1
0 / 0 / 0
Регистрация: 04.04.2023
Сообщений: 1
04.04.2023, 13:13
поделитесь пожалуйста окончательным вариантом
0
3 / 3 / 0
Регистрация: 25.03.2023
Сообщений: 4
04.04.2023, 13:58  [ТС]
ef1menko, Файл heroes.py
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
import random
 
 
class Hero:
    # Базовый класс, который не подлежит изменению
    # У каждого наследника будут атрибуты:
    # - Имя
    # - Здоровье
    # - Сила
    # - Жив ли объект
    # Каждый наследник будет уметь:
    # - Атаковать
    # - Получать урон
    # - Выбирать действие для выполнения
    # - Описывать своё состояние
 
    max_hp = 150
    start_power = 10
 
    def __init__(self, name):
        self.name = name
        self.__hp = self.max_hp
        self.__power = self.start_power
        self.__is_alive = True
 
    def get_hp(self):
        return self.__hp
 
    def set_hp(self, new_value):
        self.__hp = max(new_value, 0)
 
    def get_power(self):
        return self.__power
 
    def set_power(self, new_power):
        self.__power = new_power
 
    def is_alive(self): # жив или мёртв
        return self.__is_alive
 
    # Все наследники должны будут переопределять каждый метод базового класса (кроме геттеров/сеттеров)
    # Переопределенные методы должны вызывать методы базового класса (при помощи super).
    # Методы attack и __str__ базового класса можно не вызывать (т.к. в них нет кода).
    # Они нужны исключительно для наглядности.
    # Метод make_a_move базового класса могут вызывать только герои, не монстры.
    def attack(self, target):
        # Каждый наследник будет наносить урон согласно правилам своего класса
        pass
 
    def take_damage(self, damage):
        # Каждый наследник будет получать урон согласно правилам своего класса
        # При этом у всех наследников есть общая логика, которая определяет жив ли объект.
        print("\t", self.name, "Получил удар с силой равной = ",
              round(damage), ". Осталось здоровья - ",
              round(self.get_hp()))
        # Дополнительные принты помогут вам внимательнее следить за боем и изменять стратегию,
        # чтобы улучшить выживаемость героев
        if self.get_hp() <= 0:
            self.__is_alive = False
 
    def make_a_move(self, friends, enemies):
        # С каждым днём герои становятся всё сильнее.
        self.set_power(self.get_power() + 0.1)
 
    def __str__(self):
        return 'Name: {0} | HP: {1}'.format(self.name, self.get_hp())
 
 
class Healer(Hero):
    # Целитель:
    # Атрибуты:
    # - магическая сила - равна значению НАЧАЛЬНОГО показателя силы умноженному на 3 (self.__power * 3)
    # Методы:
    # - атака - может атаковать врага, но атакует только в половину силы self.__power
    # - получение урона - т.к. защита целителя слаба - он получает на 20% больше урона (1.2 * damage)
    # - исцеление - увеличивает здоровье цели на величину равную своей магической силе
    # - выбор действия - получает на вход всех союзников и всех врагов и на основе своей стратегии
    # выполняет ОДНО из действий (атака, исцеление) на выбранную им цель
 
    def __init__(self, name):
        super().__init__(name)
        self.magic_power = self.get_power() * 3
 
    def attack(self, target):
        target.take_damage(self.get_power() // 2)
 
    def take_damage(self, damage):
        super().take_damage(int(damage * 1.2))
 
    def heal(self, target):
        target.set_hp(target.get_hp() + self.magic_power)
 
    def make_a_move(self, friends, enemies):
        print(self.name, end=' ')
        target_of_potion = friends[0]
        min_health = target_of_potion.get_hp()
        for friend in friends:
            if friend.get_hp() < min_health:
                target_of_potion = friend
                min_health = target_of_potion.get_hp()
 
        if min_health < 60:
            print('Исцеляю', target_of_potion.name)
            self.heal(target_of_potion)
        else:
            if not enemies:
                return
            print('Атакую ближнего -', enemies[0].name)
            self.attack(enemies[0])
        print('\n')
 
 
class Tank(Hero):
    # Танк:
    # Атрибуты:
    # - показатель защиты - изначально равен 1, может увеличиваться и уменьшаться
    # - поднят ли щит - танк может поднимать щит, этот атрибут должен показывать поднят ли щит в данный момент
    # Методы:
    # - атака - атакует, но т.к. доспехи очень тяжелые - наносит половину урона (self.__power)
    # - получение урона - весь входящий урон делится на показатель защиты (damage/self.defense) и только потом отнимается от здоровья
    # - поднять щит - если щит не поднят - поднимает щит. Это увеличивает показатель брони в 2 раза, но уменьшает показатель силы в 2 раза.
    # - опустить щит - если щит поднят - опускает щит. Это уменьшает показатель брони в 2 раза, но увеличивает показатель силы в 2 раза.
    # - выбор действия - получает на вход всех союзников и всех врагов и на основе своей стратегии выполняет ОДНО из действий (атака,
    # поднять щит/опустить щит) на выбранную им цель
 
    def __init__(self, name):
        super().__init__(name)
        self.shield_up = False
        self.defense = 1
 
    def attack(self, target):
        target.take_damage(self.get_power() / 2)
 
    def take_damage(self, damage):
        self.set_hp(self.get_hp() - (damage / self.defense))
 
    def raise_shield(self):
        if not self.shield_up:
            self.shield_up = True
            self.defense *= 2
            self.set_power(self.get_power() / 2)
            print(f"{self.name} поднимает щит!")
 
    def lower_shield(self):
        if self.shield_up:
            self.shield_up = False
            self.defense /= 2
            self.set_power(self.get_power() / 2)
            print(f"{self.name} опускает щит!")
 
    def make_a_move(self, friends, enemies):
        print(self.name, end=' ')
        if not enemies:
            return
        if self.get_hp() > 60:
            self.lower_shield()
            print('Атакую ближнего - ', enemies[0].name)
            self.attack(enemies[0])
        else:
            self.raise_shield()
            print('Атакую ближнего - ', enemies[0].name)
            self.attack(enemies[0])
        print('\n')
 
 
class Attacker(Hero):
    # Убийца:
    # Атрибуты:
    # - коэффициент усиления урона (входящего и исходящего)
    # Методы:
    # - атака - наносит урон равный показателю силы (self.__power) умноженному на коэффициент усиления урона (self.power_multiply)
    # после нанесения урона - вызывается метод ослабления power_down.
    # - получение урона - получает урон равный входящему урона умноженному на половину коэффициента усиления урона - damage * (
    # self.power_multiply / 2)
    # - усиление (power_up) - увеличивает коэффициента усиления урона в 2 раза
    # - ослабление (power_down) - уменьшает коэффициента усиления урона в 2 раза
    # - выбор действия - получает на вход всех союзников и всех врагов и на основе своей стратегии выполняет ОДНО из действий (атака,
    # усиление, ослабление) на выбранную им цель
 
    def __init__(self, name):
        super().__init__(name)
        self.power_multiply = 1
 
    def attack(self, target):
        target.take_damage(self.get_power() * self.power_multiply)
        self.power_down()
 
    def take_damage(self, damage):
        self.set_hp(self.get_hp() - (damage - (self.power_multiply / 2)))
 
    def power_up(self):
        self.power_multiply *= 2
 
    def power_down(self):
        self.power_multiply /= 2
 
    def make_a_move(self, friends, enemies):
        print(self.name, end=' ')
        target_of_power = friends[0]
        if not enemies:
            return
        min_health = target_of_power.get_hp()
        for friend in friends:
            if friend.get_hp() < min_health:
                target_of_power = friend
                min_health = target_of_power.get_hp()
 
        if min_health < 60:
            print('Усиливаю', target_of_power.name)
            self.power_up()
        else:
            print('Атакую -', enemies[0].name)
            self.attack(enemies[0])
        print('\n')
3
0 / 0 / 0
Регистрация: 04.05.2023
Сообщений: 1
04.05.2023, 20:17
llkl12g, Спасибо! Не мог бы оставшиеся файлы тоже скинуть, пожалуйста?
0
0 / 0 / 0
Регистрация: 29.10.2018
Сообщений: 1
17.11.2023, 22:31
Если вы читаете это и пришли скопировать готовое решение - то постарайтесь исправить в нём следующие ошибки:

№1

Цитата Сообщение от llkl12g Посмотреть сообщение
def take_damage(self, damage):
        super().take_damage(int(damage * 1.2))
метод take_damage должен выполнять 2 действия:
1) расчёт урона и изменение ХП текущего героя (вызов метода set_hp)
2) вызов родительского метода take_damage, чтобы проверить жив ли герой после получения урона или нет (super().take_damage)


№2

Каждый наследник должен в методе make_a_move вызывать родительский метод make_a_move через super()

№3

Герой Tank должен совершать только одно действие за ход

Либо поднять щит, либо опустить щит, либо атаковать


№4

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

Самый простой вариант:

если коэффициент усиления меньше 4 - то усиляемся, если нет, то выбираем цель и атакуем
старайтесь выбирать цель с наименьшим количеством здоровья, НО не равным 0 (нет смысла атаковать цель с 0 хп)
0
2 / 2 / 0
Регистрация: 26.11.2014
Сообщений: 12
22.12.2023, 06:11
Решил так.
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
import random
 
class Hero:
    # Базовый класс, который не подлежит изменению
    # У каждого наследника будут атрибуты:
    # - Имя
    # - Здоровье
    # - Сила
    # - Жив ли объект
    # Каждый наследник будет уметь:
    # - Атаковать
    # - Получать урон
    # - Выбирать действие для выполнения
    # - Описывать своё состояние
 
    max_hp = 150
    start_power = 10
 
    def __init__(self, name):
        self.name = name
        self.__hp = self.max_hp
        self.__power = self.start_power
        self.__is_alive = True
 
    def get_hp(self):
        return self.__hp
 
    def set_hp(self, new_value):
        self.__hp = max(new_value, 0)
 
    def get_power(self):
        return self.__power
 
    def set_power(self, new_power):
        self.__power = new_power
 
    def is_alive(self):  # жив или мёртв
        return self.__is_alive
 
    # Все наследники должны будут переопределять каждый метод базового класса (кроме геттеров/сеттеров)
    # Переопределенные методы должны вызывать методы базового класса (при помощи super).
    # Методы attack и __str__ базового класса можно не вызывать (т.к. в них нет кода).
    # Они нужны исключительно для наглядности.
    # Метод make_a_move базового класса могут вызывать только герои, не монстры.
    def attack(self, target):
        # Каждый наследник будет наносить урон согласно правилам своего класса
        pass
 
    def take_damage(self, damage):
        # Каждый наследник будет получать урон согласно правилам своего класса
        # При этом у всех наследников есть общая логика, которая определяет жив ли объект.
        print("\t", self.name, "Получил удар с силой равной = ",
              round(damage), ". Осталось здоровья - ",
              round(self.get_hp()))
        # Дополнительные принты помогут вам внимательнее следить за боем и изменять стратегию,
        # чтобы улучшить выживаемость героев
        if self.get_hp() <= 0:
            self.__is_alive = False
 
    def make_a_move(self, friends, enemies):
        # С каждым днём герои становятся всё сильнее.
        self.set_power(self.get_power() + 0.1)
 
    def __str__(self):
        return 'Name: {0} | HP: {1}'.format(self.name, self.get_hp())
 
 
class Healer(Hero):
    # Целитель:
    # Атрибуты:
    def __init__(self, name):
        super().__init__(name)
        # - магическая сила - равна значению НАЧАЛЬНОГО показателя силы умноженному на 3 (self.__power * 3)
        self.magic_power = self.get_power() * 3
 
    # Методы:
    # - атака - может атаковать врага, но атакует только в половину силы self.__power
    def attack(self, target):
        target.take_damage(self.get_power() / 2)
 
    # - получение урона - т.к. защита целителя слаба - он получает на 20% больше урона (1.2 * damage)
    def take_damage(self, damage):
        self.set_hp(self.get_hp() - (damage * 1.2))
        super().take_damage(damage)
 
    # - исцеление - увеличивает здоровье цели на величину равную своей магической силе
    def heal(self, target):
        target.set_hp(target.get_hp() + self.magic_power)
 
    # - выбор действия - получает на вход всех союзников и всех врагов и на основе своей стратегии
    # выполняет ОДНО из действий (атака, исцеление) на выбранную им цель
    def make_a_move(self, friends, enemies):
        print(self.name, end=' ')
        target_of_heal = friends[0]
        min_health = target_of_heal.get_hp()
        for friend in friends:
            if friend.get_hp() < min_health:
                target_of_heal = friend
                min_health = target_of_heal.get_hp()
 
        if min_health < 60:
            print("исцеляет", target_of_heal.name)
            self.heal(target_of_heal)
        else:
            if not enemies:
                return
            print("атакует -", enemies[0].name)
            self.attack(enemies[0])
        print('\n')
 
            # if enemies:
            #     print('атакует - {}'.format(enemies[0].name))
            #     self.attack(enemies[0])
            # else:
            #     print('Нет подходящей цели для атаки.')
        print('\n')
 
 
class Tank(Hero):
    # Танк:
    # Атрибуты:
    def __init__(self, name):
        super().__init__(name)
        # - показатель защиты - изначально равен 1, может увеличиваться и уменьшаться
        self.defense = 1
         # - поднят ли щит - танк может поднимать щит, этот атрибут должен показывать поднят ли щит в данный момент
        self.shield_up = False
    # Методы:
    # - атака - атакует, но т.к. доспехи очень тяжелые - наносит половину урона (self.__power)
    def attack(self, target):
        target.take_damage(self.get_power() / 2)
 
 
    # - получение урона - весь входящий урон делится на показатель защиты (damage/self.defense) и только потом отнимается от здоровья
    def take_damage(self, damage):
        self.set_hp(self.get_hp() - (damage / self.defense))
        super().take_damage(damage)
 
    # - поднять щит - если щит не поднят - поднимает щит. Это увеличивает показатель брони в 2 раза, но уменьшает показатель силы в 2 раза.
    def raise_shield(self):
        if not self.shield_up:
            self.shield_up = True
            self.defense *= 2
            self.set_power(self.get_power() / 2)
            print('{} поднимает щит!'.format(self.name))
 
    # - опустить щит - если щит поднят - опускает щит. Это уменьшает показатель брони в 2 раза, но увеличивает показатель силы в 2 раза.
    def lower_shield(self):
        if self.shield_up:
            self.shield_up = False
            self.defense /= 2
            self.set_power(self.get_power() * 2)
            print('{} опускает щит!'.format(self.name))
 
    # - выбор действия - получает на вход всех союзников и всех врагов и на основе своей стратегии выполняет ОДНО из действий (атака,
    # поднять щит/опустить щит) на выбранную им цель
 
        print('\n')
    def make_a_move(self, friends, enemies):
        print(self.name, end=' ')
        if not enemies:
            return
        if self.get_hp() > 70:
            if self.shield_up == False:
                print("атакует двуручным оружием -", enemies[0].name)
                self.attack(enemies[0])
            else:
                self.lower_shield()
                print('{} опускает щит!'.format(self.name))
 
        else:
            if self.shield_up == True:
                print('атакует из-за щита - {}'.format(enemies[0].name))
                self.attack(enemies[0])
            else:
                self.raise_shield()
                print('{} поднимает щит!'.format(self.name))
 
        print('\n')
class Attacker(Hero):
    # Убийца:
    # Атрибуты:
    def __init__(self, name):
        super().__init__(name)
        # - коэффициент усиления урона (входящего и исходящего)
        self.power_multiply = 1
 
    # Методы:
    # - атака - наносит урон равный показателю силы (self.__power) умноженному на коэффициент усиления урона (self.power_multiply)
    def attack(self, target):
        target.take_damage(self.get_power() * self.power_multiply)
        # после нанесения урона - вызывается метод ослабления power_down.
        self.power_down()
 
    # - получение урона - получает урон равный входящему урона умноженному на половину коэффициента усиления урона - damage * (
    # self.power_multiply / 2)
    def take_damage(self, damage):
        self.set_hp(self.get_hp() - (damage * (self.power_multiply / 2)))
        super().take_damage(damage)
 
    # - усиление (power_up) - увеличивает коэффициента усиления урона в 2 раза
    def power_up(self):
        self.power_multiply *= 2
 
    # - ослабление (power_down) - уменьшает коэффициента усиления урона в 2 раза
    def power_down(self):
        self.power_multiply /= 2
 
    # - выбор действия - получает на вход всех союзников и всех врагов и на основе своей стратегии выполняет ОДНО из действий (атака,
    # усиление, ослабление) на выбранную им цель
    def make_a_move(self, friends, enemies):
        print(self.name, end=' ')
 
        if self.power_multiply < 2:
            print('Усиливаемся!')
            self.power_up()
        else:
            target_of_attack = None
            min_health = float('inf')
 
            for enemy in enemies:
                if 0 < enemy.get_hp() < min_health:
                    target_of_attack = enemy
                    min_health = enemy.get_hp()
 
            if target_of_attack:
                print('атакует - {}.'.format(target_of_attack.name))
                self.attack(target_of_attack)
            else:
                print('Нет подходящей цели для атаки. Восстанавливает силы')
 
        super().make_a_move(friends, enemies)
        print('\n')
1
0 / 0 / 0
Регистрация: 14.02.2025
Сообщений: 1
14.02.2025, 23:51
Что не так с этим кодом?
Python
1
2
3
4
5
6
7
8
9
10
11
12
    def make_a_move(self, friends, enemies):
        print(self.name, end=', ')
        if self.power_multiply < 4:
            self.power_up()
            print(" Увеличиваю коэффициент усиления -", self.power_multiply)
        else:
            count_enemies = len(enemies) - 1
            print(count_enemies)
            target = enemies[count_enemies]
            print(" Атакую -", target.name)
            self.attack(target)
        super().make_a_move(self, friends)
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38162 / 21097 / 4306
Регистрация: 12.02.2012
Сообщений: 34,685
Записей в блоге: 14
15.02.2025, 13:40
Lyud, этот код имеет отношение к теме?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.02.2025, 13:40
Помогаю со студенческими работами здесь

Нужно найти старую игру про бегуна паркурщика
Помогите найти старую игру про бегуна паркурщика, описание: мини-игра, про бегуна паркурщика забирающегося в верх, маленький черный...

Проверьте игру(нужно исправить ошибки)
#include&lt;iostream&gt; #include&lt;windows.h&gt; using namespace std; int main () { int...

Нужно чтобы задания были отдельно как это исправить?
//Дана непустая последовательность слов из строчных русских букв //между соседними словами – запятая, за последним словом – точка. ...

При выполнении задания предусмотреть выбор вида функции (исправить код)
все вроде бы правильно... но когда делаю проверку ответы не сходятся... помогите пожалуйста найти ошибку в формулах При выполнении...

Нужно написать код задания на С++


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru