void IterableChess::pushPawnMoves(int posy, int posx, ChessColor player, std::vector<ChessMove>& moves) const { int begins_from_y; // Where it begins int direction; // 1 for forward, -1 for backward if (player == B) { begins_from_y = 6; direction = -1; } else { begins_from_y = 1; direction = 1; } if (posy == begins_from_y) { insert_move_if_empty(posy, posx, posy+2*direction, posx, moves, m_state); } if (posy + 1*direction < CHESS_DIMENTION_Y) { insert_move_if_empty(posy, posx, posy+1*direction, posx, moves, m_state); // check the possibility of eating if (posx < CHESS_DIMENTION_X-1) { if (m_state[posy+1*direction][posx+1].color == OtherColor(player) && m_state[posy+1*direction][posx+1].type != EMPTY) { moves.push_back(ChessMove(posy, posx, posy+1*direction, posx+1)); } } if (posx >= 1) { if (m_state[posy+1*direction][posx-1].color == OtherColor(player) && m_state[posy+1*direction][posx-1].type != EMPTY) { moves.push_back(ChessMove(posy, posx, posy+1*direction, posx-1)); } } } }
BOOL BOARD::canCastle(MOVETYPE whichCastle, PIECECOLOR color) { int col = color == WHITE ? 0 : 7; int row, rowStep; BOARDMETRIC metric; if (whichCastle == QUEENSIDECASTLE) { row = 0; rowStep = 1; } else { row = 7; rowStep = -1; } // make sure king & rook in initial positions and have never been // moved. if (!brd[row][col]) return(FALSE); if (brd[row][col]->hasBeenMoved()) return(FALSE); if (!brd[4][col]) return(FALSE); if (brd[4][col]->hasBeenMoved()) return(FALSE); // make sure no pieces in between for ( ; ; ) { row += rowStep; if (row == 4) break; if (brd[row][col]) return(FALSE); } // make sure king is not in check findBestMoves(1, OtherColor(color), metric, (BESTMOVES *) 0); if (metric.kingSituation[color] == KINGLOST) return(FALSE); // make sure king would not be in check in intermediate position brd[4 - rowStep][col] = brd[4][col]; brd[4][col] = (PIECE *) 0; findBestMoves(1, OtherColor(color), metric, (BESTMOVES *) 0); brd[4][col] = brd[4 - rowStep][col]; brd[4 - rowStep][col] = (PIECE *) 0; return(metric.kingSituation[color] == KINGOK); }
bool Board::DoesEnPassantCaptureCauseDiscoveredCheck(int square, int color) { assert(this->enPassantRights.HasEnPassant()); int attackerColor = OtherColor(color); int kingSquare = GetKingSquare(color); int kingRow = GetRow(kingSquare); int pieceRow = GetRow(square); int dr = pieceRow - kingRow; ulong defenderKing = 1ULL << kingSquare; if (dr == 0) { ulong myRankAttacks = MoveGenerator::rankAttacks[square][GetRankStatus(square)]; ulong theirRankAttacks = MoveGenerator::rankAttacks[enPassantRights.PawnSquare()][GetRankStatus(enPassantRights.PawnSquare())]; ulong defenderKing = 1ULL << kingSquare; if ((defenderKing & myRankAttacks) != 0 || (defenderKing & theirRankAttacks) != 0) { ulong attackers = GetPieceBitBoard(Pieces::GetPiece(PieceTypes::Rook, attackerColor)) | GetPieceBitBoard(Pieces::GetPiece(PieceTypes::Queen, attackerColor)); if ((myRankAttacks & attackers) != 0 || (theirRankAttacks & attackers) != 0) { return true; } } } return false; }
// compare two board metrics. if the second metric is invalid, // the first metric is better. the color parameter gives the player // for whom the metric is supposed to be better. LOCAL int compareMetric ( const BOARDMETRIC &a, const BOARDMETRIC &b, BOOL bValid, PIECECOLOR color ) { PIECECOLOR otherColor = OtherColor(color); int compare; if (!bValid) return(1); compare = thisSituationCompareTable[a.kingSituation[color]] [b.kingSituation[color]]; if (compare != 0) return(compare); compare = otherSituationCompareTable[a.kingSituation[otherColor]] [b.kingSituation[otherColor]]; if (compare != 0) return(compare); compare = a.materialDiff - b.materialDiff; if (color == BLACK) compare = -compare; return(compare); }
void IterableChess::pushQueenMoves(int posy, int posx, ChessColor player, std::vector<ChessMove>& moves) const { std::vector< std::pair<int, int> > dirs; dirs.push_back(std::pair<int, int>(1, 1)); dirs.push_back(std::pair<int, int>(1, -1)); dirs.push_back(std::pair<int, int>(-1, 1));dirs.push_back(std::pair<int, int>(-1, -1)); dirs.push_back(std::pair<int, int>(1, 0)); dirs.push_back(std::pair<int, int>(-1, 0)); dirs.push_back(std::pair<int, int>(0, 1)); dirs.push_back(std::pair<int, int>(0, -1)); std::vector< std::pair<int, int> >::iterator iter = dirs.begin();; for (; iter != dirs.end(); iter++) { int desty = posy+iter->first, destx = posx+iter->second; while (destx < CHESS_DIMENTION_X && destx >= 0 && desty < CHESS_DIMENTION_Y && desty >= 0 && m_state[desty][destx].type == EMPTY) { moves.push_back(ChessMove(posy, posx, desty, destx)); desty+=iter->first; destx+=iter->second; } if (destx < CHESS_DIMENTION_X && destx >= 0 && desty < CHESS_DIMENTION_Y && desty >= 0 && m_state[desty][destx].type != EMPTY && m_state[desty][destx].color == OtherColor(player)) { moves.push_back(ChessMove(posy, posx, desty, destx)); } } }
/** * Insert the move if the destination exists on board, empty, * or filled with other color. */ static void insert_move_if_empty_exst_other(int fromy, int fromx, int toy, int tox, ChessColor player, std::vector<ChessMove> &moves, const ChessPart state[8][8]) { if ( (toy < CHESS_DIMENTION_Y && toy >= 0 && tox < CHESS_DIMENTION_X && tox >= 0) && (state[toy][tox].type == EMPTY || state[toy][tox].color == OtherColor(player)) ) { moves.push_back(ChessMove(fromy, fromx, toy, tox)); } }
MOVESTATUS BOARD::doUserMove ( POSITION start, POSITION end ) { PIECE *p = whatPiece(start.row, start.col); POSITIONLIST moves; BOARDMETRIC metric; BESTMOVES bestMoves; MOVEUNDODATA undoData; int m; if (!p) return(MOVESTATUS(ILLEGALMOVE)); p->legalMoves(start, *this, moves); for (m = 0; m < moves.nMoves; m++) { if ((moves.end[m].row == end.row) && (moves.end[m].col == end.col)) break; } if (m == moves.nMoves) return(MOVESTATUS(ILLEGALMOVE)); doMove(start, end, undoData); findBestMoves(1, OtherColor(p->whatColor()), metric, &bestMoves); if (metric.kingSituation[p->whatColor()] == KINGLOST) { undoMove(end, start, undoData); return(MOVESTATUS(WOULDLOSEKING, bestMoves.move[0].start)); } if (undoData.capturedPiece) delete undoData.capturedPiece; if (undoData.enPassantEffect == ENPASSANTCAPTURE) return(MOVESTATUS(MOVEENPASSANT)); else return(MOVESTATUS(MOVEDONE)); }
BOOL BOARD::userCanCastle ( MOVETYPE whichCastle, PIECECOLOR color ) { BOARDMETRIC metric; MOVEUNDODATA undoData; if (!canCastle(whichCastle, color)) return(FALSE); castle(whichCastle, color, undoData); // make sure king is not in check in final position findBestMoves(1, OtherColor(color), metric, (BESTMOVES *) 0); undoCastle(whichCastle, color, undoData); return(metric.kingSituation[color] == KINGOK); }
void Board::MakeEnPassantMove(bool isPawnMove, int source, int destination) { if (isPawnMove && enPassantRights.CaptureSquare() == destination) { int enPassantSquare = enPassantRights.PawnSquare(); int otherPawn = Pieces::GetPiece(PieceTypes::Pawn, OtherColor(turn)); RemovePiece(enPassantSquare, otherPawn); ulong oldKey = TranspositionTable::GetPositionKey(enPassantSquare, otherPawn); zobristKey ^= oldKey; pawnZobristKey ^= oldKey; materialScore -= Evaluation::PieceValue(otherPawn); positionalScore -= Evaluation::PieceSquareValue(otherPawn, enPassantSquare); endgamePositionalScore -= Evaluation::EndgamePieceSquareValue(otherPawn, enPassantSquare); capturedPiece = PieceTypes::Pawn; } EnPassantRights newEnPassantRights = EnPassantRights::NoEnPassant; // Update en passant rights if (isPawnMove) { int delta = source - destination; if(delta == 16 || delta == -16) { newEnPassantRights = EnPassantRights((source + destination) / 2); } } if(enPassantRights.GetRights() != newEnPassantRights.GetRights()) { zobristKey ^= TranspositionTable::GetEnPassantKey(enPassantRights); enPassantRights = newEnPassantRights; zobristKey ^= TranspositionTable::GetEnPassantKey(enPassantRights); } }
ulong Board::GetSafeKingMoves(int color) { ulong safeMoves = 0; int kingSquare = GetKingSquare(color); ulong moves = MoveGenerator::kingAttacks[kingSquare]; ulong newMoves = moves & (~colorBitBoards[color]); moves = newMoves; if(moves != 0) { RemovePiece(kingSquare, Pieces::GetPiece(PieceTypes::King, color)); while(moves != 0) { int move = PopLowestSetBit(moves); if(!IsSquareAttacked(move, OtherColor(color))) { safeMoves |= BitBoard(move); } } AddPiece(kingSquare, Pieces::GetPiece(PieceTypes::King, color)); } return safeMoves; }
ulong Board::GetPinRestrictionMask(int square, int color) { int attackerColor = OtherColor(color); int kingSquare = GetKingSquare(color); int kingRow = GetRow(kingSquare); int kingCol = GetCol(kingSquare); int pieceRow = GetRow(square); int pieceCol = GetCol(square); int dr = pieceRow - kingRow; int dc = pieceCol - kingCol; ulong defenderKing = 1ULL << kingSquare; if(dr == 0) { ulong rankAttacks = MoveGenerator::rankAttacks[square][GetRankStatus(square)]; ulong defenderKing = 1ULL << kingSquare; if((defenderKing & rankAttacks) != 0) { ulong attackers = GetPieceBitBoard(Pieces::GetPiece(PieceTypes::Rook, attackerColor)) | GetPieceBitBoard(Pieces::GetPiece(PieceTypes::Queen, attackerColor)); if((rankAttacks & attackers) != 0) { return rankAttacks; } } } else if(dc == 0) { ulong fileAttacks = MoveGenerator::fileAttacks[square][GetFileStatus(square)]; if((defenderKing & fileAttacks) != 0) { ulong attackers = GetPieceBitBoard(Pieces::GetPiece(PieceTypes::Rook, attackerColor)) | GetPieceBitBoard(Pieces::GetPiece(PieceTypes::Queen, attackerColor)); if((fileAttacks & attackers) != 0) { return fileAttacks; } } } else if(dr == dc || dr == -dc) { ulong diagAttacks = 0; if(dr == dc) { diagAttacks = MoveGenerator::diagA1H8Attacks[square][GetDiagA1H8Status(square)]; } else { diagAttacks = MoveGenerator::diagA8H1Attacks[square][GetDiagA8H1Status(square)]; } if((defenderKing & diagAttacks) != 0) { ulong attackers = GetPieceBitBoard(Pieces::GetPiece(PieceTypes::Bishop, attackerColor)) | GetPieceBitBoard(Pieces::GetPiece(PieceTypes::Queen, attackerColor)); if((diagAttacks & attackers) != 0) { return diagAttacks; } } } return ~(0ULL); }
void Board::UndoMove(int move, bool updateDrawState, const BoardState& undoState) { updateDrawState = true; isInCheck = undoState.isInCheck; castleRights = undoState.castleRights; enPassantRights = undoState.enPassantRights; drawMoveCount = undoState.drawMoveCount; materialScore = undoState.materialScore; positionalScore = undoState.positionalScore; endgamePositionalScore = undoState.endgamePositionalScore; if (move != NullMove) { turnsPlayed--; UndoMoveDrawState(updateDrawState); int source = GetSourceFromMove(move); int dest = GetDestFromMove(move); int piece = GetPiece(dest); MovePiece(dest, source, piece); if (GetPromoFromMove(move) != PieceTypes::None) { RemovePiece(source, piece); int oldPiece = Pieces::GetPiece(PieceTypes::Pawn, OtherColor(turn)); AddPiece(source, oldPiece); } if (capturedPiece != PieceTypes::None) { int capture = Pieces::GetPiece(capturedPiece, turn); // was this an en passant capture? if (enPassantRights.HasEnPassant() && dest == enPassantRights.CaptureSquare() && Pieces::GetPieceTypeFromPiece(piece) == PieceTypes::Pawn) { AddPiece(enPassantRights.PawnSquare(), capture); } else { AddPiece(dest, capture); } } // if this was a castle move, restore the rook if (Pieces::GetPieceTypeFromPiece(piece) == PieceTypes::King) { int delta = dest - source; if(delta == 2 || delta == -2) { int rookOrigin = dest + delta / 2; if(delta < 0) { rookOrigin--; } int rookDestination = dest - delta / 2; int rook = Pieces::GetPiece(PieceTypes::Rook, OtherColor(turn)); MovePiece(rookDestination, rookOrigin, rook); } } capturedPiece = undoState.capturedPiece; } turn = OtherColor(turn); zobristKey = undoState.zobristKey; pawnZobristKey = undoState.pawnZobristKey; }
void Board::MakeMove(int move, bool updateDrawState, BoardState& undoState) { updateDrawState = true; undoState.isInCheck = isInCheck; undoState.capturedPiece = capturedPiece; undoState.castleRights = castleRights; undoState.enPassantRights = enPassantRights; undoState.drawMoveCount = drawMoveCount; undoState.zobristKey = zobristKey; undoState.pawnZobristKey = pawnZobristKey; undoState.materialScore = materialScore; undoState.positionalScore = positionalScore; undoState.endgamePositionalScore = endgamePositionalScore; if (move != NullMove) { drawMoveCount++; int source = GetSourceFromMove(move); int destination = GetDestFromMove(move); int piece = GetPiece(source); int destPiece = GetPiece(destination); MakeCaptureMove(destination, destPiece); MovePiece(source, destination, piece); MakePromotionMove(move, source, destination, piece); MakeCastleMove(piece, destPiece, source, destination); bool isPawn = Pieces::GetPieceTypeFromPiece(piece) == PieceTypes::Pawn; MakeEnPassantMove(isPawn, source, destination); turn = OtherColor(turn); zobristKey ^= TranspositionTable::GetTurnKey(); //assert(!IsKingInCheck(OtherColor(turn))); ulong oldKey = TranspositionTable::GetPositionKey(source, piece); ulong newKey = TranspositionTable::GetPositionKey(destination, piece); ulong diff = oldKey ^ newKey; zobristKey ^= diff; if (isPawn) { pawnZobristKey ^= diff; drawMoveCount = 0; } positionalScore -= Evaluation::PieceSquareValue(piece, source); positionalScore += Evaluation::PieceSquareValue(piece, destination); endgamePositionalScore -= Evaluation::EndgamePieceSquareValue(piece, source); endgamePositionalScore += Evaluation::EndgamePieceSquareValue(piece, destination); MakeMoveDrawState(updateDrawState); turnsPlayed++; isInCheck = IsKingInCheck(turn); } else { // don't allow a null move when in check. assert(!GetIsInCheck()); zobristKey ^= TranspositionTable::GetEnPassantKey(enPassantRights); enPassantRights = EnPassantRights::NoEnPassant; zobristKey ^= TranspositionTable::GetEnPassantKey(enPassantRights); turn = OtherColor(turn); zobristKey ^= TranspositionTable::GetTurnKey(); } }
bool Board::IsKingInCheck(int color) const { return IsSquareAttacked(GetKingSquare(color), OtherColor(color)); }
void BOARD::helpFindBestMoves ( int lookAhead, PIECECOLOR moveColor, BOARDMETRIC &metric, BESTMOVES *bestMoves ) { POSITION where; POSITIONLIST moves; BOARDMETRIC testMetric; BOOL metricSet = FALSE; MOVEUNDODATA undoData; int m, compareResult; int origMaterialDiff = metric.materialDiff; MOVETYPE castleType; testMetric.kingSituation[WHITE] = KINGOK; testMetric.kingSituation[BLACK] = KINGOK; // try all possible moves for the given color for (where.row = 0; where.row < NUMROWS; where.row++) for (where.col = 0; where.col < NUMCOLS; where.col++) { if (whatPiece(where)) if (whatPiece(where)->whatColor() == moveColor) { whatPiece(where)->legalMoves(where, *this, moves); for (m = 0; m < moves.nMoves; m++) { testMetric.materialDiff = origMaterialDiff; doMove ( where, moves.end[m], undoData ); if (undoData.capturedPiece) { if (undoData.capturedPiece->whatType() == TYPEKING) { undoMove ( moves.end[m], where, undoData ); metric.kingSituation[OtherColor(moveColor)] = KINGLOST; if (bestMoves) { bestMoves->nMoves = 0; bestMoves->move[0] = PIECEMOVE ( NORMALMOVE, where, moves.end[m] ); } return; } testMetric.materialDiff -= undoData.capturedPiece->signedValue(); } if (canPromote(moves.end[m])) { testMetric.materialDiff -= whatPiece(moves.end[m])->signedValue(); promote(moves.end[m], TYPEQUEEN); testMetric.materialDiff += whatPiece(moves.end[m])->signedValue(); if (lookAhead > 1) helpFindBestMoves ( lookAhead - 1, OtherColor(moveColor), testMetric, (BESTMOVES *) 0 ); compareResult = compareMetric ( testMetric, metric, metricSet, moveColor ); if (compareResult >= 0) { if (compareResult > 0) { metric = testMetric; metricSet = TRUE; if (bestMoves) bestMoves->nMoves = 0; } if (bestMoves) bestMoves->move[bestMoves->nMoves++] = PIECEMOVE ( NORMALMOVE, where, moves.end[m], TYPEQUEEN ); } testMetric.materialDiff -= whatPiece(moves.end[m])->signedValue(); restorePawn(moves.end[m]); promote(moves.end[m], TYPEKNIGHT); testMetric.materialDiff += whatPiece(moves.end[m])->signedValue(); if (lookAhead > 1) helpFindBestMoves ( lookAhead - 1, OtherColor(moveColor), testMetric, (BESTMOVES *) 0 ); compareResult = compareMetric ( testMetric, metric, metricSet, moveColor ); if (compareResult >= 0) { if (compareResult > 0) { metric = testMetric; metricSet = TRUE; if (bestMoves) bestMoves->nMoves = 0; } if (bestMoves) bestMoves->move[bestMoves->nMoves++] = PIECEMOVE ( NORMALMOVE, where, moves.end[m], TYPEKNIGHT ); } restorePawn(moves.end[m]); } else // no promotion { if (lookAhead > 1) helpFindBestMoves ( lookAhead - 1, OtherColor(moveColor), testMetric, (BESTMOVES *) 0 ); compareResult = compareMetric ( testMetric, metric, metricSet, moveColor ); if (compareResult >= 0) { if (compareResult > 0) { metric = testMetric; metricSet = TRUE; if (bestMoves) bestMoves->nMoves = 0; } if (bestMoves) bestMoves->move[bestMoves->nMoves++] = PIECEMOVE ( NORMALMOVE, where, moves.end[m] ); } } undoMove ( moves.end[m], where, undoData ); } // end of for loop over each legal move for piece } } // end of double for loop over each board position // only try castling moves if look ahead move than one, since // nothing can be captured by doing a castling move if (lookAhead > 1) { castleType = QUEENSIDECASTLE; for ( ; ; ) { if (canCastle(castleType, moveColor)) { testMetric.materialDiff = origMaterialDiff; castle(castleType, moveColor, undoData); helpFindBestMoves ( lookAhead - 1, OtherColor(moveColor), testMetric, (BESTMOVES *) 0 ); compareResult = compareMetric ( testMetric, metric, metricSet, moveColor ); if (compareResult >= 0) { if (compareResult > 0) { metric = testMetric; metricSet = TRUE; if (bestMoves) bestMoves->nMoves = 0; } if (bestMoves) bestMoves->move[bestMoves->nMoves++] = PIECEMOVE(castleType); } undoCastle(castleType, moveColor, undoData); } if (castleType == KINGSIDECASTLE) break; castleType = KINGSIDECASTLE; } // see if the loss of the king is the result of a stalemate // instead of check mate if (metric.kingSituation[moveColor] == KINGLOST) { helpFindBestMoves ( 1, OtherColor(moveColor), testMetric, (BESTMOVES *) 0 ); if (testMetric.kingSituation[moveColor] != KINGLOST) // king will be lost on next move, but is not in check metric.kingSituation[moveColor] = STALEMATE; } } return; }
// is always positive for good captures, 0 for neutral captures, negative for bad captures. int StaticExchangeEvaluator::Evaluate(int move) { for (int i = 0; i < 6; i++) { attackerPieces[i] = 0; defenderPieces[i] = 0; } int source = m_board.GetPiece(GetSourceFromMove(move)); int destPiece = m_board.GetPiece(GetDestFromMove(move)); int attackingPiece = Pieces::GetPieceTypeFromPiece(source); int defendingPiece = Pieces::GetPieceTypeFromPiece(destPiece); // if(attackingPiece == PieceTypes::Pawn && defendingPiece != PieceTypes::Pawn) { // return Evaluation::PieceValue(defendingPiece) - 100; } attackerColor = Pieces::GetColorFromPiece(source); targetSquare = GetDestFromMove(move); defenderColor = OtherColor(attackerColor); attackerBits = m_board.colorBitBoards[attackerColor]; defenderBits = m_board.colorBitBoards[defenderColor]; knownPieces = 1ULL << GetSourceFromMove(move); int currentScore = Evaluation::PieceValue(Pieces::GetPieceTypeFromPiece(destPiece)); m_board.RemovePiece(GetSourceFromMove(move), source); AddSingleAttacks(); AddRankFileAttacks(); AddDiagonalAttacks(); pieces[0] = source; squares[0] = GetSourceFromMove(move); // trade off pieces int attackerIndex = 0; int defenderIndex = 0; int scoreIndex = 0; for (; ; ) { scores[scoreIndex++] = currentScore; // break if we took the king if (currentScore > 25000) break; if (defenderIndex == 6) break; while (defenderPieces[defenderIndex] == 0) { defenderIndex++; if (defenderIndex == 6) break; } if (defenderIndex == 6) break; int nextSquare = PopLowestSetBit(defenderPieces[defenderIndex]); currentScore -= Evaluation::PieceValue(Pieces::GetPieceTypeFromPiece(attackingPiece)); attackingPiece = defenderIndex; int piece = Pieces::GetPiece(attackingPiece, defenderColor); m_board.RemovePiece(nextSquare, piece); pieces[scoreIndex] = piece; squares[scoreIndex] = nextSquare; // handle revealed attacks if(defenderIndex == PieceTypes::Pawn || defenderIndex == PieceTypes::Bishop || defenderIndex == PieceTypes::Queen) { AddDiagonalAttacks(); defenderIndex = min(defenderIndex, PieceTypes::Bishop); } if(defenderIndex == PieceTypes::Rook || defenderIndex == PieceTypes::Queen) { AddRankFileAttacks(); defenderIndex = min(defenderIndex, PieceTypes::Rook); } scores[scoreIndex++] = currentScore; // break if we took the king if (currentScore < -25000) break; if (attackerIndex == 6) break; while (attackerPieces[attackerIndex] == 0) { attackerIndex++; if (attackerIndex == 6) break; } if (attackerIndex == 6) break; nextSquare = PopLowestSetBit(attackerPieces[attackerIndex]); currentScore += Evaluation::PieceValue(Pieces::GetPieceTypeFromPiece(attackingPiece)); attackingPiece = attackerIndex; piece = Pieces::GetPiece(attackingPiece, attackerColor); m_board.RemovePiece(nextSquare, piece); pieces[scoreIndex] = piece; squares[scoreIndex] = nextSquare; // handle revealed attacks if (attackerIndex == PieceTypes::Pawn || attackerIndex == PieceTypes::Bishop || attackerIndex == PieceTypes::Queen) { AddDiagonalAttacks(); attackerIndex = min(attackerIndex, PieceTypes::Bishop); } if (attackerIndex == PieceTypes::Rook || attackerIndex == PieceTypes::Queen) { AddRankFileAttacks(); attackerIndex = min(attackerIndex, PieceTypes::Rook); } } int bestScore = scores[scoreIndex - 1]; while (--scoreIndex >= 0) { m_board.AddPiece(squares[scoreIndex], pieces[scoreIndex]); if ((scoreIndex & 1) == 0) { // This is my move, opponent will try to minimize bestScore = min(bestScore, scores[scoreIndex]); } else { // Opponents move, try to maximize bestScore = max(bestScore, scores[scoreIndex]); } } return bestScore; }
void CNPair::Increment(void) {good = OtherColor(good); if (IsColorWhite(good)) fmvn++;}