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

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

27.03.2023, 19:23. Показов 22665. Ответов 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
38203 / 21135 / 4310
Регистрация: 12.02.2012
Сообщений: 34,740
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru