Esempio n. 1
0
        private static void PlayerScoreBlankBoard(IPathLengthFactory pathLengthFactory)
        {
            HexBoard       hexBoard   = new HexBoard(BoardSize);
            PathLengthBase pathLength = pathLengthFactory.CreatePathLength(hexBoard);

            // blank board
            int xScore = pathLength.PlayerScore(true);
            int yScore = pathLength.PlayerScore(false);

            Assert.AreEqual(xScore, yScore, "x and y score");

            // no advantage
            int equalMoveScore = pathLength.SituationScore();

            Assert.AreEqual(equalMoveScore, 0, "equalMoveScore");

            // all cells still on the clean path
            pathLength.PlayerScore(true);
            List <Location> cleanPathX = pathLength.GetCleanPath(true);

            pathLength.PlayerScore(false);
            List <Location> cleanPathY = pathLength.GetCleanPath(false);

            const int AllCellsCount = BoardSize * BoardSize;

            Assert.AreEqual(AllCellsCount, cleanPathX.Count, "Clean path x should have all cells");
            Assert.AreEqual(AllCellsCount, cleanPathY.Count, "Clean path y should have all cells");
        }
Esempio n. 2
0
        private static void PlayerScoreZigZag(IPathLengthFactory pathLengthFactory)
        {
            HexBoard       hexBoard   = new HexBoard(BoardSize);
            PathLengthBase pathLength = pathLengthFactory.CreatePathLength(hexBoard);

            for (int y = 0; y < hexBoard.Size - 1; y++)
            {
                hexBoard.PlayMove(2, y, true);
                hexBoard.PlayMove(5, hexBoard.Size - (1 + y), true);

                int xScore = pathLength.PlayerScore(true);
                Assert.IsTrue(xScore > 0);

                int yScore = pathLength.PlayerScore(false);
                Assert.IsTrue(yScore >= hexBoard.Size);
                if (y > (hexBoard.Size / 2))
                {
                    Assert.IsTrue(yScore > xScore);
                }

                // some advantage to player 1
                int advantageMoveScore = pathLength.SituationScore();
                Assert.IsTrue(advantageMoveScore >= y);
            }
        }
Esempio n. 3
0
        private static void PlayerScorePartBarricade(IPathLengthFactory pathLengthFactory)
        {
            HexBoard       hexBoard   = new HexBoard(BoardSize);
            PathLengthBase pathLength = pathLengthFactory.CreatePathLength(hexBoard);

            // partly baricaded board
            for (int y = 0; y < hexBoard.Size; y++)
            {
                if ((y % 2) == 0)
                {
                    hexBoard.PlayMove(2, y, true);
                }
            }

            int xScore = pathLength.PlayerScore(true);

            Assert.IsTrue(xScore > 0);

            int yScore = pathLength.PlayerScore(false);

            Assert.IsTrue(yScore > xScore);

            // some advantage to player 1
            int advantageMoveScore = pathLength.SituationScore();

            Assert.IsTrue(advantageMoveScore > 0);
        }
Esempio n. 4
0
        /// <summary>
        /// Initializes a new instance of the HexGame class, with a board size
        /// </summary>
        /// <param name="boardSize">size of the board</param>
        /// ********
        public HexGame(int boardSize)
        {
            this.board = new HexBoard(boardSize);
            IPathLengthFactory pathLengthFactory = new PathLengthAStarFactory();

            this.xPathLength = pathLengthFactory.CreatePathLength(this.board);
            this.yPathLength = pathLengthFactory.CreatePathLength(this.board);
            this.goodMoves   = new GoodMoves();
            this.goodMoves.DefaultGoodMoves(boardSize, 5);
        }
Esempio n. 5
0
        private static void PlayerScoreBaricaded(IPathLengthFactory pathLengthFactory)
        {
            HexBoard       hexBoard   = new HexBoard(BoardSize);
            PathLengthBase pathLength = pathLengthFactory.CreatePathLength(hexBoard);

            // baricaded board
            for (int y = 0; y < hexBoard.Size; y++)
            {
                hexBoard.PlayMove(2, y, true);
            }

            int xScore = pathLength.PlayerScore(true);

            Assert.AreEqual(xScore, 0);

            int yScore = pathLength.PlayerScore(false);

            Assert.IsTrue(yScore > hexBoard.Size);

            // winning advantage to player 1
            int winMoveScore = pathLength.SituationScore();

            AssertWinner(winMoveScore, Occupied.PlayerX);
        }
Esempio n. 6
0
        private MinimaxResult MiniMaxAlg(int depth, bool isComputer, HexBoard board)
        {
            BoardCache    boardCache = new BoardCache(board.Size);
            MinimaxResult bestResult = null;
            Location      cutOffMove = Location.Null;
            // az ures cellakat tartalmazza
            var possibleMoves = candidateMovesFinder.CandidateMoves(board, depth);

            foreach (Location move in possibleMoves)
            {
                if (!move.IsNull())
                {
                    // nem az eredetit modositom meg, hanem letrehozok egyet a peldajara
                    HexBoard board1 = new HexBoard(board.Size);
                    board1.CopyStateFrom(board);
                    board1.PlayMove(move, isComputer);


                    // itt szamolja ki az allast
                    PathLengthBase staticAnalysis = this.pathLengthFactory.CreatePathLength(board1);
                    int            situationScore = staticAnalysis.SituationScore();
                    MinimaxResult  moveScore      = new MinimaxResult(situationScore);

                    if (depth <= 1 || MoveScoreConverter.IsWin(situationScore))
                    {
                        moveScore = new MinimaxResult(situationScore);
                    }
                    else
                    {
                        if (depth > 1)
                        {
                            // rekurzio
                            moveScore = MiniMaxAlg(depth--, !isComputer, board1);
                            moveScore.MoveWins();
                        }
                    }

                    moveScore.Move = move;
                    // Itt nezem meg, hogy a minimum kell nekunk, vagy a maximum
                    if (bestResult == null || MoveScoreConverter.MinOrMax(moveScore.Score, bestResult.Score, isComputer))
                    {
                        bestResult = new MinimaxResult(move, moveScore);
                    }

                    alpha = CheckAlpha(moveScore.Score, isComputer);
                    if (IsAlphaBetaCutoff(isComputer))
                    {
                        cutOffMove       = move;
                        bestResult.Score = alpha;
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
            if (bestResult != null)
            {
                GoodMoves.AddGoodMove(depth, bestResult.Move);
            }

            if (cutOffMove != Location.Null)
            {
                GoodMoves.AddGoodMove(depth, cutOffMove);
            }

            return(bestResult);
        }
Esempio n. 7
0
        /// <summary>
        /// private recursive worker - does the minimax algorithm
        /// </summary>
        /// <param name="lookahead">the current ply, counts down to zero</param>
        /// <param name="stateBoard">the current board</param>
        /// <param name="isPlayerX">player X or player Y</param>
        /// <param name="alpha">alpha value used in alpha-beta pruning</param>
        /// <param name="beta">beta value used in alpha-beta pruning</param>
        /// <returns>the score of the board and best move location</returns>
        private MinimaxResult ScoreBoard(
            int lookahead,
            HexBoard stateBoard,
            bool isPlayerX,
            int alpha,
            int beta)
        {
            this.CountBoards++;

            MinimaxResult bestResult = null;
            Location      cutoffMove = Location.Null;

            var possibleMoves = this.candidateMovesFinder.CandidateMoves(stateBoard, lookahead);

            foreach (Location move in possibleMoves)
            {
                // end on null loc
                if (move.IsNull())
                {
                    break;
                }

                if (this.GenerateDebugData)
                {
                    this.AddDebugDataItem(lookahead, move, isPlayerX, alpha, beta);
                }

                // make a speculative board, like the current, but with this cell played
                HexBoard testBoard = this.boardCache.GetBoard();
                testBoard.CopyStateFrom(stateBoard);

                testBoard.PlayMove(move, isPlayerX);
                MinimaxResult moveScore;

                PathLengthBase staticAnalysis = this.pathLengthFactory.CreatePathLength(testBoard);
                int            situationScore = staticAnalysis.SituationScore();

                if (lookahead <= 1)
                {
                    // we have reached the limits of lookahead - return the situation score
                    moveScore = new MinimaxResult(situationScore);
                }
                else if (MoveScoreConverter.IsWin(situationScore))
                {
                    // stop - someone has won
                    moveScore = new MinimaxResult(situationScore);
                }
                else
                {
                    // recurse
                    moveScore = this.ScoreBoard(lookahead - 1, testBoard, !isPlayerX, beta, alpha);
                    moveScore.MoveWins();
                }

                moveScore.Move = move;

                this.boardCache.Release(testBoard);

                // higher scores are good for player x, lower scores for player y
                if (bestResult == null || MoveScoreConverter.IsBetterFor(moveScore.Score, bestResult.Score, isPlayerX))
                {
                    bestResult = new MinimaxResult(move, moveScore);
                }

                // do the alpha-beta pruning
                alpha = CheckAlpha(alpha, moveScore.Score, isPlayerX);

                if (IsAlphaBetaCutoff(isPlayerX, alpha, beta))
                {
                    cutoffMove       = move;
                    bestResult.Score = alpha;
                    break;
                }

                // end a-b pruning
            }

            if (bestResult != null)
            {
                GoodMoves.AddGoodMove(lookahead, bestResult.Move);
            }

            if (cutoffMove != Location.Null)
            {
                GoodMoves.AddGoodMove(lookahead, cutoffMove);
            }

            return(bestResult);
        }