Why does my code give a segfault whilst I haven't used raw pointers combined with the new keyword?

119 Views Asked by At

I've been working on my own little project for the last few days, and, still being a beginner, I figured it would be a good idea to make a chess game. I've already made some other simple programmes in the past for first-year university assignments, but as I'm studying mathematics, the course didn't really dive in deep. I've rewritten the code several times to make it more legible, and to remove some things others might call "bad habits", such as raw pointers and the like.

I compile my programme using this command: g++ -std=c++20 -Wall -Wextra -Werror -Wpedantic chess.cpp -g -o chess. It compiles perfectly, without any warnings given. I purposely did not separate the file into .cpp and .hpp files, as a lot of my class definitions are dependent upon one another. I've tried doing that for an assignment once, and that was incredibly difficult and even made me change the code. I do realise I could just make a chess.hpp and chess.cpp file, but seeing everything at once, especially now that I'm constantly changing everything to "beautify" it, I find it more useful to have it all in one file.

I know that using raw pointers is generally advised against, and, since I know how they work, I mostly use unique_ptr. Raw pointers I almost never use, and if I do (for simplicity's sake), I do not change them, in order to avoid segmentation errors. But somehow... It still happened. I threw my code into GDB, and it showed me the error was in line 132, called from line 218. I removed line 218, but it returned a segfault message again, except now the issue lay in some header file.

My question is: Can anyone tell me what is wrong with the aforementioned lines? Maybe by compiling it yourself? And, perhaps even more useful: Can anyone give me advice on how to further improve my code (both readability and efficiency)?

Thank you in advance!

Here you can see the code:

#include <string>
#include <cstdio>
#include <array>
#include <vector>
#include <forward_list>
#include <memory>
#include <algorithm>

#define ISINSIDE(x,y) (std::find(x.begin(), x.end(), y) != x.end())

using namespace std;

struct Chesspiece;
class Chessboard;

class Square {
    array < class Square *, 8 > _apNeighbours;
    
    void _setNeighbours (const array < class Square *, 8 > &);
    auto * const & _rcpGetNeighbour (const int &) const;
    
    public:
        unique_ptr < struct Chesspiece > mupChesspiece;
    
        auto * mpFind (const int &, const int &) const;
        
        friend class Chessboard; //friend Chessboard::Chessboard(); // was friend class Chessboard;
};

class Pieces {
    vector < struct Chesspiece * > _vpList;
    array < const struct Chesspiece *, 2 > _apcKing = {nullptr, nullptr};
    
    void _setKing (const int &, const struct Chesspiece * const &);
        
    public:
        const auto * const & mrcpcGetKing (const int &) const;
        const auto & mrcvcpGetList() const;
        void mNewPiece (struct Chesspiece * const &);
        void mDelCaptured();
        void mPossibleMoves();
    
        
        friend class Chessboard; //friend Chessboard::Chessboard(); // was friend class Chessboard;
};

class Chessboard {
    array < class Square, 64 > _aBoard;
    
    auto & _rGetSquare (const int &, const int &);
    
    public:
        class Pieces mPieces;

        Chessboard();
        auto & operator () (const int &, const int &);
        void mGetPlace (char[], const char *);
};

class Continuation {
    vector < class Square * > _vpNextMoves;
    const struct Chesspiece * const _cpcChesspiece;
    
    void _pawn();
    void _knight();
    void _bishop();
    void _rook();
    void _king();
    void _queen();
    
    public:
        Continuation (const struct Chesspiece * const cpcChesspiece) : _cpcChesspiece(cpcChesspiece) {}
        const auto & mrcvcpGetList() const;
        void mClearList();
        void mCalculate (const string &);
};

struct Chesspiece {
    const int mcColour;
    int mMoved = 0;
    class Square * mpSquare;
    class Continuation mContinuation {this};
    const string mcType;
    
    Chesspiece (const int &, class Square * const &, class Pieces * const &, const string &);
    void mPossibleMoves();
};

struct Pawn : Chesspiece {
    Pawn (const int & rcColour, class Square * const & rcpSquare, class Pieces * const & rcpPieces) : Chesspiece (rcColour, rcpSquare, rcpPieces, "pawn") {}
};

struct Knight : Chesspiece {
    Knight (const int & rcColour, class Square * const & rcpSquare, class Pieces * const & rcpPieces) : Chesspiece (rcColour, rcpSquare, rcpPieces, "knight") {}
};

struct Bishop : Chesspiece {
    Bishop (const int & rcColour, class Square * const & rcpSquare, class Pieces * const & rcpPieces) : Chesspiece (rcColour, rcpSquare, rcpPieces, "bishop") {}
};

struct Rook : Chesspiece {
    Rook (const int & rcColour, class Square * const & rcpSquare, class Pieces * const & rcpPieces) : Chesspiece (rcColour, rcpSquare, rcpPieces, "rook") {}
};

struct King : Chesspiece {
    King (const int & rcColour, class Square * const & rcpSquare, class Pieces * const & rcpPieces) : Chesspiece (rcColour, rcpSquare, rcpPieces, "king") {}
};

struct Queen : Chesspiece {
    Queen (const int & rcColour, class Square * const & rcpSquare, class Pieces * const & rcpPieces) : Chesspiece (rcColour, rcpSquare, rcpPieces, "queen") {}
};

class GameOfChess {
    mutable class Chessboard _chessboard; // mutable for constant _print() function
    forward_list < pair < pair < class Square * const, class Square * const >, unique_ptr < struct Chesspiece > > > _flMoves;
    int _player = 1;
    int _moves = 0;
    
    void _print() const;
    bool _inCheck (const int &) const;
    bool _finished();
    bool _move (class Square * const, class Square * const);
    void _undo();
    void _changePlayer();
    void _makeMove();
    
    public:
        void mMatch();
};

void Square::_setNeighbours (const array < class Square *, 8 > & rcapNeighbours) {
    _apNeighbours = rcapNeighbours;
}

auto * const & Square::_rcpGetNeighbour (const int & rcNeighbour) const {
    return _apNeighbours[rcNeighbour];
}

auto * Square::mpFind (const int & I, const int & J) const {
    auto * pSquare = (class Square *) this;

    if (I >= 0)
        for (int i = 0; pSquare && i < I; ++i)
            pSquare = pSquare->_rcpGetNeighbour(4);
    else
        for (int i = 0; pSquare && i > I; --i)
            pSquare = pSquare->_rcpGetNeighbour(0);

    if (J >= 0)
        for (int j = 0; pSquare && j < J; ++j)
            pSquare = pSquare->_rcpGetNeighbour(6);
    else
        for (int j = 0; pSquare && j > J; --j)
            pSquare = pSquare->_rcpGetNeighbour(2);

    return pSquare;
}

void Pieces::_setKing (const int & rcColour, const struct Chesspiece * const & rcpcKing) {
    _apcKing[rcColour-1] = rcpcKing;
}

const auto * const & Pieces::mrcpcGetKing (const int & rcColour) const {
    return _apcKing[rcColour-1];
}

const auto & Pieces::mrcvcpGetList() const {
    return _vpList;
}

void Pieces::mNewPiece (struct Chesspiece * const & rcpChesspiece) {
    _vpList.push_back(rcpChesspiece);
}

void Pieces::mDelCaptured() {
    for (auto it = _vpList.begin();; ++it) {
        if (!(*it)->mpSquare) {
            _vpList.erase(it);
            break;
        }
    }
}

void Pieces::mPossibleMoves() {
    for (auto * const & rcpChesspiece : _vpList)
        rcpChesspiece->mPossibleMoves();
}

auto & Chessboard::_rGetSquare (const int & I, const int & J) {
    return _aBoard[I + 8 * J];
}

Chessboard::Chessboard() {
    for (int i = 0; i < 8; ++i)
        for (int j = 0; j < 8; ++j) {
            auto & rCurrent = _rGetSquare(i, j);
            array < class Square *, 8 > apNeighbours;
            
            apNeighbours[0] = (i-1 >= 0 ? & _rGetSquare(i-1, j) : nullptr);
            apNeighbours[1] = (i-1 >= 0 && j-1 >= 0 ? & _rGetSquare(i-1, j-1) : nullptr);
            apNeighbours[2] = (j-1 >= 0 ? & _rGetSquare(i, j-1) : nullptr);
            apNeighbours[3] = (i+1 < 8 && j-1 >= 0 ? & _rGetSquare(i+1, j-1) : nullptr);
            apNeighbours[4] = (i+1 < 8 ? & _rGetSquare(i+1, j) : nullptr);
            apNeighbours[5] = (i+1 < 8 && j+1 < 8 ? & _rGetSquare(i+1, j+1) : nullptr);
            apNeighbours[6] = (j+1 < 8 ? & _rGetSquare(i, j+1) : nullptr);
            apNeighbours[7] = (i-1 >= 0 && j+1 < 8 ? & _rGetSquare(i-1, j+1) : nullptr);
            
            rCurrent._setNeighbours(apNeighbours);
        }
        
    _rGetSquare(0, 0).mupChesspiece = make_unique < struct Rook > (2, & _rGetSquare(0, 0), & mPieces); _rGetSquare(0, 1).mupChesspiece = make_unique < struct Knight > (2, & _rGetSquare(0, 1), & mPieces); _rGetSquare(0, 2).mupChesspiece = make_unique < struct Bishop > (2, & _rGetSquare(0, 2), & mPieces); _rGetSquare(0, 3).mupChesspiece = make_unique < struct Queen > (2, & _rGetSquare(0, 3), & mPieces); _rGetSquare(0, 4).mupChesspiece = make_unique < struct King > (2, & _rGetSquare(0, 4), & mPieces); _rGetSquare(0, 5).mupChesspiece = make_unique < struct Bishop > (2, & _rGetSquare(0, 5), & mPieces); _rGetSquare(0, 6).mupChesspiece = make_unique < struct Knight > (2, & _rGetSquare(0, 6), & mPieces); _rGetSquare(0, 7).mupChesspiece = make_unique < struct Rook > (2, & _rGetSquare(0, 7), & mPieces);
    _rGetSquare(1, 0).mupChesspiece = make_unique < struct Pawn > (2, & _rGetSquare(1, 0), & mPieces); _rGetSquare(1, 1).mupChesspiece = make_unique < struct Pawn > (2, & _rGetSquare(1, 1), & mPieces); _rGetSquare(1, 2).mupChesspiece = make_unique < struct Pawn > (2, & _rGetSquare(1, 2), & mPieces); _rGetSquare(1, 3).mupChesspiece = make_unique < struct Pawn > (2, & _rGetSquare(1, 3), & mPieces); _rGetSquare(1, 4).mupChesspiece = make_unique < struct Pawn > (2, & _rGetSquare(1, 4), & mPieces); _rGetSquare(1, 5).mupChesspiece = make_unique < struct Pawn > (2, & _rGetSquare(1, 5), & mPieces); _rGetSquare(1, 6).mupChesspiece = make_unique < struct Pawn > (2, & _rGetSquare(1, 6), & mPieces); _rGetSquare(1, 7).mupChesspiece = make_unique < struct Pawn > (2, & _rGetSquare(1, 7), & mPieces);
    _rGetSquare(6, 0).mupChesspiece = make_unique < struct Pawn > (1, & _rGetSquare(6, 0), & mPieces); _rGetSquare(6, 1).mupChesspiece = make_unique < struct Pawn > (1, & _rGetSquare(6, 1), & mPieces); _rGetSquare(6, 2).mupChesspiece = make_unique < struct Pawn > (1, & _rGetSquare(6, 2), & mPieces); _rGetSquare(6, 3).mupChesspiece = make_unique < struct Pawn > (1, & _rGetSquare(6, 3), & mPieces); _rGetSquare(6, 4).mupChesspiece = make_unique < struct Pawn > (1, & _rGetSquare(6, 4), & mPieces); _rGetSquare(6, 5).mupChesspiece = make_unique < struct Pawn > (1, & _rGetSquare(6, 5), & mPieces); _rGetSquare(6, 6).mupChesspiece = make_unique < struct Pawn > (1, & _rGetSquare(6, 6), & mPieces); _rGetSquare(6, 7).mupChesspiece = make_unique < struct Pawn > (1, & _rGetSquare(6, 7), & mPieces);
    _rGetSquare(7, 0).mupChesspiece = make_unique < struct Rook > (1, & _rGetSquare(7, 0), & mPieces); _rGetSquare(7, 1).mupChesspiece = make_unique < struct Knight > (1, & _rGetSquare(7, 1), & mPieces); _rGetSquare(7, 2).mupChesspiece = make_unique < struct Bishop > (1, & _rGetSquare(7, 2), & mPieces); _rGetSquare(7, 3).mupChesspiece = make_unique < struct Queen > (1, & _rGetSquare(7, 3), & mPieces); _rGetSquare(7, 4).mupChesspiece = make_unique < struct King > (1, & _rGetSquare(7, 4), & mPieces); _rGetSquare(7, 5).mupChesspiece = make_unique < struct Bishop > (1, & _rGetSquare(7, 5), & mPieces); _rGetSquare(7, 6).mupChesspiece = make_unique < struct Knight > (1, & _rGetSquare(7, 6), & mPieces); _rGetSquare(7, 7).mupChesspiece = make_unique < struct Rook > (1, & _rGetSquare(7, 7), & mPieces);
    
    mPieces._setKing(1, _rGetSquare(7, 4).mupChesspiece.get());
    mPieces._setKing(2, _rGetSquare(0, 4).mupChesspiece.get());
    
    mPieces.mPossibleMoves();
}

auto & Chessboard::operator () (const int & I, const int & J) {
    return _rGetSquare(I, J);
}

void Chessboard::mGetPlace (char aSquare[], const char * pcPrint) {
    printf("\nPlease enter the %s coordinates here: ", pcPrint);
    scanf("%s", aSquare);
    
    struct {
        bool operator () (const char aSquare[]) {
            return (aSquare[1]-'1' >= 0 && aSquare[1]-'1' < 8 && aSquare[0]-'A' >= 0 && aSquare[0]-'A' < 8);
        }
    } exists;
    
    if (!exists(aSquare)) {
        printf("\nOops, that place doesn't exist! Please try again!\n");
        mGetPlace(aSquare, pcPrint);
        return;
    }
}

void Continuation::_pawn() {
    class Square * pSquare;

    if (_cpcChesspiece->mcColour == 1) {
        pSquare = _cpcChesspiece->mpSquare->mpFind(-1,0);
        if (pSquare && !pSquare->mupChesspiece)
            _vpNextMoves.push_back(pSquare);
        pSquare = _cpcChesspiece->mpSquare->mpFind(-1,-1);
        if (pSquare && !!pSquare->mupChesspiece && pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour)
            _vpNextMoves.push_back(pSquare);
        pSquare = _cpcChesspiece->mpSquare->mpFind(-1,1);
        if (pSquare && !!pSquare->mupChesspiece && pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour)
            _vpNextMoves.push_back(pSquare);
    
        if (!_cpcChesspiece->mMoved) {
            pSquare = _cpcChesspiece->mpSquare->mpFind(-2,0);
            if (pSquare && !pSquare->mupChesspiece)
                _vpNextMoves.push_back(pSquare);
        }
    
    } else {
        pSquare = _cpcChesspiece->mpSquare->mpFind(1,0);
        if (pSquare && !pSquare->mupChesspiece)
            _vpNextMoves.push_back(pSquare);
        pSquare = _cpcChesspiece->mpSquare->mpFind(1,-1);
        if (pSquare && !!pSquare->mupChesspiece && pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour)
            _vpNextMoves.push_back(pSquare);
        pSquare = _cpcChesspiece->mpSquare->mpFind(1,1);
        if (pSquare && !!pSquare->mupChesspiece && pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour)
            _vpNextMoves.push_back(pSquare);
    
        if (!_cpcChesspiece->mMoved) {
            pSquare = _cpcChesspiece->mpSquare->mpFind(2,0);
            if (pSquare && !pSquare->mupChesspiece)
                _vpNextMoves.push_back(pSquare);
        }
    }
}

void Continuation::_knight() {
    class Square * pSquare;

    pSquare = _cpcChesspiece->mpSquare->mpFind(-2,1);
    if (pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true))
        _vpNextMoves.push_back(pSquare);

    pSquare = _cpcChesspiece->mpSquare->mpFind(-2,-1);
    if (pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true))
        _vpNextMoves.push_back(pSquare);

    pSquare = _cpcChesspiece->mpSquare->mpFind(-1,2);
    if (pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true))
        _vpNextMoves.push_back(pSquare);

    pSquare = _cpcChesspiece->mpSquare->mpFind(-1,-2);
    if (pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true))
        _vpNextMoves.push_back(pSquare);

    pSquare = _cpcChesspiece->mpSquare->mpFind(1,2);
    if (pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true))
        _vpNextMoves.push_back(pSquare);

    pSquare = _cpcChesspiece->mpSquare->mpFind(1,-2);
    if (pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true))
        _vpNextMoves.push_back(pSquare);

    pSquare = _cpcChesspiece->mpSquare->mpFind(2,1);
    if (pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true))
        _vpNextMoves.push_back(pSquare);

    pSquare = _cpcChesspiece->mpSquare->mpFind(2,-1);
    if (pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true))
        _vpNextMoves.push_back(pSquare);
}

void Continuation::_bishop() {
    for (class Square * pSquare = _cpcChesspiece->mpSquare->mpFind(1,1); pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true); pSquare = pSquare->mpFind(1,1)) {
        _vpNextMoves.push_back(pSquare);
        if (!!pSquare->mupChesspiece) break;
    }
    for (class Square * pSquare = _cpcChesspiece->mpSquare->mpFind(1,-1); pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true); pSquare = pSquare->mpFind(1,-1)) {
        _vpNextMoves.push_back(pSquare);
        if (!!pSquare->mupChesspiece) break;
    }
    for (class Square * pSquare = _cpcChesspiece->mpSquare->mpFind(-1,1); pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true); pSquare = pSquare->mpFind(-1,1)) {
        _vpNextMoves.push_back(pSquare);
        if (!!pSquare->mupChesspiece) break;
    }
    for (class Square * pSquare = _cpcChesspiece->mpSquare->mpFind(-1,-1); pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true); pSquare = pSquare->mpFind(-1,-1)) {
        _vpNextMoves.push_back(pSquare);
        if (!!pSquare->mupChesspiece) break;
    }
}

void Continuation::_rook() {
    for (class Square * pSquare = _cpcChesspiece->mpSquare->mpFind(1,0); pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true); pSquare = pSquare->mpFind(1,0)) {
        _vpNextMoves.push_back(pSquare);
        if (!!pSquare->mupChesspiece) break;
    }
    for (class Square * pSquare = _cpcChesspiece->mpSquare->mpFind(0,1); pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true); pSquare = pSquare->mpFind(0,1)) {
        _vpNextMoves.push_back(pSquare);
        if (!!pSquare->mupChesspiece) break;
    }
    for (class Square * pSquare = _cpcChesspiece->mpSquare->mpFind(-1,0); pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true); pSquare = pSquare->mpFind(-1,0)) {
        _vpNextMoves.push_back(pSquare);
        if (!!pSquare->mupChesspiece) break;
    }
    for (class Square * pSquare = _cpcChesspiece->mpSquare->mpFind(0,-1); pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true); pSquare = pSquare->mpFind(0,-1)) {
        _vpNextMoves.push_back(pSquare);
        if (!!pSquare->mupChesspiece) break;
    }
}

void Continuation::_king() {
    class Square * pSquare;

    pSquare = _cpcChesspiece->mpSquare->mpFind(-1,0);
    if (pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true))
        _vpNextMoves.push_back(pSquare);

    pSquare = _cpcChesspiece->mpSquare->mpFind(1,0);
    if (pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true))
        _vpNextMoves.push_back(pSquare);

    pSquare = _cpcChesspiece->mpSquare->mpFind(0,-1);
    if (pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true))
        _vpNextMoves.push_back(pSquare);

    pSquare = _cpcChesspiece->mpSquare->mpFind(0,1);
    if (pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true))
        _vpNextMoves.push_back(pSquare);

    pSquare = _cpcChesspiece->mpSquare->mpFind(-1,-1);
    if (pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true))
        _vpNextMoves.push_back(pSquare);

    pSquare = _cpcChesspiece->mpSquare->mpFind(-1,1);
    if (pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true))
        _vpNextMoves.push_back(pSquare);

    pSquare = _cpcChesspiece->mpSquare->mpFind(1,-1);
    if (pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true))
        _vpNextMoves.push_back(pSquare);

    pSquare = _cpcChesspiece->mpSquare->mpFind(1,1);
    if (pSquare && (!!pSquare->mupChesspiece ? pSquare->mupChesspiece->mcColour != _cpcChesspiece->mcColour : true))
        _vpNextMoves.push_back(pSquare);
}

void Continuation::_queen() {
    _bishop();
    _rook();
}

const auto & Continuation::mrcvcpGetList() const {
    return _vpNextMoves;
}

void Continuation::mClearList() {
    _vpNextMoves.clear();
}

void Continuation::mCalculate (const string & rcType) {
    mClearList();
    
    if (rcType == "pawn") _pawn();
    else if (rcType == "knight") _knight();
    else if (rcType == "bishop") _bishop();
    else if (rcType == "rook") _rook();
    else if (rcType == "king") _king();
    else if (rcType == "queen") _queen();
}

Chesspiece::Chesspiece (const int & rcColour, class Square * const & rcpSquare, class Pieces * const & rcpPieces, const string & rcType) : mcColour(rcColour), mpSquare(rcpSquare), mcType(rcType) {
    rcpPieces->mNewPiece(this);
}

void Chesspiece::mPossibleMoves() {
    mContinuation.mCalculate(mcType);
}

void GameOfChess::_print() const {
    printf("\n");
    for (int i = 0; i < 8; ++i) {
        for (int j = 0; j < 8; ++j) {
            if (!!(_chessboard(i, j).mupChesspiece)) printf("1 ");
            else printf("0 ");
        }
        printf("\n");
    }
    
    printf("\n");
    for (int i = 0; i < 8; ++i) {
        for (int j = 0; j < 8; ++j) {
            if (!!_chessboard(i, j).mupChesspiece) printf("%zu ", _chessboard(i, j).mupChesspiece->mContinuation.mrcvcpGetList().size());
            else printf("- ");
        }
        printf("\n");
    }
}

bool GameOfChess::_inCheck (const int & rcPlayer) const {
    const auto * const & rcpcKing = _chessboard.mPieces.mrcpcGetKing(rcPlayer);
    for (const auto * const & rcpcChesspiece : _chessboard.mPieces.mrcvcpGetList()) {
        if (rcpcChesspiece->mcColour == rcPlayer) continue;
        if (ISINSIDE(rcpcChesspiece->mContinuation.mrcvcpGetList(), rcpcKing->mpSquare))
            return true;
    }
    return false;
}

bool GameOfChess::_finished() {
    for (const auto * const & rcpcChesspiece : _chessboard.mPieces.mrcvcpGetList()) {
        if (rcpcChesspiece->mcColour != _player) continue;
        for (auto * const & rcpSquare : rcpcChesspiece->mContinuation.mrcvcpGetList()) {
            _move(rcpcChesspiece->mpSquare, rcpSquare);
            if (!_inCheck(_player)) {
                _undo();
                return false;
            }
            _undo();
        }
    }
    
    return true;
}

bool GameOfChess::_move (class Square * const cpNewSquare, class Square * const cpOldSquare) {
    if (!!cpOldSquare->mupChesspiece && cpOldSquare->mupChesspiece->mcColour == _player && ISINSIDE(cpOldSquare->mupChesspiece->mContinuation.mrcvcpGetList(), cpNewSquare)) {
        unique_ptr < struct Chesspiece > upChesspiece;
        
        if (!!cpNewSquare->mupChesspiece) {
            cpNewSquare->mupChesspiece.swap(upChesspiece);
            upChesspiece->mpSquare = nullptr;
            upChesspiece->mContinuation.mClearList();
            
            _chessboard.mPieces.mDelCaptured();
        }
            
        cpOldSquare->mupChesspiece.swap(cpNewSquare->mupChesspiece);
        cpNewSquare->mupChesspiece->mpSquare = cpNewSquare;
        _flMoves.push_front(make_pair(make_pair(cpNewSquare, cpOldSquare), std::move(upChesspiece)));
        
        return true;
    } else {
        printf("\nMove not allowed!\n");
        return false;
    }
}

void GameOfChess::_undo() {
    _flMoves.front().first.first->mupChesspiece.swap(_flMoves.front().first.second->mupChesspiece);
    _flMoves.front().first.second->mupChesspiece->mpSquare = _flMoves.front().first.second;
    
    if (!!_flMoves.front().second) {
        _chessboard.mPieces.mNewPiece(_flMoves.front().second.get());
        _flMoves.front().first.first->mupChesspiece.swap(_flMoves.front().second);
        _flMoves.front().first.first->mupChesspiece->mpSquare = _flMoves.front().first.first;
        _flMoves.front().first.first->mupChesspiece->mPossibleMoves();
    }
    
    _flMoves.pop_front();
}

void GameOfChess::_changePlayer() {
    _player = (_player == 1 ? 2 : 1);
}

void GameOfChess::_makeMove() {
    char aOld[3];
    _chessboard.mGetPlace(aOld, "old");
    
    char aNew[3];
    _chessboard.mGetPlace(aNew, "new");
    
    if (!_move(& _chessboard(7-aOld[1]+'1', aOld[0]-'A'), & _chessboard(7-aNew[1]+'1', aNew[0]-'A'))) {
        _makeMove();
        return;
    }
    
    _changePlayer();
    
    ++(_moves);
    ++(_chessboard(7-aNew[1]+'1', aNew[0]-'A').mupChesspiece->mMoved);
    
    _chessboard.mPieces.mPossibleMoves();
}

void GameOfChess::mMatch() {
    _print();
    do {
        _makeMove();
        _print();
    }
    while (!_finished());
}

int main() {
    class GameOfChess newGame;
    
    printf("\nHello\n");
    newGame.mMatch();
    
    return 0;
}
0

There are 0 best solutions below