Beispiel #1
0
        public static Move GetBestMove(Board b)
        {
            List<Tuple<Board, Move>> possibleNextBoards = new List<Tuple<Board, Move>>();

            foreach (Move posMove in b.AllMoves)
            {
                possibleNextBoards.Add(new Tuple<Board, Move>(b.MakeMove(posMove.From, posMove.To), posMove));
            }

            List<Tuple<Move, double>> moveScores = new List<Tuple<Move, double>>();

            foreach (var posNextBoard in possibleNextBoards)
            {
                var bestPossibleBoard = allData.Where(x => x.Item1.WhosMove == posNextBoard.Item1.WhosMove)
                                               .OrderBy(x => Similarity.Calculate(x.Item1, posNextBoard.Item1))
                                               .First();
                double score = Similarity.Calculate(bestPossibleBoard.Item1, posNextBoard.Item1);

                moveScores.Add(new Tuple<Move, double>(posNextBoard.Item2, score));
            }

            Move suggestedMove = moveScores.OrderBy(x => x.Item2).First().Item1;

            return suggestedMove;
        }
        public long GetBoardHash(Board b)
        {
            long h = 0;

            for (int i = 0; i < 64; i++)
            {
                if (b.S[i] != null)
                {
                    int pieceType = (int)b.S[i].PieceType;
                    int pieceColour = (int)b.S[i].Colour;

                    int j = ((pieceType - 1) * 2) + pieceColour;
                    h = h ^ m_Hs[i, j];
                }
            }

            if (b.WhosMove == Colour.White) h ^= m_Hs[64, 0];
            if (b.WhosMove == Colour.Black) h ^= m_Hs[64, 1];
            if (b.BlackCanKCastle) h ^= m_Hs[64, 2];
            if (b.BlackCanQCastle) h ^= m_Hs[64, 3];
            if (b.WhiteCanKCastle) h ^= m_Hs[64, 4];
            if (b.WhiteCanQCastle) h ^= m_Hs[64, 5];

            return h;
        }
        public Tuple<int, double> GetDepthScoreTuple(Board b)
        {
            long hash = GetBoardHash(b);

            if (m_Zs.ContainsKey(hash))
                return m_Zs[hash];

            return null;
        }
        private double AlphaBeta(Board b, int depth, double alpha, double beta, int colour, ref Move bestMoveYet)
        {
            if (depth == 0)
                return b.ScoreBoard();
            else
            {
                if (colour == 1)
                {
                    for (int i = 0; i < b.AllMovesCount; i++)
                    {
                        Move move = b.AllMoves[i];
                        double result = AlphaBeta(b.GetBoardAfterMove(move.From, move.To), depth - 1, alpha, beta, -colour, ref bestMoveYet);
                        nodesVisited++;

                        if (result > alpha)
                        {
                            alpha = result;
                            if (depth == MaxAlphaBetaDepth) bestMoveYet = move;
                        }
                        if (beta <= alpha)
                        {
                            betaSkips++;
                            goto skip1;
                        }
                    }
                skip1:
                    return alpha;
                }
                else if (colour == -1)
                {
                    for (int i = 0; i < b.AllMovesCount; i++)
                    {
                        Move move = b.AllMoves[i];
                        double result = AlphaBeta(b.GetBoardAfterMove(move.From, move.To), depth - 1, alpha, beta, -colour, ref bestMoveYet);
                        nodesVisited++;

                        if (result < beta)
                        {
                            beta = result;
                            if (depth == MaxAlphaBetaDepth) bestMoveYet = move;
                            //bestMoveYet = move;
                        }
                        if (beta <= alpha)
                        {
                            betaSkips++;
                            goto skip2;
                        }
                    }
                skip2:
                    return beta;
                }
                else throw new ApplicationException();
            }

            throw new ApplicationException();
        }
        public MainWindow()
        {
            InitializeComponent();
            CreatePieceBoxes();

            board = new Board();
            board.SetupStandardBoard();

            RenderBoard(board);
        }
        private double Negamax(Board b, int depth, double alpha, double beta, int colour)
        {
            Tuple<int, double> tuple = m_Zasher.GetDepthScoreTuple(b);
            // If the same or better calculation of this state has already been made, use it.
            if (tuple != null && tuple.Item1 >= depth && depth < MaxNegamaxDepth)
            {
                if (depth > 0) hashUsed++;
                if (depth >= 0) hashUsed++;
                return colour * tuple.Item2;
            }

            if (depth == 0)
            {
                double score = b.ScoreBoard();
                m_Zasher.SetDepthScoreTuple(b, new Tuple<int, double>(0, score));
                hashNotUsed++;
                return colour * score;
            }
            else
            {
                for (int i = 0; i < b.AllMovesCount; i++)
                {
                    Move move = b.AllMoves[i];
                    Board boardAfterMove = new Board(b);
                    bool moveOk = boardAfterMove.MakeMove(move.From, move.To);

                    if (moveOk)
                    {
                        double score = -Negamax(boardAfterMove, depth - 1, -beta, -alpha, -colour);

                        // Cache this score
                        m_Zasher.AddIfBetter(boardAfterMove, new Tuple<int, double>(depth - 1, colour * score));

                        nodesVisited++;
                        if (score >= beta)
                            return score;
                        if (score > alpha)
                        {
                            alpha = score;
                        }

                        if (depth == MaxNegamaxDepth)
                        {
                            m_RankedMoves.Add(new Tuple<Move, double>(move, colour * score));
                            m_Zasher.AddIfBetter(b, new Tuple<int, double>(depth, colour * score));
                        }
                    }
                }

                return alpha;
            }
        }
        public override Move ComputeBestMove()
        {
            for (int i = 0; i < 100; i++)
            {
                int r = rand.Next(0, b.AllMovesCount);

                Move randMove = new Move(b.AllMoves[r].From, b.AllMoves[r].To, -100);
                Board boardAfterMove = new Board(b);
                if (boardAfterMove.MakeMove(randMove.From, randMove.To)) return randMove;
            }

            throw new ApplicationException("Can't find possible move");
        }
Beispiel #8
0
        public Board(Board currentBoard)
        {
            this.BlackCanQCastle = currentBoard.BlackCanQCastle;
            this.BlackCanKCastle = currentBoard.BlackCanKCastle;
            this.WhiteCanQCastle = currentBoard.WhiteCanQCastle;
            this.WhiteCanKCastle = currentBoard.WhiteCanKCastle;
            this.WhosMove = currentBoard.WhosMove;

            for (int i = 0; i < 64; i++)
            {
                if (currentBoard.S[i] != null)
                    S[i] = new Piece(currentBoard.S[i]);
            }
            m_OldBoard = currentBoard;
        }
        internal void AddIfBetter(Board b, Tuple<int, double> tuple)
        {
            long hash = GetBoardHash(b);

            if (m_Zs.ContainsKey(hash))
            {
                // If this position has been calculated to a greater depth, use it instead
                if (tuple.Item1 > m_Zs[hash].Item1)
                    m_Zs[hash] = tuple;
            }
            else
            {
                m_Zs[hash] = tuple;
            }
        }
Beispiel #10
0
        public static double Calculate(Board b1, Board b2)
        {
            Stats s1 = new Stats(b1);
            Stats s2 = new Stats(b2);

            double statSimilarity = GetStatSimilarity(s1, s2);
            double boardSimilarity = 0;

            for (int i = 0; i < 63; i++)
            {
                if (b1.S[i].Colour == b2.S[i].Colour
                    && b1.S[i].PieceType == b2.S[i].PieceType)
                    boardSimilarity -= PieceValue(b1.S[i].PieceType);
            }

            //boardSimilarity = 0;

            return statSimilarity + boardSimilarity;
        }
Beispiel #11
0
        static void Main(string[] args)
        {
            string wholeFile = "";
            List<Tuple<Board, Move>> allData = new List<Tuple<Board, Move>>();

            using(StreamReader fs = new StreamReader(File.OpenRead(".\\Ivanchuk.pgn")))
                wholeFile = fs.ReadToEnd();

            string[] games = Regex.Split(wholeFile, "\\[Event.*\\]\r\n\r\n");

            PgnParser.Parser parser = new PgnParser.Parser();

            for (int i = 0; i < 100; i++)
            {
                Board board = new Board();
                var enu = parser.Parse(games[i]).GetEnumerator();
                board.SetupStandardBoard();

                while (enu.MoveNext())
                {
                    board = board.MakeMove(enu.Current.From, enu.Current.To);
                    allData.Add(new Tuple<Board, Move>(board, enu.Current));
                }
            }

            Board b = allData[263].Item1;
            var mostSimilars = allData.Where(x => x.Item1.WhosMove == b.WhosMove).
                                       OrderBy(x => Similarity.Calculate(x.Item1, b)).ToList();
            Move suggestedMove = new Move(-1, -1);

            for (int i = 0; i < mostSimilars.Count; i++)
            {
                Tuple<Board, Move> tup = mostSimilars[i];
                suggestedMove = tup.Item2;
                if (b.AllMoves.Contains(suggestedMove))
                    break;
            }
        }
Beispiel #12
0
        static Parser()
        {
            string wholeFile = "";

            using (StreamReader fs = new StreamReader(File.OpenRead(".\\Ivanchuk.pgn")))
                wholeFile = fs.ReadToEnd();

            string[] games = Regex.Split(wholeFile, "\\[Event.*\\]\r\n\r\n");

            PgnParser.Parser parser = new PgnParser.Parser();

            for (int i = 0; i < 100; i++)
            {
                Board board = new Board();
                var enu = parser.Parse(games[i]).GetEnumerator();
                board.SetupStandardBoard();

                while (enu.MoveNext())
                {
                    allData.Add(new Tuple<Board, Move>(board, enu.Current));
                    board = board.MakeMove(enu.Current.From, enu.Current.To);
                }
            }
        }
        private void HumanMoved()
        {
            int oldPos = (int)fromImage.Tag;
            int destPos = (int)toImage.Tag;

            try
            {
                board = board.MakeMove(oldPos, destPos);
                Move m = PgnParser.Parser.GetBestMove(board);
                board = board.MakeMove(m.From, m.To);
                RenderBoard(board);
            }
            catch (ApplicationException e)
            {
                MessageBox.Show(e.Message);
            }

            fromImage.Opacity = 1f;
            fromImage = null;
            toImage.Opacity = 1f;
            toImage = null;
        }
        private void RenderBoard(Board board)
        {
            for (int i = 0; i < 8; i++)
                for (int j = 0; j < 8; j++)
                {
                    Piece piece = board.S[i * 8 + j];
                    Colour squareColour = i % 2 == j % 2 ? Colour.White : Colour.Black;
                    pieceBoxes[j, i].Source = PieceImages.For(piece.Colour, squareColour, piece.PieceType);
                }

            boardCanvas.UpdateLayout();
            this.UpdateLayout();
        }
 private void UpdateUi(Board board)
 {
     RenderBoard(board);
     labelScoreBoard.Content = String.Format("{0:0.00}", computer.Board.ScoreBoard());
     //if(!computer.IsThinking)
         labelComputationTime.Content = String.Format("{0:0.00}s", (float)computer.MsTaken / 1000f);
     labelWhosTurn.Content = String.Format("Your turn");
 }
 public void SetDepthScoreTuple(Board b, Tuple<int, double> tuple)
 {
     long hash = GetBoardHash(b);
     m_Zs[hash] = tuple;
 }
Beispiel #17
0
        public Stats(Board b)
        {
            TotalPossibleMoves = b.AllMoves.Count;

            for (int i = 0; i < 64; i++)
            {
                if(b.S[i].Colour == Colour.White)
                {
                    switch (b.S[i].PieceType)
                    {
                        case PieceType.Blank:
                            break;
                        case PieceType.Pawn:
                            WPCount++;
                            WPAdvancement += i * i;
                            break;
                        case PieceType.Knight:
                            WNCount++;
                            break;
                        case PieceType.Bishop:
                            WBCount++;
                            WBMobility += b.S[i].ValidMoves.Count;
                            break;
                        case PieceType.Rook:
                            WRCount++;
                            break;
                        case PieceType.Queen:
                            WQCount++;
                            break;
                    }
                }
                else if (b.S[i].Colour == Colour.Black)
                {
                    switch (b.S[i].PieceType)
                    {
                        case PieceType.Blank:
                            break;
                        case PieceType.Pawn:
                            BPCount++;
                            BPAdvancement += (7 - i) * (7 - i);
                            break;
                        case PieceType.Knight:
                            BNCount++;
                            break;
                        case PieceType.Bishop:
                            BBCount++;
                            BBMobility += b.S[i].ValidMoves.Count;
                            break;
                        case PieceType.Rook:
                            BRCount++;
                            break;
                        case PieceType.Queen:
                            BQCount++;
                            break;
                    }
                }
            }

            TotalPieces = WPCount + WNCount + WBCount + WRCount + WQCount + BPCount + BNCount + BBCount + BRCount + BQCount;
        }
Beispiel #18
0
        public void MakeMove(int fromPos, int toPos)
        {
            if (!Board.MoveIsLegal(fromPos, toPos))
                throw new ApplicationException("Move is illegal. Try another");

            Board newBoard = new Board(Board);
            bool isLegal = newBoard.MakeMove(fromPos, toPos);

            if (isLegal)
            {
                m_OldBoards.Push(Board);
                Board = newBoard;
                WhosMove = newBoard.WhosMove;
            }
            else
            {
                throw new ApplicationException("Move is illegal. Try another");
            }
        }
Beispiel #19
0
 public void BuildInitialBoard()
 {
     b = Board.InitialStandardBoard;
 }
Beispiel #20
0
        public IEnumerable<Move> Parse(string pgn)
        {
            string tmp = RemoveNonsense(pgn);
            string[] byMoves = SplitIntoMoves(tmp);

            bool whiteMove = true;

            Thursday.Board board = new Thursday.Board();
            board.SetupStandardBoard();

            int curMove = 0;

            foreach (string move in byMoves)
            {
                string[] ms = move.Split(whiteSpaces, StringSplitOptions.RemoveEmptyEntries);

                if (ms.Length == 0)
                {
                    // Boring.  Just continue
                }
                else if (ms.Length == 2)
                {
                    if (IsEndStatement(ms[0])) goto ended;

                    Move move1 = ParseMove(ms[0], board);
                    board = board.MakeMove(move1.From, move1.To);
                    curMove++;

                    PrintDebug(curMove, board);

                    yield return move1;

                    if (IsEndStatement(ms[1])) goto ended;

                    Move move2 = ParseMove(ms[1], board);
                    board = board.MakeMove(move2.From, move2.To);
                    curMove++;

                    PrintDebug(curMove, board);

                    yield return move2;
                }
                else if (ms.Length == 1)
                {
                    if (IsEndStatement(ms[0])) goto ended;

                    Move move1 = ParseMove(ms[0], board);
                    board = board.MakeMove(move1.From, move1.To);
                    curMove++;

                    PrintDebug(curMove, board);

                    yield return move1;
                }
                else if (ms.Length == 3 && IsEndStatement(ms[2]))
                {
                    Move move1 = ParseMove(ms[0], board);
                    board = board.MakeMove(move1.From, move1.To);
                    curMove++;

                    PrintDebug(curMove, board);

                    yield return move1;

                    Move move2 = ParseMove(ms[1], board);
                    board = board.MakeMove(move2.From, move2.To);
                    curMove++;

                    PrintDebug(curMove, board);

                    yield return move2;

                    goto ended;
                }
                else
                {
                    throw new ApplicationException("Not 0 1 or 2 moves found");
                }
            }

            ended:
            ;
        }
        private void RenderBoard(Board board)
        {
            for (int i = 0; i < 8; i++)
                for (int j = 0; j < 8; j++)
                {
                    Piece piece;

                    if (m_Flipped)
                        piece = board.S[63 - (i * 8 + j)];
                    else
                        piece = board.S[i * 8 + j];

                    Colour squareColour = i % 2 == j % 2 ? Colour.White : Colour.Black;

                    if (piece == null)
                        pieceBoxes[j, i].Source = PieceImages.For(Colour.Blank, squareColour, PieceType.Blank);
                    else
                        pieceBoxes[j, i].Source = PieceImages.For(piece.Colour, squareColour, piece.PieceType);
                }

            boardCanvas.UpdateLayout();
            this.UpdateLayout();
        }