Beispiel #1
0
int main(int ununsed, char **alsoUnused)
{
  TestHashTable();

  return 0;
}
Beispiel #2
0
int AlphaBeta(board_t *brd, int alpha, int beta, int depth, searchinfo_t *sinfo, int null)
{
	if(depth == 0){
		//return Eval(brd);
		return Quiece(brd, alpha, beta, sinfo);
	}

	if(!(sinfo->nodes & 0xfff)) CheckUp(sinfo);

	sinfo->nodes++;

	ASSERT(CheckBrd(brd));

	// if we are not the root of the tree and we have a repetition
	// or we exceeded the fifty move rule, then we have a draw and return 0
	if((IsRep(brd) || brd->fifty >= 100) && brd->ply) return 0;
	if(brd->ply >= MAXDEPTH-1) return Eval(brd);	// if we are too deep, we return

	// test if we are in check
	int check = SqAttacked(brd, LOCATEBIT(brd->bb[brd->side][King]), brd->side^1);
	if(check) depth++;

	int score = -INFINITE;
	int pvMain = NO_MOVE;
	// check the transposition table if we have searched the current position before
	// if so, return what we found
	if(TestHashTable(brd, &pvMain, &score, alpha, beta, depth)) return score;

	// Before we search, we try how we do if we don't make a move
	// i.e. make a null move
	if( null && !check && brd->ply && depth >= 4 &&
		(brd->all[brd->side]^brd->bb[brd->side][Pawn]^brd->bb[brd->side][King]) )
	{
		MakeMoveNull(brd);
		// We cannot do two null moves in a row so we set the null argument here to false
		score = -AlphaBeta(brd, -beta, -beta + 1, depth-4, sinfo, false);
		TakeBackNull(brd);

		if(sinfo->stop){
			return 0;
		}
		if(score >= beta){
			return beta;
		}
	}

	mlist_t list;
	int i;
	int legal = 0;
	int bestMove = NO_MOVE;
	int bestScore = -INFINITE;
	int oldAlpha = alpha;
	score = -INFINITE;

	GenMoves(brd, &list);

	// we tested our transposition table for the best move 'pvMain'
	// if it exists we will set this move as the first move to be searched
	if(pvMain != NO_MOVE){

		if(MakeMove(brd, pvMain)){
			score = -AlphaBeta(brd, -beta, -alpha, depth-1, sinfo, true);
			TakeBack(brd);

			bestScore = score;
			if(score > alpha){
				if(score >= beta){
					if(!(pvMain & FLAGCAP)){
						brd->betaMoves[1][brd->ply] = brd->betaMoves[0][brd->ply];
						brd->betaMoves[0][brd->ply] = pvMain;
					}
					return beta;
				}
				alpha = score;
				bestMove = pvMain;
			}
		}
		/*/
		for(i = 0; i < list.len; i++){
			if(list.move[i].move == pvMain){
				list.move[i].score = 5000000;
				break;
			}
		}//*/
	}

	for(i = 0; i < list.len; i++) // Loop through all moves
	{
		if(sinfo->stop) return 0;

		SelectNextMove(&list, i);

		if(!MakeMove(brd, list.move[i].move)) continue;

		legal++; // we have found a legal move so we need not check for mate afterwards
		// call AlphaBeta in a negamax fashion
		score = -AlphaBeta(brd, -beta, -alpha, depth-1, sinfo, true);
		TakeBack(brd);

		if(score > bestScore){
			bestScore = score;
			if(score > alpha){
				if(score >= beta){
					if(legal==1) sinfo->fhf++; 	// count the number of beta cutoffs searched first
					sinfo->fh++;				// compared to all beta cutoffs (measure of efficiency)
					if(!(list.move[i].move & FLAGCAP)){
						brd->betaMoves[1][brd->ply] = brd->betaMoves[0][brd->ply];
						brd->betaMoves[0][brd->ply] = list.move[i].move;
					}
					// Store the move in the transposition table as a beta (killer) move
					StorePvMove(brd, bestMove, depth, beta, HFBETA);
					return beta;
				}
				alpha = score;
				bestMove = list.move[i].move;
			}
		}
	}
	if(legal == 0){ // We havn't found a legal move
		if(check){
			// if we are in check it is mate; but we want the shortest path
			// to it so we'll subtract the path length
			return -MATE + brd->ply;
		}
		return 0; // Stalemate
	}

	if(oldAlpha != alpha){
		// Store exact (normal) transposition entry
		StorePvMove(brd, bestMove, depth, bestScore, HFEXACT);
	}
	else {
		// Store alpha cutoff transposition entry
		StorePvMove(brd, bestMove, depth, alpha, HFALPHA);
	}

	return alpha;
}