Ejemplo n.º 1
0
        public List <Board> GenerateSafeBoards(bool includeCheckmates)
        {
            List <Board> boards       = this.GenerateSubBoards();
            Board        workingBoard = new Board();

            for (int k = 0; k < boards.Count; k++)
            {
                workingBoard.Copy(boards[k]);

                foreach (Board b in workingBoard.GenerateSubBoards())
                {
                    if (b.GetWinner() == workingBoard.CurrentPlayer)
                    {
                        boards.RemoveAt(k);
                        k--;
                        break;
                    }
                    if (includeCheckmates &&
                        BoardEvaluator.HasCheckmate(b, workingBoard.CurrentPlayer))
                    {
                        boards.RemoveAt(k);
                        k--;
                        break;
                    }
                }
            }
            return(boards);
        }
Ejemplo n.º 2
0
        // Negamax style alpha beta pruning search
        private int AlphaBeta(Board b, int depth, int alpha, int beta)
        {
            if (depth == 0)
            {
                return(-b.Evaluation);
            }

            switch (b.GetWinner())
            {
            case PieceColor.White:
                return((b.CurrentPlayer == PieceColor.White) ? BoardEvaluator.EVAL_WHITE_WIN : -BoardEvaluator.EVAL_WHITE_WIN);

            case PieceColor.Black:
                return((b.CurrentPlayer == PieceColor.White) ? BoardEvaluator.EVAL_BLACK_WIN : -BoardEvaluator.EVAL_BLACK_WIN);

            case PieceColor.Both:
                return(BoardEvaluator.EVAL_DRAW);

            case PieceColor.Empty:
                break;
            }

            List <Board> boards = b.GenerateSubBoards();

            if (boards.Count == 0)
            {
                return(NOMOVES);
            }

            positionsEvaluated += boards.Count;

            BoardEvaluator.SortBoards(ref boards);

            int current;
            int best       = MINSCORE;
            int localAlpha = alpha;

            for (int i = 0; i < boards.Count; i++)
            {
                current = -AlphaBeta(boards[i], depth - 1, -beta, -localAlpha);
                if (current == -NOMOVES)
                {
                    current = boards[i].Evaluation;
                }

                best = Math.Max(current, best);

                if (best >= beta)
                {
                    return(beta);
                }

                if (best > localAlpha)
                {
                    localAlpha = best;
                }
            }
            return(best);
        }
Ejemplo n.º 3
0
        // Finds all unique boards possible after applying a move by the current player
        public List <Board> GenerateSubBoards()
        {
            Dictionary <Board, int> boards = new Dictionary <Board, int>(256);

            if (this.GetWinner() != PieceColor.Empty)
            {
                return(new List <Board>());
            }

            Board b = new Board(this);

            for (int i = 0; i < 6; i++)
            {
                for (int j = 0; j < 6; j++)
                {
                    if (this.GetColorAt(i, j) == PieceColor.Empty)
                    {
                        b.Copy(this);
                        b.ApplyMoveFast(i, j, this.CurrentPlayer, Rotation.LowerLeftAntiClockwise);
                        if (!boards.ContainsKey(b))
                        {
                            b.Evaluation = BoardEvaluator.Evaluate(ref b);
                            boards.Add(new Board(b), 0);
                        }
                        b.Copy(this);
                        b.ApplyMoveFast(i, j, this.CurrentPlayer, Rotation.LowerLeftClockwise);
                        if (!boards.ContainsKey(b))
                        {
                            b.Evaluation = BoardEvaluator.Evaluate(ref b);
                            boards.Add(new Board(b), 0);
                        }
                        b.Copy(this);
                        b.ApplyMoveFast(i, j, this.CurrentPlayer, Rotation.LowerRightAntiClockwise);
                        if (!boards.ContainsKey(b))
                        {
                            b.Evaluation = BoardEvaluator.Evaluate(ref b);
                            boards.Add(new Board(b), 0);
                        }
                        b.Copy(this);
                        b.ApplyMoveFast(i, j, this.CurrentPlayer, Rotation.LowerRightClockwise);
                        if (!boards.ContainsKey(b))
                        {
                            b.Evaluation = BoardEvaluator.Evaluate(ref b);
                            boards.Add(new Board(b), 0);
                        }
                        b.Copy(this);
                        b.ApplyMoveFast(i, j, this.CurrentPlayer, Rotation.UpperLeftAntiClockwise);
                        if (!boards.ContainsKey(b))
                        {
                            b.Evaluation = BoardEvaluator.Evaluate(ref b);
                            boards.Add(new Board(b), 0);
                        }
                        b.Copy(this);
                        b.ApplyMoveFast(i, j, this.CurrentPlayer, Rotation.UpperLeftClockwise);
                        if (!boards.ContainsKey(b))
                        {
                            b.Evaluation = BoardEvaluator.Evaluate(ref b);
                            boards.Add(new Board(b), 0);
                        }
                        b.Copy(this);
                        b.ApplyMoveFast(i, j, this.CurrentPlayer, Rotation.UpperRightAntiClockwise);
                        if (!boards.ContainsKey(b))
                        {
                            b.Evaluation = BoardEvaluator.Evaluate(ref b);
                            boards.Add(new Board(b), 0);
                        }
                        b.Copy(this);
                        b.ApplyMoveFast(i, j, this.CurrentPlayer, Rotation.UpperRightClockwise);
                        if (!boards.ContainsKey(b))
                        {
                            b.Evaluation = BoardEvaluator.Evaluate(ref b);
                            boards.Add(new Board(b), 0);
                        }
                    }
                }
            }

            return(new List <Board>(boards.Keys));
        }
Ejemplo n.º 4
0
        public override Board Play(Board b)
        {
            if (b.CurrentPlayer != this.Color)
            {
                throw new InvalidOperationException();
            }

            Debug.Assert(false, b.ToString());

            List <Board> boards;

            if (maxDepth == 2)
            {
                boards = b.GenerateSafeBoards(true);
            }
            else
            {
                boards = b.GenerateSafeBoards();
            }

            Debug.WriteLine("Safe moves: " + boards.Count.ToString());

            // if opponent wins on their next move no matter what
            if (boards.Count == 0)
            {
                // if we have a legal move, do it even though it's a loser
                boards = b.GenerateSubBoards();
                if (boards.Count == 0)
                {
                    return(b);
                }
                return(boards[0]);
            }

            BoardEvaluator.SortBoards(ref boards);

            int   current;
            int   localAlpha = MINSCORE;
            Board bestBoard  = boards[0];

            DateTime startTime = DateTime.Now;

            positionsEvaluated = 0;

            for (int i = 0; i < boards.Count; i++)
            {
                //  Console.Write("+");

                current = -AlphaBeta(boards[i], maxDepth, MINSCORE, -localAlpha);
                if (current == -NOMOVES)
                {
                    current = boards[i].Evaluation;
                }

                if (current > localAlpha)
                {
                    localAlpha = current;
                    bestBoard  = boards[i];
                    if (current == BoardEvaluator.EVAL_WHITE_WIN)
                    {
                        break;
                    }
                }
            }

            DateTime endTime  = DateTime.Now;
            TimeSpan moveTime = endTime - startTime;

            //Console.WriteLine(" Score: " + localAlpha.ToString());
            //Console.WriteLine("Time: {0}", moveTime.TotalSeconds);
            //Console.WriteLine("Moves evaluated: {0}", positionsEvaluated);
            //Console.WriteLine("Moves/sec: {0}", positionsEvaluated / moveTime.TotalSeconds);

            Debug.Assert(false, bestBoard.ToString());
            return(bestBoard);
        }
Ejemplo n.º 5
0
        public override Board Play(Board b)
        {
            if (b.CurrentPlayer != this.Color)
            {
                throw new InvalidOperationException();
            }

            List <Board> boards = b.GenerateSafeBoards(true);

            Debug.WriteLine("Safe moves: " + boards.Count.ToString());

            // if opponent wins on their next move no matter what
            if (boards.Count == 0)
            {
                // if we have a legal move, do it even though it's a loser
                boards = b.GenerateSubBoards();
                if (boards.Count == 0)
                {
                    return(b);
                }
                return(boards[0]);
            }

            BoardEvaluator.SortBoards(ref boards);

            int   current;
            int   localAlpha = MINSCORE;
            Board bestBoard  = boards[0];
            Board bestBoardLastCompletedDepth = boards[0];
            int   lastCompletedDepth          = 1;
            int   lastCompletedDepthScore     = 0;

            startTime = DateTime.Now;

            for (int depth = 1; depth < 36; depth++)
            {
                localAlpha = MINSCORE;
                int i;
                for (i = 0; i < boards.Count; i++)
                {
                    current = -AlphaBeta(boards[i], depth, MINSCORE, -localAlpha);
                    if (current == -TIMEUP)
                    {
                        break;
                    }
                    if (current == -NOMOVES)
                    {
                        current = boards[i].Evaluation;
                    }

                    boards[i].Evaluation = current;

                    if (current > localAlpha)
                    {
                        localAlpha = current;
                        bestBoard  = boards[i];
                        if (current == BoardEvaluator.EVAL_WHITE_WIN)
                        {
                            lastCompletedDepth          = depth;
                            lastCompletedDepthScore     = current;
                            bestBoardLastCompletedDepth = bestBoard;
                            break;
                        }
                    }
                }

                // bail from the loop if we didn't make it
                // all the way through the search at this depth
                if (i != boards.Count)
                {
                    break;
                }

                // otherwise save the best move
                lastCompletedDepthScore     = localAlpha;
                lastCompletedDepth          = depth;
                bestBoardLastCompletedDepth = bestBoard;

                // re-sort the boards after each completed depth
                //   to increase the number of cutoffs at the next depth
                BoardEvaluator.SortBoards(ref boards);
            }

            Debug.WriteLine(String.Format("Depth: {0} Score: {1}", lastCompletedDepth, lastCompletedDepthScore));
            return(bestBoardLastCompletedDepth);
        }