
/***************************************************************************

                                 ChessV

                   COPYRIGHT (C) 2007 BY GREGORY STRONG

This file is part of ChessV.  ChessV is free software; you can redistribute
it and/or modify it under the terms of the GNU General Public License as 
published by the Free Software Foundation; either version 2 of the License, 
or (at your option) any later version.

ChessV is distributed in the hope that it will be useful, but WITHOUT ANY 
WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
more details; the file 'COPYING' contains the License text, but if for
some reason you need a copy, please write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

****************************************************************************/


#include "StdAfx.h"
#include "../../ChessV.h"
#include "../../PieceType.h"
#include "../../Piece.h"
#include "../../Direction.h"
#include "../../Rand.h"
#include "../../GameParameters.h"
#include "LemurianShatranjGame.h"


// *** DEBUG MEMORY ALLOCATION *** //
#ifdef _DEBUG
#define new SAFE_NEW
#endif


BentHero BentHero::bentHero;
BentShaman BentShaman::bentShaman;
SlidingGeneral SlidingGeneral::slidingGeneral;


Game *CreateLemurianShatranjGame( Board &brd, Player &plr0, Player &plr1 )
{
	return new LemurianShatranjGame( brd, plr0, plr1 );
}


LemurianShatranjGame::LemurianShatranjGame( Board &board, Player &whitePlayer, Player &blackPlayer ):
	ChessGame(board, whitePlayer, blackPlayer)
{
}

void LemurianShatranjGame::AddPlayerPieceTypes( char *gameName )
{
	// *** LEMURIAN SHATRANJ *** //
	if( !strcmp( gameName, "Lemurian Shatranj" ) )
	{
		//	add the piece types that each player may have
		board.AddPlayerPieceTypeBothPlayers( WarElephant::warElephant );
		board.AddPlayerPieceTypeBothPlayers( BentHero::bentHero );
		board.AddPlayerPieceTypeBothPlayers( BentShaman::bentShaman );
		board.AddPlayerPieceTypeBothPlayers( SlidingGeneral::slidingGeneral );
		board.AddPlayerPieceTypeBothPlayers( OrthodoxKing::orthodoxKing );
		board.AddPlayerPieceTypeBothPlayers( LamePawn::lamePawn );
		//	add piece type references to the following arrays, 
		//	minorPieceTypes, etc., used for giving bonuses and 
		//	penalties in positional evaluation
		castlingPieceTypes[0] = &NullPieceType64::nullPieceType64;
		castlingPieceTypes[1] = &NullPieceType64::nullPieceType64;
		minorPieceTypes[0][0] = &WarElephant::warElephant;
		minorPieceTypes[1][0] = &WarElephant::warElephant;
		minorPieceTypes[0][1] = &BentHero::bentHero;
		minorPieceTypes[1][1] = &BentHero::bentHero;
		minorPieceTypes[0][2] = &BentShaman::bentShaman;
		minorPieceTypes[1][2] = &BentShaman::bentShaman;
		minorPieceTypes[0][3] = &SlidingGeneral::slidingGeneral;
		minorPieceTypes[1][3] = &SlidingGeneral::slidingGeneral;
		colorboundPieceTypes[0][0] = &BentShaman::bentShaman;
		colorboundPieceTypes[1][0] = &BentShaman::bentShaman;
		colorboundPieceTypes[0][1] = &WarElephant::warElephant;
		colorboundPieceTypes[1][1] = &WarElephant::warElephant;
		queenPieceTypes[0] = &NullPieceType64::nullPieceType64;
		queenPieceTypes[1] = &NullPieceType64::nullPieceType64;
		pawnPieceTypes[0] = &LamePawn::lamePawn;
		pawnPieceTypes[1] = &LamePawn::lamePawn;
		castlingPiecesSlideNorth[0] = false;
		castlingPiecesSlideNorth[1] = false;
	}
}

void LemurianShatranjGame::ChangeRulesByVariant
	( char *gameName,
	  char *&array,
	  char *&book )
{
	// *** LEMURIAN SHATRANJ *** //
	if( !strcmp( gameName, "Lemurian Shatranj" ) )
	{
		//	no castling in Lemurian Shatranj
		castlingType = CASTLING_TYPE_NONE;
		//	no en-Passant
		enPassant = false;
		//	use 'bare king' rule
		bareKingRule = true;
		//	stalemate is a win
		stalemateResult = INFINITY;
		//	change pawn promotion
		LamePawn::lamePawn.SetPromotionType( PromoteByReplacementOrToVariableTypes );
		//	place pieces
		array = "_wehsgksh_we/pppppppp/8/8/8/8/PPPPPPPP/_WEHSGKSH_WE";
		//	set name of opening book
		book = "openings\\LemurianShatranj.txt";
	}
}

void LemurianShatranjGame::InitializationComplete
	( char *gameName )
{
	ChessGame::InitializationComplete( gameName );

	//	initialize special bitboards required for move generation in this game
	InitializeMovementBitboards();
}

bool LemurianShatranjGame::MoveBeingMade
	( MoveInfo &moveInfo,
	  GameRec &gameRecord )
{
	if( moveInfo.type == Replacement || 
		moveInfo.type == CaptureWithReplacement )
	{
		if( moveInfo.pPieceMoved->GetPlayerNumber() == 0 )
		{
			if( (moveInfo.promotion) == &WarElephant::warElephant )
			{
				if( (WarElephant::warElephant.GetPieces( 0 ) & whiteSquares).GetBitCount() > 1 )
					return false;
				if( (WarElephant::warElephant.GetPieces( 0 ) & blackSquares).GetBitCount() > 1 )
					return false;
			}
			else if( (moveInfo.promotion) == &BentShaman::bentShaman )
			{
				if( (BentShaman::bentShaman.GetPieces( 0 ) & whiteSquares).GetBitCount() > 1 )
					return false;
				if( (BentShaman::bentShaman.GetPieces( 0 ) & blackSquares).GetBitCount() > 1 )
					return false;
			}
		}
		else if( moveInfo.pPieceMoved->GetPlayerNumber() == 1 )
		{
			if( (moveInfo.promotion) == &WarElephant::warElephant )
			{
				if( (WarElephant::warElephant.GetPieces( 1 ) & whiteSquares).GetBitCount() > 1 )
					return false;
				if( (WarElephant::warElephant.GetPieces( 1 ) & blackSquares).GetBitCount() > 1 )
					return false;
			}
			else if( (moveInfo.promotion) == &BentShaman::bentShaman )
			{
				if( (BentShaman::bentShaman.GetPieces( 1 ) & whiteSquares).GetBitCount() > 1 )
					return false;
				if( (BentShaman::bentShaman.GetPieces( 1 ) & blackSquares).GetBitCount() > 1 )
					return false;
			}
		}
	}

	return ChessGame::MoveBeingMade( moveInfo, gameRecord );
}

int LemurianShatranjGame::EnumeratePromotions
	( Piece *piece, 
	  int fromSquare,
	  int toSquare,
	  PieceType **promotions,
	  bool quiescentSearch )
{
	int count = 1;

	promotions[0] = &(SlidingGeneral::slidingGeneral);

	return count;
}

int LemurianShatranjGame::EnumeratePromotions
	( Piece *piece, 
	  int fromSquare,
	  int toSquare,
	  Piece **pieces,
	  bool quiescentSearch )
{
	int count = 0;

	bool heroFound = false;
	bool shamanFound = false;
	bool warElephantFound = false;

	for( int x = 0; x < board.GetNumberOfPieces( piece->GetPlayerNumber() ); x++ )
	{
		Piece *currentPiece = board.GetPiece( piece->GetPlayerNumber(), x );
		if( currentPiece->IsCaptured() )
		{
			if( &(currentPiece->GetType()) == &(BentHero::bentHero) && !heroFound )
			{
				heroFound = true;
				pieces[count++] = currentPiece;
			}
			else if( &(currentPiece->GetType()) == &(BentShaman::bentShaman) && !shamanFound )
			{
				shamanFound = true;
				pieces[count++] = currentPiece;
			}
			else if( &(currentPiece->GetType()) == &(WarElephant::warElephant) && !warElephantFound )
			{
				warElephantFound = true;
				pieces[count++] = currentPiece;
			}
		}
	}

	return count;
}

void LemurianShatranjGame::InitializeMovementBitboards()
{
	for( int rank = 0; rank < board.GetNumberOfRanks(); rank++ )
	{
		for( int file = 0; file < board.GetNumberOfFiles(); file++ )
		{
			int square = rank * board.GetNumberOfFiles() + file;
			int newSquare;

			//	initialize bitboards of squares with a possible 
			//	indirect attack by a bent hero
			if( board.GetMovementMatrix( DIRECTION_N )[square] >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_N )[square];
				if( board.GetMovementMatrix( DIRECTION_N )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_N )[newSquare];
					if( board.GetMovementMatrix( DIRECTION_N )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_N )[newSquare2];
						bb64indirectBentHeroAttacks[square].SetBit( newSquare3 );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare2 );
					}
					if( board.GetMovementMatrix( DIRECTION_E )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_E )[newSquare2];
						bb64indirectBentHeroAttacks[square].SetBit( newSquare3 );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare2 );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( board.GetMovementMatrix( DIRECTION_E )[square] );
					}
					if( board.GetMovementMatrix( DIRECTION_W )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_W )[newSquare2];
						bb64indirectBentHeroAttacks[square].SetBit( newSquare3 );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare2 );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( board.GetMovementMatrix( DIRECTION_W )[square] );
					}
				}
				if( board.GetMovementMatrix( DIRECTION_E )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_E )[newSquare];
					if( board.GetMovementMatrix( DIRECTION_E )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_E )[newSquare2];
						bb64indirectBentHeroAttacks[square].SetBit( newSquare3 );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( board.GetMovementMatrix( DIRECTION_S )[newSquare3] );
					}
				}
				if( board.GetMovementMatrix( DIRECTION_W )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_W )[newSquare];
					if( board.GetMovementMatrix( DIRECTION_W )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_W )[newSquare2];
						bb64indirectBentHeroAttacks[square].SetBit( newSquare3 );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( board.GetMovementMatrix( DIRECTION_S )[newSquare3] );
					}
				}
			}
			if( board.GetMovementMatrix( DIRECTION_S )[square] >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_S )[square];
				if( board.GetMovementMatrix( DIRECTION_S )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_S )[newSquare];
					if( board.GetMovementMatrix( DIRECTION_S )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_S )[newSquare2];
						bb64indirectBentHeroAttacks[square].SetBit( newSquare3 );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare2 );
					}
					if( board.GetMovementMatrix( DIRECTION_E )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_E )[newSquare2];
						bb64indirectBentHeroAttacks[square].SetBit( newSquare3 );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare2 );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( board.GetMovementMatrix( DIRECTION_E )[square] );
					}
					if( board.GetMovementMatrix( DIRECTION_W )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_W )[newSquare2];
						bb64indirectBentHeroAttacks[square].SetBit( newSquare3 );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare2 );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( board.GetMovementMatrix( DIRECTION_W )[square] );
					}
				}
				if( board.GetMovementMatrix( DIRECTION_E )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_E )[newSquare];
					if( board.GetMovementMatrix( DIRECTION_E )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_E )[newSquare2];
						bb64indirectBentHeroAttacks[square].SetBit( newSquare3 );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( board.GetMovementMatrix( DIRECTION_N )[newSquare3] );
					}
				}
				if( board.GetMovementMatrix( DIRECTION_W )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_W )[newSquare];
					if( board.GetMovementMatrix( DIRECTION_W )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_W )[newSquare2];
						bb64indirectBentHeroAttacks[square].SetBit( newSquare3 );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( board.GetMovementMatrix( DIRECTION_N )[newSquare3] );
					}
				}
			}
			if( board.GetMovementMatrix( DIRECTION_E )[square] >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_E )[square];
				if( board.GetMovementMatrix( DIRECTION_E )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_E )[newSquare];
					if( board.GetMovementMatrix( DIRECTION_E )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_E )[newSquare2];
						bb64indirectBentHeroAttacks[square].SetBit( newSquare3 );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare2 );
					}
				}
			}
			if( board.GetMovementMatrix( DIRECTION_W )[square] >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_W )[square];
				if( board.GetMovementMatrix( DIRECTION_W )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_W )[newSquare];
					if( board.GetMovementMatrix( DIRECTION_W )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_W )[newSquare2];
						bb64indirectBentHeroAttacks[square].SetBit( newSquare3 );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare );
						bb64indirectBentHeroAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare2 );
					}
				}
			}

			//	initialize bitboards of squares with a possible 
			//	indirect attack by a bent shaman
			if( board.GetMovementMatrix( DIRECTION_NE )[square] >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_NE )[square];
				if( board.GetMovementMatrix( DIRECTION_NE )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_NE )[newSquare];
					if( board.GetMovementMatrix( DIRECTION_NE )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_NE )[newSquare2];
						bb64indirectBentShamanAttacks[square].SetBit( newSquare3 );
						bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare );
						bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare2 );
					}
					if( board.GetMovementMatrix( DIRECTION_NW )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_NW )[newSquare2];
						bb64indirectBentShamanAttacks[square].SetBit( newSquare3 );
						bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare2 );
						if( board.GetMovementMatrix( DIRECTION_NW )[square] >= 0 )
							bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( board.GetMovementMatrix( DIRECTION_NW )[square] );
					}
					if( board.GetMovementMatrix( DIRECTION_SE )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_SE )[newSquare2];
						bb64indirectBentShamanAttacks[square].SetBit( newSquare3 );
						bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare2 );
						if( board.GetMovementMatrix( DIRECTION_SE )[square] >= 0 )
							bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( board.GetMovementMatrix( DIRECTION_SE )[square] );
					}
				}
				if( board.GetMovementMatrix( DIRECTION_NW )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_NW )[newSquare];
					if( board.GetMovementMatrix( DIRECTION_NW )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_NW )[newSquare2];
						bb64indirectBentShamanAttacks[square].SetBit( newSquare3 );
						bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare );
						if( board.GetMovementMatrix( DIRECTION_SW )[newSquare3] >= 0 )
							bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( board.GetMovementMatrix( DIRECTION_SW )[newSquare3] );
					}
				}
				if( board.GetMovementMatrix( DIRECTION_SE )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_SE )[newSquare];
					if( board.GetMovementMatrix( DIRECTION_SE )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_SE )[newSquare2];
						bb64indirectBentShamanAttacks[square].SetBit( newSquare3 );
						bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare );
						if( board.GetMovementMatrix( DIRECTION_SW )[newSquare3] >= 0 )
							bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( board.GetMovementMatrix( DIRECTION_SW )[newSquare3] );
					}
				}
			}
			if( board.GetMovementMatrix( DIRECTION_SW )[square] >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_SW )[square];
				if( board.GetMovementMatrix( DIRECTION_SW )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_SW )[newSquare];
					if( board.GetMovementMatrix( DIRECTION_SW )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_SW )[newSquare2];
						bb64indirectBentShamanAttacks[square].SetBit( newSquare3 );
						bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare );
						bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare2 );
					}
					if( board.GetMovementMatrix( DIRECTION_SE )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_SE )[newSquare2];
						bb64indirectBentShamanAttacks[square].SetBit( newSquare3 );
						bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare2 );
						if( board.GetMovementMatrix( DIRECTION_SE )[square] >= 0 )
							bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( board.GetMovementMatrix( DIRECTION_SE )[square] );
					}
					if( board.GetMovementMatrix( DIRECTION_NW )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_NW )[newSquare2];
						bb64indirectBentShamanAttacks[square].SetBit( newSquare3 );
						bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare2 );
						if( board.GetMovementMatrix( DIRECTION_NW )[square] >= 0 )
							bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( board.GetMovementMatrix( DIRECTION_NW )[square] );
					}
				}
				if( board.GetMovementMatrix( DIRECTION_SE )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_SE )[newSquare];
					if( board.GetMovementMatrix( DIRECTION_SE )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_SE )[newSquare2];
						bb64indirectBentShamanAttacks[square].SetBit( newSquare3 );
						bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare );
						if( board.GetMovementMatrix( DIRECTION_NE )[newSquare3] >= 0 )
							bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( board.GetMovementMatrix( DIRECTION_NE )[newSquare3] );
					}
				}
				if( board.GetMovementMatrix( DIRECTION_NW )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_NW )[newSquare];
					if( board.GetMovementMatrix( DIRECTION_NW )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_NW )[newSquare2];
						bb64indirectBentShamanAttacks[square].SetBit( newSquare3 );
						bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare );
						if( board.GetMovementMatrix( DIRECTION_NE )[newSquare3] >= 0 )
							bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( board.GetMovementMatrix( DIRECTION_NE )[newSquare3] );
					}
				}
			}
			if( board.GetMovementMatrix( DIRECTION_SE )[square] >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_SE )[square];
				if( board.GetMovementMatrix( DIRECTION_SE )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_SE )[newSquare];
					if( board.GetMovementMatrix( DIRECTION_SE )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_SE )[newSquare2];
						bb64indirectBentShamanAttacks[square].SetBit( newSquare3 );
						bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare );
						bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare2 );
					}
				}
			}
			if( board.GetMovementMatrix( DIRECTION_NW )[square] >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_NW )[square];
				if( board.GetMovementMatrix( DIRECTION_NW )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_NW )[newSquare];
					if( board.GetMovementMatrix( DIRECTION_NW )[newSquare2] >= 0 )
					{
						int newSquare3 = board.GetMovementMatrix( DIRECTION_NW )[newSquare2];
						bb64indirectBentShamanAttacks[square].SetBit( newSquare3 );
						bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare );
						bb64indirectBentShamanAttackMustBeFreeSquares[square][newSquare3].SetBit( newSquare2 );
					}
				}
			}

			//	initialize bitboards of squares with a possible 
			//	indirect attack by a sliding general
			if( board.GetMovementMatrix( DIRECTION_N )[square] >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_N )[square];
				if( board.GetMovementMatrix( DIRECTION_N )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_N )[newSquare];
					bb64indirectSlidingGeneralAttacks[square].SetBit( newSquare2 );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( newSquare );
					if( board.GetMovementMatrix( DIRECTION_E )[newSquare] >= 0 )
						bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( board.GetMovementMatrix( DIRECTION_E )[newSquare] );
					if( board.GetMovementMatrix( DIRECTION_W )[newSquare] >= 0 )
						bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( board.GetMovementMatrix( DIRECTION_W )[newSquare] );
				}
				if( board.GetMovementMatrix( DIRECTION_NE )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_NE )[newSquare];
					bb64indirectSlidingGeneralAttacks[square].SetBit( newSquare2 );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( newSquare );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( board.GetMovementMatrix( DIRECTION_E )[newSquare] );
				}
				if( board.GetMovementMatrix( DIRECTION_NW )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_NW )[newSquare];
					bb64indirectSlidingGeneralAttacks[square].SetBit( newSquare2 );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( newSquare );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( board.GetMovementMatrix( DIRECTION_W )[newSquare] );
				}
			}
			if( board.GetMovementMatrix( DIRECTION_E )[square] >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_E )[square];
				if( board.GetMovementMatrix( DIRECTION_E )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_E )[newSquare];
					bb64indirectSlidingGeneralAttacks[square].SetBit( newSquare2 );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( newSquare );
					if( board.GetMovementMatrix( DIRECTION_N )[newSquare] >= 0 )
						bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( board.GetMovementMatrix( DIRECTION_N )[newSquare] );
					if( board.GetMovementMatrix( DIRECTION_S )[newSquare] >= 0 )
						bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( board.GetMovementMatrix( DIRECTION_S )[newSquare] );
				}
				if( board.GetMovementMatrix( DIRECTION_NE )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_NE )[newSquare];
					bb64indirectSlidingGeneralAttacks[square].SetBit( newSquare2 );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( newSquare );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( board.GetMovementMatrix( DIRECTION_N )[newSquare] );
				}
				if( board.GetMovementMatrix( DIRECTION_SE )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_SE )[newSquare];
					bb64indirectSlidingGeneralAttacks[square].SetBit( newSquare2 );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( newSquare );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( board.GetMovementMatrix( DIRECTION_S )[newSquare] );
				}
			}
			if( board.GetMovementMatrix( DIRECTION_S )[square] >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_S )[square];
				if( board.GetMovementMatrix( DIRECTION_S )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_S )[newSquare];
					bb64indirectSlidingGeneralAttacks[square].SetBit( newSquare2 );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( newSquare );
					if( board.GetMovementMatrix( DIRECTION_E )[newSquare] >= 0 )
						bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( board.GetMovementMatrix( DIRECTION_E )[newSquare] );
					if( board.GetMovementMatrix( DIRECTION_W )[newSquare] >= 0 )
						bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( board.GetMovementMatrix( DIRECTION_W )[newSquare] );
				}
				if( board.GetMovementMatrix( DIRECTION_SE )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_SE )[newSquare];
					bb64indirectSlidingGeneralAttacks[square].SetBit( newSquare2 );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( newSquare );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( board.GetMovementMatrix( DIRECTION_E )[newSquare] );
				}
				if( board.GetMovementMatrix( DIRECTION_SW )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_SW )[newSquare];
					bb64indirectSlidingGeneralAttacks[square].SetBit( newSquare2 );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( newSquare );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( board.GetMovementMatrix( DIRECTION_W )[newSquare] );
				}
			}
			if( board.GetMovementMatrix( DIRECTION_W )[square] >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_W )[square];
				if( board.GetMovementMatrix( DIRECTION_W )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_W )[newSquare];
					bb64indirectSlidingGeneralAttacks[square].SetBit( newSquare2 );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( newSquare );
					if( board.GetMovementMatrix( DIRECTION_N )[newSquare] >= 0 )
						bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( board.GetMovementMatrix( DIRECTION_N )[newSquare] );
					if( board.GetMovementMatrix( DIRECTION_S )[newSquare] >= 0 )
						bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( board.GetMovementMatrix( DIRECTION_S )[newSquare] );
				}
				if( board.GetMovementMatrix( DIRECTION_NW )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_NW )[newSquare];
					bb64indirectSlidingGeneralAttacks[square].SetBit( newSquare2 );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( newSquare );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( board.GetMovementMatrix( DIRECTION_N )[newSquare] );
				}
				if( board.GetMovementMatrix( DIRECTION_SW )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_SW )[newSquare];
					bb64indirectSlidingGeneralAttacks[square].SetBit( newSquare2 );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( newSquare );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( board.GetMovementMatrix( DIRECTION_S )[newSquare] );
				}
			}
			if( board.GetMovementMatrix( DIRECTION_NE )[square] >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_NE )[square];
				if( board.GetMovementMatrix( DIRECTION_NE )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_NE )[newSquare];
					bb64indirectSlidingGeneralAttacks[square].SetBit( newSquare2 );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( newSquare );
				}
			}
			if( board.GetMovementMatrix( DIRECTION_NW )[square] >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_NW )[square];
				if( board.GetMovementMatrix( DIRECTION_NW )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_NW )[newSquare];
					bb64indirectSlidingGeneralAttacks[square].SetBit( newSquare2 );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( newSquare );
				}
			}
			if( board.GetMovementMatrix( DIRECTION_SE )[square] >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_SE )[square];
				if( board.GetMovementMatrix( DIRECTION_SE )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_SE )[newSquare];
					bb64indirectSlidingGeneralAttacks[square].SetBit( newSquare2 );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( newSquare );
				}
			}
			if( board.GetMovementMatrix( DIRECTION_SW )[square] >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_SW )[square];
				if( board.GetMovementMatrix( DIRECTION_SW )[newSquare] >= 0 )
				{
					int newSquare2 = board.GetMovementMatrix( DIRECTION_SW )[newSquare];
					bb64indirectSlidingGeneralAttacks[square].SetBit( newSquare2 );
					bb64indirectSlidingGeneralAttackMustBeFreeSquares[square][newSquare2].SetBit( newSquare );
				}
			}

			//	initialize bitboards of wazir moves
			bb64wazirMoves[square].Clear();
			newSquare = board.GetMovementMatrix( DIRECTION_N )[square];
			if( newSquare >= 0 )
				bb64wazirMoves[square].SetBit( newSquare );
			newSquare = board.GetMovementMatrix( DIRECTION_S )[square];
			if( newSquare >= 0 )
				bb64wazirMoves[square].SetBit( newSquare );
			newSquare = board.GetMovementMatrix( DIRECTION_W )[square];
			if( newSquare >= 0 )
				bb64wazirMoves[square].SetBit( newSquare );
			newSquare = board.GetMovementMatrix( DIRECTION_E )[square];
			if( newSquare >= 0 )
				bb64wazirMoves[square].SetBit( newSquare );

			//	initialize bitboards of ferz moves
			bb64ferzMoves[square].Clear();
			newSquare = board.GetMovementMatrix( DIRECTION_NE )[square];
			if( newSquare >= 0 )
				bb64ferzMoves[square].SetBit( newSquare );
			newSquare = board.GetMovementMatrix( DIRECTION_SE )[square];
			if( newSquare >= 0 )
				bb64ferzMoves[square].SetBit( newSquare );
			newSquare = board.GetMovementMatrix( DIRECTION_NW )[square];
			if( newSquare >= 0 )
				bb64ferzMoves[square].SetBit( newSquare );
			newSquare = board.GetMovementMatrix( DIRECTION_SW )[square];
			if( newSquare >= 0 )
				bb64ferzMoves[square].SetBit( newSquare );

			//	initialize bitboards of dababbah moves
			bb64dababbahMoves[square].Clear();
			newSquare = board.GetMovementMatrix( DIRECTION_N )[square];
			if( newSquare >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_N )[newSquare];
				if( newSquare >= 0 )
					bb64dababbahMoves[square].SetBit( newSquare );
			}
			newSquare = board.GetMovementMatrix( DIRECTION_E )[square];
			if( newSquare >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_E )[newSquare];
				if( newSquare >= 0 )
					bb64dababbahMoves[square].SetBit( newSquare );
			}
			newSquare = board.GetMovementMatrix( DIRECTION_S )[square];
			if( newSquare >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_S )[newSquare];
				if( newSquare >= 0 )
					bb64dababbahMoves[square].SetBit( newSquare );
			}
			newSquare = board.GetMovementMatrix( DIRECTION_W )[square];
			if( newSquare >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_W )[newSquare];
				if( newSquare >= 0 )
					bb64dababbahMoves[square].SetBit( newSquare );
			}

			//	initialize bitboards of alfil moves
			bb64alfilMoves[square].Clear();
			newSquare = board.GetMovementMatrix( DIRECTION_NE )[square];
			if( newSquare >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_NE )[newSquare];
				if( newSquare >= 0 )
					bb64alfilMoves[square].SetBit( newSquare );
			}
			newSquare = board.GetMovementMatrix( DIRECTION_NW )[square];
			if( newSquare >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_NW )[newSquare];
				if( newSquare >= 0 )
					bb64alfilMoves[square].SetBit( newSquare );
			}
			newSquare = board.GetMovementMatrix( DIRECTION_SE )[square];
			if( newSquare >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_SE )[newSquare];
				if( newSquare >= 0 )
					bb64alfilMoves[square].SetBit( newSquare );
			}
			newSquare = board.GetMovementMatrix( DIRECTION_SW )[square];
			if( newSquare >= 0 )
			{
				newSquare = board.GetMovementMatrix( DIRECTION_SW )[newSquare];
				if( newSquare >= 0 )
					bb64alfilMoves[square].SetBit( newSquare );
			}

			//	initialize bitboards of wazir+dababbah moves
			bb64wazirDababbahMoves[square] = bb64wazirMoves[square] | bb64dababbahMoves[square];

			//	initialize bitboards of ferz+alfil moves
			bb64ferzAlfilMoves[square] = bb64ferzMoves[square] | bb64alfilMoves[square];

			//	initialize bitboards of ferz+wazir moves
			bb64ferzWazirMoves[square] = bb64ferzMoves[square] | bb64wazirMoves[square];
		}
	}
}

void LemurianShatranjGame::GenerateMovesForPieceByBitboard
	( int startSquare, 
	  BitBoard64 moves,
	  MovementList &list )
{
	while( moves )
	{
		int target = moves.ExtractLSB();
		Piece *pieceToCapture = board.GetSquareContents( target );
		if( pieceToCapture == NULL )
			list.AddMove( startSquare, target );
		else
			list.AddCapture( startSquare, target );
	}
}

void LemurianShatranjGame::GenerateBentHeroMoves
	( int currentPlayer, 
	  MovementList &list, 
	  bool quiescentSearch )
{
	BitBoard64 bentHeroes = BentHero::bentHero.GetPieces( currentPlayer );
	int nextSquare;

	while( bentHeroes )
	{
		int square = bentHeroes.ExtractLSB();

		//	calculate single step and leap moves
		BitBoard64 moveToSquares = bb64wazirDababbahMoves[square];

		//	calculate single step followed by leap moves
		nextSquare = board.GetMovementMatrix( DIRECTION_N )[square];
		if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
			moveToSquares |= bb64dababbahMoves[nextSquare];

		nextSquare = board.GetMovementMatrix( DIRECTION_E )[square];
		if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
			moveToSquares |= bb64dababbahMoves[nextSquare];

		nextSquare = board.GetMovementMatrix( DIRECTION_S )[square];
		if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
			moveToSquares |= bb64dababbahMoves[nextSquare];

		nextSquare = board.GetMovementMatrix( DIRECTION_W )[square];
		if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
			moveToSquares |= bb64dababbahMoves[nextSquare];

		//	calculate leap followed by single step moves
		nextSquare = board.GetMovementMatrix( DIRECTION_N )[square];
		if( nextSquare >= 0 )
		{
			nextSquare = board.GetMovementMatrix( DIRECTION_N )[nextSquare];
			if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
				moveToSquares |= bb64wazirMoves[nextSquare];
		}
		
		nextSquare = board.GetMovementMatrix( DIRECTION_E )[square];
		if( nextSquare >= 0 )
		{
			nextSquare = board.GetMovementMatrix( DIRECTION_E )[nextSquare];
			if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
				moveToSquares |= bb64wazirMoves[nextSquare];
		}
		
		nextSquare = board.GetMovementMatrix( DIRECTION_S )[square];
		if( nextSquare >= 0 )
		{
			nextSquare = board.GetMovementMatrix( DIRECTION_S )[nextSquare];
			if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
				moveToSquares |= bb64wazirMoves[nextSquare];
		}
		
		nextSquare = board.GetMovementMatrix( DIRECTION_W )[square];
		if( nextSquare >= 0 )
		{
			nextSquare = board.GetMovementMatrix( DIRECTION_W )[nextSquare];
			if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
				moveToSquares |= bb64wazirMoves[nextSquare];
		}

		//	can't capture friends or make a null move
		moveToSquares = moveToSquares & ~board.BB64_GetFriends( currentPlayer );

		//	if quiescent search, only consider captures
		if( quiescentSearch )
			moveToSquares = moveToSquares & board.BB64_GetFriends( FLIP(currentPlayer) );

		//	now actually generate the moves
		GenerateMovesForPieceByBitboard( square, moveToSquares, list );
	}
}

void LemurianShatranjGame::GenerateBentShamanMoves
	( int currentPlayer, 
	  MovementList &list,
	  bool quiescentSearch )
{
	BitBoard64 bentShamen = BentShaman::bentShaman.GetPieces( currentPlayer );
	int nextSquare;

	while( bentShamen )
	{
		int square = bentShamen.ExtractLSB();

		//	calculate single step and leap moves
		BitBoard64 moveToSquares = bb64ferzAlfilMoves[square];

		//	calculate single step followed by leap moves
		nextSquare = board.GetMovementMatrix( DIRECTION_NE )[square];
		if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
			moveToSquares |= bb64alfilMoves[nextSquare];

		nextSquare = board.GetMovementMatrix( DIRECTION_SE )[square];
		if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
			moveToSquares |= bb64alfilMoves[nextSquare];

		nextSquare = board.GetMovementMatrix( DIRECTION_NW )[square];
		if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
			moveToSquares |= bb64alfilMoves[nextSquare];

		nextSquare = board.GetMovementMatrix( DIRECTION_SW )[square];
		if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
			moveToSquares |= bb64alfilMoves[nextSquare];

		//	calculate leap followed by single step moves
		nextSquare = board.GetMovementMatrix( DIRECTION_NE )[square];
		if( nextSquare >= 0 )
		{
			nextSquare = board.GetMovementMatrix( DIRECTION_NE )[nextSquare];
			if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
				moveToSquares |= bb64ferzMoves[nextSquare];
		}
		
		nextSquare = board.GetMovementMatrix( DIRECTION_NW )[square];
		if( nextSquare >= 0 )
		{
			nextSquare = board.GetMovementMatrix( DIRECTION_NW )[nextSquare];
			if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
				moveToSquares |= bb64ferzMoves[nextSquare];
		}
		
		nextSquare = board.GetMovementMatrix( DIRECTION_SE )[square];
		if( nextSquare >= 0 )
		{
			nextSquare = board.GetMovementMatrix( DIRECTION_SE )[nextSquare];
			if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
				moveToSquares |= bb64ferzMoves[nextSquare];
		}
		
		nextSquare = board.GetMovementMatrix( DIRECTION_SW )[square];
		if( nextSquare >= 0 )
		{
			nextSquare = board.GetMovementMatrix( DIRECTION_SW )[nextSquare];
			if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
				moveToSquares |= bb64ferzMoves[nextSquare];
		}

		//	can't capture friends or make a null move
		moveToSquares = moveToSquares & ~board.BB64_GetFriends( currentPlayer );

		//	if quiescent search, only consider captures
		if( quiescentSearch )
			moveToSquares = moveToSquares & board.BB64_GetFriends( FLIP(currentPlayer) );

		//	now actually generate the moves
		GenerateMovesForPieceByBitboard( square, moveToSquares, list );
	}
}

void LemurianShatranjGame::GenerateSlidingGeneralMoves
	( int currentPlayer, 
	  MovementList &list,
	  bool quiescentSearch )
{
	BitBoard64 slidingGenerals = SlidingGeneral::slidingGeneral.GetPieces( currentPlayer );
	int nextSquare;

	while( slidingGenerals )
	{
		int square = slidingGenerals.ExtractLSB();

		//	calculate single step moves
		BitBoard64 moveToSquares = bb64ferzWazirMoves[square];

		//	calculate double step moves
		nextSquare = board.GetMovementMatrix( DIRECTION_N )[square];
		if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
			moveToSquares |= bb64ferzWazirMoves[nextSquare];

		nextSquare = board.GetMovementMatrix( DIRECTION_E )[square];
		if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
			moveToSquares |= bb64ferzWazirMoves[nextSquare];

		nextSquare = board.GetMovementMatrix( DIRECTION_S )[square];
		if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
			moveToSquares |= bb64ferzWazirMoves[nextSquare];

		nextSquare = board.GetMovementMatrix( DIRECTION_W )[square];
		if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
			moveToSquares |= bb64ferzWazirMoves[nextSquare];

		nextSquare = board.GetMovementMatrix( DIRECTION_NE )[square];
		if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
			moveToSquares |= bb64ferzWazirMoves[nextSquare];

		nextSquare = board.GetMovementMatrix( DIRECTION_SE )[square];
		if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
			moveToSquares |= bb64ferzWazirMoves[nextSquare];

		nextSquare = board.GetMovementMatrix( DIRECTION_NW )[square];
		if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
			moveToSquares |= bb64ferzWazirMoves[nextSquare];

		nextSquare = board.GetMovementMatrix( DIRECTION_SW )[square];
		if( nextSquare >= 0 && board.GetSquareContents( nextSquare ) == NULL )
			moveToSquares |= bb64ferzWazirMoves[nextSquare];

		//	can't capture friends or make a null move
		moveToSquares = moveToSquares & ~board.BB64_GetFriends( currentPlayer );

		//	if quiescent search, only consider captures
		if( quiescentSearch )
			moveToSquares = moveToSquares & board.BB64_GetFriends( FLIP(currentPlayer) );

		//	now actually generate the moves
		GenerateMovesForPieceByBitboard( square, moveToSquares, list );
	}
}

void LemurianShatranjGame::AddSpecialMoves
	( int currentPlayer, 
	  MovementList &moveList,
	  GameRec &gameRecord,
	  bool quiescentSearch )
{
	GenerateBentHeroMoves( currentPlayer, moveList, quiescentSearch );
	GenerateBentShamanMoves( currentPlayer, moveList, quiescentSearch );
	GenerateSlidingGeneralMoves( currentPlayer, moveList, quiescentSearch );
}

bool LemurianShatranjGame::IsSquareAttacked
	( int squareNumber, 
	  int playerNumber )
{
	//	check for attacks from pawns
	if( LamePawn::lamePawn.GetPieces( playerNumber ) & 
		LamePawn::lamePawn.bb64_attack[FLIP(playerNumber)][squareNumber] )
		return true;

	//	check for direct attacks from war elephant
	if( WarElephant::warElephant.GetPieces( playerNumber ) & 
		WarElephant::warElephant.bb64_attack[FLIP(playerNumber)][squareNumber] )
		return true;

	//	check for direct attacks from bent hero
	if( BentHero::bentHero.GetPieces( playerNumber ) & 
		bb64wazirDababbahMoves[squareNumber] )
		//	square is attacked by bent hero
		return true;

	//	check for indirect attacks from bent hero
	BitBoard64 possibleAttackers = BentHero::bentHero.GetPieces( playerNumber ) & 
		bb64indirectBentHeroAttacks[squareNumber];
	while( possibleAttackers )
	{
		int square = possibleAttackers.ExtractLSB();
		if( bb64indirectBentHeroAttackMustBeFreeSquares[squareNumber][square] & 
			~board.bb64_blocker )
			//  square is attacked by bent hero
			return true;
	}

	//	check for direct attacks from bent shaman
	if( BentShaman::bentShaman.GetPieces( playerNumber ) & 
		bb64ferzAlfilMoves[squareNumber] )
		//  square is attacked by bent shaman
		return true;

	//	check for indirect attacks from bent shaman
	possibleAttackers = BentShaman::bentShaman.GetPieces( playerNumber ) & 
		bb64indirectBentShamanAttacks[squareNumber];
	while( possibleAttackers )
	{
		int square = possibleAttackers.ExtractLSB();
		if( bb64indirectBentShamanAttackMustBeFreeSquares[squareNumber][square] & 
			~board.bb64_blocker )
			//  square is attacked by bent shaman
			return true;
	}

	//	check for direct attacks from sliding general
	if( SlidingGeneral::slidingGeneral.GetPieces( playerNumber ) & 
		bb64ferzWazirMoves[squareNumber] )
		//	square is attacked by sliding general
		return true;

	//	check for indirect attacks from sliding general
	possibleAttackers = SlidingGeneral::slidingGeneral.GetPieces( playerNumber ) & 
		bb64indirectSlidingGeneralAttacks[squareNumber];
	while( possibleAttackers )
	{
		int square = possibleAttackers.ExtractLSB();
		if( bb64indirectSlidingGeneralAttackMustBeFreeSquares[squareNumber][square] & 
			~board.bb64_blocker )
			//  square is attacked by sliding general
			return true;
	}

	return false;
}
