我正在写国际象棋程序,我有一个名为Pieces
的抽象类。我通过使用指针在我的主类中使用这个抽象类,如:Pieces * newset = currentboard[][];
如果我在这个棋盘上移动,那么移动实际上就是这样。我想分析电路板的当前状态,从而创建电路板的副本。我怎么做?
我的Piece
课程样本以及我正在做的事情如下。
class Piece
{
public:
Piece(char cColor) : mcColor(cColor) {}
~Piece() {}
virtual char GetPiece() = 0;
virtual int GetValue() = 0;
virtual int GetPieceActionValue() = 0;
char GetColor() {
return mcColor;
}
bool IsLegalMove(int CurrentRow, int CurrentCol, int DestRow, int DestCol, Piece* NewBoard[8][8]) {
Piece* qpDest = NewBoard[DestRow][DestCol];
if ((qpDest == 0) || (mcColor != qpDest->GetColor())) {
return LegalSquares(CurrentRow, CurrentCol, DestRow, DestCol, NewBoard);
}
return false;
}
private:
virtual bool LegalSquares(int CurrentRow, int CurrentCol, int DestRow, int DestCol, Piece* NewBoard[8][8]) = 0;
char mcColor;
};
以下是派生类的示例:
class Bishop
{
public:
Bishop(char cColor) : Piece(cColor) {}
~Bishop() {}
private:
virtual char GetPiece() {
return 'B';
}
virtual int GetValue() {
return 325;
}
virtual int GetPieceActionValue() {
return 3;
}
bool LegalSquares(int CurrentRow, int CurrentCol, int DestRow, int DestCol, Piece* NewBoard[8][8]) {
if ((DestCol - CurrentCol == DestRow - CurrentRow) || (DestCol - CurrentCol == CurrentRow - DestRow)) {
// Make sure that all invervening squares are empty
int iRowOffset = (DestRow - CurrentRow > 0) ? 1 : -1;
int iColOffset = (DestCol - CurrentCol > 0) ? 1 : -1;
int iCheckRow;
int iCheckCol;
for (iCheckRow = CurrentRow + iRowOffset, iCheckCol = CurrentCol + iColOffset;
iCheckRow != DestRow;
iCheckRow = iCheckRow + iRowOffset, iCheckCol = iCheckCol + iColOffset)
{
if (NewBoard[iCheckRow][iCheckCol] != 0) {
return false;
}
}
return true;
}
return false;
}
};
使用班级进行移动:
if (qpCurrPiece->IsLegalMove(StartRow, StartCol, EndRow, EndCol, NewBoard)) {
// Make the move
Piece* qpTemp = NewBoard[EndRow][EndCol];
NewBoard[EndRow][EndCol] = NewBoard[StartRow][StartCol];
NewBoard[StartRow][StartCol] = 0;
// Make sure that the current player is not in check
if (!GameBoard.IsInCheck(mcPlayerTurn)) {
delete qpTemp;
bValidMove = true;
} else {
// Undo the last move
NewBoard[StartRow][StartCol] = NewBoard[EndRow][EndCol];
NewBoard[EndRow][EndCol] = qpTemp;
}
}
我希望能够在不使用指针的情况下引用此类,以便不对板进行永久性更改。
答案 0 :(得分:4)
你需要为每个类提供一个虚拟Clone()函数,对于Bishop看起来像:
Piece * Bishop :: Clone() {
return new Bishop( * this );
}
现在从OldBoard克隆电路板,如:
Board newboard; // assume board is 8x8 matrix of Piece *
for ( int i = 0; i < 8; i++ ) {
for ( int j = 0; j < 8; j++ ) {
newboard[i][j] = OldBoard[i][j]->Clone();
}
}
答案 1 :(得分:2)
你需要一个抽象的方法
Piece *Piece::Duplicate()
然后在子类中实现它,即
class Bishop {
Bishop(const Bishop &b) { ... } // copy constructor
Piece *Duplicate() { Bishop *n = new Bishop(*this); // calls copy constructor
return n; }
}
答案 2 :(得分:1)
或者你可以写一个拷贝构造函数给Bishop类,它反过来实现一个深层拷贝,假设你的currentBoard是Bishop类的一个实例。