예제 #1
0
 private Player DeterminePlayerColour(MinimaxPlayerType minimaxPlayerType)
 {
     if (whoAmI == Player.BLUE)
     {
         if (minimaxPlayerType == MinimaxPlayerType.MAX)
         {
             return(Player.BLUE);
         }
         else
         {
             return(Player.RED);
         }
     }
     else
     {
         if (minimaxPlayerType == MinimaxPlayerType.MAX)
         {
             return(Player.RED);
         }
         else
         {
             return(Player.BLUE);
         }
     }
 }
예제 #2
0
        private int ConstructTree(MinimaxTreeNode parentNode, int depth, MinimaxPlayerType minimaxPlayer, int alpha, int beta)
        {
            // return estimation function if max tree depth reached or game is in finished state
            if (depth == maxTreeDepth || parentNode.NonExistingLines.Count == 0)
            {
                return(EstimationFunction(parentNode));
            }

            if (minimaxPlayer == MinimaxPlayerType.MAX)
            {
                int bestValue = int.MinValue;

                for (int i = 0; i < parentNode.NonExistingLines.Count; i++)
                {
                    #region New Node Creation
                    MinimaxTreeNode node = new MinimaxTreeNode();

                    // calculate estimation function only for leaf nodes
                    node.Player = (parentNode.Player == MinimaxPlayerType.MAX ? MinimaxPlayerType.MIN : MinimaxPlayerType.MAX);

                    node.ExistingLines.AddRange(parentNode.ExistingLines);
                    node.ExistingLines.Add(parentNode.NonExistingLines[i]);

                    node.NonExistingLines.AddRange(parentNode.NonExistingLines);
                    node.NonExistingLines.Remove(parentNode.NonExistingLines[i]);

                    node.Boxes.AddRange(parentNode.Boxes);
                    List <Box> newBoxes = AICommon.TryClosingBoxes(parentNode.ExistingLines, DeterminePlayerColour(node.Player), parentNode.NonExistingLines[i], out int[] notUsed);
                    node.Boxes.AddRange(newBoxes);

                    node.DeltaMove = parentNode.NonExistingLines[i];
                    #endregion

                    /* don't go through this subtree if the delta move is drawing third edge
                     * unless it the only move
                     */
                    AICommon.TryClosingBoxes(node.ExistingLines,
                                             DeterminePlayerColour(node.Player),
                                             node.DeltaMove,
                                             out int[] surroundingEdges);

                    if ((surroundingEdges[0] == 2 || surroundingEdges[1] == 2))
                    {
                        if (!(i == parentNode.NonExistingLines.Count - 1 && parentNode.Children.Count == 0))
                        {
                            Debug.WriteLine(node.DeltaMove.ToString() + " was thrown.");
                            continue;
                        }
                    }

                    node.EstimationScore = ConstructTree(node, depth + 1, MinimaxPlayerType.MIN, alpha, beta);

                    bestValue = (bestValue > node.EstimationScore ? bestValue : node.EstimationScore);
                    alpha     = (alpha > bestValue ? alpha : bestValue);

                    parentNode.Children.Add(node);

                    if (beta <= alpha)
                    {
                        break;
                    }
                }

                parentNode.EstimationScore = bestValue;
                return(bestValue);
            }
            else
            {
                int bestValue = int.MaxValue;

                for (int i = 0; i < parentNode.NonExistingLines.Count; i++)
                {
                    #region New Node Creation
                    MinimaxTreeNode node = new MinimaxTreeNode();

                    // calculate estimation function only for leaf nodes
                    node.Player = (parentNode.Player == MinimaxPlayerType.MAX ? MinimaxPlayerType.MIN : MinimaxPlayerType.MAX);

                    node.ExistingLines.AddRange(parentNode.ExistingLines);
                    node.ExistingLines.Add(parentNode.NonExistingLines[i]);

                    node.NonExistingLines.AddRange(parentNode.NonExistingLines);
                    node.NonExistingLines.Remove(parentNode.NonExistingLines[i]);

                    node.Boxes.AddRange(parentNode.Boxes);
                    List <Box> newBoxes = AICommon.TryClosingBoxes(parentNode.ExistingLines, DeterminePlayerColour(node.Player), parentNode.NonExistingLines[i], out int[] notUsed);
                    node.Boxes.AddRange(newBoxes);

                    node.DeltaMove = parentNode.NonExistingLines[i];
                    #endregion

                    /* don't go through this subtree if the delta move is drawing third edge
                     * unless it the only move
                     */

                    AICommon.TryClosingBoxes(node.ExistingLines,
                                             DeterminePlayerColour(node.Player),
                                             node.DeltaMove,
                                             out int[] surroundingEdges);

                    if ((surroundingEdges[0] == 2 || surroundingEdges[1] == 2))
                    {
                        if (!(i == parentNode.NonExistingLines.Count - 1 && parentNode.Children.Count == 0))
                        {
                            Debug.WriteLine(node.DeltaMove.ToString() + " was thrown.");
                            continue;
                        }
                    }

                    node.EstimationScore = ConstructTree(node, depth + 1, MinimaxPlayerType.MAX, alpha, beta);

                    bestValue = (bestValue < node.EstimationScore ? bestValue : node.EstimationScore);
                    beta      = (beta < bestValue ? beta : bestValue);

                    parentNode.Children.Add(node);

                    if (beta <= alpha)
                    {
                        break;
                    }
                }

                parentNode.EstimationScore = bestValue;
                return(bestValue);
            }

            throw new Exception("Something wrong in minimax happened");
        }