/* * 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; }
int MinimaxStrategy::minimax() { Move m; MoveList list; // int maxEval, minEval; int bestEval; int eval; int sign; if(current_depth == MAX_DEPTH) return evaluate(); bestEval = -17000; // maxEval = -17000; // minEval = 17000; generateMoves(list); if(evaluate() == 16000) { if(current_depth == 0) finishedNode(0,0); pretty_print("current_depth", current_depth); return ((current_depth % 2) ==0) ? -16000 : 16000; } if((MAX_DEPTH-current_depth)%2 == 1) sign = 1; else sign = -1; while(list.getNext(m)) { if(current_depth < MAX_DEPTH) { current_depth++; playMove(m); eval=minimax(); takeBack(); current_depth--; } if(sign*eval > bestEval) { bestEval = sign*eval; if(unlikely(current_depth == 0)) { pretty_print("Eval", bestEval); foundBestMove(0, m, eval); } } #if 0 if((MAX_DEPTH - current_depth +1) % 2 == 0) { if(eval > maxEval) { maxEval=eval; if(current_depth == 0) { pretty_print("Eval", eval); foundBestMove(0, m, eval); } } } else { if(eval < minEval) { minEval=eval; if(current_depth == 0) { pretty_print("Eval2", eval); foundBestMove(0, m, eval); } } } #endif } bestEval = sign*bestEval; if(current_depth == 0) finishedNode(0,0); #if 0 if((MAX_DEPTH - current_depth +1) % 2 == 0) return maxEval; else return minEval; #endif return bestEval; }
Move Board::moveToReach(Board* b, bool fuzzy) { Move m; /* can not move from invalid position */ int state = validState(); if ((state != valid1) && (state != valid2)) return m; if (!fuzzy) { if (b->moveNo() != _moveNo+1) { if (_verbose) printf("Board::moveToReach: moveNo %d => %d ?!\n", _moveNo, b->moveNo()); return m; } /* only time left for player can have decreased */ int opponent = (color == color1) ? color2 : color1; if (_msecsToPlay[opponent] != b->msecsToPlay(opponent)) { if (_verbose) printf("Board::moveToReach: Opponent time changed ?!\n"); return m; } if (_msecsToPlay[color] < b->msecsToPlay(color)) { if (_verbose) printf("Board::moveToReach: Player time increased ?!\n"); return m; } } /* detect move drawn */ MoveList l; generateMoves(l); if (_verbose) { printf("Board::moveToReach - %d allowed moves:\n", l.getLength()); Move found; int type = Move::none; while(l.getNext(m, Move::maxMoveType)) { playMove(m); bool isSame = hasSameFields(b); takeBack(); if (isSame) found = m; if (m.type != type) { type = m.type; printf(" %s:\n", m.typeName()); } printf(" %s%s\n", m.name(), isSame ? " <== Choosen":""); } m = found; } else { while(l.getNext(m, Move::maxMoveType)) { playMove(m); bool isSame = hasSameFields(b); takeBack(); if (isSame) break; } } return m; }
int MinimaxStrategy::minimax() { Move m; Move bestestMove; //;-p This is the cumulative best move among all threads. MoveList list; int bestEval; int eval; int sign; int move_counter=0; int i=0; if(current_depth == MAX_DEPTH) return evaluate(); bestEval = -17000; generateMoves(list); if(evaluate() == 16000) { if(current_depth == 0) finishedNode(0,0); pretty_print("current_depth", current_depth); return ((current_depth % 2) ==0) ? -16000 : 16000; } if(current_depth == 0) { for(i=0;i<thread_rank;i++) list.getNext(m); } if((MAX_DEPTH-current_depth)%2 == 1) sign = 1; else sign = -1; while(list.getNext(m)) { if(current_depth < MAX_DEPTH) { current_depth++; playMove(m); eval=minimax(); takeBack(); current_depth--; } if(sign*eval > bestEval) { bestEval = sign*eval; if(unlikely(current_depth == 0)) { pretty_print("Eval", bestEval); foundBestMove(0, m, eval); } } if(current_depth == 0) { for(i=1;i<num_threads;i++) list.getNext(m); } } bestEval = sign*bestEval; if(current_depth == 0) { if(thread_rank==0) { Move *moves=NULL; int *eval_results; moves=(Move*)malloc((num_threads -1)*sizeof(Move)); eval_results=(int*)malloc((num_threads - 1)*sizeof(int)); //all threads send value to thread 0 for(int i=1;i<num_threads;i++) { MPI_Status status; MPI_Recv((void*)&moves[i-1], sizeof(Move), MPI_BYTE, i, 10, MPI_COMM_WORLD, &status); MPI_Recv(&eval_results[i-1], 1, MPI_INT, i, 10, MPI_COMM_WORLD, &status); } bestestMove=_bestMove; for(int i=0;i<num_threads-1;i++) { if(sign*eval_results[i] > sign*bestEval) { bestEval = eval_results[i]; bestestMove=moves[i]; } } for(int i=1;i<num_threads;i++) { MPI_Send (&bestestMove, sizeof(Move), MPI_BYTE, i, 10, MPI_COMM_WORLD); MPI_Send (&bestEval, 1, MPI_INT, i, 10, MPI_COMM_WORLD); } } else { MPI_Send (&_bestMove, sizeof(Move), MPI_BYTE, 0, 10, MPI_COMM_WORLD); MPI_Send (&bestEval, 1, MPI_INT, 0, 10, MPI_COMM_WORLD); MPI_Status status; MPI_Recv(&bestestMove, sizeof(Move), MPI_BYTE, 0, 10, MPI_COMM_WORLD, &status); MPI_Recv(&bestEval, 1, MPI_INT, 0, 10, MPI_COMM_WORLD, &status); } foundBestMove(0, bestestMove, bestEval); finishedNode(0,0); } return bestEval; }
int main() { char line[256]; char args[4][64]; /* It mainly calls ComputerThink(maxdepth) to calculate to desired ply */ char s[256]; int from; int dest; int i; hashRndInit(); startgame (); maxDepth = 6; /* Max depth to search */ MOVE moveBuf[200]; MOVE theBest; int movecnt; /* Belka */ puts (" \n Kitteneitor version June 5th 2013 by Emilio Diaz \n =================================================\n\n"); puts (" Help overview:"); puts (" making a move: e.g. e2e4, c7c5, a7a8q, e1g1 etc."); puts (" d ............ displaying current board"); puts (" on ........... forcing the engine to move"); puts (" sd <n> ....... setting depth to <n> plies"); puts (" undo ......... taking back last move (ply)"); puts (" quit ......... quit console application \n\n"); /* Belka */ side = WHITE; computerSide = BLACK; /* Human is white side */ hdp = 0; /* Current move order */ for (;;) { fflush (stdout); if (side == computerSide) { /* Computer's turn */ theBest = ComputerThink (maxDepth); if (theBest.type_of_move > 8) printf ("type of move the best %d \n", theBest.type_of_move); makeMove (theBest); /* Just the move without pawn crown */ printf("move %c%d%c%d", 'a' + COL(theBest.from), 8 - ROW(theBest.from), 'a' + COL(theBest.dest), 8 - ROW(theBest.dest)); /* Check whether it's a crown */ switch (theBest.type_of_move) { case MOVE_TYPE_PROMOTION_TO_QUEEN: printf("q\n"); break; case MOVE_TYPE_PROMOTION_TO_ROOK: printf("r\n"); break; case MOVE_TYPE_PROMOTION_TO_BISHOP: printf("b\n"); break; case MOVE_TYPE_PROMOTION_TO_KNIGHT: printf("n\n"); break; default: printf("\n"); } /* end switch */ printBoard (); printf ("Castle rights: %d\n", castle); fflush (stdout); continue; } printf ("k> "); /* Get user input */ if (!fgets (line, 256, stdin)) return 0; if (line[0] == '\n') continue; sscanf (line, "%s", s); // if (scanf ("%s", s) == EOF) /* Shut down the program */ // return 0; if (!strcmp (s, "d")) { printBoard (); continue; } if (!strcmp (s, "test1")) { test1 (); printBoard(); continue; } if (!strcmp (s, "test2")) { test2 (); printBoard(); continue; } if (!strcmp (s, "test3")) { test3 (); printBoard(); continue; } if (!strcmp (s, "test4")) { test4 (); printBoard(); continue; } if (!strcmp (s, "test5")) { test5 (); printBoard(); continue; } if (!strcmp (s, "test6")) { test6 (); printBoard(); continue; } if (!strcmp (s, "test7")) { test7 (); printBoard(); continue; } if (!strcmp (s, "test8")) { test8 (); printBoard(); continue; } if (!strcmp (s, "test9")) { test9 (); printBoard(); continue; } if (!strcmp (s, "test10")) { test10 (); printBoard(); continue; } if (!strcmp (s, "test11")) { test11 (); printBoard(); continue; } if (!strcmp (s, "test12")) { test12 (); printBoard(); continue; } if (!strcmp (s, "test13")) { test13 (); printBoard(); continue; } if (!strcmp (s, "test14")) { test14 (); printBoard(); continue; } if (!strcmp (s, "testMoveGen")) //Belka: McKenzie test position { testMoveGen(); printBoard(); continue; } if (!strcmp (s, "testEvalSym")) //Belka: McKenzie test position { testEvalSym(); continue; } if (!strcmp (s, "countNodes")) { countNodes(); continue; } if (!strcmp (s, "testWhitePassedPawns")) { testWhitePassedPawns (); continue; } if (!strcmp (s, "testBlackPassedPawns")) { testBlackPassedPawns (); continue; } if (!strcmp (s, "testWhiteDoubledPawns")) { testWhiteDoubledPawns (); continue; } if (!strcmp (s, "testBlackDoubledPawns")) { testBlackDoubledPawns (); continue; } if (!strcmp (s, "testIsIsolatedPawnWhite")) { testIsIsolatedPawnWhite (); continue; } if (!strcmp (s, "testIsIsolatedPawnBlack")) { testIsIsolatedPawnBlack (); continue; } if (!strcmp (s, "showPawnsInfo")) { showPawnsInfo (); continue; } if (!strcmp (s, "testisSqProtectedByAPawn")) { testisSqProtectedByAPawn(); continue; } // if (!strcmp (s, "testIsSqProtectedByAKnight")) // { // testIsSqProtectedByAKnight(); // continue; // } // if (!strcmp (s, "testIsSqProtectedByABishop")) // { // testIsSqProtectedByABishop(); // continue; // } if (!strcmp (s, "testOpenCols")) { testOpenCols(); continue; } if (!strcmp (s, "undo")) { takeBack (); printBoard (); computerSide = (WHITE + BLACK) - computerSide; continue; } if (!strcmp(s,"setboard")) { strcpy(fenBuf, ""); sscanf(line, "setboard %s %s %s %s", args[0],args[1],args[2],args[3]); strcat(fenBuf, args[0]); strcat(fenBuf, args[1]); strcat(fenBuf, args[2]); strcat(fenBuf, args[3]); setBoard(fenBuf); continue; } if (!strcmp (s, "xboard")) { xboard (); return 0; } if (!strcmp (s, "on")) { computerSide = side; continue; } if (!strcmp (s, "pass")) { side = (WHITE + BLACK) - side; computerSide = (WHITE + BLACK) - side; continue; } if (!strcmp (s, "sd")) { sscanf (line, "sd %d", &maxDepth); continue; } // if (!strcmp (s, "fen")) // { // strcpy (fenstring, ""); // sscanf (linea, "fen %s %s %s %s", args[0], args[1], args[2], // args[3]); // strcat (fenstring, args[0]); // strcat (fenstring, args[1]); // strcat (fenstring, args[2]); // strcat (fenstring, args[3]); // fen (fenstring); // } if (!strcmp (s, "perft")) { sscanf (line, "perft %d", &maxDepth); clock_t start; clock_t stop; double t = 0.0; /* Start timer */ start = clock (); U64 count = perft (maxDepth); /* Stop timer */ stop = clock (); t = (double) (stop - start) / CLOCKS_PER_SEC; // printf ("nodes = %'llu\n", count); printf ("nodes = %8" PRId64 "\n", count); // Belka printf ("time = %.2f s\n", t); continue; } if (!strcmp (s, "quit")) { printf ("Good bye!\n"); return 0; } /* Maybe the user entered a move? */ from = s[0] - 'a'; from += 8 * (8 - (s[1] - '0')); dest = s[2] - 'a'; dest += 8 * (8 - (s[3] - '0')); ply = 0; movecnt = genMoves (side, moveBuf); /* Loop through the moves to see whether it's legal */ for (i = 0; i < movecnt; i++) if (moveBuf[i].from == from && moveBuf[i].dest == dest) { /* Promotion move? */ if (piece[from] == PAWN && (dest < 8 || dest > 55)) { switch (s[4]) { case 'q': moveBuf[i].type_of_move = MOVE_TYPE_PROMOTION_TO_QUEEN; break; case 'r': moveBuf[i].type_of_move = MOVE_TYPE_PROMOTION_TO_ROOK; break; case 'b': moveBuf[i].type_of_move = MOVE_TYPE_PROMOTION_TO_BISHOP; break; case 'n': moveBuf[i].type_of_move = MOVE_TYPE_PROMOTION_TO_KNIGHT; break; default: puts("Promoting to a McGuffin..., I'll give you a queen"); moveBuf[i].type_of_move = MOVE_TYPE_PROMOTION_TO_QUEEN; } } if (!makeMove (moveBuf[i])) { takeBack (); printf ("Illegal move.\n"); } break; } printBoard (); } }
void xboard() { char line[256], command[256], c; char args[4][64]; int from, dest, i; MOVE moveBuf[200]; MOVE theBest; int movecnt; //int illegal_king = 0; signal(SIGINT, SIG_IGN); printf ("\n"); // hashKeyPosition(); /* hash of the initial position */ // hashRndInit(); startgame (); /* Waiting for a command from GUI */ for (;;) { fflush (stdout); if (side == computerSide) { /* Computer's turn */ /* Find out the best move to reply to the current position */ theBest = ComputerThink (maxDepth); if (theBest.type_of_move > 8) printf ("type of move the best %d \n", theBest.type_of_move); makeMove (theBest); /* send move */ switch (theBest.type_of_move) { case MOVE_TYPE_PROMOTION_TO_QUEEN: c = 'q'; break; case MOVE_TYPE_PROMOTION_TO_ROOK: c = 'r'; break; case MOVE_TYPE_PROMOTION_TO_BISHOP: c = 'b'; break; case MOVE_TYPE_PROMOTION_TO_KNIGHT: c = 'n'; break; default: c = ' '; } printf ("move %c%d%c%d%c\n", 'a' + COL(theBest.from), 8 - ROW(theBest.from), 'a' + COL(theBest.dest), 8 - ROW(theBest.dest), c); fflush(stdout); continue; } if (!fgets (line, 256, stdin)) return; if (line[0] == '\n') continue; sscanf (line, "%s", command); if (!strcmp (command, "xboard")) { continue; } if (!strcmp (command, "d")) { printBoard (); continue; } if (!strcmp (command, "new")) { startgame (); continue; } if (!strcmp (command, "quit")) { return; } if (!strcmp (command, "force")) { computerSide = EMPTY; continue; } /* If we get a result the engine must stop */ if (!strcmp(command, "result")) { computerSide = EMPTY; continue; } if (!strcmp(command, "?")) { computerSide = EMPTY; continue; } if (!strcmp(command, ".")) { continue; } if (!strcmp(command, "exit")) { continue; } if (!strcmp(command,"setboard")) { strcpy(fenBuf, ""); sscanf(line, "setboard %s %s %s %s", args[0],args[1],args[2],args[3]); strcat(fenBuf, args[0]); strcat(fenBuf, args[1]); strcat(fenBuf, args[2]); strcat(fenBuf, args[3]); setBoard(fenBuf); continue; } if (!strcmp (command, "white")) { side = WHITE; computerSide = BLACK; continue; } if (!strcmp (command, "black")) { side = BLACK; computerSide = WHITE; continue; } if (!strcmp (command, "sd")) { sscanf (line, "sd %d", &maxDepth); continue; } if (!strcmp (command, "go")) { computerSide = side; continue; } /* Taken from TSCP: we receive from the GUI the time we have */ if (!strcmp(command, "time")) { sscanf (line, "time %ld", &maxTime); /* Convert to miliseconds */ maxTime *= 10; maxTime /= 10; maxTime -= 300; totalTime = maxTime; // if (totalTime < 3000) // maxDepth = 6; // else maxDepth = 32; continue; } if (!strcmp(command, "otim")) { continue; } if (!strcmp (command, "undo")) { if (hdp == 0) continue; takeBack (); continue; } if (!strcmp (command, "remove")) { if (hdp <= 1) continue; takeBack (); takeBack (); continue; } /* Maybe the user entered a move? */ /* Is that a move? */ if (command[0] < 'a' || command[0] > 'h' || command[1] < '0' || command[1] > '9' || command[2] < 'a' || command[2] > 'h' || command[3] < '0' || command[3] > '9') { printf("Error (unknown command): %s\n", command); /* No move, unknown command */ continue; } from = command[0] - 'a'; from += 8 * (8 - (command[1] - '0')); dest = command[2] - 'a'; dest += 8 * (8 - (command[3] - '0')); ply = 0; movecnt = genMoves (side, moveBuf); /* Loop through the moves to see if it's legal */ for (i = 0; i < movecnt; ++i) { if (moveBuf[i].from == from && moveBuf[i].dest == dest) { if (piece[from] == PAWN && (dest < 8 || dest > 55)) { if (command[4] != 'q' && command[4] != 'r' && command[4] != 'b' && command[4] != 'n') { printf ("Illegal move. Bad letter for promo\n"); goto goon; } switch (command[4]) { case 'q': moveBuf[i].type_of_move = MOVE_TYPE_PROMOTION_TO_QUEEN; break; case 'r': moveBuf[i].type_of_move = MOVE_TYPE_PROMOTION_TO_ROOK; break; case 'b': moveBuf[i].type_of_move = MOVE_TYPE_PROMOTION_TO_BISHOP; break; case 'n': moveBuf[i].type_of_move = MOVE_TYPE_PROMOTION_TO_KNIGHT; break; } } if (moveBuf[i].type_of_move > 8) printf ("Type of move the best %d \n", moveBuf[i].type_of_move); if (makeMove (moveBuf[i])) { goto goon; /* Legal move */ } else { printf ("Illegal move. King is in check\n"); goto goon; } } } printf ("Illegal move.\n"); /* illegal move */ goon: continue; } }
/* * 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; }