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

时间:2010-04-29 01:46:04

标签: c++ recursion

我正在尝试创建此游戏的基于文本的版本:
http://www.cse.nd.edu/java/SameGame.html

这是我到目前为止的代码:

#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()方法,以便返回正确数量的已销毁块?

2 个答案:

答案 0 :(得分:1)

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

你是对的,第一个电话没有被计算,它只计算递归电话。

答案 1 :(得分:0)

0基于索引。你不想检查&gt;你想要&gt; =

你想检查行&gt; = 12 col&gt; = 8