С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
0 / 0 / 0
Регистрация: 16.10.2023
Сообщений: 12

Реализовать список по другому

23.10.2023, 17:41. Показов 963. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Задание: Постановка задачи: Создать набор классов согласно выбранному варианту задания. Реализовать процедуры ввода и отображения данных. Написать программу, в которой создаются объекты различных классов из иерархии и помещаются в список, после чего список просматривается. Использовать полиморфизм.

В качестве эксперимента сделать соответствующие методы (связанные наследованием) не виртуальными и посмотреть, как поведут себя экземпляры классов в этом случае.

ВНИМАНИЕ! Замечания по итогам некоторых вопросов:
1) нет смысла создавать экземпляры(объекты) класса-родителя, т.е. если у вас есть иерархия: просто машина и ее потомки - легковушка и грузовик - не надо делать отдельную просто машину, или если у вас есть насекомые и их разновидности - не надо создавать в программе просто насекомое.
2) в некоторых задачах стоит подумать о том, что является предком, а что потомком

Нельзя использовать библиотеку стл и массивы. Посоветуйте как это сделать


C++
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
#include <iostream>
#include <string>
#include <list>
//класс Hero, суперкласс для Warrior и Mage, содержит общие характеристики: имя, хп, армор, сила атаки
class Hero {
public:
    Hero(const std::string& name, int health, int armor, int attack_power)
        : name_(name), health_(health), armor_(armor), attack_power_(attack_power) {}
 
    // Получение свойств класса
    const std::string& GetName() const { return name_; }
    int GetHealth() const { return health_; }
    int GetArmor() const { return armor_; }
    int GetAttackPower() const { return attack_power_; }
 
    // Установка свойств класса
    void SetName(const std::string& name) { name_ = name; }
    void SetHealth(int health) { health_ = health; }
    void SetArmor(int armor) { armor_ = armor; }
    void SetAttackPower(int attack_power) { attack_power_ = attack_power; }
    
    
private:
    std::string name_;
    int health_;
    int armor_;
    int attack_power_;
};
 
//класс Воина
class Warrior : public Hero {
public:
    //наследование воина от Hero, добавление свойства weapon - название оружия
    Warrior(const std::string& name, int health, int armor, int attackDamage, const std::string& weapon)
        : Hero(name, health, armor, attackDamage), weapon_(weapon) {}
    //Получение названия и замена оружия
    const std::string& GetWeapon() const { return weapon_; }
    void SetWeapon(const std::string& weapon) { weapon_ = weapon; }
    //Полиморфный метод Info, печатающий информацию о персонаже
    void Info() {
        std::cout << "Имя: " << GetName() << std::endl
            << "Здоровье: " << GetHealth() << std::endl
            << "Броня: " << GetArmor() << std::endl
            << "Оружие: " << GetWeapon() << std::endl
            << "Сила атаки: " << GetAttackPower() << std::endl << std::endl;
    }
    //полиморфный метод strike, симулирующий удар воина. Пока у противника есть броня, урон проходит по ней. Если её нет - по хп
    void Strike(Hero& target) {
        int damage = GetAttackPower();
        int armor = target.GetArmor();
        if (armor > 0) {
            armor -= damage;
            if (armor < 0) {
                damage = -armor;
                armor = 0;
            }
            else {
                damage = 0;
            }
            target.SetArmor(armor);
        }
        if (damage > 0) {
            int health = target.GetHealth() - damage;
            if (health < 0) {
                health = 0;
            }
            target.SetHealth(health);
        }
        std::cout << GetName() << " атакует " << target.GetName()
            << " с помощью " << GetWeapon() << " (физический урон: " << GetAttackPower() << ") " << std::endl <<
            target.GetName() << " броня: " << target.GetArmor() << ", здоровье: " << target.GetHealth() << std::endl;
    }
    private:
        std::string weapon_;
 
};
//класс Воина
class Mage : public Hero {
public:
    //наследование мага от Hero, добавление свойства spell - название заклинания
    Mage(const std::string& name, int health, int armor, int attackDamage, const std::string& spell)
        : Hero(name, health, armor, attackDamage), spell_(spell) {}
    //Получение названия и замена заклинания
    const std::string& GetSpell() const { return spell_; }
    void SetSpell(const std::string& spell) { spell_ = spell; }
    //Полиморфный метод Info, печатающий информацию о персонаже
    void Info() {
        std::cout << "Имя: " << GetName() << std::endl
            << "Здоровье: " << GetHealth() << std::endl
            << "Броня: " << GetArmor() << std::endl
            << "Заклинание: " << GetSpell() << std::endl
            << "Сила атаки: " << GetAttackPower() << std::endl << std::endl;
    }
    //полиморфный метод strike, симулирующий удар мага. Пока у противника есть броня, урон проходит по ней. Если её нет - по хп
    void Strike(Hero& target) {
        int damage = GetAttackPower();
        int armor = target.GetArmor();
        if (armor > 0) {
            armor -= damage;
            if (armor < 0) {
                damage = -armor;
                armor = 0;
            }
            else {
                damage = 0;
            }
            target.SetArmor(armor);
        }
        if (damage > 0) {
            int health = target.GetHealth() - damage;
            if (health < 0) {
                health = 0;
            }
            target.SetHealth(health);
        }
 
        std::cout << GetName() << " атакует " << target.GetName()
            << " с помощью " << GetSpell() << " (магический урон: " << GetAttackPower() << ") " << std::endl <<
            target.GetName() << " броня: " << target.GetArmor() << ", здоровье: " << target.GetHealth() << std::endl;
    }
    private:
        std::string spell_;
 
};
int main() {
    setlocale(LC_ALL, "Russian");
    //создание по экземпляру воина и мага
    Warrior warrior("Довакин", 100, 50, 10, "Деревянный меч (легендарн.)");
    Mage mage("Ксардас", 100, 50, 50, "Огненный шторм");
    warrior.Info();
    mage.Info();
    std::cout << "Да начнётся битва" << std::endl;
    bool Turn = true;
    
    //симуляция дуэли до тех пор, пока у одного из персонажей хп не упадёт до 0
    while (true)
    {
        if (Turn)
        {
            warrior.Strike(mage);
        }
        else
        {
            mage.Strike(warrior);
        }
 
        if (warrior.GetHealth() <= 0)
        {
            std::cout << warrior.GetName() << " повержен!\n";
            break;
        }
        else if (mage.GetHealth() <= 0)
        {
            std::cout << mage.GetName() << " повержен\n";
            break;
        }
        Turn = !Turn;
    }
    
    Warrior warrior2("Старнник", 100, 50, 10, "Посох");
    Mage mage2("Саурон", 100, 50, 50, "Огненный шар");
    Warrior warrior3("Мастер Чиф", 100, 50, 10, "Плазменный меч");
    Mage mage3("Скарлет", 100, 50, 50, "Кровавый дождь");
    //список георев разных классов
    std::list<Hero> heroes;
    heroes.push_back(mage);
    heroes.push_back(warrior);
    heroes.push_back(mage2);
    heroes.push_back(warrior2);
    heroes.push_back(mage3);
    heroes.push_back(warrior3);
    //просмотр списка
    for (Hero i: heroes) {
        std::cout << "Имя: " << i.GetName() << std::endl;
    }
    return 0;
}
Добавлено через 18 минут
Речь идет про реализацию списка

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/список георев разных классов
    std::list<Hero> heroes;
    heroes.push_back(mage);
    heroes.push_back(warrior);
    heroes.push_back(mage2);
    heroes.push_back(warrior2);
    heroes.push_back(mage3);
    heroes.push_back(warrior3);
    //просмотр списка
    for (Hero i: heroes) {
        std::cout << "Имя: " << i.GetName() << std::endl;
    }
    return 0;
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.10.2023, 17:41
Ответы с готовыми решениями:

Реализовать передачу текстовых данных от одного ПК локалки к другому
Гайз, заранее извиняюсь, в сетях полный профан, все такое. В общем, необоходимо реализовать передачу текстовых данных от одного ПК...

Реализовать проверку в массиве по другому массиву
Нужно сделать проверку массива. Прокомментировал код, что и где. Заранее спасибо! using System; using System.Drawing; using...

Как реализовать обращение из одного ListBox1 к другому ListBox2?
Интересует такой вопрос, как реализовать обращение из одного ListBox1 к другому ListBox2, путем выбора одного из элементов ListBox1. Если...

11
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
24.10.2023, 02:48
Цитата Сообщение от Mariale Посмотреть сообщение
//полиморфный метод strike, симулирующий удар воина. Пока у противника есть броня, урон проходит по ней. Если её нет - по хп
    void Strike(Hero& target) {
А с чего вы взяли, что он полиморфный?

Цитата Сообщение от Mariale Посмотреть сообщение
std::list<Hero> heroes;
    heroes.push_back(mage);
Когда вы так делаете, полиморфизма нет. Должна быть ссылка или указатель.

Цитата Сообщение от Mariale Посмотреть сообщение
Речь идет про реализацию списка
Ну штош...

C++
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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
#include <iostream>
 
struct LinkedListNodeBase {
    LinkedListNodeBase() : next{this}, prev{this} {}
 
    LinkedListNodeBase(LinkedListNodeBase *before) : next{before}, prev{before->prev} {
        next->prev = prev->next = this;
    }
 
    virtual ~LinkedListNodeBase() {
        prev->next = next;
        next->prev = prev;
    }
 
    LinkedListNodeBase *next;
    LinkedListNodeBase *prev;
};
 
// структура, хранящая один элемент списка;
template<typename T>
struct LinkedListNode : public LinkedListNodeBase {
    T value;
 
    LinkedListNode(LinkedListNodeBase *before, const T &value) : LinkedListNodeBase{before}, value{value} {}
};
 
// простенький класс-обёртка для удобства работы с нодой двусвязного списка
// класс позволет удобно ходить по двусвязному списку,
// сравнивать позиции и получать значения ноды с помощью операторов
template<typename T>
struct LinkedListIterator {
    using iterator_category = std::bidirectional_iterator_tag;
    using difference_type = std::ptrdiff_t;
    using value_type = T;
    using pointer = value_type *;
    using reference = value_type &;
 
    LinkedListIterator(LinkedListNodeBase *node) : node{node} {}
 
    // получение значения в ноде
    reference operator*() const {
        return dynamic_cast<LinkedListNode<T> *>(node)->value;
    }
 
    // получение значения в ноде
    pointer operator->() {
        return &(dynamic_cast<LinkedListNode<T> *>(node)->value);
    }
 
    // переход на следующую ноду префиксный
    LinkedListIterator &operator++() {
        node = node->next;
        return *this;
    }
 
    // переход на следующую ноду постфиксный
    LinkedListIterator operator++(int) {
        LinkedListIterator tmp = *this;
        ++(*this);
        return tmp;
    }
 
    // переход на предыдущую ноду префиксный
    LinkedListIterator &operator--() {
        node = node->prev;
        return *this;
    }
 
    // переход на предыдущую ноду постфиксный
    LinkedListIterator operator--(int) {
        LinkedListIterator tmp = *this;
        --(*this);
        return tmp;
    }
 
    // сравнения нод
    friend bool operator==(const LinkedListIterator &a, const LinkedListIterator &b) {
        return a.node == b.node;
    };
 
    friend bool operator!=(const LinkedListIterator &a, const LinkedListIterator &b) {
        return a.node != b.node;
    };
 
    // увеличение на значение
    friend LinkedListIterator operator+(LinkedListIterator iterator, std::size_t n) {
        while (n--) {
            ++iterator;
        }
        return iterator;
    }
 
    // уменьшение на значение
    friend LinkedListIterator operator-(LinkedListIterator iterator, std::size_t n) {
        while (n--) {
            --iterator;
        }
        return iterator;
    }
 
    // нода двусвязного списка
    LinkedListNodeBase *node;
};
 
// такой же, но для константного контекста
template<typename T>
struct ConstLinkedListIterator {
    using iterator_category = std::bidirectional_iterator_tag;
    using difference_type = std::ptrdiff_t;
    using value_type = T;
    using pointer = value_type *;
    using reference = value_type &;
 
    ConstLinkedListIterator(const LinkedListNodeBase *node) : node{node} {}
 
    ConstLinkedListIterator(LinkedListIterator<T> other) : node{other.node} {}
 
    // получение значения в ноде
    reference operator*() const {
        return const_cast<LinkedListNode<T>*>(dynamic_cast<const LinkedListNode<T> *>(node))->value;
    }
 
    // получение значения в ноде
    pointer operator->() {
        return &(const_cast<LinkedListNode<T>*>(dynamic_cast<const LinkedListNode<T> *>(node))->value);
    }
 
    // переход на следующую ноду префиксный
    ConstLinkedListIterator &operator++() {
        node = node->next;
        return *this;
    }
 
    // переход на следующую ноду постфиксный
    ConstLinkedListIterator operator++(int) {
        LinkedListIterator tmp = *this;
        ++(*this);
        return tmp;
    }
 
    // переход на предыдущую ноду префиксный
    ConstLinkedListIterator &operator--() {
        node = node->prev;
        return *this;
    }
 
    // переход на предыдущую ноду постфиксный
    ConstLinkedListIterator operator--(int) {
        LinkedListIterator tmp = *this;
        --(*this);
        return tmp;
    }
 
    // сравнения нод
    friend bool operator==(const ConstLinkedListIterator &a, const ConstLinkedListIterator &b) {
        return a.node == b.node;
    };
 
    friend bool operator!=(const ConstLinkedListIterator &a, const ConstLinkedListIterator &b) {
        return a.node != b.node;
    };
 
    // увеличение на значение
    friend ConstLinkedListIterator operator+(ConstLinkedListIterator iterator, std::size_t n) {
        while (n--) {
            ++iterator;
        }
        return iterator;
    }
 
    // уменьшение на значение
    friend ConstLinkedListIterator operator-(ConstLinkedListIterator iterator, std::size_t n) {
        while (n--) {
            --iterator;
        }
        return iterator;
    }
 
    // нода двусвязного списка
    const LinkedListNodeBase *node;
};
 
// структура двусвязного списка
template<typename T>
struct LinkedList {
public:
    using ConstIterator = ConstLinkedListIterator<T>;
    using Iterator = LinkedListIterator<T>;
 
    LinkedList() : base{} {}
 
    LinkedList(const LinkedList<T> &other) : base{} {
        for (const auto &i : other) {
            pushBack(i);
        }
    }
 
    LinkedList(LinkedList<T> && other) noexcept : base{} {
        swap(*this, other);
    }
 
    LinkedList<T> &operator=(LinkedList<T> other) noexcept {
        swap(*this, other);
        return *this;
    }
 
    ~LinkedList() {
        clear();
    }
 
    friend void swap(LinkedList<T> &a, LinkedList<T> &b) noexcept {
        using std::swap;
        swap(a.base, b.base);
    }
 
    // добавление элемента в конец списка;
    Iterator pushBack(const T &value) {
        return insert(end(), value);
    }
 
    Iterator pushFront(const T &value) {
        return insert(begin(), value);
    }
 
    // добавление элемента в заданную позицию списка
    Iterator insert(ConstIterator position, const T &value) {
        return new LinkedListNode{const_cast<LinkedListNodeBase*>(position.node), value};
    }
 
    // удаление элемента списка по указанной позиции в списке
    Iterator erase(ConstIterator position) {
        LinkedListNodeBase *result = position.node->next;
        delete position.node;
        return result;
    }
 
    // получение элемента списка по указанной позиции в списке
    Iterator begin() {
        return base.next;
    }
 
    ConstIterator begin() const {
        return base.next;
    }
 
    Iterator end() {
        return &base;
    }
 
    ConstIterator end() const {
        return &base;
    }
 
    typename Iterator::difference_type getSize() const {
        return distance(begin(), end());
    }
 
    bool isEmpty() const {
        return base.next == &base;
    }
 
    void clear() {
        while (!isEmpty()) {
            delete base.next;
        }
    }
 
private:
    LinkedListNodeBase base;
};
 
class Hero {
public:
    // вот этот метод -- виртуальный
    virtual const std::string &GetName() const = 0;
    virtual ~Hero() = default;
};
 
class Warrior : public Hero {
public:
    Warrior(const std::string &name) : name(name) {}
 
    const std::string &GetName() const override {
        return name;
    }
 
private:
    std::string name;
};
 
class Mage : public Hero {
public:
    Mage(const std::string &name) : name(name) {}
 
    const std::string &GetName() const override {
        return name;
    }
 
private:
    std::string name;
};
 
int main() {
 
    // чтоб был полиморфизм в списке должны быть указатели
    LinkedList<Hero*> x;
 
    x.pushBack(new Warrior("ImaWarrior!"));
    x.pushBack(new Mage("ImaMage!"));
    x.pushBack(new Mage("ImAnotherMage!"));
 
    // вот теперь полиморфизм
    for (const auto &i : x) {
        std::cout << i->GetName() << '\n';
    }
 
    // и не забыть их освободить
    for (const auto &i : x) {
        delete i;
    }
 
    return 0;
}
1
0 / 0 / 0
Регистрация: 16.10.2023
Сообщений: 12
24.10.2023, 11:12  [ТС]
Спасибо. Попробовала сделать, код не запускается

C++
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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
#include <iostream>
#include <string>
#include <list>
 
// Класс Hero, суперкласс для Warrior и Mage, содержит общие характеристики: имя, хп, армор, сила атаки
class Hero {
public:
    Hero(const std::string& name, int health, int armor, int attack_power)
        : name_(name), health_(health), armor_(armor), attack_power_(attack_power) {}
 
    // Получение свойств класса
    const std::string& GetName() const { return name_; }
    int GetHealth() const { return health_; }
    int GetArmor() const { return armor_; }
    int GetAttackPower() const { return attack_power_; }
 
    // Установка свойств класса
    void SetName(const std::string& name) { name_ = name; }
    void SetHealth(int health) { health_ = health; }
    void SetArmor(int armor) { armor_ = armor; }
    void SetAttackPower(int attack_power) { attack_power_ = attack_power; }
 
private:
    std::string name_;
    int health_;
    int armor_;
    int attack_power_;
};
 
// Класс Воина
class Warrior : public Hero {
public:
    // Наследование воина от Hero, добавление свойства weapon - название оружия
    Warrior(const std::string& name, int health, int armor, int attackDamage, const std::string& weapon)
        : Hero(name, health, armor, attackDamage), weapon_(weapon) {}
 
    // Получение названия и замена оружия
    const std::string& GetWeapon() const { return weapon_; }
    void SetWeapon(const std::string& weapon) { weapon_ = weapon; }
 
    // Полиморфный метод Info, печатающий информацию о персонаже
    void Info() {
        std::cout << "Имя: " << GetName() << std::endl
            << "Здоровье: " << GetHealth() << std::endl
            << "Броня: " << GetArmor() << std::endl
            << "Оружие: " << GetWeapon() << std::endl
            << "Сила атаки: " << GetAttackPower() << std::endl << std::endl;
    }
 
    // Полиморфный метод strike, симулирующий удар воина. Пока у противника есть броня, урон проходит по ней. Если её нет - по хп
    void Strike(Hero& target) {
        int damage = GetAttackPower();
        int armor = target.GetArmor();
        if (armor > 0) {
            armor -= damage;
            if (armor < 0) {
                damage = -armor;
                armor = 0;
            }
            else {
                damage = 0;
            }
            target.SetArmor(armor);
        }
        if (damage > 0) {
            int health = target.GetHealth() - damage;
            if (health < 0) {
                health = 0;
            }
            target.SetHealth(health);
        }
 
        std::cout << GetName() << " атакует " << target.GetName()
            << " с помощью " << GetWeapon() << " (физический урон: " << GetAttackPower() << ") " << std::endl <<
            target.GetName() << " броня: " << target.GetArmor() << ", здоровье: " << target.GetHealth() << std::endl;
    }
 
private:
    std::string weapon_;
};
class Mage : public Hero {
public:
    // Наследование мага от Hero, добавление свойства spell - название заклинания
    Mage(const std::string& name, int health, int armor, int attackDamage, const std::string& spell)
        : Hero(name, health, armor, attackDamage), spell_(spell) {}
 
    // Получение названия и замена заклинания
    const std::string& GetSpell() const { return spell_; }
    void SetSpell(const std::string& spell) { spell_ = spell; }
 
    // Полиморфный метод Info, печатающий информацию о персонаже
    void Info() {
        std::cout << "Имя: " << GetName() << std::endl
            << "Здоровье: " << GetHealth() << std::endl
            << "Броня: " << GetArmor() << std::endl
            << "Заклинание: " << GetSpell() << std::endl
            << "Сила атаки: " << GetAttackPower() << std::endl << std::endl;
    }
 
    // Полиморфный метод strike, симулирующий удар мага. Пока у противника есть броня, урон проходит по ней. Если её нет - по хп
    void Strike(Hero& target) {
        int damage = GetAttackPower();
        int armor = target.GetArmor();
        if (armor > 0) {
            armor -= damage;
            if (armor < 0) {
                damage = -armor;
                armor = 0;
            }
            else {
                damage = 0;
            }
            target.SetArmor(armor);
        }
        if (damage > 0) {
            int health = target.GetHealth() - damage;
            if (health < 0) {
                health = 0;
            }
            target.SetHealth(health);
        }
 
        std::cout << GetName() << " атакует " << target.GetName()
            << " с помощью " << GetSpell() << " (магический урон: " << GetAttackPower() << ") " << std::endl <<
            target.GetName() << " броня: " << target.GetArmor() << ", здоровье: " << target.GetHealth() << std::endl;
    }
 
private:
    std::string spell_;
};
 
// Класс HeroList, представляющий двусвязный список героев
class HeroList {
public:
    HeroList() : head(nullptr), tail(nullptr) {}
 
    // Добавить героя в начало списка
    void PushFront(Hero* hero) {
        // Создать новый узел списка
        HeroNode* newNode = new HeroNode();
        newNode->hero = hero;
 
        // Если список пуст, то новый узел будет и первым, и последним
        if (head == nullptr) {
            head = newNode;
            tail = newNode;
        } else {
            // Иначе, новый узел будет первым, а предыдущий первый узел будет указывать на него
            newNode->next = head;
            head->prev = newNode;
            head = newNode;
        }
    }
 
    // Добавить героя в конец списка
    void PushBack(Hero* hero) {
        // Создать новый узел списка
        HeroNode* newNode = new HeroNode();
        newNode->hero = hero;
 
        // Если список пуст, то новый узел будет и первым, и последним
        if (tail == nullptr) {
            head = newNode;
            tail = newNode;
        } else {
            // Иначе, новый узел будет последним, а следующий последний узел будет указывать на него
            newNode->prev = tail;
            tail->next = newNode;
            tail = newNode;
        }
    }
 
    // Вставить героя после определенного героя
    void InsertAfter(Hero* hero, Hero* after) {
        // Если after == nullptr, то добавить героя в начало списка
        if (after == nullptr) {
            PushFront(hero);
            return;
        }
 
        // Найти узел, после которого нужно вставить новый узел
        HeroNode* current = head;
        while (current != nullptr && current->hero != after) {
            current = current->next;
        }
 
        // Если after не найден, то ничего не делать
        if ( if (after != nullptr) {
            return;
    }
            // Если after найден, то вставить новый узел после него
        if (current != nullptr) {
            // Создать новый узел списка
            HeroNode* newNode = new HeroNode();
            newNode->hero = hero;
 
            // Связать новый узел с предыдущим и последующим узлами
            newNode->prev = current;
            newNode->next = current->next;
            current->next->prev = newNode;
            current->next = newNode;
        }
    }
 
    // Удалить героя из списка
    void Remove(Hero* hero) {
        // Если список пуст, то ничего не делать
        if (head == nullptr) {
            return;
        }
 
        // Найти узел с указанным героем
        HeroNode* current = head;
        while (current != nullptr && current->hero != hero) {
            current = current->next;
        }
 
        // Если герой не найден, то ничего не делать
        if (current == nullptr) {
            return;
        }
 
        // Если удаляемый герой является первым или последним, то изменить ссылки на первый или последний элемент списка
        if (current == head) {
            head = current->next;
            if (head != nullptr) {
                head->prev = nullptr;
            }
        } else if (current == tail) {
            tail = current->prev;
            if (tail != nullptr) {
                tail->next = nullptr;
            }
        } else {
            // Если удаляемый герой находится в середине списка, то изменить ссылки на предыдущий и следующий узлы
            current->prev->next = current->next;
            current->next->prev = current->prev;
        }
 
        // Удалить узел из памяти
        delete current;
    }
 
    // Получить первый элемент списка
    Hero* GetHead() {
        return head->hero;
    }
 
    // Получить последний элемент списка
    Hero* GetTail() {
        return tail->hero;
    }
 
    // Получить количество элементов в списке
    int GetSize() {
        int size = 0;
        HeroNode* current = head;
        while (current != nullptr) {
            size++;
            current = current->next;
        }
        return size;
    }
 
private:
    // Структура узла списка
    struct HeroNode {
        Hero* hero;
        HeroNode* prev;
        HeroNode* next;
    };
 
    HeroNode* head;
    HeroNode* tail;
};
 
int main() {
    // Создать список героев
    HeroList list;
 
    // Добавить героев в список
    list.PushFront(new Warrior("Довакин", 100, 50, 10, "Деревянный меч (легендарн.)"));
    list.PushFront(new Mage("Ксардас", 100, 50, 50, "Огненный шторм"));
    list.PushBack(new Warrior("Старнник", 100, 50, 10, "Посох"));
    list.PushBack(new Mage("Саурон", 100, 50, 50, "Огненный шар"));
    list.PushBack(new Warrior("Мастер Чиф", 100, 50, 10, "Плазменный меч"));
    list.PushBack(new Mage("Скарлет", 100, 50, 50, "Кровавый дождь"));
 
    // Просмотреть список
    for (Hero* hero : list) {
        std::cout << "Имя: " << hero->GetName() << std::endl;
    }
 
    // Удалить героя из списка
    list.Remove(new Warrior("Мастер Чиф"));
 
    // Просмотреть список после удаления
    for (Hero* hero : list) {
        std::cout << "Имя: " << hero->GetName() << std::endl;
    }
 
    return 0;
}
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
24.10.2023, 11:51
Цитата Сообщение от Mariale Посмотреть сообщение
class HeroList {
public:
    HeroList() : head(nullptr), tail(nullptr) {}
Класс не освобождает занятую им память.
Нет деструктора и прочих методов по "правилу пяти".
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
24.10.2023, 13:06
Цитата Сообщение от Mariale Посмотреть сообщение
if ( if (after != nullptr) {
            return;
    }
Синтаксическая ошибка.
Весь метод как-то очень странно написан, как будто компиляция двух разных кодов.

Цитата Сообщение от Mariale Посмотреть сообщение
// Просмотреть список
    for (Hero* hero : list) {
Это сработает только в довольно специфичном случае -- если у list есть методы begin и end и они возвращают итераторы.

В этом коде связного списка нет вообще способа просмотреть содержимое этого списка. Только начало и конец. В моём примере используется подход "итераторов" -- специальных объектов, оборачивающих узел двусвязного списка и позволяющих ходить по нему вперёд-назад.

Вам надо придумать такой способ. )

Добавлено через 3 минуты
Цитата Сообщение от Mariale Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Класс Hero, суперкласс для Warrior и Mage, содержит общие характеристики: имя, хп, армор, сила атаки
class Hero {
public:
    Hero(const std::string& name, int health, int armor, int attack_power)
        : name_(name), health_(health), armor_(armor), attack_power_(attack_power) {}
// Получение свойств класса
    const std::string& GetName() const { return name_; }
    int GetHealth() const { return health_; }
    int GetArmor() const { return armor_; }
    int GetAttackPower() const { return attack_power_; }
// Установка свойств класса
    void SetName(const std::string& name) { name_ = name; }
    void SetHealth(int health) { health_ = health; }
    void SetArmor(int armor) { armor_ = armor; }
    void SetAttackPower(int attack_power) { attack_power_ = attack_power; }
private:
    std::string name_;
    int health_;
    int armor_;
    int attack_power_;
};
В вашем базовом классе нет ни одного виртуального метода.
Соотвественно, никакого праздника полиморфизма.
Скорее всего вы захотите пометить методы, которые будут расширяться потомками, как virtual.

Добавлено через 7 минут
Цитата Сообщение от Mariale Посмотреть сообщение
class HeroList {
public:
    HeroList() : head(nullptr), tail(nullptr) {}
Класс не освобождает занятую им память.
Нет деструктора и прочих методов по "правилу пяти".

Добавлено через 1 час 4 минуты
Можно как-то так попробовать сделать:
C++
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
#include <iostream>
#include <string>
 
// Класс Hero, суперкласс для Warrior и Mage, содержит общие характеристики: имя, хп, армор, сила атаки
class Hero {
public:
    Hero(const std::string &name) : name(name) {}
 
    virtual const std::string &getName() const {
        return name;
    }
 
    virtual std::ostream &operator<<(std::ostream &os) const = 0;
 
    virtual ~Hero() = default;
 
 
private:
    std::string name;
};
 
class Fighter : public Hero {
public:
    Fighter(const std::string &name, int strength) : Hero(name), strength(strength) {}
 
    virtual int getStrength() const {
        return strength;
    };
 
private:
    int strength;
};
 
class Caster : public Hero {
public:
    Caster(const std::string &name, int intelligence) : Hero(name), intelligence(intelligence) {}
 
    virtual int getIntelligence() const {
        return intelligence;
    }
 
private:
    int intelligence;
};
 
class Warrior : public Fighter {
public:
    Warrior(const std::string &name, int strength, const std::string &weapon)
        : Fighter(name, strength), weapon(weapon) {}
 
    virtual const std::string &getWeapon() const {
        return weapon;
    }
 
    std::ostream &operator<<(std::ostream &out) const override {
        return out << "Warrior{"
                << "name='" << getName() << "',"
                << "weapon='" << getWeapon() << "',"
                << "strength=" << getStrength()
                << "}";
    }
 
private:
    std::string weapon;
};
 
class Wizard : public Caster {
public:
    Wizard(const std::string &name, int intelligence, const std::string &spell)
        : Caster(name, intelligence), spell(spell) {}
 
    virtual const std::string &getSpell() const {
        return spell;
    }
 
    std::ostream &operator<<(std::ostream &out) const override {
        return out << "Wizard{"
                   << "name='" << getName() << "',"
                   << "spell='" << getSpell() << "',"
                   << "strength=" << getIntelligence()
                   << "}";
    }
 
private:
    std::string spell;
};
 
std::ostream &operator<<(std::ostream &out, const Hero &hero) {
    hero << out;
    return out;
}
 
// добавим сущность "базового" узла двусвязного списка
// который будет самовставляться
struct Node {
    // в базовом конструкторе нода ссылается на саму себя
    Node() : prev(this), next(this) {}
    // в этом конструкторе нода сама вставляется после указанной ноды
    Node(Node *after) : prev(after), next(after->next) {
        prev->next = next->prev = this;
    }
    // при вызове деструктора такая нода самоудаляется из двусвязного списка
    virtual ~Node() {
        prev->next = next;
        next->prev = prev;
    }
    Node *prev;
    Node *next;
};
 
// Структура узла списка
struct HeroNode : public Node {
    HeroNode(Node *after, Hero *hero) : Node(after), hero(hero) {}
    Hero* hero;
};
 
// Класс HeroList, представляющий двусвязный список героев
class HeroList {
public:
    HeroList() : base() {}
 
    // в деструкторе удаляются все ноды
    ~HeroList() {
        clear();
    }
 
    // следующие пять штук надо по "правилу пяти"
    // для простоты оставил пустыми
    HeroList(const HeroList &) = delete;
    HeroList(HeroList &&) noexcept = delete;
    HeroList &operator=(const HeroList &) = delete;
    HeroList &operator=(HeroList &&) noexcept = delete;
 
    // Добавить героя в начало списка
    void PushFront(Hero* hero) {
        // Создать новый узел списка
        new HeroNode(&base, hero);
    }
 
    // Добавить героя в конец списка
    void PushBack(Hero* hero) {
        // Создать новый узел списка
        new HeroNode(base.prev, hero);
    }
 
    // Вставить героя после определенного героя
    void InsertAfter(Hero* hero, Node* after) {
        new HeroNode(after, hero);
    }
 
    // Удалить героя из списка
    void Remove(Node* position) {
        delete position;
    }
 
    // метод, удаляющий все ноды из списка
    void clear() {
        while (base.next != &base) {
            delete base.next;
        }
    }
 
    Node *begin() {
        return base.next;
    }
 
    Node *end() {
        return &base;
    }
 
private:
    // базовая нода двусвязного списка
    Node base;
};
 
int main() {
    // Создать список героев
    HeroList list;
 
    // Добавить героев в список
    list.PushFront(new Warrior("Довакин", 100, "Деревянный меч (легендарн.)"));
    list.PushFront(new Wizard("Ксардас", 100, "Огненный шторм"));
    list.PushBack(new Warrior("Старнник", 100, "Посох"));
    list.PushBack(new Wizard("Саурон", 100, "Огненный шар"));
    list.PushBack(new Warrior("Мастер Чиф", 100, "Плазменный меч"));
    list.PushBack(new Wizard("Скарлет", 100,"Кровавый дождь"));
 
    // Просмотреть список
    for (Node *i = list.begin(); i != list.end(); i = i->next) {
        std::cout << "Герой: "
            << *dynamic_cast<HeroNode*>(i)->hero
            << std::endl;
    }
 
    // Удалить первого героя из списка
    // сначала освободить память, выделенную ранее под героя
    delete dynamic_cast<HeroNode*>(list.begin())->hero;
    // теперь удалить указатель из списка
    list.Remove(list.begin());
 
    // Просмотреть список после удаления
    for (Node *i = list.begin(); i != list.end(); i = i->next) {
        std::cout << "Герой: "
            << *dynamic_cast<HeroNode*>(i)->hero
            << std::endl;
    }
 
    // освободить выделенную под героев память
    for (Node *i = list.begin(); i != list.end(); i = i->next) {
        delete dynamic_cast<HeroNode*>(i)->hero;
    }
 
    return 0;
}
0
0 / 0 / 0
Регистрация: 24.10.2023
Сообщений: 13
25.10.2023, 00:43
Спасибо большое, а можете пож.луйста показать как реализовать в данном вашем коде дуэль между двумя персонажами? Вывод должен быть такой примерно

Code
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
Имя: Довакин
Здоровье: 100
Броня: 50
Оружие: Деревянный меч (легендарн.)
Сила атаки: 10
 
Имя: Ксардас
Здоровье: 100
Броня: 50
Заклинание: Огненный шторм
Сила атаки: 50
 
Да начнётся битва
Довакин атакует Ксардас с помощью Деревянный меч (легендарн.) (физический урон: 10) 
Ксардас броня: 40, здоровье: 100
Ксардас атакует Довакин с помощью Огненный шторм (магический урон: 50) 
Довакин броня: 0, здоровье: 100
Довакин атакует Ксардас с помощью Деревянный меч (легендарн.) (физический урон: 10) 
Ксардас броня: 30, здоровье: 100
Ксардас атакует Довакин с помощью Огненный шторм (магический урон: 50) 
Довакин броня: 0, здоровье: 50
Довакин атакует Ксардас с помощью Деревянный меч (легендарн.) (физический урон: 10) 
Ксардас броня: 20, здоровье: 100
Ксардас атакует Довакин с помощью Огненный шторм (магический урон: 50) 
Довакин броня: 0, здоровье: 0
Довакин повержен!
Герой: Wizard{name='Ксардас',spell='Огненный шторм',strength=100}
Герой: Warrior{name='Довакин',weapon='Деревянный меч (легендарн.)',strength=100}
Герой: Warrior{name='Старнник',weapon='Посох',strength=100}
Герой: Wizard{name='Саурон',spell='Огненный шар',strength=100}
Герой: Warrior{name='Мастер Чиф',weapon='Плазменный меч',strength=100}
Герой: Wizard{name='Скарлет',spell='Кровавый дождь',strength=100}
Герой: Warrior{name='Довакин',weapon='Деревянный меч (легендарн.)',strength=100}
Герой: Warrior{name='Старнник',weapon='Посох',strength=100}
Герой: Wizard{name='Саурон',spell='Огненный шар',strength=100}
Герой: Warrior{name='Мастер Чиф',weapon='Плазменный меч',strength=100}
Герой: Wizard{name='Скарлет',spell='Кровавый дождь',strength=10
Добавлено через 43 минуты
C++
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
#include <iostream>
#include <string>
 
// Базовый класс героя
class Hero {
public:
    Hero(const std::string& name, int health, const std::string& weapon)
        : name(name), health(health), armor(50), weapon(weapon) {}
 
    virtual ~Hero() {}
 
    virtual int attack() = 0;
    virtual void defend(int damage) = 0;
 
    const std::string& getName
() const {
        return name;
    }
 
    int getHealth() const {
        return health;
    }
 
    int getArmor() const {
        return armor;
    }
 
    const std::string& getWeapon() const {
        return weapon;
    }
 
protected:
    std::string name;
    int health;
    int armor;
    std::string weapon;
};
// Класс воина, наследуется от класса героя
class Warrior : public Hero {
public:
    Warrior(const std::string& name, int health, const std::string& weapon)
        : Hero(name, health, weapon) {}
 
    int attack() override {
        return 10;
    }
    void defend(int damage) override {
        int actualDamage = damage - armor;
        if (actualDamage > 0) {
            health -= actualDamage;
        }
    }
};
// Класс мага, наследуется от класса героя
class Wizard : public Hero {
public:
    Wizard(const std::string& name, int health, const std::string& spell)
        : Hero(name, health, spell) {}
 
    int attack() override {
        return 50;
    }
 
    void defend(int damage) override {
        int actualDamage = damage - armor;
        if (actualDamage > 0) {
            health -= actualDamage;
        }
    }
};
// Узел списка героев
struct Node {
    Node* next;
    Node* prev;
};
// Узел списка героев, содержит указатель на объект героя
struct HeroNode : public Node {
    Hero* hero;
};
 
// Список героев
class HeroList {
public:
    HeroList() : head(nullptr), tail(nullptr) {}
 
    ~HeroList() {
        Node* current = head;
        while (current != nullptr) {
            Node* next = current->next;
            delete current;
            current = next;
        }
    }
 
    void PushFront(Hero* hero) {
        HeroNode* heroNode = new HeroNode;
        heroNode->hero = hero;
        heroNode->prev = nullptr;
        heroNode->next = head;
 
        if (head != nullptr) {
            head->prev = heroNode;
        } else {
            tail = heroNode;
        }
 
        head = heroNode;
    }
 
    void PushBack(Hero* hero) {
        HeroNode* heroNode = new HeroNode;
        heroNode->hero = hero;
        heroNode->prev = tail;
        heroNode->next = nullptr;
 
        if (tail != nullptr) {
            tail->next = heroNode;
        } else {
            head = heroNode;
        }
 
        tail = heroNode;
    }
 
    Node* begin() const {
        return head;
    }
 
    Node* end() const {
        return nullptr;
    }
 
private:
    Node* head;
    Node* tail;
};
 
// Добавим функцию для проведения дуэли
void duel(Hero* hero1, Hero* hero2) {
    std::cout << "Да начнётся битва" << std::endl;
 
    while (hero1->getHealth() > 0 && hero2->getHealth() > 0) {
        // Герой 1 атакует героя 2
        int damage1 = hero1->attack();
        hero2->defend(damage1);
        std::cout << hero1->getName() << " атакует " << hero2->getName() << " с помощью " << hero1->getWeapon() << " (физический урон: " << damage1 << ")" << std::endl;
        std::cout << hero2->getName() << " броня: " << hero2->getArmor() << ", здоровье: " << hero2->getHealth() << std::endl;
 
        if (hero2->getHealth() <= 0) {
            std::cout << hero2->getName() << " повержен!" << std::endl;
            break;
        }
        // Герой 2 атакует героя 1
        int damage2 = hero2->attack();
        hero1->defend(damage2);
        std::cout << hero2->getName() << " атакует " << hero1->getName() << " с помощью " << hero2->getWeapon() << " (физический урон: " << damage2 << ")" << std::endl;
        std::cout << hero1->getName() << " броня: " << hero1->getArmor() << ", здоровье: " << hero1->getHealth() << std::endl;
 
        if (hero1->getHealth() <= 0) {
            std::cout << hero1->getName() << " повержен!" << std::endl;
            break;
        }
    }
}
int main() {
    // Создать список героев
    HeroList list;
 
    // Добавить героев в список
    list.PushFront(new Warrior("Довакин", 100, "Деревянный меч (легендарн.)"));
    list.PushFront(new Wizard("Ксардас", 100, "Огненный шторм"));
    list.PushBack(new Warrior("Старнник", 100, "Посох"));
    list.PushBack(new Wizard("Саурон", 100, "Огненный шар"));
    list.PushBack(new Warrior("Мастер Чиф", 100, "Плазменный меч"));
    list.PushBack(new Wizard("Скарлет", 100, "Кровавый дождь"));
 
    // Просмотреть список
    for (Node* i = list.begin(); i != list.end(); i = i->next) {
        std::cout << "Герой: " << *dynamic_cast<HeroNode*>(i)->hero << std::endl;
    }
 
    // Начать дуэль между первыми двумя героями
    Hero* hero1 = dynamic_cast<HeroNode*>(list.begin())->hero;
    Hero* hero2 = dynamic_cast<HeroNode*>(list.begin()->next)->hero;
    duel(hero1, hero2);
 
    // Освободить выделенную под героев память
    for (Node* i = list.begin(); i != list.end(); i = i->next) {
        delete dynamic_cast<HeroNode*>(i)->hero;
    }
 
    return 0;
}
Добавлено через 2 часа 6 минут
полностью задание вот такое
Изучи условие задания Постановка задачи: Создать набор классов согласно выбранному варианту задания. Реализовать процедуры ввода и отображения данных. Написать программу, в которой создаются объекты различных классов из иерархии и помещаются в список, после чего список просматривается. Использовать полиморфизм. Создайте иерархию классов, имитирующих поведение двух игровых персонажей разных игровых классов/рас/профессий (например, «воин» и «маг»). Каждый персонаж должен обладать набором некоторых характеристик (например, «очки здоровья», «сила атаки», «коэффициент брони», модификатор спас-бросков по ловкости, интеллекту и т.п.). Подключите разработанные классы к основной программе и реализуйте «дуэль» между этими персонажами.
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
25.10.2023, 00:54
Цитата Сообщение от Nikhamile421 Посмотреть сообщение
Создайте иерархию классов, имитирующих поведение двух игровых персонажей разных игровых классов/рас/профессий (например, «воин» и «маг»). Каждый персонаж должен обладать набором некоторых характеристик (например, «очки здоровья», «сила атаки», «коэффициент брони», модификатор спас-бросков по ловкости, интеллекту и т.п.).
Честно скажу -- не интересно мне такое задание. =)
Да и к тому, что вы выше выложили оно не имеет отношения -- я отвечал на "двусвязный список". )

Добавлено через 3 минуты
Если у меня будет время и желание -- возможно займусь завтра. Не ждите.
0
0 / 0 / 0
Регистрация: 24.10.2023
Сообщений: 13
25.10.2023, 04:43
Скажите пожалуйста я примерно хотя бы правильно пишу спасибо я всунула сюда дуэль а реализацию списка взяла вашу

C++
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
#include <iostream>
#include <string>
 
// Класс Hero, суперкласс для Warrior и Mage, содержит общие характеристики: имя, хп, армор, сила атаки
class Hero {
public:
    Hero(const std::string& name) : name(name) {}
 
    virtual const std::string& getName() const {
        return name;
    }
 
    virtual std::ostream& operator<<(std::ostream& os) const = 0;
 
    virtual ~Hero() = default;
 
private:
    std::string name;
};
 
class Fighter : public Hero {
public:
    Fighter(const std::string& name, int strength) : Hero(name), strength(strength) {}
 
    virtual int getStrength() const {
        return strength;
    };
 
private:
    int strength;
};
 
class Caster : public Hero {
public:
    Caster(const std::string& name, int intelligence) : Hero(name), intelligence(intelligence) {}
 
    virtual int getIntelligence() const {
        return intelligence;
    }
 
private:
    int intelligence;
};
 
class Warrior : public Fighter {
public:
    Warrior(const std::string& name, int strength, const std::string& weapon)
        : Fighter(name, strength), weapon(weapon) {}
 
    virtual const std::string& getWeapon() const {
        return weapon;
    }
 
    std::ostream& operator<<(std::ostream& out) const override {
        return out << "Warrior{"
                   << "name='" << getName() << "',"
                   << "weapon='" << getWeapon() << "',"
                   << "strength=" << getStrength()
                   << "}";
    }
 
private:
    std::string weapon;
};
 
class Wizard : public Caster {
public:
    Wizard(const std::string& name, int intelligence, const std::string& spell)
        : Caster(name, intelligence), spell(spell) {}
 
    virtual const std::string& getSpell() const {
        return spell;
    }
 
    std::ostream& operator<<(std::ostream& out) const override {
        return out << "Wizard{"
                   << "name='" << getName() << "',"
                   << "spell='" << getSpell() << "',"
                   << "intelligence=" << getIntelligence()
                   << "}";
    }
 
private:
    std::string spell;
};
 
std::ostream& operator<<(std::ostream& out, const Hero& hero) {
    hero << out;
    return out;
}
 
// добавим сущность "базового" узла двусвязного списка
// который будет самовставляться
struct Node {
    // в базовом конструкторе нода ссылается на саму себя
    Node() : prev(this), next(this) {}
    // в этом конструкторе нода сама вставляется после указанной ноды
    Node(Node* after) : prev(after), next(after->next) {
        prev->next = next->prev = this;
    }
    // при вызове деструктора такая нода самоудаляется из двусвязного списка
    virtual ~Node() {
        prev->next = next;
        next->prev = prev;
    }
    Node* prev;
    Node* next;
};
 
// Структура узла списка
struct HeroNode : public Node {
    HeroNode(Node* after, Hero* hero) : Node(after), hero(hero) {}
    Hero* hero;
};
 
// Класс HeroList, представляющий двусвязный список героев
class HeroList {
public:
    HeroList() : base() {}
 
    // в деструкторе удаляются все ноды
    ~HeroList() {
        clear();
    }
 
    // следующие пять штук надо по "правилу пяти"
    // для простоты оставил пустыми
    HeroList(const HeroList&) = delete;
    HeroList(HeroList&&) noexcept = delete;
    HeroList& operator=(const HeroList&) = delete;
    HeroList& operator=(HeroList&&) noexcept = delete;
 
    // Добавить героя в начало списка
    void PushFront(Hero* hero) {
        // Создать новый узел списка
        new HeroNode(&base, hero);
    }
 
    // Добавить героя в конец списка
    void PushBack(Hero* hero) {
        // Создать новый узел списка
        new HeroNode(base.prev, hero);
    }
 
    // Вставить героя после определенного героя
    void InsertAfter(Hero* hero, Node* a
 
fter) {
        new HeroNode(after, hero);
    }
 
    // Удалить героя из списка
    void Remove(Node* position) {
        delete position;
    }
 
    // метод, удаляющий все ноды из списка
    void clear() {
        while (base.next != &base) {
            delete base.next;
        }
    }
 
    Node* begin() {
        return base.next;
    }
 
    Node* end() {
        return &base;
    }
 
    void Duel(Hero* h1, Hero* h2) {
        std::cout << "Дуэль между " << h1->getName() << " и " << h2->getName() << " начинается!" << std::endl;
 
        // Логика для проведения дуэли между персонажами
        // Например, вы можете сравнивать их характеристики и выводить результаты
 
        if (h1->getStrength() > h2->getIntelligence()) {
            std::cout << h1->getName() << " побеждает " << h2->getName() << "!" << std::endl;
        } else if (h1->getStrength() < h2->getIntelligence()) {
            std::cout << h2->getName() << " побеждает " << h1->getName() << "!" << std::endl;
        } else {
            std::cout << "Ничья!" << std::endl;
        }
    }
 
private:
    // базовая нода двусвязного списка
    Node base;
};
 
int main() {
    // Создать список героев
    HeroList list;
 
    // Добавить героев в список
    list.PushFront(new Warrior("Довакин", 100, "Деревянный меч (легендарн.)"));
    list.PushFront(new Wizard("Ксардас", 100, "Огненный шторм"));
    list.PushBack(new Warrior("Старнник", 100, "Посох"));
    list.PushBack(new Wizard("Саурон", 100, "Огненный шар"));
    list.PushBack(new Warrior("Мастер Чиф", 100, "Плазменный меч"));
    list.PushBack(new Wizard("Скарлет", 100, "Кровавый дождь"));
 
    // Просмотреть список и вывод характеристик героев
    for (Node* i = list.begin(); i != list.end(); i = i->next) {
        std::cout << "Герой: " << *dynamic_cast<HeroNode*>(i)->hero << std::endl;
    }
 
    // Выбрать персонажей для дуэли
    Hero* hero1 = dynamic_cast<HeroNode*>(list.begin())->hero;
    Hero* hero2 = dynamic_cast<HeroNode*>(list.begin()->next)->hero;
 
    // Проведение дуэли
    list.Duel(hero1, hero2);
 
    // Освобождение памяти, выделенной под героев
    list.clear();
 
    return 0;
}
Добавлено через 25 минут
скажите пожалуйста в вашем коде присутствует библиотека стл?

Добавлено через 3 часа 7 минут
У меня получилось реализовать код с двухсвязным списком. Посмотрите примерно так пойдет к условиям задания?

C++
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
#include <iostream>
#include <string>
 
class Hero {
 public:
  Hero(const std::string& name, int health, int armor, int attack_power)
      : name_(name), health_(health), armor_(armor), attack_power_(attack_power) {}
 
  const std::string& GetName() const { return name_; }
  int GetHealth() const { return health_; }
  int GetArmor() const { return armor_; }
  int GetAttackPower() const { return attack_power_; }
 
  void SetName(const std::string& name) { name_ = name; }
  void SetHealth(int health) { health_ = health; }
  void SetArmor(int armor) { armor_ = armor; }
  void SetAttackPower(int attack_power) { attack_power_ = attack_power; }
 
  virtual void Strike(Hero& target) {
    std::cout << "Метод Strike должен быть переопределен в классах-наследниках" << std::endl;
  }
 
  virtual ~Hero() {}
 
  friend std::ostream& operator<<(std::ostream& out, const Hero& hero) {
    out << "Имя: " << hero.GetName() << std::endl
        << "Здоровье: " << hero.GetHealth() << std::endl
        << "Броня: " << hero.GetArmor() << std::endl
        << "Сила атаки: " << hero.GetAttackPower() << std::endl;
    return out;
  }
 
 private:
  std::string name_;
  int health_;
  int armor_;
  int attack_power_;
};
 
class Warrior : public Hero {
 public:
  Warrior(const std::string& name, int health, int armor, int attack_power,
           const std::string& weapon)
      : Hero(name, health, armor, attack_power), weapon_(weapon) {}
 
  const std::string& GetWeapon() const { return weapon_; }
  void SetWeapon(const std::string& weapon) { weapon_ = weapon; }
 
  void Strike(Hero& target) override {
    int damage = GetAttackPower();
    int armor = target.GetArmor();
    if (armor > 0) {
      armor -= damage;
      if (armor < 0) {
        damage = -armor;
        armor = 0;
      } else {
        damage = 0;
      }
      target.SetArmor(armor);
    }
    if (damage > 0) {
      int health = target.GetHealth() - damage;
      if (health < 0) {
        health = 0;
      }
      target.SetHealth(health);
    }
    std::cout << GetName() << " атакует " << target.GetName()
              << " с помощью " << GetWeapon() << " (физический урон: " << GetAttackPower() << ") " << std::endl
              << target.GetName() << " броня: " << target.GetArmor() << ", здоровье: " << target.GetHealth() << std::endl;
  }
 
 private:
  std::string weapon_;
};
 
class Mage : public Hero {
 public:
  Mage(const std::string& name, int health, int armor, int attack_power,
         const std::string& spell)
      : Hero(name, health, armor, attack_power), spell_(spell) {}
 
  const std::string& GetSpell() const { return spell_; }
  void SetSpell(const std::string& spell) { spell_ = spell; }
 
  void Strike(Hero& target) override {
    int damage = GetAttackPower();
    int armor = target.GetArmor();
    if (armor > 0) {
      armor -= damage;
      if (armor < 0) {
        damage = -armor;
        armor = 0;
      } else {
        damage = 0;
      }
      target.SetArmor(armor);
    }
    if (damage > 0) {
      int health = target.GetHealth() - damage;
      if (health < 0) {
        health = 0;
      }
      target.SetHealth(health);
    }
    std::cout << GetName() << " атакует " << target.GetName()
              << " с помощью " << GetSpell() << " (магический урон: " << GetAttackPower() << ") " << std::endl
              << target.GetName() << " броня: " << target.GetArmor() << ", здоровье: " << target.GetHealth() << std::endl;
  }
 
 private:
  std::string spell_;
};
 
class LinkedList {
 private:
  struct Node {
    Hero* data;
    Node* prev;
    Node* next;
 
    Node(Hero* hero, Node* previous = nullptr, Node* nextNode = nullptr)
        : data(hero), prev(previous), next(nextNode) {}
  };
 
 public:
  LinkedList() : head(nullptr), tail(nullptr) {}
 
  ~LinkedList() {
    Node* current = head;
    while (current != nullptr) {
      Node* next = current->next;
      delete current->data;
      delete current;
      current = next;
    }
  }
 
  void PushBack(Hero* hero) {
    Node* newNode = new Node(hero, tail);
    if (tail != nullptr) {
      tail->next = newNode;
    } else {
      head = newNode;
    }
    tail = newNode;
  }
 
  void PopFront() {
    if (head != nullptr) {
      Node* next = head->next;
      delete head->data;
      delete head;
      head = next;
      if (next != nullptr) {
        next->prev = nullptr;
      } else {
        tail = nullptr;
      }
    }
  }
 
  void PrintList() const {
    Node* current = head;
    while (current != nullptr) {
      std::cout << *current->data << std::endl;
      current = current->next;
    }
  }
 
 private:
  Node* head;
  Node* tail;
};
 
int main() {
  Warrior warrior("Довакин", 100, 50, 10, "Деревянный меч (легендарный)");
  Mage mage("Ксардас", 100, 50, 50, "Огненный шторм");
 
  LinkedList heroes;
  heroes.PushBack(&warrior);
  heroes.PushBack(&mage);
 
  std::cout << "Да начнётся битва" << std::endl;
 
  while (warrior.GetHealth() > 0 && mage.GetHealth() > 0) {
    warrior.Strike(mage);
    if (mage.GetHealth() <= 0) {
      std::cout << "Ксардас повержен!" << std::endl;
      break;
    }
    mage.Strike(warrior);
    if (warrior.GetHealth() <= 0) {
        std::cout << "Довакин повержен!" << std::endl;
      break;
    }
  }
 
  std::cout << "Герой: Маг" << std::endl << mage << std::endl;
 
  return 0;
}
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
25.10.2023, 13:44
Цитата Сообщение от Nikhamile421 Посмотреть сообщение
скажите пожалуйста в вашем коде присутствует библиотека стл?
Класс string -- это спецификация типа basic_string, который по всем признакам является шаблонным контейнером (последовательностью символов), и, соотвественно, входит в stl. А . Так что да. И в вашем и в моём коде присутствует STL.

Цитата Сообщение от Nikhamile421 Посмотреть сообщение
Посмотрите примерно так пойдет к условиям задания?
Смотрю.
Цитата Сообщение от Nikhamile421 Посмотреть сообщение
после чего список просматривается
Список не просматривается в коде. У кода связного списка нет способа пройтись по содержимому.

Код связного списка не следует "правилу пяти".

Добавлено через 1 минуту
Цитата Сообщение от Nikhamile421 Посмотреть сообщение
C++
1
2
Hero* hero1 = dynamic_cast<HeroNode*>(list.begin())->hero;
    Hero* hero2 = dynamic_cast<HeroNode*>(list.begin()->next)->hero;
Хорошо. Если сами додумались -- вам помощь скоро не понадобится. )))

Добавлено через 2 минуты
Цитата Сообщение от Nikhamile421 Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
void Duel(Hero* h1, Hero* h2) {
        std::cout << "Дуэль между " << h1->getName() << " и " << h2->getName() << " начинается!" << std::endl;
// Логика для проведения дуэли между персонажами
        // Например, вы можете сравнивать их характеристики и выводить результаты
if (h1->getStrength() > h2->getIntelligence()) {
            std::cout << h1->getName() << " побеждает " << h2->getName() << "!" << std::endl;
        } else if (h1->getStrength() < h2->getIntelligence()) {
            std::cout << h2->getName() << " побеждает " << h1->getName() << "!" << std::endl;
        } else {
            std::cout << "Ничья!" << std::endl;
        }
    }
А вот тут не туда суёте.
"Дуэль" не имеет никакого отношения к контейнеру связного списка и должна быть выполнена "снаружи" от него.
1
0 / 0 / 0
Регистрация: 24.10.2023
Сообщений: 13
25.10.2023, 16:32
Спасибо. Просто мне препод запретил использовать библиотеки. Я сначала реализовала список простым образом через вектор, она сказала нельзя так. Решила работать с другой структурой.

Получше?

C++
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
#include <iostream>
#include <string>
 
using namespace std;
 
class Hero {
 public:
  Hero(const string& name, int health, int armor, int attack_power)
      : name_(name), health_(health), armor_(armor), attack_power_(attack_power) {}
 
  const string& GetName() const { return name_; }
  int GetHealth() const { return health_; }
  int GetArmor() const { return armor_; }
  int GetAttackPower() const { return attack_power_; }
 
  void SetName(const string& name) { name_ = name; }
  void SetHealth(int health) { health_ = health; }
  void SetArmor(int armor) { armor_ = armor; }
  void SetAttackPower(int attack_power) { attack_power_ = attack_power; }
 
  virtual void Strike(Hero& target) {
    cout << "Метод Strike должен быть переопределен в классах-наследниках" << endl;
  }
 
  virtual ~Hero() {}
 
  friend ostream& operator<<(ostream& out, const Hero& hero) {
    out << "Имя: " << hero.GetName() << endl
        << "Здоровье: " << hero.GetHealth() << endl
        << "Броня: " << hero.GetArmor() << endl
        << "Сила атаки: " << hero.GetAttackPower() << endl;
    return out;
  }
 
 private:
  string name_;
  int health_;
  int armor_;
  int attack_power_;
};
 
class Warrior : public Hero {
 public:
  Warrior(const string& name, int health, int armor, int attack_power,
           const string& weapon)
      : Hero(name, health, armor, attack_power), weapon_(weapon) {}
 
  const string& GetWeapon() const { return weapon_; }
  void SetWeapon(const string& weapon) { weapon_ = weapon; }
 
  void Strike(Hero& target) override {
    int damage = GetAttackPower();
    int armor = target.GetArmor();
    if (armor > 0) {
      armor -= damage;
      if (armor < 0) {
        damage = -armor;
        armor = 0;
      } else {
        damage = 0;
      }
      target.SetArmor(armor);
    }
    if (damage > 0) {
      int health = target.GetHealth() - damage;
      if (health < 0) {
        health = 0;
      }
      target.SetHealth(health);
    }
    cout << GetName() << " атакует " << target.GetName()
              << " с помощью " << GetWeapon() << " (физический урон: " << GetAttackPower() << ") " << endl
              << target.GetName() << " броня: " << target.GetArmor() << ", здоровье: " << target.GetHealth() << endl;
  }
 
 private:
  string weapon_;
};
 
class Mage : public Hero {
 public:
  Mage(const string& name, int health, int armor, int attack_power,
         const string& spell)
      : Hero(name, health, armor, attack_power), spell_(spell) {}
 
  const string& GetSpell() const { return spell_; }
  void SetSpell(const string& spell) { spell_ = spell; }
 
  void Strike(Hero& target) override {
    int damage = GetAttackPower();
    int armor = target.GetArmor();
    if (armor > 0) {
      armor -= damage;
      if (armor < 0) {
        damage = -armor;
        armor = 0;
      } else {
        damage = 0;
      }
      target.SetArmor(armor);
    }
    if (damage > 0) {
      int health = target.GetHealth() - damage;
      if (health < 0) {
        health = 0;
      }
      target.SetHealth(health);
    }
    cout << GetName() << " атакует " << target.GetName()
              << " с помощью " << GetSpell() << " (магический урон: " << GetAttackPower() << ") " << endl
              << target.GetName() << " броня: " << target.GetArmor() << << ", здоровье: " << target.GetHealth() << std::endl;
  }
class LinkedList {
 private:
  struct Node {
    Hero* data;
    Node* prev;
    Node* next;
 
    Node(Hero* hero, Node* previous = nullptr, Node* nextNode = nullptr)
        : data(hero), prev(previous), next(nextNode) {}
  };
 
 public:
  LinkedList() : head(nullptr), tail(nullptr) {}
 
  ~LinkedList() {
    Node* current = head;
    while (current != nullptr) {
      Node* next = current->next;
      delete current->data;
      delete current;
      current = next;
    }
  }
 
  void PushBack(Hero* hero) {
    Node* newNode = new Node(hero, tail);
    if (tail != nullptr) {
      tail->next = newNode;
    } else {
      head = newNode;
    }
    tail = newNode;
  }
 
  void PopFront() {
    if (head != nullptr) {
      Node* next = head->next;
      delete head->data;
      delete head;
      head = next;
      if (next != nullptr) {
        next->prev = nullptr;
      } else {
        tail = nullptr;
      }
    }
  }
 
  void PrintList() const {
    Node* current = head;
    while (current != nullptr) {
      cout << *current->data << endl;
      current = current->next;
    }
  }
 
  void PrintHeroes() const {
    Node* current = head;
    while (current != nullptr) {
      cout << current->data->GetName() << endl;
      current = current->next;
    }
  }
 
 private:
  Node* head;
  Node* tail;
};
 
int main() {
  Warrior warrior("Довакин", 100, 50, 10, "Деревянный меч (легендарный)");
  Mage mage("Ксардас", 100, 50, 50, "Огненный шторм");
 
  LinkedList heroes;
  heroes.PushBack(&warrior);
  heroes.PushBack(&mage);
 
  cout << "Да начнётся битва" << endl;
 
  while (warrior.GetHealth() > 0 && mage.GetHealth() > 0) {
    heroes.PrintHeroes();
    warrior.Strike(mage);
    if (mage.GetHealth() <= 0) {
      cout << "Ксардас повержен!" << endl;
      break;
    }
    mage.Strike(warrior);
    if (warrior.GetHealth() <= 0) {
      cout << "Довакин повержен!" << endl;
      break;
    }
  }
 
  return 0;
}
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
25.10.2023, 17:35
Цитата Сообщение от Nikhamile421 Посмотреть сообщение
Получше?
Код какими-то кусками. Если выложите одним куском -- я смогу посмотреть.

Работает -- уже хорошо. )))
0
0 / 0 / 0
Регистрация: 24.10.2023
Сообщений: 13
27.10.2023, 02:34
C++
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
#include <iostream>
#include <string>
 
class Hero {
public:
    Hero(const std::string& name, int strength, const std::string& weapon)
        : name(name), strength(strength), weapon(weapon) {}
 
    std::string getName() const { return name; }
    int getStrength() const { return strength; }
    std::string getWeapon() const { return weapon; }
 
private:
    std::string name;
    int strength;
    std::string weapon;
};
 
class HeroNode {
public:
    HeroNode(Hero* hero) : hero(hero), next(nullptr), prev(nullptr) {}
 
    Hero* hero;
    HeroNode* next;
    HeroNode* prev;
};
 
class HeroList {
public:
    HeroList() : base(nullptr), size(0) {}
 
    ~HeroList() {
        clear();
    }
 
    void PushFront(Hero* hero) {
        HeroNode* newNode = new HeroNode(hero);
        if (base == nullptr) {
            base = newNode;
        } else {
            newNode->next = base;
            base->prev = newNode;
            base = newNode;
        }
        size++;
    }
 
    void PushBack(Hero* hero) {
        HeroNode* newNode = new HeroNode(hero);
        if (base == nullptr) {
            base = newNode;
        } else {
            HeroNode* currentNode = base;
            while (currentNode->next != nullptr) {
                currentNode = currentNode->next;
            }
            currentNode->next = newNode;
            newNode->prev = currentNode;
        }
        size++;
    }
 
    void clear() {
        HeroNode* currentNode = base;
        while (currentNode != nullptr) {
            HeroNode* nextNode = currentNode->next;
            delete currentNode->hero;
            delete currentNode;
            currentNode = nextNode;
        }
        base = nullptr;
        size = 0;
    }
 
    HeroNode* begin() const { return base; }
    HeroNode* end() const { return nullptr; }
 
private:
    HeroNode* base;
    int size;
};
 
void Duel(Hero* h1, Hero* h2) {
    std::cout << "Дуэль между " << h1->getName() << " и " << h2->getName() << " начинается!" << std::endl;
 
    // Логика для проведения дуэли между персонажами
    if (h1->getStrength() > h2->getStrength()) {
        std::cout << h1->getName() << " побеждает " << h2->getName() << "!" << std::endl;
    } else if (h1->getStrength() < h2->getStrength()) {
        std::cout << h2->getName() << " побеждает " << h1->getName() << "!" << std::endl;
    } else {
        std::cout << "Ничья!" << std::endl;
    }
}
 
int main() {
    // Создать список героев
    HeroList list;
 
    // Добавить героев в список
    list.PushFront(new Hero("Довакин", 100, "Деревянный меч (легендарн.)"));
    list.PushFront(new Hero("Ксардас", 100, "Огненный шторм"));
    list.PushBack(new Hero("Странник", 100, "Посох"));
    list.PushBack(new Hero("Саурон", 100, "Огненный шар"));
    list.PushBack(new Hero("Мастер Чиф", 100, "Плазменный меч"));
    list.PushBack(new Hero("Скарлет", 100, "Кровавый дождь"));
 
    // Просмотреть список и вывод характеристик героев
    for (HeroNode* i = list.begin(); i != list.end(); i = i->next) {
        std::cout << "Герой: " << i->hero->getName() << std::endl;
    }
 
    // Выбрать персонажей для дуэли
    Hero* hero1 = list.begin()->hero;
    Hero* hero2 = list.begin()->next->hero;
 
    // Проведение дуэли
    Duel(hero1, hero2);
 
    // Освобождение памяти, выделенной под героев
    list.clear();
 
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
27.10.2023, 02:34
Помогаю со студенческими работами здесь

Как лучше реализовать большую таблицу? Массивом или по другому?
Здравствуйте, подскажите как правильно сделать вот такую таблицу? передавать 60 переменных в обработчик или как то можно массивом, если...

Как подключиться к другому компьютеру по IP и получить список общих папок
К примеру,я задаю IP=192.168.1.3 ,нужно сделать то что происходит в проводнике Windows по команде: \\192.168.1.3 и получить список...

Список: Не могу реализовать вывод, а может и правильное добавление в список.
Помогите пожалуйста. Не могу реализовать вывод, а может и правильное добавление в список. Вообщем вот код: #include &lt;stdio.h&gt; ...

Создать класс «Квартира», в котором список комнат реализовать как односвязный список
Добрый день,написал фот такой клас по заданию:Создать класс «Квартира», в котором список комнат реализовать как односвязный список....

Реализовать список для хранения элементов через динамический массив и односвязный список
Всем доброго дня! Возникла необходимость реализовать список для хранения элементов через динамический массив и односвязный список. ...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
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