Ejemplo n.º 1
0
/*
 * We always try the maximize the board value
 */
int Board::search(int depth, int alpha, int beta)
{
    int actValue= -14999+depth, value;
    Move m;
    MoveList list;
    bool depthPhase, doDepthSearch;

    searchCalled++;

    /* We make a depth search for the following move types... */
    int maxType = (depth < maxDepth-1)  ? Move::maxMoveType() :
					  (depth < maxDepth)    ? Move::maxPushType() :
								  Move::maxOutType();

    generateMoves(list);

#ifdef MYTRACE

    int oldRatedPositions;
    int oldWonPositions;
    int oldSearchCalled;
    int oldMoveCount;
    int oldNormalCount;
    int oldPushCount;
    int oldOutCount;
    int oldCutoffCount;

    spyDepth = depth;

    moveCount += list.getLength();

    /*
	  if (spyLevel>1) {
	  indent(depth);
	  qDebug("%s (%6d .. %6d) MaxType %s\n", depth,
	  (color==color1)?"O":"X", alpha,beta,
		 (depth < maxDepth-1) ? "Moving" :
		 (depth < maxDepth)? "Pushing" : "PushOUT" );
	}
	*/
#endif

    /* check for a old best move in main combination */
    if (inPrincipalVariation) {
	m = pv[depth];

	if ((m.type != Move::none) &&
	    (!list.isElement(m, 0, true)))
	    m.type = Move::none;

	if (m.type == Move::none)
	    inPrincipalVariation = false;

#ifdef MYTRACE
	else {
	    if (spyLevel>1) {
		indent(spyDepth);
		qDebug("Got from pv !\n" );
	    }
	}
#endif
    }

    // first, play all moves with depth search
    depthPhase = true;

    while (1) {

	// get next move
	if (m.type == Move::none) {
	    if (depthPhase)
		depthPhase = list.getNext(m, maxType);
	    if (!depthPhase)
		if (!list.getNext(m, Move::none)) break;
	}
	// we could start with a non-depth move from principal variation
	doDepthSearch = depthPhase && (m.type <= maxType);

#ifdef MYTRACE

	if (m.isOutMove()) outCount++;
	else if (m.isPushMove()) pushCount++;
	else normalCount++;

	if (doDepthSearch) {
	    oldRatedPositions = ratedPositions;
	    oldWonPositions = wonPositions;
	    oldSearchCalled = searchCalled;
	    oldMoveCount = moveCount;
	    oldNormalCount = normalCount;
	    oldPushCount = pushCount;
	    oldOutCount = outCount;
	    oldCutoffCount = cutoffCount;

	    if (spyLevel>1) {
		indent(spyDepth);
		qDebug("%s [%6d .. %6d] ",
		       (color==color1)?"O":"X", alpha,beta);
		m.print();
		qDebug("\n");
	    }

#ifdef SPION
	    if (bUpdateSpy) emit update(depth, 0, m, false);
#endif
	}
#endif

	playMove(m);
	if (!isValid()) {
	    /* Possibility (1) to win: Piece Count <9 */
	    value = 14999-depth;
	    //  value = ((depth < maxDepth) ? 15999:14999) - depth;
#ifdef MYTRACE
	    wonPositions++;
#endif
	}
	else {

	    if (doDepthSearch) {
		/* opponent searches for his maximum; but we want the
	       * minimum: so change sign (for alpha/beta window too!)
	       */
		value = - search(depth+1,-beta,-alpha);
	    }
	    else {
		ratedPositions++;

		value = calcEvaluation();
	    }
	}
	takeBack();

	/* For GUI response */
	if (doDepthSearch && (maxDepth - depth >2))
	    emit searchBreak();

#ifdef MYTRACE

	if (doDepthSearch) {
	    spyDepth = depth;

	    if (spyLevel>1) {

		indent(spyDepth);
		if (oldSearchCalled < searchCalled) {
		    qDebug("  %d Calls", searchCalled-oldSearchCalled);
		    if (cutoffCount>oldCutoffCount)
			qDebug(" (%d Cutoffs)", cutoffCount-oldCutoffCount);
		    qDebug(", GenMoves %d (%d/%d/%d played)",
			   moveCount - oldMoveCount,
			   normalCount - oldNormalCount,
			   pushCount-oldPushCount,
			   outCount-oldOutCount);
		    qDebug(", Rate# %d",
			   ratedPositions+wonPositions
			   - oldRatedPositions - oldWonPositions);
		    if (wonPositions > oldWonPositions)
			qDebug(" (%d Won)", wonPositions- oldWonPositions);
		    qDebug("\n");
		    indent(spyDepth);
		}

		qDebug("  => Rated %d%s\n",
		       value,
		       (value>14900)  ? ", WON !":
					(value>=beta)  ? ", CUTOFF !":
							 (value>actValue)  ? ", Best !": "");
	    }
	}
	else {
	    if (spyLevel>2) {
		indent(spyDepth);
		qDebug("%s (%6d .. %6d) %-25s => Rating %6d%s\n",
		       (color==color1)?"O":"X", alpha,beta,
		       m.name().toLatin1(),
		       value,
		       (value>14900)  ? ", WON !":
					(value>=beta)  ? ", CUTOFF !":
							 (value>actValue)  ? ", Best !": "");
	    }
	}

	if (value>=beta) cutoffCount++;
#endif

#ifdef SPION
	if (bUpdateSpy) {
	    if (value > actValue)
		emit updateBest(depth, value, m, value >= beta);
	    emit update(depth, value, m, true);
	}
#endif
	if (value > actValue) {
	    actValue = value;
	    pv.update(depth, m);

	    // Only update best move if not stopping search
	    if (!breakOut && (depth == 0)) {
		_bestMove = m;

		if (bUpdateSpy) {
		    emit updateBestMove(m, actValue);
#ifdef MYTRACE
		    if (spyLevel>0) {
			int i;
			qDebug(">      New pv (Rating %d):", actValue);
			for(i=0;i<=maxDepth;i++) {
			    qDebug("\n>          D %d: %s",
				   i, pv[i].name().toLatin1() );
			}
			qDebug("\n>\n");
		    }
#endif
		}
	    }

	    if (actValue>14900 || actValue >= beta)
		return actValue;

	    /* maximize alpha */
	    if (actValue > alpha) alpha = actValue;
	}

	if (breakOut) depthPhase=false;
	m.type = Move::none;
    }

    return actValue;
}
Ejemplo n.º 2
0
/*
 * We always try the maximize the board value
 */
int Board::search(int depth, int alpha, int beta)
{
	int actValue=-16000, value;
	Move m;
	MoveList list;
	bool stop = false;

	/* We make a depth search for the following move types... */
	int maxType = (depth < maxDepth/2) ? Move::maxMoveType() :
	              (depth < maxDepth)   ? Move::maxPushType() : 
                                             Move::maxOutType();

	generateMoves(list);

#ifdef MYTRACE
	printf(">>>>>>>> Depth %d\n", depth);
#endif
	
	/* check for a old best move in main combination */
	if (inMainCombination) {
		m = mc[depth];
		if (!list.isElement(m, 0)) 
		  m.type = Move::none;
		if (m.type == Move::none)
		  inMainCombination = false;
		if (m.type > maxType)
		  m.type = Move::none;
	}
	if (m.type == Move::none)
	  stop = !list.getNext(m, maxType);

	/* depth first search */
	while(!stop) {

#ifdef MYTRACE
	  indent(depth);
	  m.print();
	  printf("\n");
#endif	
		
#ifdef SPION
	  	if (bUpdateSpy) emit update(depth, 0, m, false);
#endif
		playMove(m);
		if (!isValid())
		  value = ((depth < maxDepth) ? 15999:14999) - depth;
		else {
		  /* opponent searches for his maximum; but we won't the
		   * minimum: so change sign (for alpha/beta window too!)
		   */
		  value = - search(depth+1,-beta,-alpha);
		}
		takeBack();

		/* For GUI response */
		if (maxDepth - depth >2)
		  emit searchBreak();		

#ifdef MYTRACE	
		indent(depth);
		printf("=> (%d - %d): Value %d [ %d ] for ",
		       alpha, beta, value,actValue);
		m.print();
	  printf("\n");
#endif

#ifdef SPION
		if (bUpdateSpy) {
		  if (value > actValue)
		    emit updateBest(depth, value, m, value >= beta);
		  emit update(depth, value, m, true);
		}		  
#endif
		if (value > actValue) {
			actValue = value;
			mc.update(depth, m);

			if (bUpdateSpy && depth == 0)
			  emit updateBestMove(m, actValue);
			
			if (actValue >= beta) {
#ifdef MYTRACE
			  indent(depth);
			  printf("CUTOFF\n");
#endif
			  return actValue;
			}			
			if (actValue > alpha) alpha = actValue;
		}
		
		stop = (!list.getNext(m, maxType)) || breakOut;
	}
	
	/* other moves: calculate rating */
	while(list.getNext(m, Move::none)) {
		
		playMove(m);
		if (!isValid())
		  value = ((depth < maxDepth) ? 15999:14999) - depth;
		else
		  value = calcValue();
		takeBack();

#ifdef SPION
		if (bUpdateSpy) {
		  if (value > actValue)
		    emit updateBest(depth, value, m, value >= beta);
		  emit update(depth, value, m, true);
		}		  
#endif

#ifdef MYTRACE
		indent(depth);
		printf("> (%d - %d): Value %d [ %d ] for ",
		       alpha, beta, value, actValue);
		m.print();
		printf("\n");
#endif
		if (value > actValue) {
			actValue = value;
			mc.update(depth, m);

			if (actValue >= beta) {
#ifdef MYTRACE
			  indent(depth);
			  printf("CUTOFF\n");
#endif
			  break;
			}
			
			if (actValue > alpha) alpha = actValue;
		}
	}	
	return actValue;
}