예제 #1
0
Move nextMoveDo(Position* position, Moves* moves){
	guint index;
	gint value;
	Move move;
	if(moves->state == START){
		dinamicMovesGenerate(position, moves);
		moves->state = DINAMIC;
	}
	while(moves->next < moves->size){
		if(moves->next >= moves->toSort){
			moves->toSort = moves->size;
			for(index = moves->size-1; index>moves->next; index--){
				if(moves->eval[index-1] < moves->eval[index]){
					value = moves->eval[index];
					moves->eval[index] = moves->eval[index-1];
					moves->eval[index-1] = value;
			
					move = moves->move[index];
					moves->move[index] = moves->move[index-1];
					moves->move[index-1] = move;
					moves->toSort = index;
				}
			}
		}
		if(moveDo(position,moves->move[moves->next])){
			moves->next ++;
			return moves->move[moves->next-1];
		}
		moves->next ++;
	}
	if(moves->state == DINAMIC){
		staticMovesGenerate(position, moves);
		moves->state = STATIC;
		while(moves->next < moves->size){
			if(moves->next >= moves->toSort){
				moves->toSort = moves->size;
				for(index = moves->size-1; index>moves->next; index--){
					if(moves->eval[index-1] < moves->eval[index]){
						value = moves->eval[index];
						moves->eval[index] = moves->eval[index-1];
						moves->eval[index-1] = value;
			
						move = moves->move[index];
						moves->move[index] = moves->move[index-1];
						moves->move[index-1] = move;
						moves->toSort = index;
					}
				}
			}
			if(moveDo(position,moves->move[moves->next])){
				moves->next ++;
				return moves->move[moves->next-1];
			}
			moves->next ++;
		}		
	}
	return Empty;
}
예제 #2
0
void stringMovesDo(Position* position, gchar moves[]){
	guint index=0, gindex;
	RootMoves gmoves;
	gchar smove[6], sgmove[6];
	gboolean found;
	gboolean last = FALSE;
	while(!last){
		rootMovesGenerate(position, &gmoves);
		smove[0] = '\0';
		sscanf(moves,"%s",smove);
		if(moves[strlen(smove)] == '\0' || moves[strlen(smove)] == '\n') last = TRUE;
		if(strlen(smove) == 0) break;
		moves = g_strstr_len(moves, strlen(moves), smove) + strlen(smove);
		found = FALSE;
		for(gindex = 0; gindex<gmoves.size; gindex++){
			moveToString(gmoves.move[gindex].move, sgmove);
			if(!g_ascii_strcasecmp(smove, sgmove)){
				found = TRUE;
				if(!moveDo(position,gmoves.move[gindex].move)){
					positionPrint(position);
					g_error("Wrong move:%s\n",smove);
				}
				break;
			}		
		}
		if(!found){
			positionPrint(position);
		    g_error("Can not make move (%s)!\n",smove);
		}
		index++;
	}
}
예제 #3
0
void hashCollectPV(Position* position, Move pv[]){
	HashData* hd;
	guint64 hData;
	guint index = 0;
	while(hashFind(&hd,position->key,&hData)){
		if(index < Max_Pv-1 && hashMove(hData) != Empty){
			pv[index] = hashMove(hData);
			moveDo(position,pv[index]);
			index++;
		}
		else break;
	}
	
	pv[index] = Empty;
	while(index>0){
		moveUndo(position);
		index--;
	}
}
예제 #4
0
gint threadSearch(Position* position, gint alpha, gint beta, gint depth, gint hight, const gboolean nullMove, const gboolean nodePV){
	Moves moves;
	Move move, bestMove = Empty, hMove = Empty, pMove=Empty;
	gboolean extend=FALSE, endGamePhase;
	gint eval, tmpDepth, movesSearched = 0, pAlpha, pType;
	guint idleThreads;
	guint64 key = position->key, hData;
	HashData* hd;

	if(stopFlag == TRUE && !ponderSearch) return EVAL_DRAW;

	searchNodes++;

	/* Draw */
	if(positionRepeat(position) >= 1 || position->staticMoves >= 100) return EVAL_DRAW;

	/* End game */
	gint numberOfPieces = numberOfBits64(position->allPieces);
	if(numberOfPieces <= 5 && egbbIsLoaded()){
		tmpDepth = (2 * iterativeDepth) / 3;
		if((numberOfPieces <= 4 || hight <= tmpDepth) &&
			(hight >= tmpDepth || positionEvalEG(position))){
			if(egbbProbe(position, &eval)){
				if(eval < 0) return eval + hight * 40 + positionMaterial(position);
				if(eval > 0) return eval - hight * 40 + positionMaterial(position);
				return eval;
			}
		}
	}

	/* Mate distance pruning */
	eval = -EVAL_MATE + hight;
	if(eval > alpha){
		if(eval >= beta) return eval;
		alpha = eval;
	}

	eval = EVAL_MATE - hight;
	if(eval < beta){
		if(eval <= alpha) return eval;
		beta = eval;
	}

	/* Hash */
	if(hashFind(&hd,key,&hData)){
		hMove = hashMove(hData);
        if(!nodePV && (gint)hashDepth(hData) >= depth){
			if(hashFlag(hData) == EXACT) return hashEval(hData);
			else if(hashFlag(hData) == ALPHA && hashEval(hData) > alpha){
				bestMove = hashMove(hData);
				alpha = hashEval(hData);
                if(alpha >= beta) return alpha;
			}
			else if(hashFlag(hData) == BETA && hashEval(hData) < beta){
				beta = hashEval(hData);
				if(alpha >= beta) return beta;
			}
		}
	}

	/* Extension */	
	if(position->extend || (nodePV && passedPawnMove(position))){
		depth ++;
		extend = TRUE;
	}

	/* Horizon */
	if(depth < 1){
		eval = quiescent(position,alpha,beta,hight+1,TRUE);
		return eval;
	}

	if(position->phase <= 7 && numberOfPieces <= 10) endGamePhase = TRUE;
	else endGamePhase = FALSE;

	/* Null move pruning */
	if (!nodePV && nullMove && depth>2 && !extend && !endGamePhase){
		if(depth > 6) tmpDepth = depth - 4;
		else tmpDepth = depth - 3;
		moveDo(position,Null_Move);
		eval = -threadSearch(position,-beta,-beta+1,tmpDepth,hight+1,FALSE,FALSE);
		moveUndo(position);
		if(eval >= beta){
			hashWrite(hd,key,depth,eval,ALPHA,Empty);
			return eval;
		}
	}

	/* Internal Iterative Deepening */
	tmpDepth = depth/2;
	if(nodePV && hMove == Empty && depth > 3 && tmpDepth >= (gint)hashDepth(hData)){
		threadSearch(position,alpha, beta, tmpDepth, hight, FALSE,nodePV);
		if(hashFind2(hd,key,&hData)) hMove = hashMove(hData);
	}

	/* First move */
	moves.state = START;
	if(hMove != Empty){
		move = hMove;
		moveDo(position,move);
	}
	else move = nextMoveDo(position,&moves);
	
	if(move != Empty){
		eval = -threadSearch(position, -beta, -alpha, depth-1, hight+1, TRUE,nodePV);
		if(eval > alpha){
			if(eval >= beta){
				moveUndo(position);
				if(moves.state == STATIC) history[moveGetFrom(move)][moveGetTo(move)] += 1<<depth;
				hashWrite(hd,key,depth,eval,ALPHA,move);
				return eval;
			}
			alpha = eval;
			bestMove = move;
		}
		moveUndo(position);
		movesSearched ++;
	}

	/* Parallel search*/
	idleThreads = searchThreads;

	while(TRUE){
		if(idleThreads > 0){
			move = nextMoveDo(position,&moves);
			/* Last moves searched sequential */
			if(move == Empty){
				parallelStopFlag = TRUE;
				moves.size = moves.next = 0;
				while(idleThreads != searchThreads){
					parallelSearchResult(&pMove,&pAlpha,&pType);
					idleThreads++;
					moves.move[moves.size] = pMove;
					moves.size ++;
				}
				parallelStopFlag = FALSE;
				moves.toSort = moves.size;
				break;
			}
			/* History pruning */
			if(!nodePV && movesSearched >= HistoryFullDepthMoves && depth > HistoryReductionLimit && 
				!extend && !position->extend){
				idleThreads--;
				parallelSearch(position, move, -(alpha+1), -alpha, depth-2, hight+1,TRUE,HP,FALSE);
				moveUndo(position);
				movesSearched ++;
			}
			else{ /* PVS */
				idleThreads--;
				parallelSearch(position, move, -(alpha+1), -alpha, depth-1, hight+1,TRUE,PVS,FALSE);
				moveUndo(position);
				movesSearched ++;
			}
		}
		else{
			eval = -parallelSearchResult(&pMove,&pAlpha,&pType);
			idleThreads++;
			pAlpha = -pAlpha - 1;
			if(pType == HP && eval > pAlpha){ /* HP */
				idleThreads--;
				moveDo(position,pMove);
				parallelSearch(position, pMove, -(pAlpha+1), -pAlpha, depth-1, hight+1,TRUE,PVS,FALSE);
				moveUndo(position);
				continue;
			}
			if(pType == PVS && eval > pAlpha && eval < beta){ /* PVS research */
				idleThreads--;
				moveDo(position,pMove);
				parallelSearch(position, pMove, -beta, -pAlpha, depth-1, hight+1,TRUE,RPVS,nodePV);
				moveUndo(position);
				continue;
			}
			if(eval > alpha){
				if(eval >= beta){
					parallelSearchStop(idleThreads);
					if(moveGetType(pMove) == Normal) history[moveGetFrom(pMove)][moveGetTo(pMove)] += 1<<depth;
					hashWrite(hd,key,depth,eval,ALPHA,pMove);
					return eval;
				}
				alpha = eval;
				bestMove = pMove;
			}
		}
	}

	/* Last moves searched sequential */
	move = nextMoveDo(position,&moves);
	while(move != Empty){
		/* History pruning */
		if(!nodePV && movesSearched >= HistoryFullDepthMoves && depth > HistoryReductionLimit && 
			!extend && !position->extend){
			eval = -threadSearch(position, -(alpha+1), -alpha, depth-2, hight+1, TRUE, FALSE);
		}
		else eval = alpha + 1;

		/* PVS */
		if(eval > alpha){
			eval = -threadSearch(position, -(alpha+1), -alpha, depth-1, hight+1, TRUE, FALSE);
			if(eval > alpha && eval < beta)
				eval = -threadSearch(position, -beta, -alpha, depth-1, hight+1, TRUE, nodePV);
		}
		moveUndo(position);
		if(eval > alpha){
			if(eval >= beta){
				if(moveGetType(pMove) == Normal) history[moveGetFrom(move)][moveGetTo(move)] += 1<<depth;
				hashWrite(hd,key,depth,eval,ALPHA,move);
				return eval;
			}
			alpha = eval;
			bestMove = move;
		}
		movesSearched ++;
		move = nextMoveDo(position,&moves);
	}

	/* Mate or pat */
	if(movesSearched == 0){
		if(position->inCheck == TRUE){
			eval = -EVAL_MATE+hight;
			hashWrite(hd,key,depth,eval,EXACT,Empty);
			return eval;
		}
		else{  
			hashWrite(hd,key,depth,EVAL_DRAW,EXACT,Empty);
			return EVAL_DRAW;
		}
	}

	/* hash is update */
	if(bestMove != Empty) hashWrite(hd,key,depth,alpha,EXACT,bestMove);
	else hashWrite(hd,key,depth,alpha,BETA,hMove);

	return alpha;
}