```cpp
#include <iostream>
#include <vector>
#include <ctime>
#include <cstdlib>
#include <conio.h>

using namespace std;

const int WIDTH = 21;
const int HEIGHT = 11;
const char WALL = '#';
const char PATH = ' ';
const char PLAYER = '@';

enum Direction { UP, DOWN, LEFT, RIGHT };

struct Cell {
    int x, y;
    bool visited;
};

void generateMaze(vector<vector<char>>& maze) {
    vector<Cell> frontier;

    auto addFrontier = [&](int x, int y) {
        if (x >= 0 && x < WIDTH && y >= 0 && y < HEIGHT && !maze[y][x]) {
            frontier.push_back({x, y});
            maze[y][x] = WALL;
        }
    };

    srand(time(0));
    int startX = rand() % WIDTH | 1;
    int startY = rand() % HEIGHT | 1;
    maze[startY][startX] = PATH;
    addFrontier(startX - 2, startY);
    addFrontier(startX + 2, startY);
    addFrontier(startX, startY - 2);
    addFrontier(startX, startY + 2);

    while (!frontier.empty()) {
        int index = rand() % frontier.size();
        Cell current = frontier[index];
        frontier.erase(frontier.begin() + index);

        vector<Direction> directions;
        if (current.y > 1 && maze[current.y - 2][current.x] == PATH)
            directions.push_back(UP);
        if (current.y < HEIGHT - 2 && maze[current.y + 2][current.x] == PATH)
            directions.push_back(DOWN);
        if (current.x > 1 && maze[current.y][current.x - 2] == PATH)
            directions.push_back(LEFT);
        if (current.x < WIDTH - 2 && maze[current.y][current.x + 2] == PATH)
            directions.push_back(RIGHT);

        if (!directions.empty()) {
            Direction dir = directions[rand() % directions.size()];
            switch (dir) {
                case UP:
                    maze[current.y - 1][current.x] = PATH;
                    addFrontier(current.x, current.y - 2);
                    break;
                case DOWN:
                    maze[current.y + 1][current.x] = PATH;
                    addFrontier(current.x, current.y + 2);
                    break;
                case LEFT:
                    maze[current.y][current.x - 1] = PATH;
                    addFrontier(current.x - 2, current.y);
                    break;
                case RIGHT:
                    maze[current.y][current.x + 1] = PATH;
                    addFrontier(current.x + 2, current.y);
                    break;
            }
        }
    }
}

void printMaze(const vector<vector<char>>& maze, int playerX, int playerY) {
    for (int y = 0; y < HEIGHT; ++y) {
        for (int x = 0; x < WIDTH; ++x) {
            if (x == playerX && y == playerY)
                cout << PLAYER;
            else
                cout << maze[y][x];
        }
        cout << endl;
    }
}

bool movePlayer(vector<vector<char>>& maze, int& playerX, int& playerY, Direction dir) {
    int newX = playerX;
    int newY = playerY;

    switch (dir) {
        case UP: --newY; break;
        case DOWN: ++newY; break;
        case LEFT: --newX; break;
        case RIGHT: ++newX; break;
    }

    if (maze[newY][newX] == PATH) {
        playerX = newX;
        playerY = newY;
        return true;
    }

    return false;
}

int main() {
    vector<vector<char>> maze(HEIGHT, vector<char>(WIDTH));
    generateMaze(maze);

    int playerX = 1;
    int playerY = 1;

    while (true) {
        system("CLS");
        printMaze(maze, playerX, playerY);
        if (_kbhit()) {
            char key = _getch();
            Direction dir;
            switch (key) {
                case 'w': case 'W': dir = UP; break;
                case 's': case 'S': dir = DOWN; break;
                case 'a': case 'A': dir = LEFT; break;
                case 'd': case 'D': dir = RIGHT; break;
                default: continue;
            }
            movePlayer(maze, playerX, playerY, dir);
        }
    }

    return 0;
}
```

This C++ program generates random mazes using Prim's algorithm and displays them as ASCII art. The user can navigate through the maze using keyboard input (WASD keys). Note that this code uses `system("CLS")` to clear the console screen, which is platform-dependent and may not work on all systems. Additionally, it uses `_kbhit()` and `_getch()` functions from `<conio.h>` header, which are also platform-dependent and may require adjustments for non-Windows platforms.
```cpp
#include <iostream>
#include <vector>
#include <ctime>
#include <cstdlib>
#include <conio.h>

using namespace std;

const int WIDTH = 21;
const int HEIGHT = 11;
const char WALL = '#';
const char PATH = ' ';
const char PLAYER = '@';

enum Direction { UP, DOWN, LEFT, RIGHT };

struct Cell {
    int x, y;
    bool visited;
};

void generateMaze(vector<vector<char>>& maze) {
    vector<Cell> frontier;

    auto addFrontier = [&](int x, int y) {
        if (x >= 0 && x < WIDTH && y >= 0 && y < HEIGHT && !maze[y][x]) {
            frontier.push_back({x, y});
            maze[y][x] = WALL;
        }
    };

    srand(time(0));
    int startX = rand() % WIDTH | 1;
    int startY = rand() % HEIGHT | 1;
    maze[startY][startX] = PATH;
    addFrontier(startX - 2, startY);
    addFrontier(startX + 2, startY);
    addFrontier(startX, startY - 2);
    addFrontier(startX, startY + 2);

    while (!frontier.empty()) {
        int index = rand() % frontier.size();
        Cell current = frontier[index];
        frontier.erase(frontier.begin() + index);

        vector<Direction> directions;
        if (current.y > 1 && maze[current.y - 2][current.x] == PATH)
            directions.push_back(UP);
        if (current.y < HEIGHT - 2 && maze[current.y + 2][current.x] == PATH)
            directions.push_back(DOWN);
        if (current.x > 1 && maze[current.y][current.x - 2] == PATH)
            directions.push_back(LEFT);
        if (current.x < WIDTH - 2 && maze[current.y][current.x + 2] == PATH)
            directions.push_back(RIGHT);

        if (!directions.empty()) {
            Direction dir = directions[rand() % directions.size()];
            switch (dir) {
                case UP:
                    maze[current.y - 1][current.x] = PATH;
                    addFrontier(current.x, current.y - 2);
                    break;
                case DOWN:
                    maze[current.y + 1][current.x] = PATH;
                    addFrontier(current.x, current.y + 2);
                    break;
                case LEFT:
                    maze[current.y][current.x - 1] = PATH;
                    addFrontier(current.x - 2, current.y);
                    break;
                case RIGHT:
                    maze[current.y][current.x + 1] = PATH;
                    addFrontier(current.x + 2, current.y);
                    break;
            }
        }
    }
}

void printMaze(const vector<vector<char>>& maze, int playerX, int playerY) {
    for (int y = 0; y < HEIGHT; ++y) {
        for (int x = 0; x < WIDTH; ++x) {
            if (x == playerX && y == playerY)
                cout << PLAYER;
            else
                cout << maze[y][x];
        }
        cout << endl;
    }
}

bool movePlayer(vector<vector<char>>& maze, int& playerX, int& playerY, Direction dir) {
    int newX = playerX;
    int newY = playerY;

    switch (dir) {
        case UP: --newY; break;
        case DOWN: ++newY; break;
        case LEFT: --newX; break;
        case RIGHT: ++newX; break;
    }

    if (maze[newY][newX] == PATH) {
        playerX = newX;
        playerY = newY;
        return true;
    }

    return false;
}

int main() {
    vector<vector<char>> maze(HEIGHT, vector<char>(WIDTH));
    generateMaze(maze);

    int playerX = 1;
    int playerY = 1;

    while (true) {
        system("CLS");
        printMaze(maze, playerX, playerY);
        if (_kbhit()) {
            char key = _getch();
            Direction dir;
            switch (key) {
                case 'w': case 'W': dir = UP; break;
                case 's': case 'S': dir = DOWN; break;
                case 'a': case 'A': dir = LEFT; break;
                case 'd': case 'D': dir = RIGHT; break;
                default: continue;
            }
            movePlayer(maze, playerX, playerY, dir);
        }
    }

    return 0;
}
```

이 C++ 프로그램은 프림의 알고리즘을 사용하여 무작위 미로를 생성하고 이를 아스키 아트로 표시합니다. 사용자는 키보드 입력(WASD 키)을 사용하여 미로를 탐색할 수 있습니다. 이 코드는 `system("CLS")`를 사용하여 콘솔 화면을 지우는데, 이는 플랫폼에 따라 다르며 모든 시스템에서 작동하지 않을 수 있다는 점에 유의하세요. 또한 `<conio.h>` 헤더의 `_kbhit()` 및 `_getch()` 함수를 사용하는데, 이 함수 역시 플랫폼에 따라 다르며 Windows 이외의 플랫폼에서는 조정이 필요할 수 있습니다.