Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: GCC and 64bit Integers

Author: Frank Phillips

Date: 01:57:03 04/02/00

Go up one level in this thread


On April 01, 2000 at 09:22:18, Dave Gomboc wrote:

>On April 01, 2000 at 09:19:52, Frank Phillips wrote:
>
>>I would be grateful if any Linux users could shed any light on the following:
>>
>>Having just upgraded from SuSe 6.2 to Mandrake 7.0 my chess program compiles but
>>does not correctly update the 64bit hash codes (using xor) during the search.
>>This is confirmed by a debug function which compares the incrementally updated
>>value with that calculated from scratch.
>>
>>Mandrake gcc, version 2.95.2   19991024  seems to cause the problem.
>>
>>After forcing version 2.91.66  19990314 to install in Mandrake from an old
>>RedHat 6.0 RPM, everything is back to normal.
>>
>>Frank
>
>You might consider posting a code snippet that people can look at.


Dave

This is embarrassing because I am not a programmer, but learning.  Here are some
snippets of code.  I have chosen the makemove functions since these update the
hash codes.  Lets just say that the code is still developing……….

/*
*****************************************************************************
*																			*
*	Make the move pointed to by pmove on the global board (board).			*
*	Update various characteristics of the current search position including	*
*	the hash code, pawn hash code and  piece bitboards.						*
*	Store board and search details in node[ply] for use in unmake move.		*
*	Check if the move is legal and if not unmake it.	 					*
*																			*
*	board->ep is only set if the xstm can actually make an ep capture,		*
*	following Bruce Moreland's advice that the alternative is inefficient.	*
*	And to prevent generating ep moves when there are no actual captures.	*
*																			*
*	You may only wish to XOR in en-passant target square info if an			*
*	en-passant capture appears to be possible, otherwise you end up			*
*	with a different hash key for 1. e4 e5 2. c4 than you do for			*
*	1. c4 e5 2. e4, and that's	surprisingly inefficient.					*
*	bruce																	*
*																			*
*	Return TRUE if the move is legal, otherwise return false.				*
*																			*
*****************************************************************************
*/
int MakeMove(BoardT *pboard, MoveT *pmove, SearchNodeT *pnode)
{
int stm=pboard->stm;

/*
 -------------------------------------------------------------------
|																	|
|	Store board details at this ply to undo later.					|
|																	|
 -------------------------------------------------------------------
*/
pnode->ep=pboard->ep;
pnode->castle=pboard->castle;
pnode->fifty=pboard->fifty;
pnode->hash=pboard->hash;
pnode->pawn_hash=pboard->pawn_hash;
pnode->stm=pboard->stm;
pnode->last_move=pboard->last_move;	//Move played that _led_ to current pboard.

/*
 -------------------------------------------------------------------
|																	|
|	Undo hash code for ep and castle rights.						|
|																	|
 -------------------------------------------------------------------
*/
pboard->hash ^= ep_hash[pboard->ep];
pboard->hash ^= castle_hash[pboard->castle];

/*
 -------------------------------------------------------------------
|																	|
|	Update the last ply's board variables.							|
|																	|
 -------------------------------------------------------------------
*/
pboard->castle=pboard->castle & castle_mask[pmove->from] &
castle_mask[pmove->to];

(pmove->type==CAPTURE_MOVE || pmove->piece==PAWN) ? pboard->fifty=0 :
pboard->fifty++;

pboard->stm = stm^1;		//Side to move in this position (after move played).
pboard->last_move=*pmove;	//Move made to cause current (next) position.
pboard->ep=0;				//ep will be set if there _is_ an ep capture.

/*
 -------------------------------------------------------------------
|																	|
|	Make the move.													|
|																	|
 -------------------------------------------------------------------
*/
switch (pmove->type)
{
	case CASTLE_KINGSIDE:	 //we already know is legal.
		if(stm == WHITE)
		{
			pboard->piece[E1]=pboard->colour[E1]=EMPTY;
			pboard->piece[G1]=KING;
			pboard->colour[G1]=WHITE;
			pboard->piece[H1]=pboard->colour[H1]=EMPTY;
			pboard->piece[F1]=ROOK;
			pboard->colour[F1]=WHITE;

			pboard->hash ^= (hashcode[WHITE][KING][E1] ^ hashcode[WHITE][KING][G1]);
			pboard->hash ^= (hashcode[WHITE][ROOK][H1] ^ hashcode[WHITE][ROOK][F1]);

			//Update hash code for new ep and castling rights before returning!
			pboard->hash ^= castle_hash[pboard->castle];
			pboard->hash ^= ep_hash[pboard->ep];

			//Update pboard
			pboard->whiteking ^= mask.square[E1];
			pboard->whiteking ^= mask.square[G1];
			pboard->whiterooks ^= mask.square[H1];
			pboard->whiterooks ^= mask.square[F1];

			pboard->whitepieces ^= mask.square[E1];
			pboard->whitepieces ^= mask.square[G1];
			pboard->whitepieces ^= mask.square[H1];
			pboard->whitepieces ^= mask.square[F1];

			pboard->white_has_castled=TRUE;
			pboard->king[WHITE]=G1;

			return TRUE;
		}
		else	//stm==BLACK.
		{
			pboard->piece[E8]=pboard->colour[E8]=EMPTY;
			pboard->piece[G8]=KING;
			pboard->colour[G8]=BLACK;
			pboard->piece[H8]=pboard->colour[H8]=EMPTY;
			pboard->piece[F8]=ROOK;
			pboard->colour[F8]=BLACK;

			pboard->hash ^= (hashcode[BLACK][KING][E8] ^ hashcode[BLACK][KING][G8]);
			pboard->hash ^= (hashcode[BLACK][ROOK][H8] ^ hashcode[BLACK][ROOK][F8]);

			//Update hash code for new ep and castling rights before returning!
			pboard->hash ^= castle_hash[pboard->castle];
			pboard->hash ^= ep_hash[pboard->ep];

			//Update pboard.
			pboard->blackking ^= mask.square[E8];
			pboard->blackking ^= mask.square[G8];
			pboard->blackrooks ^= mask.square[H8];
			pboard->blackrooks ^= mask.square[F8];

			pboard->blackpieces ^= mask.square[E8];
			pboard->blackpieces ^= mask.square[G8];
			pboard->blackpieces ^= mask.square[H8];
			pboard->blackpieces ^= mask.square[F8];

			pboard->black_has_castled=TRUE;
			pboard->king[BLACK]=G8;

			return TRUE;

		}
		break;

	case CASTLE_QUEENSIDE:	//We already know is legal.
		if(stm == WHITE)
		{
			pboard->piece[E1]=pboard->colour[E1]=EMPTY;
			pboard->piece[C1]=KING;
			pboard->colour[C1]=WHITE;
			pboard->piece[A1]=pboard->colour[A1]=EMPTY;
			pboard->piece[D1]=ROOK;
			pboard->colour[D1]=WHITE;

			pboard->hash ^= (hashcode[WHITE][KING][E1] ^ hashcode[WHITE][KING][C1]);
			pboard->hash ^= (hashcode[WHITE][ROOK][A1] ^ hashcode[WHITE][ROOK][D1]);

			//Update hash code for new ep and castling rights before returning!
			pboard->hash ^= castle_hash[pboard->castle];
			pboard->hash ^= ep_hash[pboard->ep];

			//Update bitpboard->
			pboard->whiteking ^= mask.square[E1];
			pboard->whiteking ^= mask.square[C1];
			pboard->whiterooks ^= mask.square[A1];
			pboard->whiterooks ^= mask.square[D1];

			pboard->whitepieces ^= mask.square[E1];
			pboard->whitepieces ^= mask.square[C1];
			pboard->whitepieces ^= mask.square[A1];
			pboard->whitepieces ^= mask.square[D1];

			pboard->white_has_castled=TRUE;
			pboard->king[WHITE]=C1;

			return TRUE;
		}
		else	//stm==BLACK.
		{
			pboard->piece[E8]=pboard->colour[E8]=EMPTY;
			pboard->piece[C8]=KING;
			pboard->colour[C8]=BLACK;
			pboard->piece[A8]=pboard->colour[A8]=EMPTY;
			pboard->piece[D8]=ROOK;
			pboard->colour[D8]=BLACK;

			pboard->hash ^= (hashcode[BLACK][KING][E8] ^ hashcode[BLACK][KING][C8]);
			pboard->hash ^= (hashcode[BLACK][ROOK][A8] ^ hashcode[BLACK][ROOK][D8]);

			//Update hash code for new ep and castling rights before returning!
			pboard->hash ^= castle_hash[pboard->castle];
			pboard->hash ^= ep_hash[pboard->ep];

			//Update bitpboard->
			pboard->blackking  ^= mask.square[E8];
			pboard->blackking  ^= mask.square[C8];
			pboard->blackrooks ^= mask.square[A8];
			pboard->blackrooks ^= mask.square[D8];

			pboard->blackpieces ^= mask.square[E8];
			pboard->blackpieces ^= mask.square[C8];
			pboard->blackpieces ^= mask.square[A8];
			pboard->blackpieces ^= mask.square[D8];

			pboard->black_has_castled=TRUE;
			pboard->king[BLACK]=C8;

			return TRUE;
		}
		break;

	case NORMAL_MOVE:
		UpdateBitBoard(pboard,pmove->from,pmove->to);	//Before square colours change!

		pboard->colour[pmove->to]=stm;
		pboard->piece[pmove->to]=pmove->piece;
		pboard->piece[pmove->from]=pboard->colour[pmove->from]=EMPTY;

		pboard->hash ^= (hashcode[stm][pmove->piece][pmove->from] ^
						hashcode[stm][pmove->piece][pmove->to]);

		if (pmove->piece == PAWN)
			pboard->pawn_hash ^= (hashcode[stm][PAWN][pmove->from] ^
								hashcode[stm][PAWN][pmove->to]);

		break;

	case CAPTURE_MOVE:
		UpdateBitBoard(pboard,pmove->from,pmove->to);
		UpdateBitBoardCapture(pboard,pmove->to);

		pboard->colour[pmove->to]=stm;
		pboard->piece[pmove->to]=pmove->piece;
		pboard->piece[pmove->from]=pboard->colour[pmove->from]=EMPTY;

		if (pmove->capture == PAWN)
			pboard->pawn_hash ^= hashcode[stm^1][PAWN][pmove->to];

		pboard->hash ^= hashcode[stm^1][pmove->capture][pmove->to];
		pboard->hash ^= (hashcode[stm][pmove->piece][pmove->from] ^
						hashcode[stm][pmove->piece][pmove->to]);

		if (pmove->piece == PAWN)
			pboard->pawn_hash ^= (hashcode[stm][PAWN][pmove->from] ^
								hashcode[stm][PAWN][pmove->to]);
		break;

	case PROMOTION_MOVE:
		//Captured piece or empty square is stored in move[m].capture.
		if (pmove->capture != EMPTY)
			UpdateBitBoardCapture(pboard,pmove->to);
		UpdateBitBoardCapture(pboard,pmove->from);	//Remove the pawn.
		UpdateBitBoardPromotion(pboard,stm,pmove->to,pmove->promote);

		pboard->colour[pmove->to]=stm;
		pboard->piece[pmove->to]=pmove->promote;
		pboard->piece[pmove->from]=pboard->colour[pmove->from]=EMPTY;

		if (pmove->capture != EMPTY)
			pboard->hash ^= hashcode[stm^1][pmove->capture][pmove->to];

		pboard->hash ^= (hashcode[stm][PAWN][pmove->from] ^
						hashcode[stm][pmove->promote][pmove->to]);

		pboard->pawn_hash ^= hashcode[stm][PAWN][pmove->from];
		break;

	case ENPASSANT_MOVE:
		UpdateBitBoard(pboard,pmove->from,pmove->to);
		if (stm == WHITE)
			UpdateBitBoardCapture(pboard,pmove->to -8);
		else
			UpdateBitBoardCapture(pboard,pmove->to +8);

		pboard->colour[pmove->to]=stm;
		pboard->piece[pmove->to]=PAWN;
		pboard->piece[pmove->from]=pboard->colour[pmove->from]=EMPTY;
		if(stm == WHITE)
		{
			pboard->piece[pmove->to -8]=pboard->colour[pmove->to -8]=EMPTY;
			pboard->hash ^= hashcode[stm^1][PAWN][pmove->to -8];
			pboard->pawn_hash ^= hashcode[stm^1][PAWN][pmove->to -8];
		}
		else
		{
			pboard->piece[pmove->to +8]=pboard->colour[pmove->to +8]=EMPTY;
			pboard->hash ^= hashcode[stm^1][PAWN][pmove->to +8];
			pboard->pawn_hash ^= hashcode[stm^1][PAWN][pmove->to +8];
		}

		pboard->hash ^= (hashcode[stm][PAWN][pmove->from] ^
						hashcode[stm][PAWN][pmove->to]);

		pboard->pawn_hash ^= (hashcode[stm][PAWN][pmove->from] ^
							hashcode[stm][PAWN][pmove->to]);
		break;

	case LEAVE_ENPASSANT_SQ:
		UpdateBitBoard(pboard,pmove->from,pmove->to);

		pboard->colour[pmove->to]=stm;
		pboard->piece[pmove->to]=PAWN;
		pboard->piece[pmove->from]=pboard->colour[pmove->from]=EMPTY;

		//If xstm can actually make an ep capture then set pboard->ep
		if (pboard->stm == WHITE)
		{
			if (pboard->whitepawns & mask.attack_w[pmove->ep])
				pboard->ep=pmove->ep;
		}
		else
			if (pboard->blackpawns & mask.attack_b[pmove->ep])
				pboard->ep=pmove->ep;

		pboard->hash ^= (hashcode[stm][PAWN][pmove->from] ^
						hashcode[stm][PAWN][pmove->to]);

		pboard->pawn_hash ^= (hashcode[stm][PAWN][pmove->from] ^
							hashcode[stm][PAWN][pmove->to]);
		break;

	case NULL_MOVE:
		break;

	default:
		break;
}

/*
 -------------------------------------------------------------------
|																	|
|	Update hash code for ep and castle rights.						|
|																	|
 -------------------------------------------------------------------
*/
pboard->hash ^= castle_hash[pboard->castle];
pboard->hash ^= ep_hash[pboard->ep];

/*
 -------------------------------------------------------------------
|																	|
|	If the king is not in check return true to signal that			|
|	a legal move has been made on the <pboard>						|
|																	|
 -------------------------------------------------------------------
*/
if (!Attack(pboard,pboard->king[stm],stm^1))
	return (TRUE);

/*
 -------------------------------------------------------------------
|																	|
|	Otherwise its an illegal move, so we better unmake it all		|
|	and return (FALSE) to indicate that no move has been made.		|
|																	|
 -------------------------------------------------------------------
*/
UnMakeMove(pboard,pmove,pnode);

return (FALSE);
}



****************  This an example of the UpdateBitBoard() functions ********

/*
*****************************************************************************
*																			*
*	Update a board data.													*
*	Simply XORs the from and to square.										*
*																			*
*****************************************************************************
*/
void UpdateBitBoard(BoardT *pboard, int from, int to)
{
//Combine <from> and <to> squares to update bitboards in one XOR operation.
BITBOARD temp=mask.square[from] | mask.square[to];

if (pboard->colour[from] == WHITE)
	switch (pboard->piece[from])
	{
	case KING:
		pboard->whiteking ^= temp;
		pboard->whitepieces ^= temp;
		pboard->king[WHITE]=to;
		break;
	case PAWN:
		pboard->whitepawns ^= temp;
		pboard->whitepieces ^= temp;
		break;
	case ROOK:
		pboard->whiterooks ^= temp;
		pboard->whitepieces ^= temp;
		break;



***************  And a few macros *****************

#define ZeroSquare(a,b)		((a) &= (~mask.square[b]))	//Correct but
#define ClearSquare(a,b)	((a) ^= (mask.square[b]))		//Toggle is quicker!

>
>Dave



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.