C++:地下城爬行者 - 更新数组时出现问题



我正在为我的C++类开发地牢爬行器,并且在更新/显示代表我角色的数组元素时遇到了问题。"向上"、"向左"和"向右"功能正常工作(IE,对应于 x/y 位置的数组元素增加或减少 1 并准确显示更新(,但"向下"移动会导致字符消失。我尝试更改字符,删除覆盖旧位置的代码,以及其他一些事情来确定到底发生了什么,但无济于事。非常感谢任何反馈(请注意,checkWin 函数不完整(。

#include <iostream>
#include <iomanip>
#include <cctype>
#include <cstdlib>
#include <ctime>
using namespace std;
const int max_row = 10;
const int max_col = 10;
const char character = 'O', treasure = 'X', traps = 'T', space = '.';
void showInstructions();
void createDungeon(char dungeon[max_row][max_col], int max_col);
void displayDungeon(char dungeon[max_row][max_col], int max_col);
void getMove(char& movement, char dungeon[max_row][max_col],int max_col);
void checkMove(char& movement, char dungeon[max_row][max_col], int max_col);
void updateDungeon(char& movement, char dungeon[max_row][max_col], int max_col);
int checkCharPositionY(char dungeon[max_row][max_col], int max_col);
int checkCharPositionX(char dungeon[max_row][max_col], int max_col);
void checkWin (char dungeon[max_row][max_col], int max_col, bool& playing);
string getDirection(char movement);

int main()
{
    bool playing = true;
    int character_pos, trap_pos[3], treasure_pos;
    char movement;
    char dungeon[max_row][max_col] = {{'.','.','.','.','.','.','.','.','.','.'},
                                      {'.','.','.','.','.','.','.','.','.','.'},
                                      {'.','.','.','.','.','.','.','.','.','.'},
                                      {'.','.','.','.','.','.','.','.','.','.'},
                                      {'.','.','.','.','.','.','.','.','.','.'},
                                      {'.','.','.','.','.','.','.','.','.','.'},
                                      {'.','.','.','.','.','.','.','.','.','.'},
                                      {'.','.','.','.','.','.','.','.','.','.'},
                                      {'.','.','.','.','.','.','.','.','.','.'},
                                      {'.','.','.','.','.','.','.','.','.','.'}};
    showInstructions();
    createDungeon(dungeon, max_col);
    while (playing) {
    displayDungeon(dungeon, max_col);
    getMove(movement, dungeon, max_col);
    checkMove(movement, dungeon, max_col);
    updateDungeon(movement, dungeon, max_col);
    checkWin(dungeon, max_col, playing);
    }
}
void createDungeon(char dungeon[][max_col], int max_col) {
    int trap_count = 0, srand(time(0));
    dungeon[0][0] = character;
    while(trap_count < 3) {
        if(dungeon[rand() % 10][rand() % 10] == space) {
            dungeon[rand() % 10][rand() % 10] = traps;
            trap_count++;
        }
    }
    if (dungeon[rand() % 10][rand() % 10] == space) {
        dungeon[rand() % 10][rand() % 10] = treasure;
    }
}
void showInstructions() {
    cout << "Hello and welcome to your doom! Whether by fate or fiat, you have entered the n";
    cout << "dungeon. To win, make your way to the treasure. If you find a trap, you will n";
    cout << "instead find death. With treasure comes release and fortune. Your character is n";
    cout << "represented with 'O', traps with 'T', and the treasure with 'X'. You will always";
    cout << "begin in the upper left hand corner of the maze. Good luck - you'll need it. n";
    cout << "nTo navigate the dungeon, use the 'W','A','S', and 'D' keys as shown below:nn";
    cout << setw(39) << "^n";
    cout << setw(40) << "[W]n";
    cout << setw(46) << " < [A]   [S] > n";
    cout << setw(40) << " [D]n";
    cout << setw(39) << "vn";
}
void displayDungeon(char dungeon[max_row][max_col], int max_col) {
    for(int row = 0; row < max_col; row++) {
        cout << endl;
        cout << setw(23);
        for(int col = 0; col < max_col; col++) {
            cout << " " << dungeon[row][col] << " ";
        }
    }
}
void getMove(char& movement, char dungeon[max_row][max_col], int max_col) {
    cout << "nnPick a direction for your character to move.n";
    cin >> movement;
    while (movement != 'w' && movement != 'a' && movement != 's' && movement != 'd' &&
           movement != 'W' && movement != 'A' && movement != 'S' && movement != 'D'    ) {
        cin.clear();
        cout << "That was not a valid selection. Please navigate using W, A, S, or D.n";
        cin >> movement;
    }
    if (movement == 'w') {
        movement = 'W';
    }
    else if (movement == 'a') {
        movement = 'A';
    }
    else if (movement == 's') {
        movement = 'S';
    }
    else if (movement == 'd') {
        movement = 'D';
    }
}
void checkMove(char& movement, char dungeon[max_row][max_col], int max_col) {
    while (movement == 'W' && checkCharPositionY(dungeon, max_col) == 0) {
        cin.clear();
        cout << "nYou cannot exit the dungeon that way! Try again. n";
        getMove(movement, dungeon, max_col);
    }
    while (movement == 'S' && checkCharPositionY(dungeon, max_col) == 9) {
        cin.clear();
        cout << "nYou cannot exit the dungeon that way! Try again. n";
        getMove(movement, dungeon, max_col);
    }
    while (movement == 'A' && checkCharPositionX(dungeon, max_col) == 0) {
        cin.clear();
        cout << "nYou cannot exit the dungeon that way! Try again. n";
        getMove(movement, dungeon, max_col);
    }
    while (movement == 'D' && checkCharPositionX(dungeon, max_col) == 9) {
        cin.clear();
        cout << "nYou cannot exit the dungeon that way! Try again. n";
        getMove(movement, dungeon, max_col);
    }
    cout << "You moved " << getDirection(movement) << endl;
}
void updateDungeon(char& movement, char dungeon[max_row][max_col], int max_col) {
    switch (movement) {
        case 'W':
            for (int i = 0; i < max_col; i++) {
                for(int j = 0; j < max_col; j++) {
                    if (dungeon[i][j] == 'O') {
                        dungeon[i][j] = '.';
                        dungeon[i - 1][j] = 'O';
                        break;
                    }
                }
            }
            break;
        case 'A':
            for (int i = 0; i < max_col; i++) {
                for(int j = 0; j < max_col; j++) {
                    if (dungeon[i][j] == 'O') {
                        dungeon[i][j] = '.';
                        dungeon[i][j - 1] = 'O';
                        break;
                    }
                }
            }
            break;
        case 'S':
            for (int i = 0; i < max_col; i++) {
                for(int j = 0; j < max_col; j++) {
                    if (dungeon[i][j] == 'O') {
                        dungeon[i+1][j] = 'O';
                        dungeon[i][j] = '.';
                        break;
                    }
                }
            }
            break;
        case 'D':
            for (int i = 0; i < max_col; i++) {
                for(int j = 0; j < max_col; j++) {
                    if (dungeon[i][j] == 'O') {
                        dungeon[i][j] = '.';
                        dungeon[i][j + 1] = 'O';
                        break;
                    }
                }
            }
            break;
        default:
            break;
    }
}
string getDirection(char movement) {
    string direction;
    if (movement == 'W' || movement == 'w') {
        direction = "up.";
    }
    else if (movement == 'A' || movement == 'a') {
        direction = "left.";
    }
    else if (movement == 'D' || movement == 'd') {
        direction = "right.";
    }
    else if (movement == 'S' || movement == 's') {
        direction = "down.";
    }
    return direction;
}
int checkCharPositionY(char dungeon[max_row][max_col], int max_col) {
    for (int row = 0; row < max_col; row++) {
            for(int col = 0; col < max_col; col++) {
                if (dungeon[row][col] == 'O') {
                    return row;
                }
            }
    }
}
int checkCharPositionX(char dungeon[max_row][max_col], int max_col) {
    for (int row = 0; row < max_col; row++) {
            for(int col = 0; col < max_col; col++) {
                if (dungeon[row][col] == 'O') {
                    return col;
                }
            }
    }
}
void checkWin (char dungeon[max_row][max_col], int max_col, bool& playing) {
    int treasurepos[max_row][max_col], trappos[max_row][max_col];
    for (int i = 0; i < max_col; i++) {
            for(int j = 0; j < max_col; j++) {
                if (dungeon[i][j] == 'X') {
                    treasurepos[i][j] = dungeon[i][j];
                }
            }
    }
    for (int i = 0; i < max_col; i++) {
            for(int j = 0; j < max_col; j++) {
                if (dungeon[i][j] == 'T') {
                    trappos[i][j] = dungeon[i][j];
                }
            }
    }

}

编辑:尽管有break语句,但该问题似乎与它没有退出循环有关。陷阱将在索引 0 中生成,如果我尝试向下移动,则会被覆盖。将"."字符转换为 @ 或其他字符将显示它一直写入索引 0。

正在发生的事情是,一旦你找到正确的位置,你就不会打破你的循环。因此,对于 updatedDungeon() 中的S情况,当您找到它时,您将O移动到 1 个位置以上。下次通过循环时,您再次找到O,然后再次移动它。下次通过循环时,您再次找到O并再次移动它。等。您需要在找到并移动角色后立即停止循环。

另一种可能更好的移动字符的方法可能是将其位置保留在单独的变量中,更新该变量,然后使用新信息重新绘制棋盘。

最新更新