Hey everyone, I have a problem in a project of mine and was wondering if anyone could offer any suggestions.

I'll try to explain as best I can what the problem is and if anyone feels they can offer some assistance, I'll send them the source code over a private message.

The problem I have is that I have multiple functions that rely on each other, causing a loop. I can't think of a way of re-writing the functions.

It goes something like this:

Function1 returns a value which it obtains by calling Function2
Function2 returns a value which it obtains by calling Function3
Function3 returns a value which it obtains by calling Function1

This means that whenever Function1 is called, it is called again and again and again and causes a loop.

If anyone is willing to take a look at my source code and offer suggestions, please let me know and I'll send it.

Thank you very much.

I have a better idea. You tell us what problem you're trying to solve, and we'll help you come up with a better algorithm.

[QUOTE=David_Omid;1593002]checking if the king can be taken by an enemy piece[/QUOTE]

... shall not be tested for pins. You need a separate method to test for square exposure (instead of generic CanOtherPieceBeTakenAfterPieceMoving).

[B]> What do you mean by that?[/B]

Consider the position:
W: Ke1, Rg1, Nf2
B: Kg8, Bg3
Is 1. Nd1 valid?. It passes the "geometrical validity" test, but makes possible 1. ... Bxe1 - the white King becomes exposed even though the Bishop is pinned. In your logic however, you …

## All 12 Replies

I have a better idea. You tell us what problem you're trying to solve, and we'll help you come up with a better algorithm.

commented: + +17

If you want someone to look at your source code, why not post it in your topic to begin with?
It's why they invented the code-tag.

Here's the code. Sorry it's so much to look through but the big problem involves functions like these:

IsValidMove calling CanOtherPieceBeTakenAfterPieceMoving
CanOtherPieceBeTakenAfterPieceMoving then calling CanPieceBeTakenByEnemy
CanPieceBeTakenByEnemy then calling IsValidMove

There's also I think the same situation sometimes occurring with:

IsValidMove calling IsValidMoveForKing
IsValidMoveForKing calling CanSquareBeTakenByEnemyOfPiece
CanSquareBeTakenByEnemyOfPiece calling IsValidMove

Again, thank you very much to anyone who offers help

``````bool IsValidMoveForPawn(int OriginSquareID, int DestinationSquareID)
{
int PieceID = GetPieceOccupyingSquare(OriginSquareID);
int PieceType = GetPieceType(PieceID);
int PieceColour = GetPieceColour(PieceID);
int X1 = GetSquareXCoord(OriginSquareID);
int Y1 = GetSquareYCoord(OriginSquareID);
int X2 = GetSquareXCoord(DestinationSquareID);
int Y2 = GetSquareYCoord(DestinationSquareID);
int XDifference = (X2 - X1);
int YDifference = (Y2 - Y1);
//EnPassantInProgress = 0;
/*ToggleCurrentPlayer();
EnPassantPossible[CurrentPlayer] = 0;
ToggleCurrentPlayer();*/
EnPassantCurrentlyPossible[OriginSquareID][DestinationSquareID] = 0;

if(YDifference < 0)
{
if(PieceColour == 1)return false;
}
if(YDifference > 0)
{
if(PieceColour == 2)return false;
}
if(PieceColour == 1)
{
if(Y1 == 2 && Y2 == 4)
{
if(IsSquareOccupiedByEnemyOfPlayer(GetSquareIDFromCoords((X1-1),Y2),GetPlayerUsingPieceColour(1)) || IsSquareOccupiedByEnemyOfPlayer(GetSquareIDFromCoords((X1+1),Y2),GetPlayerUsingPieceColour(1)))
{
int	EnemyPawnID = -1;
EnemyPawnID = GetPieceOccupyingSquare(GetSquareIDFromCoords((X1-1),Y2));
if(EnemyPawnID == -1)EnemyPawnID = GetPieceOccupyingSquare(GetSquareIDFromCoords((X1+1),Y2));
if(GetPieceType(EnemyPawnID) != 1) EnemyPawnID = GetPieceOccupyingSquare(GetSquareIDFromCoords((X1+1),Y2));
if(GetPieceType(EnemyPawnID) == 1)
{
EnPassantTargetPieceID = PieceID;
ToggleCurrentPlayer();
EnPassantPossible[CurrentPlayer] = 1;
ToggleCurrentPlayer();
//this->SquareID[OriginSquareID]->BackColor = System::Drawing::Color::Yellow; //Test purposes only
}
}
}
}
if(PieceColour == 2)
{
if(Y1 == 7 && Y2 == 5)
{
if(IsSquareOccupiedByEnemyOfPlayer(GetSquareIDFromCoords((X1-1),Y2),GetPlayerUsingPieceColour(2)) || IsSquareOccupiedByEnemyOfPlayer(GetSquareIDFromCoords((X1+1),Y2),GetPlayerUsingPieceColour(2)))
{
int	EnemyPawnID = -1;
EnemyPawnID = GetPieceOccupyingSquare(GetSquareIDFromCoords((X1-1),Y2));
if(EnemyPawnID == -1)EnemyPawnID = GetPieceOccupyingSquare(GetSquareIDFromCoords((X1+1),Y2));
if(GetPieceType(EnemyPawnID) != 0) EnemyPawnID = GetPieceOccupyingSquare(GetSquareIDFromCoords((X1+1),Y2));
if(GetPieceType(EnemyPawnID) == 0)
{
EnPassantTargetPieceID = PieceID;
ToggleCurrentPlayer();
EnPassantPossible[CurrentPlayer] = 1;
ToggleCurrentPlayer();
//this->SquareID[OriginSquareID]->BackColor = System::Drawing::Color::Yellow; //Test purposes only
}
}
}
}
if(XDifference != 0)
{
if(YDifference == 0) return false;
if(YDifference > 1 || YDifference < -1) return false;
if(XDifference > 1 || XDifference < -1) return false;
if(EnPassantPossible[CurrentPlayer] == 1)
{
if(EnPassantTargetPieceID != -1)
{
if(Y1 == PieceYCoord[EnPassantTargetPieceID])
{
if(X2 == PieceXCoord[EnPassantTargetPieceID])
{
if(GetPieceColour(PieceID) == 1 && GetPieceColour(EnPassantTargetPieceID) == 2)
{
if(YDifference == 1)
{
EnPassantCurrentlyPossible[OriginSquareID][DestinationSquareID] = 1;
return true;
}
}
if(GetPieceColour(PieceID) == 2 && GetPieceColour(EnPassantTargetPieceID) == 1)
{
if(YDifference == -1)
{
EnPassantCurrentlyPossible[OriginSquareID][DestinationSquareID] = 1;
return true;
}
}
}
}
}
}
if(!IsSquareOccupiedByEnemyOfPiece(PieceID,DestinationSquareID)) return false;
}
if(XDifference == 0)
{
if(IsSquareOccupiedByEnemyOfPiece(PieceID,DestinationSquareID)) return false;
}
if(YDifference > 2 || YDifference < -2) return false;
if(YDifference == 2 || YDifference == -2)
{
if(!IsPieceInStartPosition(PieceID)) return false;
if(HasPieceMovedSinceStart(PieceID)) return false;
if(YDifference == 2)
{
if(IsSquareOccupied(GetSquareIDFromCoords(X1,(Y1+1)))) return false;
}
if(YDifference == -2)
{
if(IsSquareOccupied(GetSquareIDFromCoords(X1,(Y1-1)))) return false;
}
}
return true;
}
bool IsValidMoveForRook(int OriginSquareID, int DestinationSquareID)
{
int PieceID = GetPieceOccupyingSquare(OriginSquareID);
int PieceType = GetPieceType(PieceID);
int PieceColour = GetPieceColour(PieceID);
int X1 = GetSquareXCoord(OriginSquareID);
int Y1 = GetSquareYCoord(OriginSquareID);
int X2 = GetSquareXCoord(DestinationSquareID);
int Y2 = GetSquareYCoord(DestinationSquareID);
int XDifference = (X2 - X1);
int YDifference = (Y2 - Y1);
if(YDifference != 0 && XDifference != 0) return false;
if(XDifference > 0)
{
for(int a=XDifference-1;a>0;a--)
{
if(IsSquareOccupied(GetSquareIDFromCoords((X1+a),Y1))) return false;
}
}
if(XDifference < 0)
{
for(int a=XDifference+1;a<0;a++)
{
if(IsSquareOccupied(GetSquareIDFromCoords((X1+a),Y1))) return false;
}
}
if(YDifference > 0)
{
for(int a=YDifference-1;a>0;a--)
{
if(IsSquareOccupied(GetSquareIDFromCoords(X1,(Y1+a)))) return false;
}
}
if(YDifference < 0)
{
for(int a=YDifference+1;a<0;a++)
{
if(IsSquareOccupied(GetSquareIDFromCoords(X1,(Y1+a)))) return false;
}
}
return true;
}
bool IsValidMoveForKnight(int OriginSquareID, int DestinationSquareID)
{
int PieceID = GetPieceOccupyingSquare(OriginSquareID);
int PieceType = GetPieceType(PieceID);
int PieceColour = GetPieceColour(PieceID);
int X1 = GetSquareXCoord(OriginSquareID);
int Y1 = GetSquareYCoord(OriginSquareID);
int X2 = GetSquareXCoord(DestinationSquareID);
int Y2 = GetSquareYCoord(DestinationSquareID);
int XDifference = (X2 - X1);
int YDifference = (Y2 - Y1);
if(((YDifference != 2) && (YDifference != -2)) && ((XDifference != 2) && (XDifference != -2))) return false;
if(YDifference == 2)
{
if(XDifference != 1 && XDifference != -1) return false;
}
if(YDifference == -2)
{
if(XDifference != 1 && XDifference != -1) return false;
}
if(XDifference == 2)
{
if(YDifference != 1 && YDifference != -1) return false;
}
if(XDifference == -2)
{
if(YDifference != 1 && YDifference != -1) return false;
}
return true;
}
bool IsValidMoveForBishop(int OriginSquareID, int DestinationSquareID)
{
int PieceID = GetPieceOccupyingSquare(OriginSquareID);
int PieceType = GetPieceType(PieceID);
int PieceColour = GetPieceColour(PieceID);
int X1 = GetSquareXCoord(OriginSquareID);
int Y1 = GetSquareYCoord(OriginSquareID);
int X2 = GetSquareXCoord(DestinationSquareID);
int Y2 = GetSquareYCoord(DestinationSquareID);
int XDifference = (X2 - X1);
int YDifference = (Y2 - Y1);
if(XDifference == 0 || YDifference == 0) return false;
if((YDifference != XDifference) && (YDifference != -XDifference)) return false;
if(XDifference == YDifference)
{
if(XDifference > 0)
{
for(int a=XDifference-1;a>0;a--)
{
if(IsSquareOccupied(GetSquareIDFromCoords(X1+a,(Y1+a)))) return false;
}
}
if(XDifference < 0)
{
for(int a=XDifference+1;a<0;a++)
{
if(IsSquareOccupied(GetSquareIDFromCoords(X1+a,(Y1+a)))) return false;
}
}
}
if(XDifference == -YDifference)
{
if(XDifference > 0)
{
for(int a=XDifference-1;a>0;a--)
{
if(IsSquareOccupied(GetSquareIDFromCoords(X1+a,(Y1-a)))) return false;
}
}
if(XDifference < 0)
{
for(int a=XDifference+1;a<0;a++)
{
if(IsSquareOccupied(GetSquareIDFromCoords(X1+a,(Y1-a)))) return false;
}
}
}
return true;
}
bool IsValidMoveForQueen(int OriginSquareID, int DestinationSquareID)
{
if(!IsValidMoveForRook(OriginSquareID,DestinationSquareID) && !IsValidMoveForBishop(OriginSquareID,DestinationSquareID)) return false;
return true;
}
bool IsValidMoveForKing(int OriginSquareID, int DestinationSquareID)
{
CastlingCurrentlyPossible[OriginSquareID][DestinationSquareID] = 0;
//CastlingInProgress = 0;
//CastlingRookID = -1;
//CastlingRookX = -1;
//CastlingRookY = -1;
int PieceID = GetPieceOccupyingSquare(OriginSquareID);
int PieceType = GetPieceType(PieceID);
int PieceColour = GetPieceColour(PieceID);
int X1 = GetSquareXCoord(OriginSquareID);
int Y1 = GetSquareYCoord(OriginSquareID);
int X2 = GetSquareXCoord(DestinationSquareID);
int Y2 = GetSquareYCoord(DestinationSquareID);
int XDifference = (X2 - X1);
int YDifference = (Y2 - Y1);
if(YDifference > 1 || YDifference < -1) return false;
if(XDifference > 2 || XDifference < -2) return false;

if(CanPieceBeTakenByEnemyAfterMoving(PieceID,DestinationSquareID)) return false;

if(XDifference == 2 || XDifference == -2)
{
if(YDifference != 0) return false;
if(HasPieceMovedSinceStart(PieceID)) return false;
if(IsSquareOccupied(GetSquareIDFromCoords(X2,Y2))) return false;
if(XDifference == 2)
{
int PieceID2;
if(PieceColour == 1) PieceID2 = 9;
if(PieceColour == 2) PieceID2 = 25;
if(HasPieceMovedSinceStart(PieceID2)) return false;
if(IsSquareOccupied(GetSquareIDFromCoords((X1+1),Y2))) return false;
if(CanSquareBeOccupiedByEnemyOfPiece(PieceID,GetSquareIDFromCoords((X1+1),Y2))) return false;
if(CanSquareBeOccupiedByEnemyOfPiece(PieceID,GetSquareIDFromCoords((X1+2),Y2))) return false;

//if(CanPieceBeTakenByEnemyAfterMoving(PieceID,GetSquareIDFromCoords((X1+1),Y2))) return false;
//if(CanPieceBeTakenByEnemyAfterMoving(PieceID,GetSquareIDFromCoords((X1+2),Y2))) return false;

CastlingCurrentlyPossible[OriginSquareID][DestinationSquareID] = 1;
//CastlingInProgress = 1;
CastlingRookID = PieceID2;
CastlingRookX = (X1+1);
CastlingRookY = Y2;
return true;
}
if(XDifference == -2)
{
int PieceID2;
if(PieceColour == 1) PieceID2 = 8;
if(PieceColour == 2) PieceID2 = 24;
if(HasPieceMovedSinceStart(PieceID2)) return false;
if(IsSquareOccupied(GetSquareIDFromCoords((X1-1),Y2))) return false;
if(IsSquareOccupied(GetSquareIDFromCoords((X1-2),Y2))) return false;
if(IsSquareOccupied(GetSquareIDFromCoords((X1-3),Y2))) return false;
if(CanSquareBeOccupiedByEnemyOfPiece(PieceID,GetSquareIDFromCoords((X1-1),Y2))) return false;
if(CanSquareBeOccupiedByEnemyOfPiece(PieceID,((X1-2),Y2))) return false;

//if(CanPieceBeTakenByEnemyAfterMoving(PieceID,GetSquareIDFromCoords((X1-1),Y2))) return false;
//if(CanPieceBeTakenByEnemyAfterMoving(PieceID,((X1-2),Y2))) return false;

CastlingCurrentlyPossible[OriginSquareID][DestinationSquareID] = 1;
//CastlingInProgress = 1;
CastlingRookID = PieceID2;
CastlingRookX = (X1-1);
CastlingRookY = Y2;
return true;
}
}
return true;
}

bool CanPieceBeTakenByEnemy(int PieceID)
{
if(!IsValidPieceID(PieceID)) return false;
if(!IsValidSquareID(GetSquarePieceIsOccupying(PieceID))) return false;
//if(CanSquareBeOccupiedByEnemyOfPiece(PieceID,GetSquarePieceIsOccupying(PieceID))) return true;

// The first check is for pieces being taken in the normal way (the enemy piece removes them from their square and occupies their square instead)
for(int PieceID2=0;PieceID2<MAX_PIECES;PieceID2++)
{
if(!IsValidPieceID(PieceID2))continue;
if(!IsValidSquareID(GetSquarePieceIsOccupying(PieceID2))) continue;
if(PieceColour[PieceID2] != PieceColour[PieceID])
{
if(IsValidMove(GetSquarePieceIsOccupying(PieceID2),GetSquarePieceIsOccupying(PieceID))) return true;
}
}

// The next two checks are for pawns taking other pawns via the En Passant move (as the enemy pawn doesn't occupy the target pawn's square after taking it)
if(PieceType[PieceID] == 0)
{
for(int PieceID2=0;PieceID2<MAX_PIECES;PieceID2++)
{
if(!IsValidPieceID(PieceID2)) continue;
if(PieceType[PieceID2] == 1)
{
if(SquareXCoord[GetSquarePieceIsOccupying(PieceID)] != SquareXCoord[GetSquarePieceIsOccupying(PieceID2)])
{
if(SquareYCoord[GetSquarePieceIsOccupying(PieceID)] == SquareYCoord[GetSquarePieceIsOccupying(PieceID2)])
{
if(IsValidMove(GetSquarePieceIsOccupying(PieceID2),GetSquareIDFromCoords(GetSquareXCoord(GetSquarePieceIsOccupying(PieceID)),GetSquareYCoord(GetSquarePieceIsOccupying(PieceID))-1))) return true;
}
}
}
}
}
if(PieceType[PieceID] == 1)
{
for(int PieceID2=0;PieceID2<MAX_PIECES;PieceID2++)
{
if(!IsValidPieceID(PieceID2)) continue;
if(PieceType[PieceID2] == 0)
{
if(SquareXCoord[GetSquarePieceIsOccupying(PieceID)] != SquareXCoord[GetSquarePieceIsOccupying(PieceID2)])
{
if(SquareYCoord[GetSquarePieceIsOccupying(PieceID)] == SquareYCoord[GetSquarePieceIsOccupying(PieceID2)])
{
if(IsValidMove(GetSquarePieceIsOccupying(PieceID2),GetSquareIDFromCoords(GetSquareXCoord(GetSquarePieceIsOccupying(PieceID)),GetSquareYCoord(GetSquarePieceIsOccupying(PieceID))+1))) return true;
}
}
}
}
}
return false;
}

bool CanPieceBeTakenByEnemyAfterMoving(int PieceID, int DestinationSquareID)
{
if(!IsValidSquareID(DestinationSquareID)) return false;
if(!IsValidPieceID(PieceID)) return false;
int RealSquareOccupant[MAX_SQUARES];
int RealPieceXCoord[MAX_PIECES];
int RealPieceYCoord[MAX_PIECES];
int RealPieceMoved[MAX_PIECES];
int OriginSquareID = GetSquarePieceIsOccupying(PieceID);
int PieceID2 = -1;
if(IsSquareOccupied(DestinationSquareID))
{
PieceID2 = GetPieceOccupyingSquare(DestinationSquareID);
}
for(int SquareID=0;SquareID<MAX_SQUARES;SquareID++)
{
RealSquareOccupant[SquareID] = SquareOccupant[SquareID];
}
for(int PieceID3=0;PieceID3<MAX_PIECES;PieceID3++)
{
RealPieceXCoord[PieceID3] = PieceXCoord[PieceID3];
RealPieceYCoord[PieceID3] = PieceYCoord[PieceID3];
RealPieceMoved[PieceID3] = PieceMoved[PieceID3];
}
SquareOccupant[DestinationSquareID] = PieceID;
PieceXCoord[PieceID] = GetSquareXCoord(DestinationSquareID);
PieceYCoord[PieceID] = GetSquareYCoord(DestinationSquareID);
SquareOccupant[OriginSquareID] = -1;
if(PieceID2 > -1)
{
PieceXCoord[PieceID2] = -1;
PieceYCoord[PieceID2] = -1;
}
if(CanPieceBeTakenByEnemy(PieceID))
{
for(int SquareID=0;SquareID<MAX_SQUARES;SquareID++)
{
SquareOccupant[SquareID] = RealSquareOccupant[SquareID];
}
for(int PieceID3=0;PieceID3<MAX_PIECES;PieceID3++)
{
PieceXCoord[PieceID3] = RealPieceXCoord[PieceID3];
PieceYCoord[PieceID3] = RealPieceYCoord[PieceID3];
PieceMoved[PieceID3] = RealPieceMoved[PieceID3];
}
return true;
}
for(int SquareID=0;SquareID<MAX_SQUARES;SquareID++)
{
SquareOccupant[SquareID] = RealSquareOccupant[SquareID];
}
for(int PieceID3=0;PieceID3<MAX_PIECES;PieceID3++)
{
PieceXCoord[PieceID3] = RealPieceXCoord[PieceID3];
PieceYCoord[PieceID3] = RealPieceYCoord[PieceID3];
PieceMoved[PieceID3] = RealPieceMoved[PieceID3];
}
return false;
}

bool CanSquareBeOccupiedByEnemyOfPiece(int PieceID, int SquareID)
{
if(!IsValidSquareID(SquareID)) return false;
if(!IsValidPieceID(PieceID)) return false;
for(int PieceID2=0;PieceID2<MAX_PIECES;PieceID2++)
{
if(!IsValidPieceID(PieceID2)) continue;
if(!IsValidSquareID(GetSquarePieceIsOccupying(PieceID2))) continue;
if(PieceColour[PieceID] == PieceColour[PieceID2]) continue;
if(IsValidMove(GetSquarePieceIsOccupying(PieceID2),SquareID)) return true;
}
return false;
}

bool CanOtherPieceBeTakenByEnemyAfterPieceMoving(int TargetPieceID, int PieceID, int DestinationSquareID)
{
if(!IsValidSquareID(DestinationSquareID)) return false;
if(!IsValidPieceID(PieceID)) return false;
if(!IsValidPieceID(TargetPieceID)) return false;

if(!IsValidSquareID(GetSquarePieceIsOccupying(PieceID))) return false;
if(!IsValidSquareID(GetSquarePieceIsOccupying(TargetPieceID))) return false;

int RealSquareOccupant[MAX_SQUARES];
int RealPieceXCoord[MAX_PIECES];
int RealPieceYCoord[MAX_PIECES];
int RealPieceMoved[MAX_PIECES];
int OriginSquareID = GetSquarePieceIsOccupying(PieceID);
int PieceID2 = -1;
if(IsSquareOccupied(DestinationSquareID))
{
PieceID2 = GetPieceOccupyingSquare(DestinationSquareID);
}
for(int SquareID=0;SquareID<MAX_SQUARES;SquareID++)
{
RealSquareOccupant[SquareID] = SquareOccupant[SquareID];
}
for(int PieceID3=0;PieceID3<MAX_PIECES;PieceID3++)
{
RealPieceXCoord[PieceID3] = PieceXCoord[PieceID3];
RealPieceYCoord[PieceID3] = PieceYCoord[PieceID3];
RealPieceMoved[PieceID3] = PieceMoved[PieceID3];
}
SquareOccupant[DestinationSquareID] = PieceID;
PieceXCoord[PieceID] = GetSquareXCoord(DestinationSquareID);
PieceYCoord[PieceID] = GetSquareYCoord(DestinationSquareID);
SquareOccupant[OriginSquareID] = -1;
if(IsValidPieceID(PieceID2))
{
PieceXCoord[PieceID2] = -1;
PieceYCoord[PieceID2] = -1;
}
if(CanPieceBeTakenByEnemy(TargetPieceID))
{
for(int SquareID=0;SquareID<MAX_SQUARES;SquareID++)
{
SquareOccupant[SquareID] = RealSquareOccupant[SquareID];
}
for(int PieceID3=0;PieceID3<MAX_PIECES;PieceID3++)
{
PieceXCoord[PieceID3] = RealPieceXCoord[PieceID3];
PieceYCoord[PieceID3] = RealPieceYCoord[PieceID3];
PieceMoved[PieceID3] = RealPieceMoved[PieceID3];
}
return true;
}
for(int SquareID=0;SquareID<MAX_SQUARES;SquareID++)
{
SquareOccupant[SquareID] = RealSquareOccupant[SquareID];
}
for(int PieceID3=0;PieceID3<MAX_PIECES;PieceID3++)
{
PieceXCoord[PieceID3] = RealPieceXCoord[PieceID3];
PieceYCoord[PieceID3] = RealPieceYCoord[PieceID3];
PieceMoved[PieceID3] = RealPieceMoved[PieceID3];
}
return false;
}

bool IsValidMove(int OriginSquareID, int DestinationSquareID)
{
if(!IsValidSquareID(OriginSquareID) || !IsValidSquareID(DestinationSquareID)) return false;
if(OriginSquareID == DestinationSquareID) return false;
if(!IsSquareOccupied(OriginSquareID)) return false;
int PieceID = GetPieceOccupyingSquare(OriginSquareID);
if(IsSquareOccupiedByAllyOfPiece(PieceID,DestinationSquareID)) return false;
int PieceType = GetPieceType(PieceID);
if(PieceType == 0 || PieceType == 1) // Pawn
{
if(!IsValidMoveForPawn(OriginSquareID,DestinationSquareID)) return false;
}
if(PieceType == 2 || PieceType == 3) // Rook
{
if(!IsValidMoveForRook(OriginSquareID,DestinationSquareID)) return false;
}
if(PieceType == 4 || PieceType == 5) // Knight
{
if(!IsValidMoveForKnight(OriginSquareID,DestinationSquareID)) return false;
}
if(PieceType == 6 || PieceType == 7) // Bishop
{
if(!IsValidMoveForBishop(OriginSquareID,DestinationSquareID)) return false;
}
if(PieceType == 8 || PieceType == 9) // Queen
{
if(!IsValidMoveForQueen(OriginSquareID,DestinationSquareID)) return false;
}
if(PieceType == 10 || PieceType == 11) // King
{
if(!IsValidMoveForKing(OriginSquareID,DestinationSquareID)) return false;
}

int TargetPieceID = -1;
//if(PlayerPieceColour[CurrentPlayer] == 1)TargetPieceID = 15; // THIS IS A PROBLEM as the CurrentPlayer variable shouldn't be used here
//if(PlayerPieceColour[CurrentPlayer] == 2)TargetPieceID = 31; // THIS IS A PROBLEM as the CurrentPlayer variable shouldn't be used here
if(PieceColour[PieceID] == 1)TargetPieceID = 15;
if(PieceColour[PieceID] == 2)TargetPieceID = 31;
if(IsValidPieceID(TargetPieceID))
{
if(CanOtherPieceBeTakenByEnemyAfterPieceMoving(TargetPieceID,PieceID,DestinationSquareID)) return false;
}
return true;
}``````

I haven't gone through the code in detail, it is too much. But it looks to me like you are doing an exhaustive search of all possible future move sequences in a chess game. I could hardly expect this to finish running any time soon. It may not be an infinite loop, just a really really long one.

Even if you decided to use this algorithm, you have to use loops, not functions. This kind of indirect recursive function calls will create very deep nesting and you will get a "stack-overflow" error, eventually.

Thanks for the reply. How would I rewrite this into loops instead of functions?

Answering that question would be easier if you could state what it is exactly you're trying to achieve.
Saves us from trying to figure it out through your code.

IsValidMove checks if a certain chess piece on a certain square is able to move to another square on the chess board.

CanOtherPieceBeTakenAfterPieceMoving is used to check if moving the piece will cause the king to be in check, meaning that move for that piece isn't possible (as in chess you can't check yourself). It does this by hypothetically moving the piece to a chosen square and then checking if the king can be taken by an enemy piece.

CanPieceBeTakenByEnemy simply checks if a certain piece can be taken by the opponent.

checking if the king can be taken by an enemy piece

... shall not be tested for pins. You need a separate method to test for square exposure (instead of generic CanOtherPieceBeTakenAfterPieceMoving).

... shall not be tested for pins.

What do you mean by that?

You need a separate method to test for square exposure (instead of generic CanOtherPieceBeTakenAfterPieceMoving).

By testing for square exposure, you mean testing to make sure the king can't be taken? How else can I do this though WITHOUT using IsValidMove or CanPieceBeTakenByEnemy?

> What do you mean by that?

Consider the position:
W: Ke1, Rg1, Nf2
B: Kg8, Bg3
Is 1. Nd1 valid?. It passes the "geometrical validity" test, but makes possible 1. ... Bxe1 - the white King becomes exposed even though the Bishop is pinned. In your logic however, you would try to validate 1. ... Bxe1 all the way.

> How else can I do this though WITHOUT using IsValidMove or CanPieceBeTakenByEnemy?

As I said, IsSquareExposed() method is a way to go. Something along the lines of

``````IsValidMove(from, to)
{
if(!IsPathOk(from, to))
return False();
PretendDoMove(from, to);
if(IsSquareExposed(kingSquare))
return False;
return True;
}

IsSquareExposed(square)
{
for_all_opponent_pieces(p) {
if(IsPathOk(p, square))
return True;
return False;
}``````
commented: This single piece of advice saved me a LOT of time! +2