예제 #1
0
 // Holds the move for negamax
 public CalculatedMove(float value, Position moveFrom, MoveSet moveset)
 {
     // Automatically does the negating
     Value    = -value;
     MoveFrom = moveFrom;
     Moveset  = moveset;
 }
예제 #2
0
파일: MoveSet.cs 프로젝트: wrb06/Draughts
 public MoveSet(MoveSet moveset)
 {
     _moves = new List <Position>();
     if (moveset.NumberOfStages() > 0)
     {
         foreach (Position p in moveset.Moves)
         {
             _moves.Add(p);
         }
     }
 }
예제 #3
0
        // Non recursive checking the 4 moves around the piece
        public override List <MoveSet> GetNonTakeMoves(Board board)
        {
            List <MoveSet> Moves = new List <MoveSet>();

            // Adds backwards non take moves
            Position LB = this.CurrentPosition.GetLeftBack(IsWhite);
            Position RB = this.CurrentPosition.GetRightBack(IsWhite);
            Position LF = this.CurrentPosition.GetLeftForward(IsWhite);
            Position RF = this.CurrentPosition.GetRightForward(IsWhite);

            if (LF.InBoard())
            {
                if (board.GetPiece(LF) == null)
                {
                    MoveSet moveset = new MoveSet(LF);
                    Moves.Add(moveset);
                }
            }
            if (RF.InBoard())
            {
                if (board.GetPiece(RF) == null)
                {
                    MoveSet moveset = new MoveSet(RF);
                    Moves.Add(moveset);
                }
            }
            if (LB.InBoard())
            {
                if (board.GetPiece(LB) == null)
                {
                    MoveSet moveset = new MoveSet(LB);
                    Moves.Add(moveset);
                }
            }
            if (RB.InBoard())
            {
                if (board.GetPiece(RB) == null)
                {
                    MoveSet moveset = new MoveSet(RB);
                    Moves.Add(moveset);
                }
            }

            return(Moves);
        }
예제 #4
0
        // Searches Depth moves ahead in the game and finds the best move
        private CalculatedMove NegaMax(int Depth, int PlayerColour, float alpha, float beta, Board board, BackgroundWorker worker)
        {
            // Setup
            float          BestValue       = float.MinValue;
            bool           FoundTakeMove   = false;
            bool           AppliedTakeMove = false;
            List <MoveSet> possibleMovesets;

            List <Position> usablepieces = new List <Position>();

            if (PlayerColour == 1)
            {
                usablepieces = board.GetWhitePositions();
            }
            else
            {
                usablepieces = board.GetBlackPositions();
            }

            //Show the tree (to the console)
            if (Debug && Depth > 0)
            {
                Console.WriteLine();
                for (int p = 0; p < (DepthOfSearch - Depth); p++)
                {
                    Console.Write("\t");
                }

                if ((DepthOfSearch % 2 == Depth % 2 && IsWhite) || (DepthOfSearch % 2 != Depth % 2 && !IsWhite))
                {
                    Console.Write("> MAX | ");
                }
                else
                {
                    Console.Write("> MIN | ");
                }

                Console.Write("Depth: " + Depth.ToString());
                Console.WriteLine();
            }
            if (Debug)
            {
                ShowBoard(board, Depth + 1);
            }

            // detect if we should stop
            if (Depth == 0 || usablepieces.Count == 0 || board.WhiteHasWon() || board.BlackHasWon())
            {
                return(new CalculatedMove(PlayerColour * board.EvaluateBoard(), new Position(-1, -1), new MoveSet()));
            }

            // If we can carry on searching, setup BestPiece and BestMoveset with first valid move we come accross
            Position BestPiecePosition = new Position(-1, -1);
            MoveSet  BestMoveset       = new MoveSet();

            foreach (Position p in usablepieces)
            {
                BestPiecePosition = p;
                if (board.GetPiece(p).GetMoves(board).Count > 0)
                {
                    BestMoveset = board.GetPiece(p).GetMoves(board).First();
                    break;
                }
            }

            // Counts the number of pieces we have searched
            int piececount = 0;

            foreach (Position pieceposition in usablepieces)
            {
                if (Debug)
                {
                    Console.WriteLine();
                    for (int p = -1; p < (DepthOfSearch - Depth); p++)
                    {
                        Console.Write("\t");
                    }
                    Console.WriteLine("NEW PIECE at " + pieceposition.ToString());
                }

                // generate all possible take movesets
                possibleMovesets = board.GetPiece(pieceposition).GetTakeMovesOnly(board);
                if (possibleMovesets.Count > 0)
                {
                    if (!FoundTakeMove && !AppliedTakeMove)
                    {
                        // if this is the first piece that has take movesets, mark it so that every move is better than what we had.
                        FoundTakeMove = true;
                    }
                }
                else if (!FoundTakeMove)
                {
                    possibleMovesets = board.GetPiece(pieceposition).GetMoves(board);
                }

                if (Debug)
                {
                    for (int p = 0; p < (DepthOfSearch - Depth); p++)
                    {
                        Console.Write("\t");
                    }
                    Console.WriteLine("Take Moves found: " + FoundTakeMove);
                }

                bool BreakOuterLoop = false;
                foreach (MoveSet moveset in possibleMovesets)
                {
                    // Make test board
                    Board testboard = board.MakeNewCopyOf();

                    // Make move
                    Position oldpos = pieceposition;
                    foreach (Position move in moveset.Moves)
                    {
                        testboard.MovePeice(oldpos, move);
                        oldpos = move;
                    }

                    // Run the search
                    CalculatedMove Move = NegaMax(Depth - 1, -PlayerColour, -beta, -alpha, testboard, worker);

                    // Change the best result if we need to
                    if (BestValue < Move.Value || (FoundTakeMove && !AppliedTakeMove))
                    {
                        if (FoundTakeMove && !AppliedTakeMove)
                        {
                            AppliedTakeMove = true;
                        }

                        BestMoveset       = moveset;
                        BestPiecePosition = pieceposition;

                        if (Debug && Move.Moveset.NumberOfStages() > 0)
                        {
                            for (int p = 0; p < (DepthOfSearch - Depth); p++)
                            {
                                Console.Write("\t");
                            }
                            Console.WriteLine("New best move from " + Move.MoveFrom.ToString() + " to " + Move.Moveset.Last().ToString() + " with score of: " + Move.Value.ToString() + " breating previous of: " + BestValue.ToString());
                        }
                        BestValue = Move.Value;
                    }
                    alpha = Math.Max(alpha, BestValue);

                    if (Debug)
                    {
                        for (int p = -1; p < (DepthOfSearch - Depth); p++)
                        {
                            Console.Write("\t");
                        }
                        Console.WriteLine(" | Current Board Score: " + (PlayerColour * testboard.EvaluateBoard()).ToString() + " | Best Value: " + BestValue.ToString());
                    }

                    if (alpha >= beta && UsePruning)
                    {
                        if (Debug)
                        {
                            for (int p = 0; p < (DepthOfSearch - Depth); p++)
                            {
                                Console.Write("\t");
                            }
                            Console.WriteLine(alpha.ToString() + " " + beta.ToString() + "Broke");
                        }
                        BreakOuterLoop = true;
                        break;
                    }
                }

                // If its the first call (highest depth) and we have finished a piece, report back to the worker our progress
                if (Depth == DepthOfSearch)
                {
                    worker.ReportProgress((int)(100f * piececount) / usablepieces.Count);
                }
                piececount++;

                if (BreakOuterLoop)
                {
                    break;
                }
            }
            return(new CalculatedMove(BestValue, BestPiecePosition, BestMoveset));
        }
예제 #5
0
        // recursive structure to find multi-step moves around the piece
        private List <MoveSet> GetTakeMoves(Board board, Position position, bool iswhite, MoveSet moveset)
        {
            List <MoveSet> Moves = new List <MoveSet>();

            Position LB  = position.GetLeftBack(iswhite);
            Position LBT = position.GetLeftBackTake(IsWhite);

            Position RB  = position.GetRightBack(IsWhite);
            Position RBT = position.GetRightBackTake(IsWhite);

            Position LF  = position.GetLeftForward(iswhite);
            Position LFT = position.GetLeftForwardTake(IsWhite);

            Position RF  = position.GetRightForward(IsWhite);
            Position RFT = position.GetRightForwardTake(IsWhite);

            MoveSet CurrentMove = new MoveSet(moveset);

            if (LB.InBoard() && LBT.InBoard())
            {
                if (board.GetPiece(LB) != null && board.GetPiece(LBT) == null)
                {
                    if (board.GetPiece(LB).IsWhite != this.IsWhite)
                    {
                        Board testboard = board.MakeNewCopyOf();
                        testboard.RemovePeice(testboard.GetPiece(LB));
                        CurrentMove.Add(LBT);
                        Moves.Add(CurrentMove);

                        moveset.Add(LBT);
                        Moves.AddRange(GetTakeMoves(testboard, LBT, IsWhite, moveset));
                        moveset.Remove(LBT);
                    }
                }
            }
            CurrentMove = new MoveSet(moveset);
            if (RB.InBoard() && RBT.InBoard())
            {
                if (board.GetPiece(RB) != null && board.GetPiece(RBT) == null)
                {
                    if (board.GetPiece(RB).IsWhite != this.IsWhite)
                    {
                        Board testboard = board.MakeNewCopyOf();
                        testboard.RemovePeice(testboard.GetPiece(RB));
                        CurrentMove.Add(RBT);
                        Moves.Add(CurrentMove);

                        moveset.Add(RBT);
                        Moves.AddRange(GetTakeMoves(testboard, RBT, IsWhite, moveset));

                        moveset.Remove(RBT);
                    }
                }
            }
            CurrentMove = new MoveSet(moveset);
            if (LF.InBoard() && LFT.InBoard())
            {
                if (board.GetPiece(LF) != null && board.GetPiece(LFT) == null)
                {
                    if (board.GetPiece(LF).IsWhite != this.IsWhite)
                    {
                        Board testboard = board.MakeNewCopyOf();
                        testboard.RemovePeice(testboard.GetPiece(LF));

                        CurrentMove.Add(LFT);
                        Moves.Add(CurrentMove);

                        moveset.Add(LFT);
                        Moves.AddRange(GetTakeMoves(testboard, LFT, IsWhite, moveset));
                        moveset.Remove(LFT);
                    }
                }
            }
            CurrentMove = new MoveSet(moveset);
            if (RF.InBoard() && RFT.InBoard())
            {
                if (board.GetPiece(RF) != null && board.GetPiece(RFT) == null)
                {
                    if (board.GetPiece(RF).IsWhite != this.IsWhite)
                    {
                        Board testboard = board.MakeNewCopyOf();
                        testboard.RemovePeice(testboard.GetPiece(RF));
                        CurrentMove.Add(RFT);
                        Moves.Add(CurrentMove);

                        moveset.Add(RFT);
                        Moves.AddRange(GetTakeMoves(testboard, RFT, IsWhite, moveset));
                        moveset.Remove(RFT);
                    }
                }
            }

            return(Moves);
        }