为什么我的简单递归方法的最终返回值总是减 1?

发布于 2024-08-30 07:34:24 字数 4242 浏览 4 评论 0原文

我正在尝试创建基于文本的版本 这个游戏

代码:

#include <iostream>
#include <vector>
#include <ctime>

class Clickomania {
    public:
        Clickomania();
        std::vector<std::vector<int> > board;
        int move(int, int);
        bool isSolved();
        void print();
        void pushDown();
        bool isValid();
};

Clickomania::Clickomania()
    : board(12, std::vector<int>(8,0)) {

    srand((unsigned)time(0));

    for(int i = 0; i < 12; i++) {
        for(int j = 0; j < 8; j++) {
            int color = (rand() % 3) + 1;
            board[i][j] = color;
        }
    }
}

void Clickomania::pushDown() {
    for(int i = 0; i < 8; i++) {
        for(int j = 0; j < 12; j++) {
            if (board[j][i] == 0) {
                for(int k = j; k > 0; k--) {
                    board[k][i] = board[k-1][i];
                }
                board[0][i] = 0;
            }
        }
    }
}

int Clickomania::move(int row, int col) {
    bool match = false;
    int totalMatches = 0;
    if (row > 12 || row < 0 || col > 8 || col < 0) {
        return 0;
    }

    int currentColor = board[row][col];
    board[row][col] = 0;

    if ((row + 1) < 12) {
        if (board[row+1][col] == currentColor)
        {
            match = true;
            totalMatches++;
            totalMatches +=  move(row+1, col);
        }
    }

    if ((row - 1) >= 0) {
        if (board[row-1][col] == currentColor) {
            match = true;
            totalMatches++;
            totalMatches += move(row-1, col);
        }
    }

    if ((col + 1) < 8) {
        if (board[row][col+1] == currentColor) {
            match = true;
            totalMatches++;
            totalMatches += move(row, col+1);
        }
    }

    if ((col - 1) >= 0) {
        if (board[row][col-1] == currentColor) {
            match = true;
            totalMatches++;
            totalMatches += move(row, col-1);
        }
    }

    return totalMatches;
}

void Clickomania::print() {
    for(int i = 0; i < 12; i++) {
        for(int j = 0; j < 8; j++) {
            std::cout << board[i][j];
        }
        std::cout << "\n";
    }
}

int main() {
    Clickomania game;
    game.print();
    int row;
    int col;
    std::cout << "Enter row: ";
    std::cin >> row;
    std::cout << "Enter col: ";
    std::cin >> col;
    int numDestroyed = game.move(row,col);
    game.print();
    std::cout << "Destroyed: " << numDestroyed << "\n";
}

给我带来麻烦的方法是我的“移动”方法。这个方法,给定一对坐标,应该删除该坐标处具有相同数字的所有方块,同样删除与其连接的所有具有相同数字的方块。

如果您播放我上面提供的链接,您将看到点击后如何删除。

int Clickomania::move(int row, int col) {
        bool match = false;
        int totalMatches = 0;

        if (row > 12 || row < 0 || col > 8 || col < 0) {
            return 0;
        }

        int currentColor = board[row][col];
        board[row][col] = 0;

        if ((row + 1) < 12) {
            if (board[row+1][col] == currentColor) {
                match = true;
                totalMatches++;
                totalMatches +=  move(row+1, col);
            }
        }

        if ((row - 1) >= 0) {
            if (board[row-1][col] == currentColor) {
                match = true;
                totalMatches++;
                totalMatches += move(row-1, col);
            }
        }

        if ((col + 1) < 8) {
            if (board[row][col+1] == currentColor)
            {
                match = true;
                totalMatches++;
                totalMatches += move(row, col+1);
            }
        }

        if ((col - 1) >= 0) {
            if (board[row][col-1] == currentColor) {
                match = true;
                totalMatches++;
                totalMatches += move(row, col-1);
            }
        }

        return totalMatches;
    }

我上面的 move() 方法工作正常,因为它将删除适当的“块”并将其替换为零,但是被破坏的数量(返回的值)始终是一次性的(太小)。我相信这是因为 move() 的第一次调用没有被计算在内,但我不知道如何区分该递归方法中的第一次调用或后续调用。

如何修改 move() 方法,使其返回正确的被破坏块数?

I'm attempting to create a text-based version of this game.

Code:

#include <iostream>
#include <vector>
#include <ctime>

class Clickomania {
    public:
        Clickomania();
        std::vector<std::vector<int> > board;
        int move(int, int);
        bool isSolved();
        void print();
        void pushDown();
        bool isValid();
};

Clickomania::Clickomania()
    : board(12, std::vector<int>(8,0)) {

    srand((unsigned)time(0));

    for(int i = 0; i < 12; i++) {
        for(int j = 0; j < 8; j++) {
            int color = (rand() % 3) + 1;
            board[i][j] = color;
        }
    }
}

void Clickomania::pushDown() {
    for(int i = 0; i < 8; i++) {
        for(int j = 0; j < 12; j++) {
            if (board[j][i] == 0) {
                for(int k = j; k > 0; k--) {
                    board[k][i] = board[k-1][i];
                }
                board[0][i] = 0;
            }
        }
    }
}

int Clickomania::move(int row, int col) {
    bool match = false;
    int totalMatches = 0;
    if (row > 12 || row < 0 || col > 8 || col < 0) {
        return 0;
    }

    int currentColor = board[row][col];
    board[row][col] = 0;

    if ((row + 1) < 12) {
        if (board[row+1][col] == currentColor)
        {
            match = true;
            totalMatches++;
            totalMatches +=  move(row+1, col);
        }
    }

    if ((row - 1) >= 0) {
        if (board[row-1][col] == currentColor) {
            match = true;
            totalMatches++;
            totalMatches += move(row-1, col);
        }
    }

    if ((col + 1) < 8) {
        if (board[row][col+1] == currentColor) {
            match = true;
            totalMatches++;
            totalMatches += move(row, col+1);
        }
    }

    if ((col - 1) >= 0) {
        if (board[row][col-1] == currentColor) {
            match = true;
            totalMatches++;
            totalMatches += move(row, col-1);
        }
    }

    return totalMatches;
}

void Clickomania::print() {
    for(int i = 0; i < 12; i++) {
        for(int j = 0; j < 8; j++) {
            std::cout << board[i][j];
        }
        std::cout << "\n";
    }
}

int main() {
    Clickomania game;
    game.print();
    int row;
    int col;
    std::cout << "Enter row: ";
    std::cin >> row;
    std::cout << "Enter col: ";
    std::cin >> col;
    int numDestroyed = game.move(row,col);
    game.print();
    std::cout << "Destroyed: " << numDestroyed << "\n";
}

The method that is giving me trouble is my "move" method. This method, given a pair of coordinates, should delete all the squares at that coordinate with the same number and likewise with all the squares with the same number connected to it.

If you play the link I gave above you'll see how the deletion works on a click.

int Clickomania::move(int row, int col) {
        bool match = false;
        int totalMatches = 0;

        if (row > 12 || row < 0 || col > 8 || col < 0) {
            return 0;
        }

        int currentColor = board[row][col];
        board[row][col] = 0;

        if ((row + 1) < 12) {
            if (board[row+1][col] == currentColor) {
                match = true;
                totalMatches++;
                totalMatches +=  move(row+1, col);
            }
        }

        if ((row - 1) >= 0) {
            if (board[row-1][col] == currentColor) {
                match = true;
                totalMatches++;
                totalMatches += move(row-1, col);
            }
        }

        if ((col + 1) < 8) {
            if (board[row][col+1] == currentColor)
            {
                match = true;
                totalMatches++;
                totalMatches += move(row, col+1);
            }
        }

        if ((col - 1) >= 0) {
            if (board[row][col-1] == currentColor) {
                match = true;
                totalMatches++;
                totalMatches += move(row, col-1);
            }
        }

        return totalMatches;
    }

My move() method above works fine, as in it will delete the appropriate "blocks" and replace them with zeros, however the number of destroyed (value returned) is always one off (too small). I believe this is because the first call of move() isn't being counted, but I don't know how to differentiate between the first call or subsequent calls in that recursive method.

How can I modify my move() method so it returns the correct number of destroyed blocks?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

够运 2024-09-06 07:34:24

看起来您在错误的位置增加了totalMoves。您应该在设置 board[r][c] = 0 的位置对匹配进行计数,并删除对 totalMoves++ 的其他引用。

你是对的,第一次调用没有被计算在内,它只计算了递归调用。

It looks like you're incrementing totalMoves in the wrong place(s). You should count the match at the point where you set board[r][c] = 0 and remove the other references to totalMoves++.

You are right that the first call isn't being counted, it's only counting the recursive calls.

垂暮老矣 2024-09-06 07:34:24

基于 0 的索引。您不想检查>你想要>=

你想要检查行>=12列>=8

0 based indexing. You dont want to check > you want >=

you wanna check row >= 12 col >= 8

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文