Exemplo n.º 1
0
        /// <summary>
        /// Selects best first move using minimax
        /// </summary>
        /// <param name="args">command-line arguments</param>
        static void Main(string[] args)
        {
            // build and mark the tree with minimax scores
            MinimaxTree <char> tree = BuildTree();

            InitializeLeafScores();
            bool maximizing = true;

            Minimax(tree.Root, maximizing);

            // find optimal minimax path
            StringBuilder optimalPath = new StringBuilder();

            optimalPath.Append("Optimal Path: ");

            MinimaxTreeNode <char> currentNode = tree.Root;

            optimalPath.Append($"[{currentNode.Value}={currentNode.MinimaxScore}]");

            MinimaxTreeNode <char> nextNode = GetBestChild(currentNode, maximizing);

            while (nextNode != null)
            {
                currentNode = nextNode;
                optimalPath.Append($"=>[{currentNode.Value}], [{currentNode.Value}={currentNode.MinimaxScore}]");
                maximizing = !maximizing;
                nextNode   = GetBestChild(currentNode, maximizing);
            }

            // print best move
            Console.WriteLine(optimalPath.ToString());

            Console.WriteLine();
        }
        /// <summary>
        /// Selects best first move using minimax
        /// </summary>
        /// <param name="args">command-line arguments</param>
        static void Main(string[] args)
        {
            // build and mark the tree with minimax scores
            MinimaxTree <char> tree = BuildTree();

            //Attach scores to each of the nodes in the tree
            Minimax(tree.Root, true);

            // find child node with maximum score
            IList <MinimaxTreeNode <char> > children     = tree.Root.Children; //Save the children of the root
            MinimaxTreeNode <char>          maxChildNode = children[0];        //Max child node is the first child (Assuming that the left choice is the best)

            //Just in case we are wrong we check here if the minimax score is right and the maxchild is the greatest, if not, then reassign it
            for (int i = 1; i < children.Count; i++)
            {
                if (children[i].MinimaxScore > maxChildNode.MinimaxScore)
                {
                    maxChildNode = children[i];
                }
            }

            // print best move
            Console.WriteLine("Best move is to char " + maxChildNode.Value);


            Console.ReadLine();
        }
Exemplo n.º 3
0
 /// <summary>
 /// Removes the given node as a child this node
 /// </summary>
 /// <param name="child">child to remove</param>
 /// <returns>true if the child was removed, false otherwise</returns>
 public bool RemoveChild(MinimaxTreeNode <T> child)
 {
     // only remove children in list
     if (children.Contains(child))
     {
         child.Parent = null;
         return(children.Remove(child));
     }
     else
     {
         return(false);
     }
 }
        /// <summary>
        /// Assigns the minimax scores to the tree nodes
        /// </summary>
        /// <param name="tree">tree to mark with scores</param>
        /// <param name="maximizing">whether or not we're maximizing</param>
        static void Minimax(MinimaxTreeNode <char> tree, bool maximizing)
        {
            //Recurse the children
            IList <MinimaxTreeNode <char> > children = tree.Children;

            if (children.Count > 0)
            {
                foreach (MinimaxTreeNode <char> child in children)
                {
                    //Toggle maximizing as we move down
                    Minimax(child, !maximizing);
                }

                //Set default node minimax score
                if (maximizing)
                {
                    tree.MinimaxScore = int.MinValue;
                }
                else
                {
                    tree.MinimaxScore = int.MaxValue;
                }

                //Find maximum or minimum value in children
                foreach (MinimaxTreeNode <char> child in children)
                {
                    if (maximizing)
                    {
                        //Check for higher minimax score
                        if (child.MinimaxScore > tree.MinimaxScore)
                        {
                            tree.MinimaxScore = child.MinimaxScore;
                        }
                    }
                    else
                    {
                        //Minimizing, check for lower minimax score
                        if (child.MinimaxScore < tree.MinimaxScore)
                        {
                            tree.MinimaxScore = child.MinimaxScore;
                        }
                    }
                }
            }
            else
            {
                //Leaf nodes are the base case
                AssignMinimaxScore(tree);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Clears all the nodes from the tree
        /// </summary>
        void Clear()
        {
            // remove all the children from each node
            // so nodes can be garbage collected
            foreach (MinimaxTreeNode <T> node in nodes)
            {
                node.Parent = null;
                node.RemoveAllChildren();
            }

            // now remove all the nodes from the tree and set root to null
            for (int i = nodes.Count - 1; i >= 0; i--)
            {
                nodes.RemoveAt(i);
            }
            root = null;
        }
Exemplo n.º 6
0
        /// <summary>
        /// Removes the given node from the tree. If the node isn't
        /// found in the tree, the method returns false.
        ///
        /// Note that the subtree with the node to remove as its
        /// root is pruned from the tree
        /// </summary>
        /// <param name="removeNode">node to remove</param>
        /// <returns>true if the node is removed, false otherwise</returns>
        public bool RemoveNode(MinimaxTreeNode <T> removeNode)
        {
            if (removeNode == null)
            {
                return(false);
            }
            else if (removeNode == root)
            {
                // removing the root clears the tree
                Clear();
                return(true);
            }
            else
            {
                // remove as child of parent
                bool success = removeNode.Parent.RemoveChild(removeNode);
                if (!success)
                {
                    return(false);
                }

                // remove node from tree
                success = nodes.Remove(removeNode);
                if (!success)
                {
                    return(false);
                }

                // check for branch node
                if (removeNode.Children.Count > 0)
                {
                    // recursively prune subtree
                    IList <MinimaxTreeNode <T> > children = removeNode.Children;
                    for (int i = children.Count - 1; i >= 0; i--)
                    {
                        RemoveNode(children[i]);
                    }
                }

                return(true);
            }
        }
Exemplo n.º 7
0
        static void Minimax(MinimaxTreeNode <char> node, bool maximizing)
        {
            IList <MinimaxTreeNode <char> > children = node.Children;

            // recurse on children
            if (children.Count > 0)
            {
                // obtain score on children while toggling minmaxing
                foreach (MinimaxTreeNode <char> child in children)
                {
                    Minimax(child, !maximizing);
                }

                // initialize default
                if (maximizing)
                {
                    node.MinimaxScore = int.MinValue;
                }
                else
                {
                    node.MinimaxScore = int.MaxValue;
                }

                // find max or min from children
                foreach (MinimaxTreeNode <char> child in children)
                {
                    if (maximizing)
                    {
                        node.MinimaxScore = Math.Max(node.MinimaxScore, child.MinimaxScore);
                    }
                    else
                    {
                        node.MinimaxScore = Math.Min(node.MinimaxScore, child.MinimaxScore);
                    }
                }
            }
            else
            {
                // leaf nodes as base case
                AssignMinimaxScore(node, maximizing);
            }
        }
Exemplo n.º 8
0
 /// <summary>
 /// Adds the given node to the tree. If the given node is
 /// null the method returns false. If the parent node is null
 /// or isn't in the tree the method returns false. If the given
 /// node is already a child of the parent node the method returns
 /// false
 /// </summary>
 /// <param name="node">node to add</param>
 /// <returns>true if the node is added, false otherwise</returns>
 public bool AddNode(MinimaxTreeNode <T> node)
 {
     if (node == null ||
         node.Parent == null ||
         !nodes.Contains(node.Parent))
     {
         return(false);
     }
     else if (node.Parent.Children.Contains(node))
     {
         // node already a child of parent
         return(false);
     }
     else
     {
         // add child as tree node and as a child to parent
         nodes.Add(node);
         return(node.Parent.AddChild(node));
     }
 }
Exemplo n.º 9
0
        static MinimaxTreeNode <char> GetBestChild(MinimaxTreeNode <char> parent, bool maximizing)
        {
            IList <MinimaxTreeNode <char> > children = parent.Children;

            if (children.Count == 0)
            {
                return(null);
            }
            MinimaxTreeNode <char> bestChild = children[0];

            for (int i = 1; i < children.Count; i++)
            {
                if ((maximizing && children[i].MinimaxScore > bestChild.MinimaxScore) ||
                    (!maximizing && children[i].MinimaxScore < bestChild.MinimaxScore))
                {
                    bestChild = children[i];
                }
            }
            return(bestChild);
        }
Exemplo n.º 10
0
 /// <summary>
 /// Adds the given node as a child this node
 /// </summary>
 /// <param name="child">child to add</param>
 /// <returns>true if the child was added, false otherwise</returns>
 public bool AddChild(MinimaxTreeNode <T> child)
 {
     // don't add duplicate children
     if (children.Contains(child))
     {
         return(false);
     }
     else if (child == this)
     {
         // don't add self as child
         return(false);
     }
     else
     {
         // add as child and add self as parent
         children.Add(child);
         child.Parent = this;
         return(true);
     }
 }
Exemplo n.º 11
0
 static bool AssignMinimaxScore(MinimaxTreeNode <char> node, bool maximizing)
 {
     if (scores.ContainsKey(node.Value))
     {
         node.MinimaxScore = scores[node.Value];
         return(true);
     }
     else
     {
         // not initialized, set worst possible as default
         if (maximizing)
         {
             node.MinimaxScore = int.MinValue;
         }
         else
         {
             node.MinimaxScore = int.MaxValue;
         }
         return(false);
     }
 }
        /// <summary>
        /// Builds the tree
        /// </summary>
        /// <returns>tree</returns>
        static MinimaxTree <char> BuildTree()
        {
            MinimaxTree <char>     tree  = new MinimaxTree <char>('A');
            MinimaxTreeNode <char> bNode = new MinimaxTreeNode <char>('B', tree.Root);

            tree.AddNode(bNode);
            MinimaxTreeNode <char> cNode = new MinimaxTreeNode <char>('C', tree.Root);

            tree.AddNode(cNode);
            MinimaxTreeNode <char> dNode = new MinimaxTreeNode <char>('D', tree.Root);

            tree.AddNode(dNode);
            MinimaxTreeNode <char> eNode = new MinimaxTreeNode <char>('E', bNode);

            tree.AddNode(eNode);
            MinimaxTreeNode <char> fNode = new MinimaxTreeNode <char>('F', bNode);

            tree.AddNode(fNode);
            MinimaxTreeNode <char> gNode = new MinimaxTreeNode <char>('G', bNode);

            tree.AddNode(gNode);
            MinimaxTreeNode <char> hNode = new MinimaxTreeNode <char>('H', cNode);

            tree.AddNode(hNode);
            MinimaxTreeNode <char> iNode = new MinimaxTreeNode <char>('I', cNode);

            tree.AddNode(iNode);
            MinimaxTreeNode <char> jNode = new MinimaxTreeNode <char>('J', dNode);

            tree.AddNode(jNode);
            MinimaxTreeNode <char> kNode = new MinimaxTreeNode <char>('K', dNode);

            tree.AddNode(kNode);
            MinimaxTreeNode <char> lNode = new MinimaxTreeNode <char>('L', eNode);

            tree.AddNode(lNode);
            MinimaxTreeNode <char> mNode = new MinimaxTreeNode <char>('M', eNode);

            tree.AddNode(mNode);
            MinimaxTreeNode <char> nNode = new MinimaxTreeNode <char>('N', fNode);

            tree.AddNode(nNode);
            MinimaxTreeNode <char> oNode = new MinimaxTreeNode <char>('O', fNode);

            tree.AddNode(oNode);
            MinimaxTreeNode <char> pNode = new MinimaxTreeNode <char>('P', gNode);

            tree.AddNode(pNode);
            MinimaxTreeNode <char> qNode = new MinimaxTreeNode <char>('Q', gNode);

            tree.AddNode(qNode);
            MinimaxTreeNode <char> rNode = new MinimaxTreeNode <char>('R', hNode);

            tree.AddNode(rNode);
            MinimaxTreeNode <char> sNode = new MinimaxTreeNode <char>('S', hNode);

            tree.AddNode(sNode);
            MinimaxTreeNode <char> tNode = new MinimaxTreeNode <char>('T', iNode);

            tree.AddNode(tNode);
            MinimaxTreeNode <char> uNode = new MinimaxTreeNode <char>('U', iNode);

            tree.AddNode(uNode);
            MinimaxTreeNode <char> vNode = new MinimaxTreeNode <char>('V', jNode);

            tree.AddNode(vNode);
            MinimaxTreeNode <char> wNode = new MinimaxTreeNode <char>('W', jNode);

            tree.AddNode(wNode);
            MinimaxTreeNode <char> xNode = new MinimaxTreeNode <char>('X', kNode);

            tree.AddNode(xNode);
            MinimaxTreeNode <char> yNode = new MinimaxTreeNode <char>('Y', kNode);

            tree.AddNode(yNode);
            return(tree);
        }
        /// <summary>
        /// Assigns a minimax score to the given node
        /// </summary>
        /// <param name="node">node to mark with score</param>
        static void AssignMinimaxScore(MinimaxTreeNode <char> node)
        {
            switch (node.Value)
            {
            case 'L':
                node.MinimaxScore = 7;
                break;

            case 'M':
                node.MinimaxScore = 6;
                break;

            case 'N':
                node.MinimaxScore = 8;
                break;

            case 'O':
                node.MinimaxScore = 5;
                break;

            case 'P':
                node.MinimaxScore = 2;
                break;

            case 'Q':
                node.MinimaxScore = 3;
                break;

            case 'R':
                node.MinimaxScore = 0;
                break;

            case 'S':
                node.MinimaxScore = -2;
                break;

            case 'T':
                node.MinimaxScore = 6;
                break;

            case 'U':
                node.MinimaxScore = 2;
                break;

            case 'V':
                node.MinimaxScore = 5;
                break;

            case 'W':
                node.MinimaxScore = 8;
                break;

            case 'X':
                node.MinimaxScore = 9;
                break;

            case 'Y':
                node.MinimaxScore = 2;
                break;
            }
        }
Exemplo n.º 14
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="value">value of the root node</param>
 public MinimaxTree(T value)
 {
     root = new MinimaxTreeNode <T>(value, null);
     nodes.Add(root);
 }
Exemplo n.º 15
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="value">value for the node</param>
 /// <param name="parent">parent for the node</param>
 public MinimaxTreeNode(T value, MinimaxTreeNode <T> parent)
 {
     this.value  = value;
     this.parent = parent;
     children    = new List <MinimaxTreeNode <T> >();
 }