public void BeginSearch(string fen, ISearchResults target, TimeSpan timeVailable) { var board = CreateBoard(fen); var eg = EndGameReporter.ReportEndGame(board); if (eg != GameEnded.None) { target.SearchDone(string.Empty, eg); } else { BackgroundWorker wrk = new BackgroundWorker(); wrk.DoWork += (e, a) => { int bestMove = DoSearch(board, timeVailable); string move = string.Empty; if (bestMove != 0) { move = MovePackHelper.GetAlgebraicString(bestMove); } target.SearchDone(move, EndGameReporter.ReportEndGame(board)); }; wrk.RunWorkerAsync(); } }
protected override int OnGetBlockingMoves(int start, int[] moves, int[] ray, int rayLen) { int begin = start; for (int i = 0; i < rayLen; ++i) { int square = ray[i]; int dir = StraightAttackLookup[Square.Ox88Dist(square, HomeSquare)]; if ((PinStatus == PinStatus.None || PinCompatible(dir)) && AttackPathFree(dir, square)) { int castlingMask = 0; if (HomeSquare == kingSide) { castlingMask = MovePackHelper.GetCastlingMerge(castlingMaskKing & (int)board.CastlingStatus); } if (HomeSquare == queenSide) { castlingMask = MovePackHelper.GetCastlingMerge(castlingMaskQueen & (int)board.CastlingStatus); } moves[start++] = MovePackHelper.Pack(HomeSquare, square) | castlingMask; } } return(start - begin); }
protected override int OnGetBlockingMoves(int start, int[] moves, int[] ray, int rayLen) { int begin = start; if ((PinStatus == PinStatus.None || (PinStatus & PinStatus.NS) != 0)) { for (int i = 0; i < rayLen; ++i) { int square = ray[i]; if (square - HomeSquare == oneStep) { moves[start++] = MovePackHelper.Pack(HomeSquare, square); if (Square.Rank(square) == lastRank) { int prom = moves[start - 1]; moves[start - 1] |= MovePackHelper.GetPromotionMerge(PromotionTo.Queen); moves[start++] = prom | MovePackHelper.GetPromotionMerge(PromotionTo.Bishop); moves[start++] = prom | MovePackHelper.GetPromotionMerge(PromotionTo.Rook); moves[start++] = prom | MovePackHelper.GetPromotionMerge(PromotionTo.Knight); } } if (Square.Rank(HomeSquare) == rankForEp && board.BoardArray[HomeSquare + oneStep] == null && square - HomeSquare == twoStep) { moves[start] = MovePackHelper.Pack(HomeSquare, square); MovePackHelper.GetCleanedMove(moves[start]); start++; } } } return(start - begin); }
public Pawn(Side owner, IChessBoard board, int cell) : base(owner, board, cell) { if (owner == Side.White) { oneStep = 16; twoStep = 32; rankForEp = 2; rankForEpCapture = 5; diag1 = 17; diag2 = 15; lastRank = 8; ZKeys = ZKeysWhite; } else { oneStep = -16; twoStep = -32; rankForEp = 7; rankForEpCapture = 4; diag1 = -17; diag2 = -15; lastRank = 1; ZKeys = ZKeysBlack; } MovePackHelper.Pack(HomeSquare, HomeSquare + twoStep); epSquare = HomeSquare + oneStep; }
protected override int OnGetBlockingMoves(int start, int[] moves, int[] ray, int rayLen) { int begin = start; if (PinStatus == PinStatus.None) { for (int i = 0; i < rayLen; ++i) { int square = ray[i]; int rd = Square.Rank(square) - Square.Rank(HomeSquare); int cd = Square.Col(square) - Square.Col(HomeSquare); if (rd < 0) { rd *= -1; } if (cd < 0) { cd *= -1; } if ((cd == 1 && rd == 2) || (cd == 2 && rd == 1)) { moves[start++] = MovePackHelper.Pack(HomeSquare, square); } } } return(start - begin); }
protected override void OnUnMove(int move) { if (!MovePackHelper.HasCapture(move)) { board.ZKey ^= ZKeyForCastling[(int)board.CastlingStatus]; board.CastlingStatus ^= MovePackHelper.GetCastleMask(move); board.ZKey ^= ZKeyForCastling[(int)board.CastlingStatus]; } }
protected override void OnMove(int move) { if (Square.Rank(MovePackHelper.GetStartSquare(move)) == rankForEp && MovePackHelper.GetEndSquare(move) - MovePackHelper.GetStartSquare(move) == twoStep) { board.PlaceEnpassant(epSquare); } if ((move & MovePackHelper.EpFlag) != 0) { board.Capture(board.BoardArray[MovePackHelper.GetEndSquare(move) - oneStep]); } }
protected override void OnUnMove(int move) { //if (MovePackHelper.GetStartSquare(move)==epSquare && MovePackHelper.GetEndSquare(move)==epSquare+twoStep) if (Square.Rank(MovePackHelper.GetStartSquare(move)) == rankForEp && MovePackHelper.GetEndSquare(move) - MovePackHelper.GetStartSquare(move) == twoStep) { board.UnplaceEnPassant(); } if ((move & MovePackHelper.EpFlag) != 0) { board.UnCapture(MovePackHelper.GetEndSquare(move) - oneStep); } }
protected override int OnGetCaptureMoves(int start, int[] moves, int square) { int dir = DiagAttackLookup[Square.Ox88Dist(square, HomeSquare)]; if ((PinStatus == PinStatus.None || PinCompatible(dir)) && AttackPathFree(dir, square) && board.BoardArray[square] != null && IsEnemy(square)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[square]); return(1); } return(0); }
protected override int DoSearch(IChessBoard board, TimeSpan timeAvail) { this.totalMillisec = (int)timeAvail.TotalMilliseconds; this.board = board; int bestMove = 0; int val = 0; int alpha; bool timeout = false; kslot = new long[200]; using (clk = new RunClock()) { var preOrder = GetPreOrderedMoves(); for (int curDepth = 1; curDepth <= maxDepth; ++curDepth) // iterative deeping { alpha = -INFINITE; var moves = GetBestMoveFirst(bestMove, preOrder); //var moves = GetMoves(bestMove); foreach (var m in moves) { board.Move(m); var cm = MovePackHelper.GetAlgebraicString(m); if (m == bestMove || -AlphaBeta(curDepth - 1, -alpha - 1, -alpha) > alpha) { val = -AlphaBeta(curDepth - 1, -INFINITE, -alpha); } board.UndoMove(); if (val > alpha) { alpha = val; bestMove = m; ttable.Save(board.ZKey, curDepth, alpha, TTType.Alpha, m); } if (clk.GetElapsedMilliseconds() > timeAvail.TotalMilliseconds / .5) { timeout = true; break; } } if (timeout) { break; } ttable.Save(board.ZKey, curDepth, alpha, TTType.Alpha, bestMove); } } return(bestMove); }
protected override int OnGetBlockingMoves(int start, int[] moves, int[] ray, int rayLen) { int begin = start; for (int i = 0; i < rayLen; ++i) { int square = ray[i]; int dir = DiagAttackLookup[Square.Ox88Dist(square, HomeSquare)]; if ((PinStatus == PinStatus.None || PinCompatible(dir)) && AttackPathFree(dir, square)) { moves[start++] = MovePackHelper.Pack(HomeSquare, square); } } return(start - begin); }
int Quiesce(int alpha, int beta, int depth) { if (depth == maxQuiesceDepth) { return(StaticEval()); } var moves = GetMoves(0, 0); IEnumerable <int> selected; if (board.GetCheckCount(board.ToMove) > 0) { if (moves.Count() == 0) { return(-INFINITE);//mate } //depth -= 1; selected = moves; } else { selected = moves.Where(k => (k & MovePackHelper.Capture) != 0 || MovePackHelper.GetPromotion(k) != PromotionTo.None); } if (selected.Count() == 0) { return(StaticEval()); } foreach (var move in selected) { board.Move(move); var score = -Quiesce(-beta, -alpha, depth + 1); board.UndoMove(); if (score > alpha) { alpha = score; } if (alpha >= beta) // current player move is better than the other one better, no reason to search further { //beta cutoff !!! break; } } return(alpha); }
private int GetWeight(int m, int best, int k1, int k2) { int val = (m & MovePackHelper.GoodCapture) != 0 ? 1000 : 0; if ((m & MovePackHelper.Capture) != 0 && (m & MovePackHelper.GoodCapture) == 0) { val -= 1000; } PromotionTo to; if ((to = MovePackHelper.GetPromotion(m)) != PromotionTo.None) { switch (to) { case PromotionTo.Queen: val += 1000; break; case PromotionTo.Knight: val += 500; break; case PromotionTo.Bishop: val -= 1000; break; case PromotionTo.Rook: val -= 1000; break; } } if (m == k1 || m == k2) { val += 5000; } if (m == best) { val += 10000; } return(val); }
protected override int OnGetCaptureMoves(int start, int[] moves, int square) { int begin = start; if ((square - HomeSquare == diag1 || square - HomeSquare == diag2) && IsEnemy(square) && PinCompatible(square - HomeSquare) ) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[square]); if (Square.Rank(square) == lastRank) { int prom = moves[start - 1]; moves[start - 1] |= MovePackHelper.GetPromotionMerge(PromotionTo.Queen); moves[start++] = prom | MovePackHelper.GetPromotionMerge(PromotionTo.Bishop); moves[start++] = prom | MovePackHelper.GetPromotionMerge(PromotionTo.Rook); moves[start++] = prom | MovePackHelper.GetPromotionMerge(PromotionTo.Knight); } } // ep. if (Square.Rank(HomeSquare) == rankForEpCapture) { if (HomeSquare + diag2 - oneStep == square) // THE CAPTURED ep is the target square { if (Square.SquareValid(HomeSquare + diag2) && HomeSquare + diag2 == board.EnPassant && PinCompatible(diag2) && board.CheckIfSafeEpCapture(Owner, HomeSquare)) { moves[start++] = MovePackHelper.Pack(HomeSquare, HomeSquare + diag2) | MovePackHelper.EpFlag; } } if (HomeSquare + diag1 - oneStep == square) // THE CAPTURED ep is the target square { if (Square.SquareValid(HomeSquare + diag1) && HomeSquare + diag1 == board.EnPassant && PinCompatible(diag1) && board.CheckIfSafeEpCapture(Owner, HomeSquare)) { moves[start++] = MovePackHelper.Pack(HomeSquare, HomeSquare + diag1) | MovePackHelper.EpFlag; } } } return(start - begin); }
protected override int OnGetCaptureMoves(int start, int[] moves, int square) { if (PinStatus == PinStatus.None) { int rd = Square.Rank(square) - Square.Rank(HomeSquare); int cd = Square.Col(square) - Square.Col(HomeSquare); if (rd < 0) { rd *= -1; } if (cd < 0) { cd *= -1; } if (((cd == 1 && rd == 2) || (cd == 2 && rd == 1)) && IsEnemy(square)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[square]); return(1); } } return(0); }
protected override int OnGetMoves(int start, int[] moves) { int castling = 0; castling = MovePackHelper.GetCastlingMerge(castlingMask & (int)board.CastlingStatus); int begin = start; foreach (int dest in rose) { if (Square.SquareValid(HomeSquare + dest) && (PinEscape(dest) || dest + HomeSquare == Checker.HomeSquare) && !board.InAttack(HomeSquare + dest, Owner)) { if (board.BoardArray[HomeSquare + dest] == null) { moves[start++] = MovePackHelper.Pack(HomeSquare, HomeSquare + dest) | castling; } else if (IsEnemy(HomeSquare + dest)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[HomeSquare + dest]) | castling; } } } if (CheckCount == 0) { // castlings if (0 != ((int)board.CastlingStatus & castlingKing) && CastlingKingSideFree && KingSideUnattacked()) { moves[start++] = MovePackHelper.Pack(HomeSquare, HomeSquare + EAST + EAST) | castling | MovePackHelper.Castling; } if (0 != ((int)board.CastlingStatus & castlingQueen) && CastlingQueenSideFree && QueenSideUnattacked()) { moves[start++] = MovePackHelper.Pack(HomeSquare, HomeSquare + WEST + WEST) | castling | MovePackHelper.Castling; } } return(start - begin); }
protected override int OnGetCaptureMoves(int start, int[] moves, int square) { int rd = Square.Rank(square) - Square.Rank(HomeSquare); int cd = Square.Col(square) - Square.Col(HomeSquare); if (rd == -1) { rd *= -1; } if (cd == -1) { cd *= -1; } if (rd <= 1 && cd <= 1 && IsEnemy(square)) { int castling = MovePackHelper.GetCastlingMerge(castlingMask & (int)board.CastlingStatus); if (!board.InAttack(square, Owner)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[square]) | castling; return(1); } } return(0); }
protected override int OnGetCaptureMoves(int start, int[] moves, int square) { int dir = StraightAttackLookup[Square.Ox88Dist(square, HomeSquare)]; if ((PinStatus == PinStatus.None || PinCompatible(dir)) && AttackPathFree(dir, square) && board.BoardArray[square] != null && IsEnemy(square)) { int castlingMask = 0; if (HomeSquare == kingSide) { castlingMask = MovePackHelper.GetCastlingMerge(castlingMaskKing & (int)board.CastlingStatus); } if (HomeSquare == queenSide) { castlingMask = MovePackHelper.GetCastlingMerge(castlingMaskQueen & (int)board.CastlingStatus); } moves[start++] = MovePackHelper.Pack(this, board.BoardArray[square]) | castlingMask; return(1); } return(0); }
protected override int OnGetMoves(int start, int[] moves) { int begin = start; if (PinStatus == PinStatus.None) { foreach (int dest in rose) { if (Square.SquareValid(HomeSquare + dest)) { if (board.BoardArray[HomeSquare + dest] == null) { moves[start++] = MovePackHelper.Pack(HomeSquare, HomeSquare + dest); } else if (IsEnemy(HomeSquare + dest)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[HomeSquare + dest]); } } } } return(start - begin); }
protected override int OnGetMoves(int start, int[] moves) { int begin = start; int sq; //NE if (PinStatus == PinStatus.None || (PinStatus & PinStatus.SWNE) != 0) { sq = HomeSquare; while (Square.SquareValid(sq + NE)) { sq += NE; if (board.BoardArray[sq] == null) { moves[start++] = MovePackHelper.Pack(HomeSquare, sq); } else { if (IsEnemy(sq)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[sq]); } break; } } } //NW if (PinStatus == PinStatus.None || (PinStatus & PinStatus.NWSE) != 0) { sq = HomeSquare; while (Square.SquareValid(sq + NW)) { sq += NW; if (board.BoardArray[sq] == null) { moves[start++] = MovePackHelper.Pack(HomeSquare, sq); } else { if (IsEnemy(sq)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[sq]); } break; } } } //SW if (PinStatus == PinStatus.None || (PinStatus & PinStatus.SWNE) != 0) { sq = HomeSquare; while (Square.SquareValid(sq + SW)) { sq += SW; if (board.BoardArray[sq] == null) { moves[start++] = MovePackHelper.Pack(HomeSquare, sq); } else { if (IsEnemy(sq)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[sq]); } break; } } } //SE if (PinStatus == PinStatus.None || (PinStatus & PinStatus.NWSE) != 0) { sq = HomeSquare; while (Square.SquareValid(sq + SE)) { sq += SE; if (board.BoardArray[sq] == null) { moves[start++] = MovePackHelper.Pack(HomeSquare, sq); } else { if (IsEnemy(sq)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[sq]); } break; } } } //NORTH if (PinStatus == PinStatus.None || (PinStatus & PinStatus.NS) != 0) { sq = HomeSquare; while (Square.SquareValid(sq + NORTH)) { sq += NORTH; if (board.BoardArray[sq] == null) { moves[start++] = MovePackHelper.Pack(HomeSquare, sq); } else { if (IsEnemy(sq)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[sq]); } break; } } } //WEST if (PinStatus == PinStatus.None || (PinStatus & PinStatus.WE) != 0) { sq = HomeSquare; while (Square.SquareValid(sq + WEST)) { sq += WEST; if (board.BoardArray[sq] == null) { moves[start++] = MovePackHelper.Pack(HomeSquare, sq); } else { if (IsEnemy(sq)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[sq]); } break; } } } //SOUTH if (PinStatus == PinStatus.None || (PinStatus & PinStatus.NS) != 0) { sq = HomeSquare; while (Square.SquareValid(sq + SOUTH)) { sq += SOUTH; if (board.BoardArray[sq] == null) { moves[start++] = MovePackHelper.Pack(HomeSquare, sq); } else { if (IsEnemy(sq)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[sq]); } break; } } } //EAST if (PinStatus == PinStatus.None || (PinStatus & PinStatus.WE) != 0) { sq = HomeSquare; while (Square.SquareValid(sq + EAST)) { sq += EAST; if (board.BoardArray[sq] == null) { moves[start++] = MovePackHelper.Pack(HomeSquare, sq); } else { if (IsEnemy(sq)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[sq]); } break; } } } return(start - begin); }
protected override int OnGetMoves(int start, int[] moves) { int begin = start; if (Square.Rank(HomeSquare) != lastRank && board.BoardArray[HomeSquare + oneStep] == null && (PinStatus == PinStatus.None || (PinStatus & PinStatus.NS) != 0)) { moves[start++] = MovePackHelper.Pack(HomeSquare, HomeSquare + oneStep); if (Square.Rank(HomeSquare + oneStep) == lastRank) { int prom = moves[start - 1]; moves[start - 1] |= MovePackHelper.GetPromotionMerge(PromotionTo.Queen); moves[start++] = prom | MovePackHelper.GetPromotionMerge(PromotionTo.Bishop); moves[start++] = prom | MovePackHelper.GetPromotionMerge(PromotionTo.Rook); moves[start++] = prom | MovePackHelper.GetPromotionMerge(PromotionTo.Knight); } if (Square.Rank(HomeSquare) == rankForEp && board.BoardArray[HomeSquare + twoStep] == null) { moves[start] = MovePackHelper.Pack(HomeSquare, HomeSquare + twoStep); MovePackHelper.GetCleanedMove(moves[start]); start++; } } if (Square.Rank(HomeSquare) != lastRank) { if (PinStatus == PinStatus.None || (PinStatus & PinStatus.NS) == 0) { if (Square.SquareValid(HomeSquare + diag1) && IsEnemy(HomeSquare + diag1) && PinCompatible(diag1)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[HomeSquare + diag1]); if (Square.Rank(HomeSquare + diag1) == lastRank) { int prom = moves[start - 1]; moves[start - 1] |= MovePackHelper.GetPromotionMerge(PromotionTo.Queen); moves[start++] = prom | MovePackHelper.GetPromotionMerge(PromotionTo.Bishop); moves[start++] = prom | MovePackHelper.GetPromotionMerge(PromotionTo.Rook); moves[start++] = prom | MovePackHelper.GetPromotionMerge(PromotionTo.Knight); } } if (Square.SquareValid(HomeSquare + diag2) && IsEnemy(HomeSquare + diag2) && PinCompatible(diag2)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[HomeSquare + diag2]); if (Square.Rank(HomeSquare + diag2) == lastRank) { int prom = moves[start - 1]; moves[start - 1] |= MovePackHelper.GetPromotionMerge(PromotionTo.Queen); moves[start++] = prom | MovePackHelper.GetPromotionMerge(PromotionTo.Bishop); moves[start++] = prom | MovePackHelper.GetPromotionMerge(PromotionTo.Rook); moves[start++] = prom | MovePackHelper.GetPromotionMerge(PromotionTo.Knight); } } // ep. if (Square.Rank(HomeSquare) == rankForEpCapture) { if (Square.SquareValid(HomeSquare + diag2) && HomeSquare + diag2 == board.EnPassant && PinCompatible(diag2) && board.CheckIfSafeEpCapture(Owner, HomeSquare)) { moves[start++] = MovePackHelper.Pack(HomeSquare, HomeSquare + diag2) | MovePackHelper.EpFlag; } if (Square.SquareValid(HomeSquare + diag1) && HomeSquare + diag1 == board.EnPassant && PinCompatible(diag1) && board.CheckIfSafeEpCapture(Owner, HomeSquare)) { moves[start++] = MovePackHelper.Pack(HomeSquare, HomeSquare + diag1) | MovePackHelper.EpFlag; } } } } return(start - begin); }
protected override int OnGetMoves(int start, int[] moves) { int begin = start; int sq; //NORTH int castlingMask = 0; if (HomeSquare == kingSide) { castlingMask = MovePackHelper.GetCastlingMerge(castlingMaskKing & (int)board.CastlingStatus); } if (HomeSquare == queenSide) { castlingMask = MovePackHelper.GetCastlingMerge(castlingMaskQueen & (int)board.CastlingStatus); } if (PinStatus == PinStatus.None || (PinStatus & PinStatus.NS) != 0) { sq = HomeSquare; while (Square.SquareValid(sq + NORTH)) { sq += NORTH; if (board.BoardArray[sq] == null) { moves[start++] = MovePackHelper.Pack(HomeSquare, sq) | castlingMask; } else { if (IsEnemy(sq)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[sq]) | castlingMask; } break; } } } //WEST if (PinStatus == PinStatus.None || (PinStatus & PinStatus.WE) != 0) { sq = HomeSquare; while (Square.SquareValid(sq + WEST)) { sq += WEST; if (board.BoardArray[sq] == null) { moves[start++] = MovePackHelper.Pack(HomeSquare, sq) | castlingMask; } else { if (IsEnemy(sq)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[sq]) | castlingMask; } break; } } } //SOUTH if (PinStatus == PinStatus.None || (PinStatus & PinStatus.NS) != 0) { sq = HomeSquare; while (Square.SquareValid(sq + SOUTH)) { sq += SOUTH; if (board.BoardArray[sq] == null) { moves[start++] = MovePackHelper.Pack(HomeSquare, sq) | castlingMask; } else { if (IsEnemy(sq)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[sq]) | castlingMask; } break; } } } //EAST if (PinStatus == PinStatus.None || (PinStatus & PinStatus.WE) != 0) { sq = HomeSquare; while (Square.SquareValid(sq + EAST)) { sq += EAST; if (board.BoardArray[sq] == null) { moves[start++] = MovePackHelper.Pack(HomeSquare, sq) | castlingMask; } else { if (IsEnemy(sq)) { moves[start++] = MovePackHelper.Pack(this, board.BoardArray[sq]) | castlingMask; } break; } } } return(start - begin); }