stage 5.2 has been completed

This commit is contained in:
solovevds 2026-05-23 00:04:45 +03:00
parent 1edbb037d0
commit 5dc9777c5a

View File

@ -4,6 +4,7 @@
#include <stdexcept> /*для ошибок*/ #include <stdexcept> /*для ошибок*/
#include <cmath> #include <cmath>
#include <chrono> /*мерит время*/ #include <chrono> /*мерит время*/
#include <cstdlib> /*волшебная отрисовка*/
class cell{ class cell{
private: private:
@ -627,7 +628,7 @@ class MazeSolver{
maze* labirint; maze* labirint;
PathFindingStrategy* strategy; PathFindingStrategy* strategy;
public: public:
MazeSolver(maze* labirint) {this->labirint = labirint;} MazeSolver(maze* labirint) {this->labirint = labirint; this->strategy = nullptr;}
void setStrategy(PathFindingStrategy* strategy){ void setStrategy(PathFindingStrategy* strategy){
this->strategy = strategy; this->strategy = strategy;
@ -652,9 +653,202 @@ class MazeSolver{
SearchStats stats(duration.count(), visitedCells, pathLength); SearchStats stats(duration.count(), visitedCells, pathLength);
return stats; 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(){ int main(){