// Slow Chess 
// by Jonathan Kreuzer
// copyright 2003

#include <windows.h>
#include <stdio.h>
#include "data.h"
#include "gui.h"
#include "transcript.h"
#include "search.h"
#include "moves.h"
#include "movegenNC.cpp"
   
//
// MOVELIST FUNCTIONS
//
// ----------------
// Clear the Movelist
// ----------------
void inline Clear_Movelist(Movestruct &Movelist)
        {
		 Movelist.nummoves = 0;
         Movelist.numAttackmoves = 0;
		 Movelist.extended = 0;
        }

// -----------------
// Add a Move to Movelist (used for castling moves)
// -----------------
void inline AddCastleMove ( Movestruct &Movelist, const int src, const int dst, const int type, const int piece)
        {
        Movelist.nummoves ++;
        Movelist.Moves[ Movelist.nummoves + 50 ] = src | (dst<<7) | (type<<16) | (3 << 14);
        }
        
// ----------------
// Returns 1 if color is currently in Check
// ----------------
int IsCheck(unsigned char color, SBoard &Board)
     {
	 if (KingAttacks[ 128 + Board.WPiece[ 15 ] - Board.BPiece[ 15 ] ] ) return 1;
     if (color == WHITE) return normAttackedByBlack (&Board.Sq[ Board.WPiece[ 15 ] ] );
                    else return normAttackedByWhite (&Board.Sq[ Board.BPiece[ 15 ] ] );
     }

// -----------------
//  Find Moves for a promoted pawn
// -----------------
void FindMovesWhitePromotedPawn ( Movestruct *WMoves, SBoard &Board, unsigned char *Boardptr, int data)
        {
         if     (*Boardptr == WQUEEN)   FindMovesWhiteQueen (*WMoves, Board.Sq, Boardptr - Board.Sq, data);
         else if (*Boardptr == WROOK)   FindMovesWhiteRook  (*WMoves, Board.Sq, Boardptr - Board.Sq, data);
         else if (*Boardptr == WBISHOP) FindMovesWhiteBishop(*WMoves, Board.Sq, Boardptr - Board.Sq, data);
		 else if (*Boardptr == WKNIGHT) FindMovesWhiteKnight(*WMoves, Board.Sq, Boardptr - Board.Sq, data);
         else if (*Boardptr == WPAWN)   FindMovesWhitePawn  (*WMoves, Board.Sq, Boardptr - Board.Sq, data, Board.EnPassant);
         }

void FindMovesBlackPromotedPawn ( Movestruct *WMoves, SBoard &Board, unsigned char *Boardptr, int data)
        {
         if      (*Boardptr == BQUEEN)  FindMovesBlackQueen (*WMoves, Board.Sq, Boardptr- Board.Sq, data);
         else if (*Boardptr == BROOK)   FindMovesBlackRook  (*WMoves, Board.Sq, Boardptr- Board.Sq, data);
         else if (*Boardptr == BBISHOP) FindMovesBlackBishop(*WMoves, Board.Sq, Boardptr - Board.Sq, data);
         else if (*Boardptr == BKNIGHT) FindMovesBlackKnight(*WMoves, Board.Sq, Boardptr- Board.Sq, data);
         else if (*Boardptr == BPAWN)   FindMovesBlackPawn  (*WMoves, Board.Sq, Boardptr- Board.Sq, data, Board.EnPassant);
         }    

void FindAMovesWhitePromotedPawn ( Movestruct *WMoves, SBoard &Board, unsigned char *Boardptr, int data)
        {
         if      (*Boardptr == WQUEEN)  FindAMovesWhiteQueen    (*WMoves, Board.Sq, Boardptr - Board.Sq, data);
         else if (*Boardptr == WROOK)   FindAMovesWhiteRook     (*WMoves, Board.Sq, Boardptr - Board.Sq, data);
         else if (*Boardptr == WBISHOP) FindAMovesWhiteBishop   (*WMoves, Board.Sq, Boardptr - Board.Sq, data);
         else if (*Boardptr == WKNIGHT) FindMovesWhiteKnight    (*WMoves, Board.Sq, Boardptr - Board.Sq, data);
         else if (*Boardptr == WPAWN)   FindMovesWhitePawn      (*WMoves, Board.Sq, Boardptr - Board.Sq, data, Board.EnPassant);
         }

void FindAMovesBlackPromotedPawn ( Movestruct *WMoves, SBoard &Board, unsigned char *Boardptr, int data)
        {
         if      (*Boardptr == BQUEEN)  FindAMovesBlackQueen  (*WMoves, Board.Sq, Boardptr - Board.Sq, data);
         else if (*Boardptr == BROOK)   FindAMovesBlackRook   (*WMoves, Board.Sq, Boardptr - Board.Sq, data);
         else if (*Boardptr == BBISHOP) FindAMovesBlackBishop (*WMoves, Board.Sq, Boardptr - Board.Sq, data);
         else if (*Boardptr == BKNIGHT) FindAMovesBlackKnight (*WMoves, Board.Sq, Boardptr - Board.Sq, data);
         else if (*Boardptr == BPAWN)   FindAMovesBlackPawn   (*WMoves, Board.Sq, Boardptr - Board.Sq, data, Board.EnPassant);
         }         

// -----------------------------------
// Find all the moves on a Board for WHITE and store in WMoves
// -----------------------------------
void FindMovesWhite(SBoard &Board, Movestruct &WMoves)
        {
         Clear_Movelist(WMoves); 

		 // Castling!
         if (WMoves.ischeck == 0) 
            {
		     if (Board.WCastle == 1 || Board.WCastle == 0)
                if (Board.Sq [96] == WKING && Board.Sq [97] == EMPTY && Board.Sq [98] == EMPTY && Board.Sq [99] == WROOK)
			 	  if (IsAttacked (Board, 97, WHITE) == 0)
						AddCastleMove (WMoves, 124, 98, 15, EMPTY);
                   
             if (Board.WCastle == 2 || Board.WCastle == 0)
                if (Board.Sq [96] == WKING && Board.Sq [95] == EMPTY && Board.Sq [94] == EMPTY && Board.Sq [93] == EMPTY && Board.Sq [92] == WROOK)
				  if (IsAttacked (Board, 95, WHITE) == 0)
					AddCastleMove (WMoves, 125, 94, 15, EMPTY);
            }

		  int nLoc;
		  // Pawn Moves
		  for (int i = 0; i < 8; i++)
			{
			nLoc = Board.WPiece[ i ];
			if (nLoc !=CAPTURED)
				{
                if (Board.Sq[ nLoc ] == WPAWN) 	FindMovesWhitePawn(WMoves, Board.Sq, nLoc, nLoc + (i << 16) + (3 << 14), Board.EnPassant );
					else FindMovesWhitePromotedPawn(&WMoves, Board, &Board.Sq [ nLoc ], nLoc + (i << 16) );
				}
			}

           nLoc = Board.WPiece[ 8 ]; if (nLoc !=CAPTURED) FindMovesWhiteKnight(WMoves, Board.Sq, nLoc, nLoc + (8<<16));
           nLoc = Board.WPiece[ 9 ]; if (nLoc !=CAPTURED) FindMovesWhiteKnight(WMoves, Board.Sq, nLoc, nLoc + (9<<16));
           nLoc = Board.WPiece[ 10]; if (nLoc !=CAPTURED) FindMovesWhiteBishop(WMoves, Board.Sq, nLoc, nLoc + (10<<16));
           nLoc = Board.WPiece[ 11]; if (nLoc !=CAPTURED) FindMovesWhiteBishop(WMoves, Board.Sq, nLoc, nLoc + (11<<16));
           nLoc = Board.WPiece[ 12]; if (nLoc !=CAPTURED) FindMovesWhiteRook  (WMoves, Board.Sq, nLoc, nLoc + (12<<16));
           nLoc = Board.WPiece[ 13]; if (nLoc !=CAPTURED) FindMovesWhiteRook  (WMoves, Board.Sq, nLoc, nLoc + (13<<16));
           nLoc = Board.WPiece[ 14]; if (nLoc !=CAPTURED) FindMovesWhiteQueen (WMoves, Board.Sq, nLoc, nLoc + (14<<16));
           nLoc = Board.WPiece[ 15]; FindMovesWhiteKing(WMoves, Board.Sq, nLoc, nLoc + (15<<16));
   		   return;
       }

// Check Test First
void FindMovesWhiteCh(SBoard &Board, Movestruct &Moves)
{
	Moves.ischeck = IsCheck (WHITE, Board);
	FindMovesWhite ( Board, Moves );
}

// Rook and Queen Moves only
void FindHeavyMovesWhite ( SBoard &Board, Movestruct &WMoves )
{
 Clear_Movelist(WMoves); 
 if (Board.WPiece[12 ]!=CAPTURED) FindMovesWhiteRook  (WMoves, Board.Sq, Board.WPiece[12 ], Board.WPiece[12] + 12 * 65536);
 if (Board.WPiece[13 ]!=CAPTURED) FindMovesWhiteRook  (WMoves, Board.Sq, Board.WPiece[13 ], Board.WPiece[13] + 13 * 65536);
 if (Board.WPiece[14 ]!=CAPTURED) FindMovesWhiteQueen (WMoves, Board.Sq, Board.WPiece[14 ], Board.WPiece[14] + 14 * 65536);
}
// -------------------------------------------------
// Find all the moves on a Board for BLACK and store in BMoves
// -------------------------------------------------
void FindMovesBlack(SBoard &Board, Movestruct &BMoves )
        {
         Clear_Movelist(BMoves);

		 // Castling!
         if (BMoves.ischeck == 0) 
            {
		     if (Board.BCastle == 1 || Board.BCastle == 0)
                 if (Board.Sq [26] == BKING && Board.Sq[27] == EMPTY && Board.Sq[28] == EMPTY && Board.Sq[29] == BROOK)
                       if (IsAttacked (Board, 27, BLACK) == 0)
                              AddCastleMove (BMoves, 126, 28, 15, EMPTY);
                   
             if (Board.BCastle == 2 || Board.BCastle == 0)
                 if (Board.Sq[26] == BKING && Board.Sq[25] == EMPTY && Board.Sq[24] == EMPTY && Board.Sq[23] == EMPTY && Board.Sq[22] == BROOK)
                       if (IsAttacked (Board, 25, BLACK) == 0)
							 AddCastleMove (BMoves, 127, 24, 15, EMPTY);
            }

		  int nLoc;
		  // Pawn Moves
		  for (int i = 0; i < 8; i++)
			{
			nLoc = Board.BPiece[ i ];
			if (nLoc !=CAPTURED)
				{
                if (Board.Sq[ nLoc ] == BPAWN) 	FindMovesBlackPawn(BMoves, Board.Sq, nLoc, nLoc + (i<<16)+ (3 << 14), Board.EnPassant );
					else FindMovesBlackPromotedPawn(&BMoves, Board, &Board.Sq [ nLoc ], nLoc + (i<<16) );
				}
			}
  
		   nLoc = Board.BPiece[ 8 ]; if (nLoc !=CAPTURED) FindMovesBlackKnight(BMoves, Board.Sq, nLoc , nLoc + (8<<16));
           nLoc = Board.BPiece[ 9 ]; if (nLoc !=CAPTURED) FindMovesBlackKnight(BMoves, Board.Sq, nLoc , nLoc + (9<<16));
           nLoc = Board.BPiece[ 10]; if (nLoc !=CAPTURED) FindMovesBlackBishop(BMoves, Board.Sq, nLoc , nLoc + (10<<16));
           nLoc = Board.BPiece[ 11]; if (nLoc !=CAPTURED) FindMovesBlackBishop(BMoves, Board.Sq, nLoc , nLoc + (11<<16));
           nLoc = Board.BPiece[ 12]; if (nLoc !=CAPTURED) FindMovesBlackRook  (BMoves, Board.Sq, nLoc , nLoc + (12<<16));
           nLoc = Board.BPiece[ 13]; if (nLoc !=CAPTURED) FindMovesBlackRook  (BMoves, Board.Sq, nLoc , nLoc + (13<<16));
           nLoc = Board.BPiece[ 14]; if (nLoc !=CAPTURED) FindMovesBlackQueen (BMoves, Board.Sq, nLoc , nLoc + (14<<16));
           nLoc = Board.BPiece[ 15]; FindMovesBlackKing(BMoves, Board.Sq, nLoc, nLoc + (15<<16));
 
   		   return;
       }

// Check Test First
void FindMovesBlackCh(SBoard &Board, Movestruct &Moves)
{
	Moves.ischeck = IsCheck (BLACK, Board);
	FindMovesBlack ( Board, Moves );
}
// Rook and Queen Moves only
void FindHeavyMovesBlack ( SBoard &Board, Movestruct &BMoves )
{
 Clear_Movelist(BMoves); 
 if (Board.BPiece[12 ]!=CAPTURED) FindMovesBlackRook  (BMoves, Board.Sq, Board.BPiece[12 ], Board.BPiece[12] + 12 * 65536);
 if (Board.BPiece[13 ]!=CAPTURED) FindMovesBlackRook  (BMoves, Board.Sq, Board.BPiece[13 ], Board.BPiece[13] + 13 * 65536);
 if (Board.BPiece[14 ]!=CAPTURED) FindMovesBlackQueen (BMoves, Board.Sq, Board.BPiece[14 ], Board.BPiece[14 ] + 14 * 65536);
}
// -----------------------------------
// Find all ATTACKING moves on a Board for WHITE
// -----------------------------------
void FindAttackMovesWhite(SBoard &Board, Movestruct &WMoves)
     {
     Clear_Movelist(WMoves);
	 int nLoc;
          
     for (int i = 0; i < 8; i++)
		{
		nLoc = Board.WPiece[ i ];
		if (nLoc !=CAPTURED)
			{
            if (Board.Sq[ nLoc ] == WPAWN) 	// Find Attacks & Promotions
				FindAMovesWhitePawn(WMoves, Board.Sq, nLoc , nLoc + (i<<16) + (3 << 14), Board.EnPassant );
			else FindAMovesWhitePromotedPawn(&WMoves, Board, &Board.Sq [ nLoc ], nLoc + (i<<16));
			}
		}
  
     nLoc = Board.WPiece[ 8 ]; if (nLoc !=CAPTURED) FindAMovesWhiteKnight(WMoves, Board.Sq, nLoc, nLoc + (8<<16));
     nLoc = Board.WPiece[ 9 ]; if (nLoc !=CAPTURED) FindAMovesWhiteKnight(WMoves, Board.Sq, nLoc, nLoc + (9<<16));
     nLoc = Board.WPiece[ 10]; if (nLoc !=CAPTURED) FindAMovesWhiteBishop(WMoves, Board.Sq, nLoc, nLoc + (10<<16));
     nLoc = Board.WPiece[ 11]; if (nLoc !=CAPTURED) FindAMovesWhiteBishop(WMoves, Board.Sq, nLoc, nLoc + (11<<16));
     nLoc = Board.WPiece[ 12]; if (nLoc !=CAPTURED) FindAMovesWhiteRook  (WMoves, Board.Sq, nLoc, nLoc + (12<<16));
     nLoc = Board.WPiece[ 13]; if (nLoc !=CAPTURED) FindAMovesWhiteRook  (WMoves, Board.Sq, nLoc, nLoc + (13<<16));
     nLoc = Board.WPiece[ 14]; if (nLoc !=CAPTURED) FindAMovesWhiteQueen (WMoves, Board.Sq, nLoc, nLoc + (14<<16));
     nLoc = Board.WPiece[ 15]; FindAMovesWhiteKing(WMoves, Board.Sq, nLoc, nLoc + (15<<16));
     }

// -----------------------------------
// Find all ATTACKING moves on a Board for BLACK
// -----------------------------------
void FindAttackMovesBlack(SBoard &Board, Movestruct &BMoves)
    {
     Clear_Movelist(BMoves);
	 int nLoc;
		 
	 for (int i = 0; i < 8; i++)
		{
		nLoc = Board.BPiece[ i ];
		if (nLoc !=CAPTURED)
			{
            if (Board.Sq[ nLoc ] == BPAWN) FindAMovesBlackPawn(BMoves, Board.Sq, nLoc, nLoc + (i<<16) + (3 << 14), Board.EnPassant );				
				else FindAMovesBlackPromotedPawn(&BMoves, Board, &Board.Sq [ nLoc ], nLoc + (i<<16));
			}
		}
  
	 nLoc = Board.BPiece[ 8 ]; if (nLoc !=CAPTURED) FindAMovesBlackKnight(BMoves, Board.Sq, nLoc, nLoc + (8<<16));
     nLoc = Board.BPiece[ 9 ]; if (nLoc !=CAPTURED) FindAMovesBlackKnight(BMoves, Board.Sq, nLoc, nLoc + (9<<16));
     nLoc = Board.BPiece[ 10]; if (nLoc !=CAPTURED) FindAMovesBlackBishop(BMoves, Board.Sq, nLoc , nLoc + (10<<16));
     nLoc = Board.BPiece[ 11]; if (nLoc !=CAPTURED) FindAMovesBlackBishop(BMoves, Board.Sq, nLoc , nLoc + (11<<16));
     nLoc = Board.BPiece[ 12]; if (nLoc !=CAPTURED) FindAMovesBlackRook  (BMoves, Board.Sq, nLoc , nLoc + (12<<16));
     nLoc = Board.BPiece[ 13]; if (nLoc !=CAPTURED) FindAMovesBlackRook  (BMoves, Board.Sq, nLoc , nLoc + (13<<16));
     nLoc = Board.BPiece[ 14]; if (nLoc !=CAPTURED) FindAMovesBlackQueen (BMoves, Board.Sq, nLoc, nLoc + (14<<16));
     nLoc = Board.BPiece[ 15]; FindAMovesBlackKing(BMoves, Board.Sq, nLoc, nLoc + (15<<16));
    }       

//
// Error log of illegal positions encountered during search
//
void AddToErrorLog ( SBoard &Board, int Move )
{
	static char sText [ 512 ];
//	Board.SideToMove ^=1;
	
	FILE *fp = fopen ("errorlog.txt", "at");
	if (fp == NULL) return;
	CopyPosition ( sText, GameBoard );
	fprintf (fp, "GameBoard: %s \n", sText);
	CopyPosition ( sText, Board );
	fprintf (fp, "Move (%d), Invalid Position in search: %s \n", Move, sText);
	fclose ( fp );
}

// ----------------------
//   Move the Pieces on array specified by Board
//   Returns a nonzero value if a capture is made 
//   Also includes special code for Castling, En Passant, and promotion.
// ----------------------
int Do_Move (SBoard &Board, const int Move, int &u1, int &u2, const int nUpgrade)
        {
        int retVal = NO_EXT;

        int src = MSrc (Move); // Source Square
        int dst = MDst (Move); // Destination Square
        int nPiece = MPiece(Move); // Piece Number
		int nPType = Board.Sq [ src ];	// Piece Type
		int nCap   = Board.Sq [ dst ];	// Piece Type

        u1 = dst | (src << 8);
		u2 = nCap | ( nPType <<8 ); // for Undo

		Board.GameTime++; 
		Board.SideToMove ^= 3;
        
        // Castling
        if (src > 123)
			{
			Board.EnPassant = 120; 

			switch (src - 124)
				{
				case 0: // White Castle 
                     u1 = (96) + ((98)<<8) + ((99)<<16) + ((97)<<24);
                     u2 = Board.Sq[96] + (Board.Sq[98]<<8) + (Board.Sq[99]<<16) + (Board.Sq[97]<<24);
                     Board.Sq[96] = EMPTY;  Board.Sq[97] = WROOK; Board.Sq[98] = WKING; Board.Sq[99] = EMPTY;
                     Board.WPiece [ 15 ] = 98; Board.WPiece[ 13 ] = 97;
					 Board.WCastle = 3;
					 Board.TempValue += SquareVals [ WROOK * 128 + 97] - SquareVals [ WROOK * 128 + 99];
                     return 0;
                    
				case 1:
                     u1 = (96) + ((94)<<8) + ((92)<<16) + ((95)<<24);
                     u2 = Board.Sq[96] + (Board.Sq[94]<<8) + (Board.Sq[92]<<16) + (Board.Sq[95]<<24);
                     Board.Sq[96] = EMPTY;  Board.Sq[95] = WROOK; Board.Sq[94] = WKING;  Board.Sq[92] = EMPTY;
	                 Board.WPiece [ 15 ] = 94; Board.WPiece[ 12 ] = 95;
					 Board.WCastle = 3;
 					 Board.TempValue += SquareVals [ WROOK * 128 + 95] - SquareVals [ WROOK * 128 + 92];
                     return 0;
                    
				case 2: // Black Castle
                     u1 = (26) + ((28)<<8) + ((29)<<16) + ((27)<<24);
                     u2 = Board.Sq[26] + (Board.Sq[28]<<8) + (Board.Sq[29]<<16) + (Board.Sq[27]<<24);
                     Board.Sq[26] = EMPTY;  Board.Sq[27] = BROOK; Board.Sq[28] = BKING; Board.Sq[29] = EMPTY;
                     Board.BPiece[15] = 28; Board.BPiece[13] = 27; 
					 Board.BCastle = 3;
 					 Board.TempValue += SquareVals [ BROOK * 128 + 27] - SquareVals [ BROOK * 128 + 29];
                     return 0;
                    
				case 3:
                    u1 = (26) + ((24)<<8) + ((22)<<16) + ((25)<<24);
                    u2 = Board.Sq[26] + (Board.Sq[24]<<8) + (Board.Sq[22]<<16) + (Board.Sq[25]<<24);
                    Board.Sq[26] = EMPTY;  Board.Sq[25] = BROOK; Board.Sq[24] = BKING; Board.Sq[22] = EMPTY;
                    Board.BPiece[15] = 24; Board.BPiece[12] = 25; 
					Board.BCastle = 3;
  					Board.TempValue += SquareVals [ BROOK * 128 + 25] - SquareVals [ BROOK * 128 + 22];
                    return 0;                    
				}
			}

		// If the King is Captured, The SlowChess search may go crazy and crash
		if ( (u2&7) == (WKING) )
			{
			AddToErrorLog (  Board, Move );
			exit (2);
			}

		// Check/Update Castling Option flags
        if (Board.WCastle <3)
                {
				 if (src == 96) Board.WCastle = 3; // King Moved
                 if (src == 99 || dst == 99)  Board.WCastle |=2; // Rook Moved or was captured
                 if (src == 92 || dst == 92)  Board.WCastle |=1; // Rook Moved or was captured
                }
        if (Board.BCastle <3)
                {
				 if (src == 26) Board.BCastle = 3; 
                 if (src == 29 || dst == 29) Board.BCastle |=2;
                 if (src == 22 || dst == 22) Board.BCastle |=1;
                }
        
        // Piece Captures
		unsigned char *pPieces;

        if (nCap != EMPTY)
                {
                 Board.LastReversible = Board.GameTime +1; // unreversible

                 if (nCap < 8) // White piece Taken
                       {
						pPieces = Board.WPiece;
						if (nCap == WPAWN) 
							{
							 Board.PawnHash -= WPHashSq [ dst ];
							 Board.nWPawns--;
							 retVal = PAWNCAP;
							 if ( dst == 79 && nPiece == 14 && Board.WPiece[15] == 98 && Board.Sq[88]!=WPAWN) retVal = KINGSAFETY2;
 							}
							else 
							{
							 if ( nCap < WROOK) Board.nWMinors--;
							 if ( abs(PieceValues[ nCap ] + PieceValues[ nPType ]) < 70) retVal = dst; else retVal = CAPTURE;// for recapture ext
							 if ( (Board.nWP+Board.nBP) == 1) retVal = KINGPAWNS;
							 if ( nPiece == 15 && (dst == 39) && Board.WPiece[14] != CAPTURED ) retVal = MATETHREAT;
							 Board.nWP--;
							}
						Board.WMat -= PieceValues[ nCap ]; 
                      }
                else	// Black piece Taken
                       {
						pPieces = Board.BPiece;
						if (nCap == BPAWN) 
							{
							 Board.PawnHash -= BPHashSq [ dst ];
							 Board.nBPawns--;
							 retVal = PAWNCAP;
							 if (  dst == 49 && nPiece == 14 && Board.BPiece[15] == 28 && Board.Sq[38]!=BPAWN ) retVal = KINGSAFETY2;
							}	
							else 
							{
							 if ( nCap  < BROOK ) Board.nBMinors--;
							 if ( abs(PieceValues[ nCap ] + PieceValues[ nPType ]) < 70) retVal = dst; else retVal = CAPTURE;// for recapture ext
							 if ( (Board.nWP+Board.nBP) == 1) retVal = KINGPAWNS;
							 if ( nPiece == 15 && (dst == 89) && Board.BPiece[14] != CAPTURED ) retVal = MATETHREAT;
							 Board.nBP--;
							}
						Board.BMat -= PieceValues[ nCap&7 ]; 
                       }
				
				Board.TempValue -= SquareVals [ (nCap<<7) + dst];

                 // Mark piece as captured in location list
                 for (int x = 0; x < 16; x++)
                     if ( dst == pPieces[x]) {pPieces[x] = CAPTURED; break;}
                }
        
        // EnPassant Capture
        else if (dst == Board.EnPassant && (nPType & 7) == WPAWN) 
                {
				 if (nPType == WPAWN) // White Captures Black
                    {
					int EPsq = dst+10;
					u1|= ((EPsq)<<16); u2 |= (BPAWN<<16);
					Board.Sq[ EPsq ] = EMPTY;
					Board.PawnHash -= BPHashSq [ EPsq ];
					Board.nBPawns--;
 					Board.BMat -= PieceValues[ WPAWN ];
					Board.TempValue -= SquareVals [ (BPAWN<<7) + EPsq ];
                    for (int x = 0; x < 8; x++)
						if ( EPsq  == Board.BPiece[x])
							{ Board.BPiece[ x ] = CAPTURED; break;}
                    }
					else 	// Black Captures White
					{
					int EPsq = dst-10;
					u1|= ((EPsq)<<16); u2 |= (WPAWN<<16);
                    Board.Sq[EPsq] = EMPTY;
					Board.PawnHash -= WPHashSq [ EPsq ];
					Board.nWPawns--;
 					Board.WMat -= PieceValues[ WPAWN ];
					Board.TempValue -= SquareVals [ (WPAWN<<7) + EPsq ];
                    for ( int x = 0; x < 8; x++)
                           if ( EPsq == Board.WPiece[ x ])
                              { Board.WPiece[ x ] = CAPTURED; break; }
                    }
				retVal = ENPASSANT;
				}

		// incremental update of pieces on Square Value (for non-kings)
		if ( (nPType&7) != WKING ) Board.TempValue += SquareVals [ (nPType<<7) + dst] - SquareVals [ (nPType<<7) + src];

		// Pawn Moves
        Board.EnPassant = 120; // no Enpassant
        if (nPType == WPAWN) 
			{
			Board.PawnHash += WPHashSq [ dst ] - WPHashSq [ src ];
			Board.LastReversible = Board.GameTime+1; // unreversible
			// Set EnPassant Sq if pawn moves forwards 2 & opponent has a pawn to capture it
			if (src-dst > 12 && (Board.Sq [dst-1] == BPAWN || Board.Sq [dst+1] == BPAWN))
				{Board.EnPassant = src - 10; } 

			if (SQRANK[dst] >=6)
				{
				if (retVal != KINGPAWNS)
					{
					if (SQRANK[dst]==7) retVal = PAWNPUSH;
					else if (retVal!=ENPASSANT && SQRANK[dst]==6 && Board.nBP <=1 && Board.Sq[dst-10] == EMPTY  && Board.Sq[dst-9] != BPAWN  && Board.Sq[dst-11] != BPAWN) 
						retVal = PAWNPUSH2;
					}
				if (SQRANK[dst]==8) // PAWN promo
					{
					 Board.WMat += PieceValues[ nUpgrade ] - PieceValues[ WPAWN ];
					 if (nUpgrade < WROOK  ) Board.nWMinors++;
					 else if (nUpgrade == WQUEEN && Board.WPiece[14] == CAPTURED) { Board.WPiece[ nPiece ] = CAPTURED; nPiece = 14;}
					 Board.nWP++;
					 Board.nWPawns--;
					 nPType += (nUpgrade - WPAWN); 
					} 
				}
			}
        else if (nPType == BPAWN) 
			{
			Board.PawnHash += BPHashSq [ dst ] - BPHashSq [ src ];
			Board.LastReversible = Board.GameTime+1; // unreversible
			// Set EnPassant Sq if pawn moves forwards 2 & opponent has a pawn to capture it
			if (dst-src > 12 && (Board.Sq [dst-1] == WPAWN || Board.Sq [dst+1] == WPAWN))
				{Board.EnPassant = src + 10;}

			if ( SQRANK[dst] <=3 )
				{
				if (retVal != KINGPAWNS)
					{
					if (SQRANK[dst]==2) retVal = PAWNPUSH;
						else if (retVal!=ENPASSANT && SQRANK[dst]==3 && Board.nWP <=1 && Board.Sq[dst+10] == EMPTY && Board.Sq[dst+9] != WPAWN  && Board.Sq[dst+11] != WPAWN )
						retVal = PAWNPUSH2;
					}
				if (SQRANK[dst]==1) // PAWN promo
					{
					 Board.BMat += PieceValues[ nUpgrade ] - PieceValues[ WPAWN ];
					 if (nUpgrade < WROOK ) Board.nBMinors++;
					 else if (nUpgrade == WQUEEN && Board.BPiece[14] == CAPTURED) { Board.BPiece[ nPiece ] = CAPTURED; nPiece = 14;}
					 Board.nBP++;
					 Board.nBPawns--;
					 nPType += (nUpgrade - WPAWN); 
					}
				}
			}

        // Do the Move on the board
        Board.Sq[ src ] = EMPTY;
        Board.Sq[ dst ] = nPType;
        if (nPType > 8 ) Board.BPiece[ nPiece ] = dst;
			else Board.WPiece[ nPiece ] = dst;

		Board.MatVal = Board.WMat - Board.BMat;
        return retVal;
        }
        
//
// CHECK RELATED FUNCTIONS
// 
// ----------------------------------------------------------
// Check for a discovered attack on Sq from nDirection
// ----------------------------------------------------------
int inline CheckDirec ( int Sq, const int &nDirec, const unsigned char Board[], const int piece1, const int piece2)
{
	Sq+=nDirec;
	while (Board [Sq] == EMPTY) Sq+=nDirec;
	if (Board[Sq] == piece1 || Board[Sq] == piece2) return Sq;
	return 0;
}

int inline CheckLine ( int Sq, const int dstSq, const int &nDirec, const unsigned char Board[] )
{
	Sq+=nDirec;
	while (Board [Sq] == EMPTY) Sq+=nDirec;
	if (Sq == dstSq) return dstSq;
	return 0;
}

// ----------------------------------------------------------
//
// Test for a Discovered check
//
// ----------------------------------------------------------
int DiscoveredCheck ( int color, SBoard &TempBoard, int Move )
	{
	 int bRetVal = FALSE, enPassant = 120;
     int srcSq = MSrc(Move);
     int dstSq = MDst(Move);

	 unsigned char cPiece;

	// Check Testing
	 if (color == BLACK)
		{
		int KingSq = TempBoard.BPiece[15];
		int nDirec = acDirec [ KingSq + (srcSq<<7) ];
		if (nDirec != 0 && nDirec != acDirec [ KingSq  + (dstSq<<7) ]) 
			{
			cPiece = TempBoard.Sq [ srcSq ]; 
			if (dstSq == TempBoard.EnPassant && (TempBoard.Sq[srcSq]&7) == WPAWN)
				{
				enPassant = dstSq-10; 
				TempBoard.Sq[ enPassant ] = EMPTY;
				}
			TempBoard.Sq [ srcSq ] = EMPTY;

			if (HoriDir [ nDirec + 12 ])
				{if (CheckDirec (KingSq , nDirec, TempBoard.Sq, WROOK, WQUEEN)  ) bRetVal = TRUE;}
			 else {if (CheckDirec (KingSq , nDirec, TempBoard.Sq, WBISHOP, WQUEEN) ) bRetVal = TRUE;}

			TempBoard.Sq [ srcSq ] = cPiece;
			if (enPassant!=120)  TempBoard.Sq[enPassant] = WPAWN;
			}
		}
	 else
		{
		int KingSq = TempBoard.WPiece[15];
		int nDirec = acDirec [ KingSq + (srcSq<<7) ];
		if (nDirec != 0 && nDirec != acDirec [ KingSq  + (dstSq<<7) ]) 
			{
			cPiece = TempBoard.Sq [ srcSq ];
			if (dstSq == TempBoard.EnPassant && (TempBoard.Sq[srcSq]&7) == WPAWN)
				{
				enPassant = dstSq+10; 
				TempBoard.Sq[ enPassant ] = EMPTY;
				}
			TempBoard.Sq [ srcSq ] = EMPTY;

			if (HoriDir [ nDirec + 12 ])
				{if (CheckDirec (KingSq , nDirec, TempBoard.Sq, BROOK, BQUEEN)  ) bRetVal = TRUE;}
			 else {if (CheckDirec (KingSq , nDirec, TempBoard.Sq, BBISHOP, BQUEEN)  ) bRetVal = TRUE;}

			TempBoard.Sq [ srcSq ] = cPiece;
			if (enPassant!=120)  TempBoard.Sq[enPassant] =  BPAWN;
			}
		}
	 //

	 return bRetVal;
	}

//
// Helpers for Checking Move. 
//
int inline DiscoverCheckW (const unsigned char Board[], const int Sq, const int KingSq, const int nDirec)
{
	int nDirecD = acDirec [ KingSq + (Sq<<7) ];
	if (nDirecD != 0 && nDirecD != nDirec) 
		{if (HoriDir [ nDirecD + 12 ]) 
			 return CheckDirec (KingSq , nDirecD, Board, WROOK, WQUEEN);
			 return CheckDirec (KingSq , nDirecD, Board, WBISHOP, WQUEEN);
		}
	return 0;
}

int inline DiscoverCheckB (const unsigned char Board[], const int Sq, const int KingSq, const int nDirec)
{
	int nDirecD = acDirec [ KingSq + (Sq<<7) ];
	if (nDirecD != 0 && nDirecD != nDirec) 
		{if (HoriDir [ nDirecD + 12 ])	
			return CheckDirec (KingSq , nDirecD, Board, BROOK, BQUEEN);
			else return CheckDirec (KingSq , nDirecD, Board, BBISHOP, BQUEEN); 
		}
	return 0;
}

// ----------------------------------------------------------
//
// Test to see if Move checks the enemy King
// returns the checking Square, (or returns the number 2 if there are 2 checking squares)
//
// ----------------------------------------------------------
int CheckingMove( const int color, SBoard &TempBoard, const int Move )
{
    int srcSq = MSrc(Move); 
    int dstSq = MDst(Move); 
	int nCheck = 0, nDCheck = 0;

	// Ugg, Castling might make a rook check, so another special case
	if (srcSq > 122)
		{
		if (srcSq == 124) {dstSq = 97; srcSq = 96;}
		if (srcSq == 125) {dstSq = 95; srcSq = 96;}
		if (srcSq == 126) {dstSq = 27; srcSq = 26;}
		if (srcSq == 127) {dstSq = 25; srcSq = 26;}
		TempBoard.Sq[srcSq] = EMPTY; 
		TempBoard.Sq[dstSq] = WROOK;
		int KingSq = (color == WHITE) ? TempBoard.BPiece[15] : TempBoard.WPiece[15];
		int nDirec = acDirec [ KingSq + (dstSq<<7) ];
		if ( HoriDir [ nDirec+12 ] ) nCheck = CheckLine ( KingSq, dstSq, nDirec, TempBoard.Sq );
		TempBoard.Sq[dstSq] = EMPTY; 
		TempBoard.Sq[srcSq] = (color==WHITE) ? WKING: BKING;
		return nCheck;
		}
	// ---------------

	unsigned char piece = TempBoard.Sq [srcSq];
    unsigned char oldpiece = TempBoard.Sq [dstSq];
	TempBoard.Sq [srcSq] = EMPTY;
	TempBoard.Sq [dstSq] = piece;

// WHITE moves
if (color == WHITE)
	{
	int KingSq = TempBoard.BPiece[15];
	int nDirec = acDirec [ KingSq + (dstSq<<7) ];
	if (piece == WPAWN && SQRANK[dstSq]==8) { TempBoard.Sq[dstSq] = MPromo (Move);  }

	switch ( TempBoard.Sq[dstSq] )
		{
		case WPAWN:
			if (dstSq == KingSq+9 || dstSq == KingSq+11) nCheck = dstSq;
			//En Passant captures vacate 2 squares, so we have to have to check the captured piece square for discovered too
			else if ( dstSq == TempBoard.EnPassant ) 
				{
				TempBoard.Sq [dstSq+10] = EMPTY;
				nCheck=DiscoverCheckW (TempBoard.Sq, dstSq+10, KingSq, nDirec);
				TempBoard.Sq [dstSq+10] = BPAWN;
				}
			break;
		case WBISHOP:
			if (DiagDir [ nDirec + 12 ]) nCheck = CheckLine ( KingSq, dstSq, nDirec, TempBoard.Sq );
			break;
		case WKNIGHT:
			if (KnightAttacks [ dstSq - KingSq + 128 ] ) nCheck = dstSq;
			break;
		case WROOK:
			if (HoriDir [ nDirec + 12 ]) nCheck = CheckLine ( KingSq, dstSq, nDirec, TempBoard.Sq );
			break;
		case WQUEEN:
			if (nDirec) nCheck = CheckLine ( KingSq, dstSq, nDirec, TempBoard.Sq );
			break;
		}

	// Discovered Checks
	if ( piece != WQUEEN) nDCheck = DiscoverCheckW (TempBoard.Sq, srcSq, KingSq, nDirec);
	}
// Same as above, except for BLACK
else 
	{
	int KingSq = TempBoard.WPiece[15];
	int nDirec = acDirec [  KingSq + (dstSq<<7)];
	if (piece == BPAWN && SQRANK[dstSq]==1) { TempBoard.Sq[dstSq] = MPromo (Move) + 8;  }

	switch ( TempBoard.Sq[dstSq] )
		{
		case BPAWN:
			if (dstSq == KingSq-9 || dstSq == KingSq-11) nCheck = dstSq;
			//En Passant captures vacate 2 squares
			else if ( dstSq == TempBoard.EnPassant ) 
				{
				TempBoard.Sq [dstSq-10] = EMPTY;
				nCheck = DiscoverCheckB (TempBoard.Sq, dstSq-10, KingSq, nDirec);
				TempBoard.Sq [dstSq-10] = WPAWN;
				}
			break;
		case BBISHOP:
			if (DiagDir [ nDirec + 12 ] ) nCheck = CheckLine ( KingSq, dstSq, nDirec, TempBoard.Sq );
			break;
		case BKNIGHT:
			if (KnightAttacks [ dstSq - KingSq + 128 ] ) nCheck = dstSq;
			break;
		case BROOK:
			if (HoriDir [ nDirec + 12 ] ) nCheck = CheckLine ( KingSq, dstSq, nDirec, TempBoard.Sq );
			break;
		case BQUEEN:
			if (nDirec) nCheck = CheckLine ( KingSq, dstSq, nDirec, TempBoard.Sq );
			break;
		}

	// Discovered Checks
	if ( piece != BQUEEN) nDCheck = DiscoverCheckB (TempBoard.Sq, srcSq, KingSq, nDirec);
	}

TempBoard.Sq [dstSq] = oldpiece;
TempBoard.Sq [srcSq] = piece;

if (nCheck==0) return nDCheck;
else if (nDCheck) return 2; // 2 Checking Pieces
return nCheck;
}


//
// Generate Legal Moves to get out of Check
//
void InCheckMoveGenW ( SBoard &Board, Movestruct &Moves )
{
	Clear_Movelist ( Moves );
	int nKingSq = Board.WPiece[15];
	int nSq = Moves.ischeck;
	if (nSq == 2) // Double Check, must move the king
		{
		FindLegalMovesWhiteKing (Moves, Board,  nKingSq , nKingSq + (15<<16));
		return;
		}	

	// Take Checking Piece
	FindWhiteMovesToSq  (Moves, nSq, Board, TRUE);
	// Move King
	FindLegalMovesWhiteKing(Moves, Board,nKingSq, nKingSq + (15<<16));

	// Knight Check or Touch Check, can't block
	if (TouchChecks [ nKingSq - nSq + 128  ]) return;

	// Blocking Moves
	int nDirec = acDirec [ nSq + (nKingSq<<7) ];
	nSq+=nDirec;
	while (Board.Sq [ nSq ] == EMPTY)
		{
		FindWhiteMovesToSq  (Moves, nSq, Board, FALSE);
		nSq+=nDirec;
		}
}


void InCheckMoveGenB ( SBoard &Board, Movestruct &Moves )
{
	Clear_Movelist ( Moves );
	int nSq = Moves.ischeck;
	int nKingSq = Board.BPiece[15];
	if (nSq == 2) // Double Check
		{
		FindLegalMovesBlackKing(Moves, Board, nKingSq , nKingSq + (15<<16));
		return;
		}	

	// Take Checking Piece
	FindBlackMovesToSq  (Moves, nSq, Board, TRUE);
	// Move King
	FindLegalMovesBlackKing(Moves, Board, nKingSq , nKingSq + (15<<16));

	// Knight Check or Touch Check, can't block
	if (TouchChecks [ nKingSq - nSq + 128  ]) return;

	// Blocking Moves
	int nDirec = acDirec [ nSq + (nKingSq<<7) ];
	nSq+=nDirec;
	while (Board.Sq [ nSq ] == EMPTY)
		{
		FindBlackMovesToSq  (Moves, nSq, Board, FALSE);
		nSq+=nDirec;
		}
}

//
// Set the ischeck var of moves
//
void SetIsCheck (Movestruct &Moves, SBoard &Board )
{
 if ( IsCheck(Board.SideToMove, Board) == 1) 
	{if (Board.SideToMove == WHITE) FindBlackMovesToSq (Moves, Board.WPiece[15], Board, 2);
		else FindWhiteMovesToSq (Moves, Board.BPiece[15], Board, 2);
	 if (Moves.numAttackmoves > 1) MoveStack[1].ischeck = 2;
		else  MoveStack[1].ischeck = MSrc (Moves.Moves[1]);
	}	
 else MoveStack[1].ischeck = 0;
}

// ------------------------
// Queen Touch Mates functions
// ------------------------
int CheckSquareW ( SBoard &Board, int MateSq, int nKingSq, int nQueenSq )
{
MateSq+=nKingSq;
if (Board.Sq [ MateSq ] > 0 && Board.Sq[MateSq]<8) return 0; // Friendly piece

int nDirec = acDirec [ MateSq  + (nQueenSq<<7) ];
if (nDirec == 0) return 0;
if (CheckLine (MateSq, nQueenSq, nDirec, Board.Sq) == 0) return 0;

int bRet = 1;

Board.Sq [nQueenSq] = EMPTY;
if  ( IsAttacked ( Board, MateSq, BLACK) == 0)  // King can just take queen
	{
	 Board.Sq [nQueenSq] = WQUEEN; 
	 return 0;
	}

if ( normAttackedByBlack ( &Board.Sq[ MateSq ] )  ) bRet = 0; // Other Piece can take queen
Board.Sq [nQueenSq] = WQUEEN;

if (bRet == 0) return 0;
if (DiscoveredCheck (WHITE, Board, nQueenSq + (MateSq<<7) ) ) return 0; // Queen is Pinned

return 1;
}

//
//
//
int CheckSquareB ( SBoard &Board, int MateSq, int nKingSq, int nQueenSq )
{
MateSq+=nKingSq;
if ( Board.Sq[MateSq]>8) return 0; // Friendly piece blocking

int nDirec = acDirec [ MateSq  + (nQueenSq<<7) ];
// Is the queen lined up with the mating square? If so does it have a clear path?
if (nDirec == 0) return 0;
if (CheckLine (MateSq, nQueenSq, nDirec, Board.Sq) == 0) return 0;

int bRet = 1;

Board.Sq [nQueenSq] = EMPTY;
if  ( IsAttacked ( Board, MateSq, WHITE) == 0)  // King can just take queen
	{
	Board.Sq [nQueenSq] = BQUEEN;
	return 0;
	}

if ( normAttackedByWhite ( &Board.Sq[ MateSq ] )  ) bRet = 0; // Other Piece can take queen
Board.Sq [nQueenSq] = BQUEEN;

if (bRet == 0) return 0;

if (DiscoveredCheck (BLACK, Board, nQueenSq + (MateSq<<7) ) ) return 0; // Queen is Pinned

return 1;
}
//
//
//
int TouchMatesW ( SBoard &Board, int depth )
{
if (depth > 4) return FindMateThreat ( Board, WHITE, MAXDEPTH-1);

int nQueenSq = Board.WPiece[14];
if (nQueenSq == CAPTURED) return 0;

int nKingSq = Board.BPiece[15];
int MateSq = EDGE [nKingSq];
if (MateSq == 0) return 0;

if (CheckSquareW ( Board, MateSq, nKingSq, nQueenSq ) == 1) return 1;
if (MateSq == 9)
	{if (CheckSquareW ( Board, -1, nKingSq, nQueenSq ) == 1) return 1;
	 if (CheckSquareW ( Board, +10, nKingSq, nQueenSq ) == 1) return 1;
	 return 0;
	}
if (MateSq == 11)
	{if (CheckSquareW ( Board, 1, nKingSq, nQueenSq ) == 1) return 1;
	 if (CheckSquareW ( Board, +10, nKingSq, nQueenSq ) == 1) return 1;
	 return 0;
	}
if (MateSq==10) 
	{
	if (Board.Sq[nKingSq+9]>8 || Board.Sq[nKingSq+20] == WPAWN) 
		{if (CheckSquareW ( Board, 1, nKingSq, nQueenSq ) == 1) return 1;}
	
	if (Board.Sq [nKingSq-1] >8 && (Board.Sq [nKingSq+10] == EMPTY || Board.Sq[nKingSq+9]>8)) 
		{return CheckSquareW ( Board, 11, nKingSq, nQueenSq );}
	}

return 0;
}

int TouchMatesB ( SBoard &Board, int depth )
{
if (depth > 4) return FindMateThreat ( Board, BLACK, MAXDEPTH-1);

int nQueenSq = Board.BPiece[14];
if (nQueenSq == CAPTURED) return 0;

int nKingSq = Board.WPiece[15];
int MateSq = EDGE [nKingSq];
if (MateSq == 0) return 0;

if (CheckSquareB ( Board, MateSq, nKingSq, nQueenSq ) == 1) return 1;
if (MateSq == -9) 
	{if (CheckSquareB ( Board, 1, nKingSq, nQueenSq ) == 1) return 1;
	 if (CheckSquareB ( Board, -10, nKingSq, nQueenSq ) == 1) return 1;
	 return 0;
	}
if (MateSq == -11)
	{
	 if (CheckSquareB ( Board, -1, nKingSq, nQueenSq ) == 1) return 1;
	 if (CheckSquareB ( Board, -10, nKingSq, nQueenSq ) == 1) return 1;
	 return 0;
	}
if (MateSq== -10) 
	{
	if ( (Board.Sq[nKingSq-9] > 0 && Board.Sq[nKingSq-9] < 8) || Board.Sq[nKingSq-20] == BPAWN ) 
		{if (CheckSquareB ( Board, -1, nKingSq, nQueenSq ) == 1) return 1;}

	if (Board.Sq [nKingSq-1] != EMPTY && Board.Sq [nKingSq-1] <8 && (Board.Sq [nKingSq-10] == EMPTY || (Board.Sq[nKingSq-11]!= EMPTY && Board.Sq[nKingSq-11] < 8))) 
		return CheckSquareB ( Board, -9, nKingSq, nQueenSq );
	}

return 0;
}

// ----------------------------------
//  Find a mate threat with any rook or queen move
// ----------------------------------
int FindMateThreat ( SBoard &Board, char Color, int ahead)
{
int u1, u2, i, MMove = 0;

MoveStack[ahead].ischeck = 0;
if (Color == WHITE)	{FindHeavyMovesWhite ( Board, MoveStack[ahead]);}
if (Color == BLACK)	{FindHeavyMovesBlack ( Board, MoveStack[ahead]);}

Copy_Board2 (BoardStack[ahead], Board);

for (i = 1; i<= MoveStack[ahead].nummoves + 50; i++)
	{
	if (i == MoveStack[ahead].numAttackmoves + 1) i = 51;
	if (i > MoveStack[ahead].nummoves + 50) break;

	 MMove = MoveStack[ahead].Moves [i];
	 if (DiscoveredCheck (Color, Board, MMove) == 1 ) continue;

	 MoveStack[ahead+1].ischeck = CheckingMove (Color, Board, MMove  );
     if (MoveStack[ahead+1].ischeck == 0) continue;

	 Do_Move(Board, MMove , u1, u2, WQUEEN);	
	 if (Color == WHITE) InCheckMoveGenB (Board, MoveStack[ahead+1]);
				else InCheckMoveGenW (Board, MoveStack[ahead+1]);
	 Undo_Move (Board, BoardStack[ahead], u1, u2);
	 if ((MoveStack[ahead+1].nummoves + MoveStack[ahead+1].numAttackmoves) == 0) return MMove;	
	}

return 0;
}

// ------------------------
// DO MOVE
// Do a move on Board based on x,y Coordinates
// Returns 0 for illegal move, 1 for legal move
// ------------------------
int DoMoveXY (SBoard &Board, int x, int y, int x2, int y2, unsigned char color, unsigned char nPiece, int bAdd, STranscript *pTranscript, int &src, int &dst)
        {
        Movestruct BMoves;
        SBoard BoardTemp;
        int move = 255;
        int i, square, square2;
        int u1,u2;
        
        if (color == BLACK) FindMovesBlackCh (Board, BMoves);
                       else FindMovesWhiteCh (Board, BMoves); 

        square  = SQ (x, y);
        square2 = SQ (x2, y2);
        // Castling
		if (y != -1)
			{
	        if (Board.Sq [ square ] == WKING && (x2-x) == 2  && y == y2 && color == WHITE)  {square =124; square2 = 98;}
		    if (Board.Sq [ square ] == WKING && (x2-x) == -2 && y == y2 && color == WHITE) {square =125; square2 = 94;}
			if (Board.Sq [ square ] == BKING && (x2-x) == 2  && y == y2 && color == BLACK) {square =126; square2 = 28;}
			if (Board.Sq [ square ] == BKING && (x2-x) == -2 && y == y2 && color == BLACK) {square =127; square2 = 24;}
			}
        
		// Look for (x,y)-(x2,y2) move in movelist BMoves
		// x == -1 or y == -1 means they can be any value
        for (i = 1; i<= BMoves.nummoves + 50; i++)
                {
				if (i == BMoves.numAttackmoves + 1) i = 51;
				if (i > BMoves.nummoves + 50) break;
				// Test to make sure this move doesn't check yourself.
				BoardTemp = Board;
				Do_Move (BoardTemp, BMoves.Moves [i], u1, u2, WQUEEN); 
				if (IsCheck (color, BoardTemp) == 0)
					{
					// Test to see if this valid move matches data sent in.
					if (y == -1 || x == -1) // wildcards?
						{
						if ( x == -1 || SQFILE[ MSrc(BMoves.Moves[i]) ] == (x+1) )
							if ( y == -1 || SQRANK[ MSrc(BMoves.Moves[i]) ] == (8 - y) )
								if ( MDst(BMoves.Moves[i]) == square2 && Board.Sq [ MSrc(BMoves.Moves[i]) ] == nPiece)
									{move = i;}
						}
					else
						{
						if (MSrc(BMoves.Moves[i]) == square && MDst(BMoves.Moves[i]) == square2 )
							move = i;
						}
					}
                }
        
        if (move == 255) return FALSE; // move not found, thus not a valid Move

		// src & dst are passed in as reference, so fill them in
		src = MSrc(BMoves.Moves [move]);
		dst = MDst(BMoves.Moves [move]);

		// fixme? This is a bit convoluted to be here, it stores if there can be a recap on this sq in a global
		if ( PieceValues [ Board.Sq [ dst ]&7 ] > 200 && abs (PieceValues [ Board.Sq [ dst ]&7 ] - PieceValues [ Board.Sq [ src ]&7 ]) < 70)
			g_RecapSquare = dst;
		else g_RecapSquare = 0;

		// Do the Move
		BoardTemp = Board;

		Do_Move (Board, BMoves.Moves [move], u1, u2, upgrade);

        if (bAdd == TRUE) 
			{
			AddTranscript ( pTranscript, BMoves.Moves[move], BoardTemp);
			}
             
        return TRUE;
        }