Knight Tour Index 和移动算法错误

Knight Tour Index and Moving Algorithm Bugs

这个程序的目标是让骑士绕着胸板移动并且每个点只接触一次。

每个点都已初始化并默认设置为零。 当骑士移动时,骑士接触的每个点都应与到达该点所采取的移动次数相对应。

但是,我遇到了很多问题

1) 我的马在棋盘上移动,超出多维棋盘数组的边界或操纵移动数组(水平[] 和垂直[])

2) 我的布尔函数 MoveOnBoard && MoveHasNotBeenMade 的条件是,如果下一个可能的移动是在现有的行和列之间,如果要移动到的点的值为 0(意味着它尚未移动)到)。然而,这两个条件 似乎被忽略了。

我该如何解决这个问题?

提前致谢!

下面是代码

using namespace std;
#include <iostream>
#include <array>

void DefinedMoveSet();
void RenderBoard();
void MoveKnight(int& moveChoice, int& numberOfMovesMade);
void PossibleMoves();
bool MoveOnBoard(int& moveChoice);
bool MoveHasNotBeenMade(int& moveChoice);

// Two single dimenisional arrays to store move positions for the Knight
// Arrays have yet to be assigned values
int vertical[8], horizontal[8];
int currentRow = 4, currentColumn = 3;

// Initializing an array with the dimension 8 * 8
int chestBoard[8][8] = { 0 };

int main()
{
    DefinedMoveSet();
    PossibleMoves();
    RenderBoard();
    cin.ignore();
    return 0;
}

void RenderBoard()
{
    // The outer loop goes through each row until it reaches 8
    for (int boardRow = 0; boardRow < 8; boardRow++)
    {
        // The inner loop takes in the specific row 
        for (int boardColumn = 0; boardColumn < 8; boardColumn++)
        {
            // Then iterates through the columns of that row until it reaches 8
            // Each index is seperated by a tab escape key shortcut
            cout << chestBoard[boardRow][boardColumn] << "\t";
        }
        // Back to the inner array a new line is printed for the next row
        cout << "\n";
    }
}

void DefinedMoveSet()
{
    // Values for the horizontal array at each index
    horizontal[0] = 2;
    horizontal[1] = 1;
    horizontal[2] = -1;
    horizontal[3] = -2;
    horizontal[4] = -2;
    horizontal[5] = -1;
    horizontal[6] = 1;
    horizontal[7] = 2;

    // Values for the vertical array at each index
    vertical[0] = -1;
    vertical[1] = -2;
    vertical[2] = -2;
    vertical[3] = -1;
    vertical[4] = 1;
    vertical[5] = 2;
    vertical[6] = 2;
    vertical[7] = 1;
}

bool MoveOnBoard(int& moveChoice)
{
    int futureRow = currentRow + vertical[moveChoice];
    int futureColumn = currentColumn + horizontal[moveChoice];

    if ((0 < futureRow) && (0 < futureColumn) && (futureRow < 8) && (futureColumn < 8))
        return true;
}

bool MoveHasNotBeenMade(int& moveChoice)
{
    int futureRow = currentRow + vertical[moveChoice];
    int futureColumn = currentColumn + horizontal[moveChoice];

    if (chestBoard[futureRow][futureColumn] == 0)
        return true;
}

void PossibleMoves()
{
    bool movesStillExist = true;

    int numberOfMovesMade = 1;

    while (numberOfMovesMade < 65 && movesStillExist)
    {
        for (int i = 0; i < 8; i++)
        {
            if (i == 8)
                movesStillExist = false;

            if (MoveOnBoard(i) && MoveHasNotBeenMade(i))
            {
                numberOfMovesMade++;
                MoveKnight(i, numberOfMovesMade);
            }
        }
    }
}

void MoveKnight(int &moveChoice, int &numberOfMovesMade)  
{
    // Takes in the int moveNumber as a parameter
    // MoveNumber(or case) must be between 0 and 7
    // if there is not a case for the value then the knight will not move
    //chestBoard[currentRow][currentColumn] = numberOfMovesMade;
    currentRow += vertical[moveChoice];
    currentColumn += horizontal[moveChoice];
    chestBoard[currentRow][currentColumn] = numberOfMovesMade;
}

在 MoveOnBoard 和 MoveHasNotBeenMade 中而不是

if(...)
  return true;

应该是

if(...)
  return true;
return false;

如果条件 == false,函数 returning not void 在没有 return 语句的情况下到达终点。

根据我收到的评论的建议,我能够修复索引问题以及布尔函数的 return 值。

我的主要问题是移动后没有跳出之前的循环

这个if语句很容易解决

if (MoveOnBoard(i) && MoveHasNotBeenMade(i))
        {
            MoveKnight(i);
            break;
        }

我试图通过告诉编译器来实现这一点

        if (i == 8)
            movesStillExist = false;

正如@Aziuth 所指出的,这个条件永远不会满足,因为该索引处的移动不存在。

因此,为了我的目的,我将该条件更改为

            if (i == 7)
            movesStillExist = false;

还有索引问题,我的逻辑有点不对劲

if (((0 <= futureRow) && (0 <= futureColumn)) && ((futureRow < 8) && (futureColumn < 8)))
    return true; // if the future row and column are in bounds then return true
return false; // else the default is false

此外,我的代码对于 C++ 来说并不理想化。

全局变量太多,注释不够。

由于这对我的 c++ 课程来说是一个挑战,因此需要使用一维和多维数组,请理解。

bool MoveOnBoard(int& moveChoice)
{
    int futureRow = currentRow + vertical[moveChoice];
    int futureColumn = currentColumn + horizontal[moveChoice];

    if (((0 <= futureRow) && (0 <= futureColumn)) && ((futureRow < 8) && (futureColumn < 8)))
        return true;
    return false;
}

bool MoveHasNotBeenMade(int& moveChoice)
{
    int futureRow = currentRow + vertical[moveChoice];
    int futureColumn = currentColumn + horizontal[moveChoice];

    if (chestBoard[futureRow][futureColumn] == 0)
        return true;
    return false;
}

void PossibleMoves()
{
    bool movesStillExist = true;

    while (numberOfMovesMade < 65 && movesStillExist)
    {
        for (int i = 0; i < 8; i++)
        {
            if (MoveOnBoard(i) && MoveHasNotBeenMade(i))
            {
                MoveKnight(i);
                break;
            }
            if (i == 7)
                movesStillExist = false;
        }
    }
}

void MoveKnight(int &moveChoice)
{
    // Takes in the int moveNumber as a parameter
    // MoveNumber(or case) must be between 0 and 7
    // if there is not a case for the value then the knight will not move
    chestBoard[currentRow][currentColumn] = numberOfMovesMade;
    numberOfMovesMade++;
    currentRow += vertical[moveChoice];
    currentColumn += horizontal[moveChoice];
    chestBoard[currentRow][currentColumn] = numberOfMovesMade;
}