Class GameTreeNode<N extends GameTreeNode<N,P>, P extends IGamePosition<P>>
- Type Parameters:
N- The implementing type ofGameTreeNodethat extends this class.P- The type ofIGamePositionobjects stored in this GameTreeNode, represents the game which is being represented by this game tree.
- All Implemented Interfaces:
Serializable
- Direct Known Subclasses:
DepthFirstNode,ResultTreeNode,SearchTreeNode,SimpleNode
children(MetricKeeper...) and parent() relations.
The GameTree logic is kept separate from the IGamePosition logic
to allow any kind of architecture to be more easily applied to any kind
of game without having the two sides of code interact directly.
A GameTreeNode implementation thus provides exact implementations for
data storage, retrieval, and management. Implementation details may
affect the efficiency and memory usage of algorithms using them. In
principle, any algorithm could work on any implementation of GameTreeNode,
but some algorithms may be specifically designed with a particular implementation
in mind.
- Version:
- 1.0
- Author:
- Pascal Rodrigo Anema
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordGameTreeNode.Result<N extends GameTreeNode<N,P>, P extends IGamePosition<P>> A record to hold the two best nodes (and their indices in the original collection). -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedGameTreeNode(N parent, P position, MetricKeeper... metrics) Creates a GameTreeNode in the same game tree as the given parent node, as its child node, where the given position is the current game state. -
Method Summary
Modifier and TypeMethodDescriptionprotected abstract boolean_adjustBounds(List<N> children, MetricKeeper... metrics) Method to implement functionality ofadjustBounds(List<N>, MetricKeeper...)._children(MetricKeeper... metrics) Method to implement functionality ofchildren(MetricKeeper...).protected abstract long_depthOfLower(MetricKeeper... metrics) Method to implement functionality ofdepthOfLower(MetricKeeper...).protected abstract long_depthOfUpper(MetricKeeper... metrics) Method to implement functionality ofdepthOfUpper(MetricKeeper...).protected abstract double_lowerbound(MetricKeeper... metrics) Method to implement functionality oflowerbound(MetricKeeper...).protected abstract double_upperbound(MetricKeeper... metrics) Method to implement functionality ofupperbound(MetricKeeper...).static <N extends GameTreeNode<N,P>, P extends IGamePosition<P>>
booleanadjustBounds(boolean maximising, double[] lowerUpper, long[] depthLowerUpper, List<N> children, MetricKeeper... metrics) Adjust the bounds of a node.booleanadjustBounds(boolean useExpansions, MetricKeeper... metrics) booleanadjustBounds(MetricKeeper... metrics) Adjusts the bounds of this node according to the values of thechildrennodes as given bychildren(MetricKeeper...).booleanadjustBounds(List<N> children, MetricKeeper... metrics) voidattachMetrics(MetricKeeper... m) double[]CDF(int maxDepth, MetricKeeper... metrics) Computes the Cumulative Distribution Function (CDF)P(X ≤ t)of this node, assuming that the distribution is a discrete one.children(MetricKeeper... metrics) The children of this node are its direct descendants.protected voidSetsposition()tonullprotected MetricKeeper[]combineMetricList(MetricKeeper... metrics) longlongdepth()longdepthOfLower(MetricKeeper... metrics) Depth-of-lowerbound is the depth from which the lower bound of this node has been backed up.longdepthOfUpper(MetricKeeper... metrics) Depth-of-upperbound is the depth from which the upper bound of this node has been backed up.static <N extends GameTreeNode<N,P>, P extends IGamePosition<P>>
GameTreeNode.Result<N, P> findBest2(Collection<N> children, boolean maximising, boolean by_optimistic, MetricKeeper... metrics) Calculate the best 2 nodes from the perspective specified by themaximizingandby_optimisticflags.static GameTreeNode<?, ?> getAllLeafnodes(int maxDepth, Predicate<N> include, MetricKeeper... metrics) static Comparator<GameTreeNode<?, ?>> getComparator(boolean maximising, boolean by_optimistic, MetricKeeper... metrics) This method gives a comparator forGameTreeNodeobjects from the perspective of a parent node.getSavedLeafnodes(int maxDepth, Predicate<N> include) booleanabstract booleanbooleanisRelevant(MetricKeeper... metrics) booleanisRoot()static <N extends GameTreeNode<N,P>, P extends IGamePosition<P>>
GameTreeNode.Result<N, P> leastPessimistic2(Collection<N> children, boolean maximising, MetricKeeper... metrics) Same asfindBest2(Collection, boolean, boolean, MetricKeeper...)whereby_optimisticis assumedfalse.doublelowerbound(MetricKeeper... metrics) The lower-bound value is the lower bound on the game-theoretical mini-max value of this game position.abstract booleanThis isIGamePosition.maximising()from theposition()of this node.static <N extends GameTreeNode<N,P>, P extends IGamePosition<P>>
GameTreeNode.Result<N, P> mostOptimistic2(Collection<N> children, boolean maximising, MetricKeeper... metrics) Same asfindBest2(Collection, boolean, boolean, MetricKeeper...)whereby_optimisticis assumedtrue.parent()TheGameTreeNodeobject of theparent()of this node.double[]PMF(int maxDepth, MetricKeeper... metrics) Computes the Probability Mass Function (PMF)P(X = x)of this node, assuming that the distribution is a discrete one.position()The game positionIGamePositionthis node represents.printTree(int depth, boolean toString, boolean printDist, MetricKeeper... metrics) Visually represents the structure of the sub-tree starting from this node as aString.printTree(int depth, boolean toString, MetricKeeper... metrics) Visually represents the structure of the sub-tree starting from this node as aString.printTree(int depth, MetricKeeper... metrics) doubleremainingSolveEffort(MetricKeeper... metrics) static <N extends GameTreeNode<N,P>, P extends IGamePosition<P>>
booleanseparation(GameTreeNode<?, ?> n, MetricKeeper... metrics) static <N extends GameTreeNode<N,P>, P extends IGamePosition<P>>
booleanseparation(Collection<N> children, boolean maximising, MetricKeeper... metrics) protected voiddouble[]survivalFunction(int maxDepth, MetricKeeper... metrics) Computes the Survival FunctionP(X ≥ x)of this node, assuming that the distribution is a discrete one.voidvoidbooleanUses the parental line of succession of this node to retroactively addMetricKeeperobjects from this node's ancestors to this node's personal list ofMetricKeeperobjects.voidupdateTree(MetricKeeper... metrics) doubleupperbound(MetricKeeper... metrics) The upper-bound value is the upper bound on the game-theoretical mini-max value of this gameposition().
-
Constructor Details
-
GameTreeNode
Creates a GameTreeNode in the same game tree as the given parent node, as its child node, where the given position is the current game state. Or creates a new root node for the game tree of the given position ifparentisnull.- Parameters:
parent- the parent node of this node ornullif this is a root nodeposition- the current game state at this node
-
-
Method Details
-
position
The game positionIGamePositionthis node represents. This is the current game position as reached by moves after the position represented by the root node of this tree through all ancestor nodes to this one.If this node is the root node,
position()represents the current state of the game.However, it is possible that the
GameTreeNodeimplementation determines to prune this object for memory conservation purposes after all necessary information has been obtained from this game position. In which case,position()will returnnull.- Returns:
- The
IGamePositionobject representing the game position at this node, ornullif this node has been pruned for memory conservation.
-
clearPosition
protected void clearPosition()Setsposition()tonull -
parent
TheGameTreeNodeobject of theparent()of this node. the node representing the game state previous toposition.If this node is the root node of the tree, the
parentwill benull.- Returns:
- The parent
GameTreeNodeof this node.
-
depth
public long depth()- Returns:
0if this is the root, otherwise the number of ancestors until reaching the root.
-
isRoot
public boolean isRoot()- Returns:
trueif this node is a root (its parent isnull) orfalseotherwise
-
setParent
-
maximising
public abstract boolean maximising()This isIGamePosition.maximising()from theposition()of this node.- Returns:
trueif the current player-to-move is maximising the score, orfalseif it is minimising the score.
-
children
The children of this node are its direct descendants. During the search, these nodes' values may be updated with information gathered during the search. At first, the children of a node are exactly the same nodes as those returned fromIGamePosition.next(), but may be modified later to aid the search. The returnedchildrencollection may be empty, but should never benull.- Parameters:
metrics- One or moreMetricKeeperobjects to keep track of node evaluations and expansions made by thisGameTreeNodethrough this method. Or zero if there is no need to keep track of these metrics.- Returns:
- The collection of game tree nodes directly reachable by moves from the current player to move in the game position this game tree node represents.
-
_children
Method to implement functionality ofchildren(MetricKeeper...). -
savedChildren
- Returns:
- An Optional containing all children nodes saved in the memory of this
GameTreeNodeor an empty Optional if none are saved in memory. An Optional containing an empty List signifies a terminal node with no children.
-
upperbound
The upper-bound value is the upper bound on the game-theoretical mini-max value of this gameposition().For the maximising player this is the best value achievable under perfect play.
For the minimising player this is the worst-case value achievable under perfect play.
This value is initially set as the value returned by
IGamePosition.upperbound()and later updated to reflect a tighter upper-bound for the game-theoretical value of this node.- Parameters:
metrics- One or moreMetricKeeperobjects to keep track of node evaluations and expansions made by thisGameTreeNodethrough this method. Or zero if there is no need to keep track of these metrics.- Returns:
- The upper-bound value for this game position
-
_upperbound
Method to implement functionality ofupperbound(MetricKeeper...). -
lowerbound
The lower-bound value is the lower bound on the game-theoretical mini-max value of this game position.For the maximising player this is the minimum value that can be guaranteed under perfect play.
For the minimising player this is the best value achievable under perfect play.
This value is initially set as the value returned by
IGamePosition.lowerbound()and later updated to reflect a tighter lower-bound for the game-theoretical value of this node.- Parameters:
metrics- One or moreMetricKeeperobjects to keep track of node evaluations and expansions made by thisGameTreeNodethrough this method. Or zero if there is no need to keep track of these metrics.- Returns:
- The lower-bound value for this game position
-
_lowerbound
Method to implement functionality oflowerbound(MetricKeeper...). -
hasSavedBounds
public abstract boolean hasSavedBounds() -
adjustBounds
Adjusts the bounds of this node according to the values of thechildrennodes as given bychildren(MetricKeeper...). Maximising nodes will adjust their bounds to be the maximum of the lower- and upper-bound values of their children, whereas minimising nodes will instead use the minimum of the lower- and upper-bound values of their children.- Parameters:
metrics- One or moreMetricKeeperobjects to keep track of node evaluations and expansions made by thisGameTreeNodethrough this method. Or zero if there is no need to keep track of these metrics.- Returns:
trueif the bounds of this node have been altered,falseotherwise
-
adjustBounds
-
adjustBounds
-
_adjustBounds
Method to implement functionality ofadjustBounds(List<N>, MetricKeeper...). -
depthOfUpper
Depth-of-upperbound is the depth from which the upper bound of this node has been backed up. This denotes the depth of search from which the bounds of a node have been obtained. It can act as a metric to determine the effort expended at a certain node, but is not entirely reliable for this purpose.- Parameters:
metrics- One or moreMetricKeeperobjects to keep track of node evaluations and expansions made by thisGameTreeNodethrough this method. Or zero if there is no need to keep track of these metrics.- Returns:
- The depth from which the
upperbound(MetricKeeper...)has been backed-up. Or0if it has not yet been updated from the initialIGamePosition.upperbound()value.
-
_depthOfUpper
Method to implement functionality ofdepthOfUpper(MetricKeeper...). -
depthOfLower
Depth-of-lowerbound is the depth from which the lower bound of this node has been backed up.This denotes the depth of search from which the bounds of a node have been obtained.
It can act as a metric to determine the effort expended at a certain node, but is not entirely reliable for this purpose.- Parameters:
metrics- One or moreMetricKeeperobjects to keep track of node evaluations and expansions made by thisGameTreeNodethrough this method. Or zero if there is no need to keep track of these metrics.- Returns:
- The depth from which the
lowerbound(MetricKeeper...)has been backed-up. Or0if it has not yet been updated from the initialIGamePosition.lowerbound()value.
-
_depthOfLower
Method to implement functionality ofdepthOfLower(MetricKeeper...). -
countSavedSubTree
public long countSavedSubTree()- Returns:
- The size, in number of nodes, of the sub-tree of saved nodes starting at this node, including this one (minimum of
1)
-
attachMetrics
-
getAttachedMetrics
-
hasAttachedMetrics
public boolean hasAttachedMetrics() -
combineMetricList
-
updateMetricsParental
public boolean updateMetricsParental()Uses the parental line of succession of this node to retroactively addMetricKeeperobjects from this node's ancestors to this node's personal list ofMetricKeeperobjects.- Returns:
trueif the metrics of this node have been altered, andfalseotherwise.
-
updateMetrics
public void updateMetrics() -
CDF
Computes the Cumulative Distribution Function (CDF)P(X ≤ t)of this node, assuming that the distribution is a discrete one. The underlying sub-tree will not be further expanded, rather only evaluated based on its current state, and at most up to the given maximum depth.- Parameters:
maxDepth- the maximum depth to which evaluations will be performed to compute this. NO EXPANSIONS WILL BE MADE.metrics-MetricKeeperobjects to keep track of node evaluations made by this method.- Returns:
- The CDF of this node's distribution, given this distribution is assumed to be discrete.
-
survivalFunction
Computes the Survival FunctionP(X ≥ x)of this node, assuming that the distribution is a discrete one. The underlying sub-tree will not be further expanded, rather only evaluated based on its current state, and at most up to the given maximum depth.- Parameters:
maxDepth- the maximum depth to which evaluations will be performed to compute this. NO EXPANSIONS WILL BE MADE.metrics-MetricKeeperobjects to keep track of node evaluations made by this method.- Returns:
- The Survival Function of this node's distribution, given this distribution is assumed to be discrete.
-
PMF
Computes the Probability Mass Function (PMF)P(X = x)of this node, assuming that the distribution is a discrete one. The underlying sub-tree will not be further expanded, rather only evaluated based on its current state, and at most up to the given maximum depth.- Parameters:
maxDepth- the maximum depth to which evaluations will be performed to compute this. NO EXPANSIONS WILL BE MADE.metrics-MetricKeeperobjects to keep track of node evaluations made by this method.- Returns:
- The PMF of this node's distribution, given this distribution is assumed to be discrete.
-
adjustBounds
public static <N extends GameTreeNode<N,P>, P extends IGamePosition<P>> boolean adjustBounds(boolean maximising, double[] lowerUpper, long[] depthLowerUpper, List<N> children, MetricKeeper... metrics) Adjust the bounds of a node.- Type Parameters:
N- Type of the GameTreeNodeP- Type of the IGamePosition- Parameters:
maximising- whether the parent node is maximising or notlowerUpper- an array of size 2 containing the lower- and upper-bound of the parent (unchecked)depthLowerUpper- an array of size 2 containing the depth of the lower- and upper-bound of the parent (unchecked)children- the children of the parent nodemetrics-- Returns:
trueif the bounds were changed,falseotherwise.
-
findBest2
public static <N extends GameTreeNode<N,P>, P extends IGamePosition<P>> GameTreeNode.Result<N,P> findBest2(Collection<N> children, boolean maximising, boolean by_optimistic, MetricKeeper... metrics) Calculate the best 2 nodes from the perspective specified by themaximizingandby_optimisticflags.If
maximizingistrueandby_optimisticistrue, nodes with maximumupperbound()value are selected. Ties are broken with the highestlowerbound()value.If
maximizingistrueandby_optimisticisfalse, nodes with maximumlowerbound()value are selected. Ties are broken with the highestupperbound()value.If
maximizingisfalseandby_optimisticistrue, nodes with minimumlowerbound()value are selected. Ties are broken with the lowestupperbound()value.If
maximizingisfalseandby_optimisticisfalse, nodes with minimumupperbound()value are selected. Ties are broken with the lowestlowerbound()value.- Type Parameters:
N- the node type extendingGameTreeNodeP- the game-position type extendingIGamePosition- Parameters:
children- the collection of nodes to evaluatemaximising- a flag indicating whether to select from a maximising (true) or minimising (false) perspectiveby_optimistic- a flag indicating whether to select the most optimistic (true) or least pessimistic (false) nodesmetrics- an array ofMetricKeeperobjects to keep track of evaluations and expansions made through this method, can be empty- Returns:
- a record containing the best and second-best nodes and their corresponding indices.
-
mostOptimistic2
public static <N extends GameTreeNode<N,P>, P extends IGamePosition<P>> GameTreeNode.Result<N,P> mostOptimistic2(Collection<N> children, boolean maximising, MetricKeeper... metrics) Same asfindBest2(Collection, boolean, boolean, MetricKeeper...)whereby_optimisticis assumedtrue. -
leastPessimistic2
public static <N extends GameTreeNode<N,P>, P extends IGamePosition<P>> GameTreeNode.Result<N,P> leastPessimistic2(Collection<N> children, boolean maximising, MetricKeeper... metrics) Same asfindBest2(Collection, boolean, boolean, MetricKeeper...)whereby_optimisticis assumedfalse. -
separation
public static <N extends GameTreeNode<N,P>, P extends IGamePosition<P>> boolean separation(Collection<N> children, boolean maximising, MetricKeeper... metrics) - Type Parameters:
N- the node type extendingGameTreeNodeP- the game-position type extendingIGamePosition- Parameters:
children- the collection of nodes to evaluatemaximising- a flag indicating whether we are observing from a maximising (true) or minimising (false) perspectivemetrics- an array ofMetricKeeperobjects to keep track of evaluations and expansions made through this method, can be empty- Returns:
trueif the sub-tree from the parent of the givenchildrencould be terminated according to the separation rule;falseotherwise.
-
separation
public static <N extends GameTreeNode<N,P>, P extends IGamePosition<P>> boolean separation(GameTreeNode<?, ?> n, MetricKeeper... metrics) - Type Parameters:
N- TheGameTreeNodetype of the givennodeP- TheIGamePositiontype of the givennode- Parameters:
n- The node at which the sub-tree originates (usually the root node)metrics- an array ofMetricKeeperobjects to keep track of evaluations and expansions made through this method, can be empty- Returns:
trueif the sub-tree from the givennodecould be terminated according to the separation rule;falseotherwise.
-
getComparator
public static Comparator<GameTreeNode<?,?>> getComparator(boolean maximising, boolean by_optimistic, MetricKeeper... metrics) This method gives a comparator forGameTreeNodeobjects from the perspective of a parent node. Differently from natural ordering, this comparator will sort best values first. For example, for anoptimistic && maximisingperspective this means sorting by highestupperboundvalue first.- Parameters:
maximising- whether to select from a maximising perspective (true) or from a minimising perspective (false)by_optimistic- whether to select based on the optimistic value (true) or the pessimistic value (false). From amaximisingperspective, theupperboundof a node is the optimistic perspective, whereas thelowerboundis the pessimistic perspective. From aminimisingperspective, thelowerboundof a node is the optimistic perspective, whereas theupperboundis the pessimistic perspective.metrics- an array ofMetricKeeperobjects to keep track of evaluations and expansions made through this comparator, can be empty- Returns:
- A comparator which sorts a list of nodes by the best nodes first, from the specified perspective.
-
isRelevant
-
remainingSolveEffort
-
updateTree
-
getSavedLeafnodes
-
getAllLeafnodes
-
printTree
-
printTree
Visually represents the structure of the sub-tree starting from this node as aString.- Parameters:
depth- The maximum depth to which the tree should be displaced (starting from the current node)toString- Whether to print the identity of each node (rather than just its bounds)- Returns:
- A
Stringrepresentation of the sub-tree of this node, up to the specified depth
-
printTree
Visually represents the structure of the sub-tree starting from this node as aString.- Parameters:
depth- The maximum depth to which the tree should be displaced (starting from the current node)toString- Whether to print the identity of each node (rather than just its bounds)printDist- Whether to show the distribution function of each node (computed up to the maximum depth specified)- Returns:
- A
Stringrepresentation of the sub-tree of this node, up to the specified depth
-
toFile
- Throws:
IOException
-
fromFile
public static GameTreeNode<?,?> fromFile(String fileName) throws IOException, ClassNotFoundException - Throws:
IOExceptionClassNotFoundException
-