From 5dc9777c5aabb1283dc350e1d635e16bc7072c0c Mon Sep 17 00:00:00 2001 From: solovevds Date: Sat, 23 May 2026 00:04:45 +0300 Subject: [PATCH] stage 5.2 has been completed --- SolovevDS/docs/data/data_for_task2/task2.cpp | 196 ++++++++++++++++++- 1 file changed, 195 insertions(+), 1 deletion(-) diff --git a/SolovevDS/docs/data/data_for_task2/task2.cpp b/SolovevDS/docs/data/data_for_task2/task2.cpp index 05c42a2..a9df53d 100644 --- a/SolovevDS/docs/data/data_for_task2/task2.cpp +++ b/SolovevDS/docs/data/data_for_task2/task2.cpp @@ -4,6 +4,7 @@ #include /*для ошибок*/ #include #include /*мерит время*/ +#include /*волшебная отрисовка*/ class cell{ private: @@ -627,7 +628,7 @@ class MazeSolver{ maze* labirint; PathFindingStrategy* strategy; public: - MazeSolver(maze* labirint) {this->labirint = labirint;} + MazeSolver(maze* labirint) {this->labirint = labirint; this->strategy = nullptr;} void setStrategy(PathFindingStrategy* strategy){ this->strategy = strategy; @@ -652,9 +653,202 @@ class MazeSolver{ SearchStats stats(duration.count(), visitedCells, pathLength); return stats; } +}; + +class Player{ + private: + cell* current; + public: + Player(cell* current) {this->current = current;} + + cell* getCurrent() {return current;} + void moveTo(cell* cell) {this->current = cell;} +}; + +class Direction{ + private: + int dx; + int dy; + + public: + Direction(int dx, int dy) { + this->dx = dx; + this->dy = dy; + } + + int getDx() {return dx;} + int getDy() {return dy;} +}; + +class Command { + public: + virtual void execute() = 0; + virtual void undo() = 0; + virtual ~Command() {} +}; + +class MoveCommand : public Command{ + private: + Player* player; + Direction dir; + cell* previousCell; + maze* labirint; + public: + MoveCommand(Player* player, maze* labirint, Direction dir) : dir(dir) { + this->player = player; + this->labirint = labirint; + this->previousCell = nullptr; + } + + void execute() override { + cell* currentCell = player->getCurrent(); + + int newX = currentCell->getX() + dir.getDx(); + int newY = currentCell->getY() + dir.getDy(); + + cell* nextCell = labirint->getCell(newX, newY); + + if (nextCell != nullptr && nextCell->isPassable()) { + previousCell = currentCell; + player->moveTo(nextCell); + } + else { + std::cout << "Нельзя сделать ход!" << std::endl; + } + } + + void undo() override { + if (previousCell != nullptr) { + player->moveTo(previousCell); + previousCell = nullptr; + } + } }; +class ConsolController{ + private: + maze* labirint; + Player* player; + Command* lastCommand; /*указатель на последнюю команду(на объект класса command)*/ + bool running; + public: + ConsolController(maze* labirint, Player* player) { + this->labirint = labirint; + this->player = player; + this->lastCommand = nullptr; + this->running = false; + } + + ~ConsolController() { + if (lastCommand != nullptr) { + delete lastCommand; + } + } + + void run() { + running = true; + + while (running) { + clearConsole(); + drawMaze(); + + std::cout << "W/A/S/D - ход, Z - отмена, Q - выход" << std::endl; + char ch; + std::cin >> ch; + + handleInput(ch); + } + } + + void handleInput(char ch) { + switch(ch){ + case 'q': + case 'Q': + running = false; + break; + case 'z': + case 'Z': + undoLastMove(); + break; + default: + handleMove(ch); + break; + } + } + + void handleMove(char ch) { + Direction dir(0, 0); + + switch (ch) { + case 'w': + case 'W': + dir = Direction(0, -1); + break; + case 's': + case 'S': + dir = Direction(0, 1); + break; + case 'a': + case 'A': + dir = Direction(-1, 0); + break; + case 'd': + case 'D': + dir = Direction(1, 0); + break; + default: + return; + } + + if (lastCommand != nullptr) { + delete lastCommand; + lastCommand = nullptr; + } + + lastCommand = new MoveCommand(player, labirint, dir); + lastCommand->execute(); + } + + void undoLastMove() { + if (lastCommand != nullptr) { + lastCommand->undo(); + delete lastCommand; + lastCommand = nullptr; /*можно отменить только одну команду назад, указатель делаем 0, чтобы не долбится в отмену уже отмененной команды*/ + } + } + + void clearConsole() { + #ifdef _WIN32 + system("cls"); + #else + system("clear"); + #endif + } + + void drawMaze() { + for (int y = 0; y < labirint->getHeight(); y++) { + for (int x = 0; x < labirint->getWidth(); x++) { + cell* currentCell = labirint->getCell(x, y); + + if (currentCell == player->getCurrent()) + std::cout << "P"; + else if (currentCell->getIsWall()) + std::cout << "#"; + else if (currentCell->getIsStart()) + std::cout << "S"; + else if (currentCell->getIsExit()) + std::cout << "E"; + else + std::cout << " "; + } + std::cout << std::endl; + } + } +}; + + + int main(){