/// <summary> /// Expands a selected node, if possible. /// </summary> /// <param name="id">The selected node.</param> /// <param name="tree">The game tree object.</param> /// <returns></returns> private static int Expand(int id, GameTree tree) { // Get the node object that corresponds with the input ID. GameTreeNode node = tree.GetNode(id); // If the node has at least one unplayed child, is not a dead end, and is not a goal state. if (node.Unplayed.Count > 0 && !node.DeadEnd && !node.IsGoal) { // Choose an unplayed child at random. GameTreeEdge outgoing = node.Unplayed.PickRandom <GameTreeEdge>(); // Remove the child from the list of unplayed edges. node.Unplayed.Remove(outgoing); // Create the node object and store the child's ID. int child = tree.CreateNode(node.Domain, node.Problem, outgoing).ID; // Save the parent node to disk. tree.SetNode(node); // Return the child ID. return(child); } // Return the leaf node. return(node.ID); }
//public GameTreeNode (Domain domain, Problem problem, GameTreeEdge incoming, int id) : this(domain, problem, incoming.Parent, incoming, incoming.Parent.State.NewState(incoming.Action as Operator, problem.Objects), id) { } public GameTreeNode(Domain domain, Problem problem, GameTreeEdge incoming, State state, int id, int depth) { this.domain = domain; this.problem = problem; this.incoming = incoming; this.id = id; this.state = state; this.depth = depth; outgoing = new List <GameTreeEdge>(); unplayed = new List <GameTreeEdge>(); timesPlayed = 0; wins = 0; if (state.Satisfies(problem.Goal)) { satisfiesGoal = true; } else { satisfiesGoal = false; } deadEnd = false; }
/// <summary> /// Creates a new node object. /// </summary> /// <param name="domain">The node's domain.</param> /// <param name="problem">The node's problem.</param> /// <param name="incoming">The node's incoming edge.</param> /// <returns></returns> public GameTreeNode CreateNode(Domain domain, Problem problem, GameTreeEdge incoming) { // Create a placeholder for the new node object. GameTreeNode node = null; // If the node is a root, initialize a root node. if (incoming == null) { node = new GameTreeNode(domain, problem, 0); } // Otherwise, it is a child node... else { // Store the current node's ID in the incoming edge. incoming.Child = ++nodeCounter; // Create the new node object. node = new GameTreeNode(domain, problem, incoming, GetSuccessorState(incoming), incoming.Child, GetDepth(incoming.Parent) + 1); // Add the edge to the tree hashtable. tree.Add(incoming.Child, incoming.Parent); } // If the node is a goal state, iterate the goal state counter. if (node.IsGoal) { goalStateCount++; } // If the node is at a lower depth than the previous record holder, update the depth counter. if (node.Depth > lowestDepth) { lowestDepth = node.Depth; } // Find and store the node's outgoing edges. node.Outgoing = GetOutgoingEdges(node, GetCurrentTurn(node)); // Iterate through the node's outgoing edges. foreach (GameTreeEdge edge in node.Outgoing) { // And add each of them to the unplayed collection. node.Unplayed.Add(edge); } // Save the current node to disk. SetNode(node); // Return the current node object. return(node); }
/// <summary> /// Given an edge, returns the successor state. /// </summary> /// <param name="edge">The edge object.</param> /// <returns>The new state after the action is taken.</returns> private State GetSuccessorState(GameTreeEdge edge) { // Apply the edge's action to the parent state and return the result. return(GetNode(edge.Parent).State.NewState(edge.Action as Operator, problem.Objects)); }