骑士的巡回蛮力递归

时间:2018-02-08 02:37:16

标签: c++ recursion infinite-loop knights-tour

我正在尝试编写一个程序,允许用户在棋盘上输入任何坐标,并使用强力递归完成骑士之旅。我得到一个无限循环,我不知道为什么。这是在C ++中,我必须使用强力递归来编写它。进入骑士的起始位置后,我的控制台输出窗口在每次移动后打印当前电路板(仅用于故障排除),但是根据我的输出,移动号码卡在1,程序没有尝试任何其他动作。任何帮助表示赞赏。

#include "stdafx.h"
#include <iostream>
#include <iomanip>
using namespace std;

void printBoard();
bool moveKnight(int col, int row, int movNum);


int totalMoves = 0;
int board[7][7] = { { 0 } };


int main()
{
    cout << "Welcome to the Knight's Tour Program!  Enter a starting place for the knight on a chess board to get started.\n";

    int col;
    int row;

    int a;
    int b;

    while (1 == 1)
    {
        col = 0;
        row = 0;

        cout << "Enter column (0-7): ";
        cin >> col;

        cout << "Enter row (0-7): ";
        cin >> row;

        if (row < 0 || row > 7 || col < 0 || col > 7)
        {
            cout << "Invalid knight placement.  Please try again.\n";
        }

        else
        {
            break;
        }
    }

    int movNum = 1;

    board[col][row] = movNum;
    totalMoves++;

    moveKnight(col, row, movNum);

    if (moveKnight(col, row, movNum == true))
    {
        cout << "Tour finished!  Total moves: " << totalMoves << endl;
        printBoard();
        cout << "\n\n";
    }

    system("pause");
    return 0;
}


void printBoard()
{
    cout << "Current board\n";
    for (int i = 0; i < 8; i++)
    {
        for (int x = 0; x < 8; x++)
        {
            cout << setw(3) << board[i][x] << "  ";

            if (x == 7)
            {
                cout << "\n\n";
            }
        }
    }
    cout << "\n";
}


bool moveKnight(int col, int row, int movNum)
{
     printBoard(); //just for troubleshooting
     cout << "\n" << totalMoves << endl;

     if (moveKnight(col, row, movNum) == false)
     {
         board[col][row] = 0; //if there are no available moves then set the current space to 0 and move back a spot
     }

     if (movNum == 64)
     {
         return true; //if tour complete return true
     }

     if (totalMoves % 10000 == 0)
     {
         printBoard(); //printBoard() every 10000 moves
     }

     if (col >= 0 && col <= 7 && row >= 0 && row <= 7 && board[row][col] == 0) //check if space is on board and if it is unoccupied
     {
        board[col][row] = movNum;
        totalMoves++;

        if (moveKnight(col + 1, row - 2, movNum + 1) != false)
            moveKnight(col + 1, row - 2, movNum + 1);

        else if (moveKnight(col + 2, row - 1, movNum + 1) != false)
            moveKnight(col + 2, row - 1, movNum + 1);

        else if (moveKnight(col + 2, row + 1, movNum + 1) != false)
            moveKnight(col + 2, row + 1, movNum + 1);

        else if (moveKnight(col + 1, row + 2, movNum + 1) != false)
            moveKnight(col + 1, row + 2, movNum + 1);

        else if (moveKnight(col - 1, row + 2, movNum + 1) != false)
            moveKnight(col - 1, row + 2, movNum + 1);

        else if (moveKnight(col - 2, row + 1, movNum + 1) != false)
            moveKnight(col - 2, row + 1, movNum + 1);

        else if (moveKnight(col - 2, row - 1, movNum + 1) != false)
            moveKnight(col - 2, row - 1, movNum + 1);

        else if (moveKnight(col - 1, row - 2, movNum + 1) != false)
            moveKnight(col - 1, row - 2, movNum + 1);
        else
            return false;
     }
}

2 个答案:

答案 0 :(得分:0)

如果查看moveKnight()函数,请注意,无论输入是什么,行if (moveKnight(col, row, movNum) == false)都会对函数进行递归调用。

每当使用递归函数时,它必须具有所谓的基本情况,其中不会发生递归调用。否则,递归调用将继续进行直到堆栈溢出,因为函数的一次执行将启动另一个将启动另一个的函数,依此类推......

顺便说一句,函数中的一堆if语句没有任何意义,因为你正在调用一个函数并检查输出,如果它是真的那么你用相同的参数再次调用该函数。此外,如果您想要一个稍后会破坏的无限循环,则不需要while(1 == 1)之类的东西。使用while(1)while(true)

答案 1 :(得分:0)

  

right

国际象棋棋盘是8 x 8,所以你需要阵容中的8个元素(从0到最多,包括7个,那个&#39; 8)

  

var overlayTemplate = '<div class="loadgo-overlay" style="background-color:%bgcolor%;opacity:%opacity%;width:%width%px;height:%height%px;position:absolute;"></div>'; var overlayWithOptions = overlayTemplate .replace('%bgcolor%', pluginOptions.bgcolor) .replace('%opacity%', pluginOptions.opacity) .replace('%width%', _w) .replace('%height%', _h); $overlay = $(overlayWithOptions);

你有语法错误,编译器会告诉你所有这些。在Visual Studio中,确保警告级别设置为4.然后确保程序编译为零错误和零警告。

我建议编写一个不需要用户输入的程序。这样可以更容易地调试程序并修复逻辑。

下面是一个简单的递归,它会移动骑士直到骑士卡在最后。您将不得不进一步改进逻辑,以便它涵盖所有正方形。

确保允许递归函数中断。在另一个答案中对此进行了更详细的讨论。

int board[7][7] = { { 0 } };