Пример #1
0
        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);
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
            }
        }
Пример #5
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);
        }
Пример #6
0
        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);
        }
Пример #7
0
        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());
        }
Пример #8
0
        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;
                }
            }
        }