-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMemento.cpp
More file actions
131 lines (108 loc) · 4.09 KB
/
Copy pathMemento.cpp
File metadata and controls
131 lines (108 loc) · 4.09 KB
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
/*
* используется для сохранения и восстановления состояния объекта без нарушения его инкапсуляции
*
* NOTE: инкапсуляция - контроль доступа к полям и методам объекта
* через модификаторы доступа (publiс, private, protected)
*
* publiс — открытый доступ
* private — могут обращаться только методы данного класса
* protected — похож на private, только есть доступ ещё и у наследников класса
*
* если объект (Originator) содержит большие данные, то хранение множества копий может потреблять много памяти
*
* */
#include <iostream>
#include <vector>
// абстрактный класс снимка для сохранения состояния игрока
class Memento {
public:
virtual int getX() = 0;
virtual int getY() = 0;
virtual int getHP() = 0;
};
// класс снимка для хранения состояния
class GameMemento : public Memento {
private:
int x_, y_, hp_;
public:
GameMemento(int x, int y, int hp) : x_(x), y_(y), hp_(hp) {}
// следующие три метода будут использоваться классом-создателем для восстановления состояния
int getX() override {
return x_;
}
int getY() override {
return y_;
}
int getHP() override {
return hp_;
}
};
// класс создателя (Originator), состояния которого и надо будет сохранять
class Player {
private:
int x_, y_, hp_;
public:
Player(int startX, int startY, int startHP) : x_(startX), y_(startY), hp_(startHP) {}
void move(int dx, int dy) {
x_ += dx;
y_ += dy;
}
void takeDamage(int damage) {
hp_ -= damage;
if (hp_ < 0) hp_ = 0;
}
void state() const {
std::cout << "X= " << x_ << ", Y= " << y_ << ", HP= " << hp_ << std::endl;
}
// сохранение текущего состояния
GameMemento* save() {
return new GameMemento(x_, y_, hp_);
}
// восстановление состояния
void restore(Memento* memento) {
x_ = memento->getX();
y_ = memento->getY();
hp_ = memento->getHP();
}
};
// класс-хранитель истории (Caretaker)
class GameHistory {
private:
std::vector<Memento*> history;
Player* player_;
public:
GameHistory(Player* player): player_(player) {}
// сохранение состояния
void backup() {
history.push_back(player_->save());
}
// откат состояния к предыдущему
void undo() {
if (!history.empty()) {
player_->restore(history.back());
// удаление состояния из истории
history.pop_back();
std::cout << "Отмена последнего действия" << std::endl;
}
}
};
int main() {
Player* player = new Player(0, 0, 100);
GameHistory* history = new GameHistory(player);
player->state();
history->backup(); // сохраняем состояние
player->move(5, 10);
player->takeDamage(30);
player->state();
history->backup(); // сохраняем состояние
player->move(20, 5);
player->takeDamage(40);
player->state();
history->undo(); // отмена последнего действия
player->state();
history->undo(); // откат еще на одно состояние назад
player->state();
delete player;
delete history;
return 0;
}