Chessai:为什么会引用课程的参考递归以某种方式上限?

发布于 2025-01-30 19:27:59 字数 4050 浏览 3 评论 0原文

我已经做了一个C ++类来代表董事会,我注意到,如果我调用具有参数的递归函数,将其引用对木板对象,则在一段时间后停止,导致大约5000-6000个呼叫,即使 在此深度为10+的深度

是重复函数,板和输出


#include <string>
#include <vector>
#include <stdexcept>
#include <iostream>
#include <map>
#include <algorithm>
#include <bitset>
#include <iostream>
#include <array>

#include "Utils.h"

#define KING 0
#define QUEEN 1
#define BISHOP 2
#define KNIGHT 3
#define ROOK 4
#define PAWN 5

#define WHITE 0
#define BLACK 1

typedef std::pair<short, short> Tile;

namespace Chess {

    class Piece {

        public:
            short color;
            short type;

            Piece();

            Piece(char fenChr);

            Piece(short pType, short pColor);

    };

    class Board {
        private:
            std::vector<Tile> enpassant;
            bool whiteKingsidecastle = false;
            bool whiteQueensidecastle = false;
            bool blackKingsidecastle = false;
            bool blackQueensidecastle = false;
            short currentPlayer = 0;
            

        public:
            std::array<std::array<Piece, 8>, 8> _board;

            Board(std::string fenStr); // Construct a board object given a fen board

            bool inBoard(Tile t); // Check if there is a piece at a given position (t)

            std::vector<Tile> getPiecesPositions(); // Get all the pieces positions

            bool inEnpassant(Tile t); // Check if a piece at a given position (t) is eligible for enpassant (it's first move and it has moved by two tiles)

            void movePiece(Tile pos1, Tile pos2); // Move a piece at a give position (pos1) to a new position (pos2)

            std::string toFen(); // Return the fen equivalent of the current board

            short getCurrentPlayer(); // Get the color of whoever has the right to move

        
    };

std::vector<Tile> generateLegalMoves(Chess::Board& board, Tile pos) {
        std::vector<Tile> moves;

        short pieceColor = board._board[pos.first][pos.second].color;
        short pieceType = board._board[pos.first][pos.second].type;
        if (pieceColor == -1) return std::vector<Tile>();

        switch(pieceType) {
            case PAWN:
            return Chess::pawnMoves(board, pos);
            case KNIGHT:
            return Chess::knightMoves(board, pos);
            case ROOK:
            return Chess::rookMoves(board, pos);
            case BISHOP:
            return Chess::bishopMoves(board, pos);
            case QUEEN:
            return Chess::queenMoves(board, pos);
            case KING:
            return Chess::kingMoves(board, pos);
            default:
            return std::vector<Tile>();
        }

        
        return std::vector<Tile>();
    }

棋子

int moveGenTest(Chess::Board& board, int depth, short color)
{
    if (depth == 0) {
        return 1;
    }

    int numPos = 0;
    depth -= 1;
    for (uint8_t i = 0; i < 8; i++) {
        for (uint8_t g = 0; g < 8; g++) {
            if (board._board[i][g].color == color) {
                for (Tile move : Chess::generateLegalMoves(board, Tile(i, g))) {
                    board.movePiece(Tile(i, g), move);
                    numPos += moveGenTest(board, depth, !color);
                    board.movePiece(move, Tile(i, g));
                }
                
            }
        }
    }

    return numPos;
}

#include <iostream>
#include "Chess.h"
#include "TestUnit.h"

int main(int argc, char* argv[]) {

    Chess::Board board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq");

    std::cout << moveGenTest(board, 5, WHITE);
  
    return 0;
}

代码

5171 // depth 5 - should be around 4 million
5795 // depth 6 - should be around 119 million

I have made a c++ class to represent a board and i have noticed that if i call a recursive function that has as an argument the reference to a board object, it stops after a while resulting in approx 5000-6000 calls to end condition, even with a depth of 10+

Here is the code of the recurse function, the board, and the output:

Chess.h:


#include <string>
#include <vector>
#include <stdexcept>
#include <iostream>
#include <map>
#include <algorithm>
#include <bitset>
#include <iostream>
#include <array>

#include "Utils.h"

#define KING 0
#define QUEEN 1
#define BISHOP 2
#define KNIGHT 3
#define ROOK 4
#define PAWN 5

#define WHITE 0
#define BLACK 1

typedef std::pair<short, short> Tile;

namespace Chess {

    class Piece {

        public:
            short color;
            short type;

            Piece();

            Piece(char fenChr);

            Piece(short pType, short pColor);

    };

    class Board {
        private:
            std::vector<Tile> enpassant;
            bool whiteKingsidecastle = false;
            bool whiteQueensidecastle = false;
            bool blackKingsidecastle = false;
            bool blackQueensidecastle = false;
            short currentPlayer = 0;
            

        public:
            std::array<std::array<Piece, 8>, 8> _board;

            Board(std::string fenStr); // Construct a board object given a fen board

            bool inBoard(Tile t); // Check if there is a piece at a given position (t)

            std::vector<Tile> getPiecesPositions(); // Get all the pieces positions

            bool inEnpassant(Tile t); // Check if a piece at a given position (t) is eligible for enpassant (it's first move and it has moved by two tiles)

            void movePiece(Tile pos1, Tile pos2); // Move a piece at a give position (pos1) to a new position (pos2)

            std::string toFen(); // Return the fen equivalent of the current board

            short getCurrentPlayer(); // Get the color of whoever has the right to move

        
    };

std::vector<Tile> generateLegalMoves(Chess::Board& board, Tile pos) {
        std::vector<Tile> moves;

        short pieceColor = board._board[pos.first][pos.second].color;
        short pieceType = board._board[pos.first][pos.second].type;
        if (pieceColor == -1) return std::vector<Tile>();

        switch(pieceType) {
            case PAWN:
            return Chess::pawnMoves(board, pos);
            case KNIGHT:
            return Chess::knightMoves(board, pos);
            case ROOK:
            return Chess::rookMoves(board, pos);
            case BISHOP:
            return Chess::bishopMoves(board, pos);
            case QUEEN:
            return Chess::queenMoves(board, pos);
            case KING:
            return Chess::kingMoves(board, pos);
            default:
            return std::vector<Tile>();
        }

        
        return std::vector<Tile>();
    }

Here is the code of the recursive function:

TestUnit.cpp:

int moveGenTest(Chess::Board& board, int depth, short color)
{
    if (depth == 0) {
        return 1;
    }

    int numPos = 0;
    depth -= 1;
    for (uint8_t i = 0; i < 8; i++) {
        for (uint8_t g = 0; g < 8; g++) {
            if (board._board[i][g].color == color) {
                for (Tile move : Chess::generateLegalMoves(board, Tile(i, g))) {
                    board.movePiece(Tile(i, g), move);
                    numPos += moveGenTest(board, depth, !color);
                    board.movePiece(move, Tile(i, g));
                }
                
            }
        }
    }

    return numPos;
}

main.cpp:

#include <iostream>
#include "Chess.h"
#include "TestUnit.h"

int main(int argc, char* argv[]) {

    Chess::Board board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq");

    std::cout << moveGenTest(board, 5, WHITE);
  
    return 0;
}

output:

5171 // depth 5 - should be around 4 million
5795 // depth 6 - should be around 119 million

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文