示例#1
0
        /// <summary>
        /// Calculate the node
        /// </summary>
        /// <param name="board">Current board state</param>
        /// <param name="currentPosition">Position in board to set</param>
        /// <param name="currentMove">Current move (either Computer or Human)</param>
        /// <param name="depth">Current depth. Used for choosing earliest winning/losing move</param>
        public MiniMaxNode(Board board, int currentPosition, Board.Cell currentMove, int depth)
        {
            // Create the child nodes list
            this.ChildNodes = new List <MiniMaxNode>();

            // Save the index to the cell we are updating. This way we always know what move
            // this node corresponds to
            this.UpdatedCellIndex = currentPosition;
            // Set the cell to Computer/Human
            board.Cells[this.UpdatedCellIndex] = currentMove;

            if (board.GetState() == Board.State.ComputerWins)
            {
                // If Computer wins, give it a high score, but deduct the current depth
                // (So that quick wins have higher scores than lengthy wins)
                this.Score = 10 - depth;
            }
            else if (board.GetState() == Board.State.HumanWins)
            {
                // If Human wins, give it a low score, but add the current depth
                // (So that quick loses have lower scores than lengthy loses)
                this.Score = -10 + depth;
            }
            else if (board.GetState() == Board.State.Draw)
            {
                // If it's a draw, just set to neutral
                this.Score = 0;
            }
            else
            {
                // Invert the player
                var nextMove = currentMove == Board.Cell.Computer ? Board.Cell.Human : Board.Cell.Computer;

                for (var i = 0; i < Board.BoardSize; i++)
                {
                    // For each empty cell
                    if (board.Cells[i] == Board.Cell.Empty)
                    {
                        // Clone the board
                        var childBoard = board.Clone();
                        // Calculate child moves
                        var miniMaxNode = new MiniMaxNode(childBoard, i, nextMove, depth + 1);
                        ChildNodes.Add(miniMaxNode);
                    }
                }

                if (currentMove == Board.Cell.Computer)
                {
                    // Since this isn't a terminal node, give the current node the best score
                    // amongst the child nodes..
                    this.Score = this.ChildNodes.OrderBy(n => n.Score).First().Score;
                }
                else
                {
                    // ..or for Human moves, give it the worst score amongst the children
                    this.Score = this.ChildNodes.OrderBy(n => n.Score).Last().Score;
                }
            }
        }
示例#2
0
        /// <summary>
        /// Calculates the MiniMax tree for a particular board
        /// </summary>
        /// <param name="board">Current state of board</param>
        public MiniMaxTree(Board board)
        {
            // MiniMaxTree is only ever called for the Computer player, so presume next move
            // will always be computer.

            // Create the list of child nodes
            this.ChildNodes = new List <MiniMaxNode>();
            for (var i = 0; i < Board.BoardSize; i++)
            {
                // For each empty cell in the current board
                if (board.Cells[i] == Board.Cell.Empty)
                {
                    // Make a copy of the current board..
                    var childBoard = board.Clone();
                    // ..fill in the cell with Computers move and calculate score recursively
                    var miniMaxNode = new MiniMaxNode(childBoard, i, Board.Cell.Computer, 0);
                    // Finally, add the node to the children
                    ChildNodes.Add(miniMaxNode);
                }
            }
        }