public bool ValidateAndMove(ChessMove chessMove, ChessColor playerColor) { if (promotionDetector.IsPromotionRequired()) { return(ValidateAndPromote(chessMove)); } var piece = chessBoard.Pieces .FirstOrDefault(p => p.Position == chessMove.StartingPosition); if (piece == null) { return(false); } if (piece.Color != playerColor) { return(false); } var movements = legalMovement.GetAvailableLegalMoves(piece); if (!movements.Contains(chessMove)) { return(false); } chessBoard.Move(chessMove); return(true); }
int AlphaBeta(int depth, int alpha, int beta) { int score = 0; int ttMove = 0; int bestMove = 0; TTType ttFlag = TTType.Alpha; if (clk.GetElapsedMilliseconds() > totalMillisec) { return(0); // timeout } if (depth == 0) { return(Quiesce(alpha, beta, 0)); } else { if (ttable.Probe(board.ZKey, depth, alpha, beta, ref ttMove, ref score)) { return(score); } bestMove = ttMove; var moves = GetMoves(bestMove, depth); if (moves.Count() == 0) { score = board.InCheck(board.ToMove)?-INFINITE:0; ttable.Save(board.ZKey, depth, score, TTType.Exact, 0); return(score); } foreach (var move in moves) { board.Move(move); score = -AlphaBeta(depth - 1, -beta, -alpha); board.UndoMove(); if (score > alpha) { bestMove = move; alpha = score; ttFlag = TTType.Exact; } if (alpha >= beta) // current plaier move is better than the other one better, no reason to search further { //beta cutoff !!! ttable.Save(board.ZKey, depth, beta, TTType.Beta, bestMove); if (0 != (MovePackHelper.Capture & move)) { StoreKiller(depth, move); } return(beta); } } ttable.Save(board.ZKey, depth, alpha, ttFlag, bestMove); return(alpha); } }
public void Pawn_Move_IllegalCoordinates_Right_DoesNotMove() { chessBoard.Add(pawnBlack, 6, 3); var outcome = chessBoard.Move(MovementType.Move, 6, 3, 7, 3); Assert.AreEqual(outcome, MoveOutcome.Illegal); Assert.AreEqual(pawnBlack.XCoordinate, 6); Assert.AreEqual(pawnBlack.YCoordinate, 3); }
public int Search(IChessBoard board, int alpha, int beta, int depth) { if (depth == 0) { return(quiesce(board, alpha, beta)); } else { var moves = getMoves(board); if (moves.Count() == 0) { return(zeroMoveEval()); } foreach (var move in moves) { board.Move(move); var score = -Search(board, -beta, -alpha, depth - 1); board.UndoMove(); if (score > alpha) { foundMove(board, move, depth, score); alpha = score; } if (alpha >= beta) // current plaier move is better than the other one better, no reason to search further { //beta cutoff !!! betaCutoff(board, move, depth, score); break; } } return(alpha); } }
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); }
public IEnumerable <ChessMove> GetAvailableLegalMoves(IReadOnlyChessPiece chessPiece) { var filteredMoves = new List <ChessMove>(); foreach (var chessMove in movement.GetAvailableMoves(chessPiece)) { chessBoard.Move(chessMove); if (!checkDetector.IsChecked(chessPiece.Color)) { filteredMoves.Add(chessMove); } chessBoard.ReverseLastMove(); } return(filteredMoves); }
public static string ProduceShortAlgebraicString(IChessBoard board, int p) { board.TestInCheck(board.ToMove); int [] moves = new int[200]; board.GetMoves(0, moves); List <int> possibles = new List <int>(); int end = MovePackHelper.GetEndSquare(p); foreach (var m in moves) { if (GetEndSquare(m) == end && board.BoardArray[GetStartSquare(m)].Type == board.BoardArray[GetStartSquare(p)].Type) { possibles.Add(p); } } StringBuilder sb = new StringBuilder(); var spiece = board.BoardArray[GetStartSquare(p)]; if (spiece.Type != PieceType.Pawn) { sb.Append(spiece.ToString().ToUpper()); } if (possibles.Count > 1) { var squares = possibles.Select(k => GetSquareString(GetStartSquare(k))); if (squares.Select(k => k[0]).Distinct().Count() > 1) { sb.Append(GetSquareString(GetStartSquare(p))[0]); } else if (squares.Select(k => k[1]).Distinct().Count() > 1) { sb.Append(GetSquareString(GetStartSquare(p))[1]); } else { sb.Append(GetSquareString(GetStartSquare(p))); } } if (HasCapture(p)) { sb.Append("x"); } sb.Append(GetSquareString(GetEndSquare(p))); board.Move(p); board.TestInCheck(board.ToMove); int cnt = board.GetCheckCount(board.ToMove); if (cnt > 0) { int[] tmp = new int[200]; if (0 == board.GetMoves(0, tmp)) { sb.Append("#"); } else { sb.Append(new string('+', cnt)); } } board.UndoMove(); return(sb.ToString()); }
public void Consume(string input) { string[] tokens = input.Split(' '); string rPart = ""; for (int i = 1; i < tokens.Length; ++i) { rPart += tokens[i]; rPart += " "; } rPart = rPart.Trim(); if (!edit) { switch (tokens[0]) { //Ignore unhandled commands case "level": case "otim": case "time": case "random": case "hard": case "easy": case "sd": case "st": case "strong": case "post": case "result": case "computer": case "?": break; case "savepos": OnMessageToWinboard(board.SavePos()); break; case "divide": int depth = int.Parse(rPart); board.DividePartialResult += new EventHandler(div_DividePartialResult); DivideResults div = board.Divide(depth); OnMessageToWinboard(string.Format("Total Nodes: {0}", div.NodesCount)); OnMessageToWinboard(string.Format("Moves Count: {0}", div.MovesCount)); board.DividePartialResult -= new EventHandler(div_DividePartialResult); break; case "qperft": OnMessageToWinboard("Performing perft with hash table"); depth = int.Parse(rPart); PerfResults res2 = board.Perft(depth, true, hashTable); OnMessageToWinboard(string.Format("Depth: {3} {0} moves {1:0.00} seconds. {2:0.000} Move/s. Hash Hit={4}", res2.MovesCount, (double)res2.Elapsed / 1000.0, (double)res2.MovesCount / (res2.Elapsed / 1000.0), depth, res2.HashHit)); break; case "perft": depth = int.Parse(rPart); PerfResults res = board.Perft(depth, false, null); OnMessageToWinboard(string.Format("Depth: {3} {0} moves {1:0.00} seconds. {2:0.000} Move/s", res.MovesCount, (double)res.Elapsed / 1000.0, (double)res.MovesCount / (res.Elapsed / 1000.0), depth)); break; case "perf": PerfResults undoRedo; PerfResults mgen = board.Perf(out undoRedo, 400000); OnMessageToWinboard(string.Format("Generated {0} moves in {1:0.00} seconds. {2:0.00} Move/s", mgen.MovesCount, (double)mgen.Elapsed / 1000.0, (double)mgen.MovesCount / (mgen.Elapsed / 1000.0))); OnMessageToWinboard(string.Format("{0} moves Done/Undone in {1:0.00} seconds. {2:0.00} Move/s", undoRedo.MovesCount, (double)undoRedo.Elapsed / 1000.0, (double)undoRedo.MovesCount / (undoRedo.Elapsed / 1000.0))); break; case "setboard": board.SetBoard(rPart); break; case "remove": Break(); board.UndoMove(); board.UndoMove(); break; case "undo": board.UndoMove(); break; case "new": Break(); force = false; board.SetBoard("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); InitializeEngine(); break; case "dump": StringBuilder sb = new StringBuilder(); board.Dump(new StringWriter(sb)); OnMessageToWinboard(sb.ToString()); break; case "go": force = false; AsyncStartPlay(); break; case "force": Break(); force = true; break; case "black": Break(); movingSide = Side.Black; throw new NotImplementedException(); case "white": Break(); movingSide = Side.White; throw new NotImplementedException(); case "edit": Break(); edit = true; break; default: try { board.Move(tokens[0]); } catch (Exception e) { string s = string.Format("Error ({0}):", e.Message); OnMessageToWinboard(s); } break; } } else { switch (tokens[0]) { case "#": board.SetBoard("/8/8/8/8/8/8/8/8 w KQkq - 0 1"); //engine.Board = board; editingSide = Side.White; break; case ".": throw new NotImplementedException(); //edit = false; //engine.OpeningBook = null; // remove opening book break; case "c": editingSide = Side.Black; break; default: break; } } }