CubeTwister 2.0alpha142 2012-02-11

ch.randelshofer.rubik.parser
Class PermutationNode

java.lang.Object
  extended by javax.swing.tree.DefaultMutableTreeNode
      extended by ch.randelshofer.rubik.parser.Node
          extended by ch.randelshofer.rubik.parser.PermutationNode
All Implemented Interfaces:
java.io.Serializable, java.lang.Cloneable, javax.swing.tree.MutableTreeNode, javax.swing.tree.TreeNode

public class PermutationNode
extends Node
implements java.lang.Cloneable

A PermutationNode holds a single permutation and orientatin change cycle of cube parts of a single type. The side effect of a permutation node to a Cube is a permutation and orientation change the cube parts in the cycle.

Version:
5.2.1 2009-04-11 Fixed validation of side part number for cubes with more than 5 layers.
5.2 2009-01-05 Removed static method toPermutationString(), because it is redundant with methods in class ch.randelshofer.rubik.Cubes.
5.1 2008-01-08 Added support for multiple part numbers.
5.0 2005-01-31 Reworked.
2.0 2004-07-07 Support for multiple sign positions added.
1.2 2002-12-26 Support for the identity permutation added.
1.1.2 2002-12-23 Signs were not applied properly to the cube.
1.1.1 2002-05-18 Method applyInverseTo did not apply orientation changes properly to the cube.
1.1 2001-12-27 Corner Permutation can not be clockwise and anticlockwise at the same time. Method addPermItem checks now if this is valid.
Author:
werni
See Also:
Serialized Form

Field Summary
static int CORNER_PERMUTATION
           
static int EDGE_PERMUTATION
           
static int MINUS_SIGN
           
static int NO_SIGN
           
static int PLUS_SIGN
           
static int PLUSPLUS_SIGN
           
static int SIDE_PERMUTATION
           
static int UNDEFINED_PERMUTATION
           
static int UNDEFINED_SIGN
           
 
Fields inherited from class ch.randelshofer.rubik.parser.Node
endpos, layerCount, startpos, symbol
 
Fields inherited from class javax.swing.tree.DefaultMutableTreeNode
allowsChildren, children, EMPTY_ENUMERATION, parent, userObject
 
Constructor Summary
PermutationNode(int layerCount)
          Creates a new PermutationNode.
PermutationNode(int layerCount, int startpos, int endpos)
          Creates a new PermutationNode.
 
Method Summary
 void addPermItem(int type, Symbol signSymbol, Symbol[] faceSymbols)
          Throws illegal argument exception if this permutation already has permutation items of a different type.
 void addPermItem(int type, Symbol signSymbol, Symbol[] faceSymbols, int partNumber, int layerCount)
          Throws illegal argument exception if this permutation already has permutation items of a different type.
 void applyTo(Cube cube, boolean inverse)
          Applies the symbol represented by this node to the cube.
 java.lang.Object clone()
           
 int getFullTurnCount()
          Gets the full turn count of the subtree starting at this node.
 int getPermItemCount()
           
 int getQuarterTurnCount()
          Gets the quarter turn count of the subtree starting at this node.
 int getType()
           
 void inverse()
          Inverses the subtree starting at this node.
 void reflect()
          Reflects the subtree starting at this node.
 java.util.Enumeration resolvedEnumeration(boolean inverse)
          Enumerate this symbol and all of its children.
 void setPermutationSign(Symbol signSymbol)
           
 java.util.List toResolvedList()
          Returns a String that describes the current permutation of the cube.
 java.lang.String toString()
          Returns a string representation of this node.
 void transform(int axis, int layerMask, int angle)
          Transforms the node by the given ScriptParser.symbol constant.
 void writeTokens(java.io.PrintWriter w, Notation p, java.util.Map<java.lang.String,MacroNode> macroMap)
          Writes the token(s) represented by the subtree starting at this node.
 
Methods inherited from class ch.randelshofer.rubik.parser.Node
cloneSubtree, dumpTree, enumerateChildrenReversed, getBlockTurnCount, getChildAt, getChildren, getEndPosition, getFaceTurnCount, getLayerTurnCount, getStartPosition, getSymbol, overwritePositions, setEndPosition, setStartPosition, toString, toString, transform, transformOrientation
 
Methods inherited from class javax.swing.tree.DefaultMutableTreeNode
add, breadthFirstEnumeration, children, depthFirstEnumeration, getAllowsChildren, getChildAfter, getChildBefore, getChildCount, getDepth, getFirstChild, getFirstLeaf, getIndex, getLastChild, getLastLeaf, getLeafCount, getLevel, getNextLeaf, getNextNode, getNextSibling, getParent, getPath, getPathToRoot, getPreviousLeaf, getPreviousNode, getPreviousSibling, getRoot, getSharedAncestor, getSiblingCount, getUserObject, getUserObjectPath, insert, isLeaf, isNodeAncestor, isNodeChild, isNodeDescendant, isNodeRelated, isNodeSibling, isRoot, pathFromAncestorEnumeration, postorderEnumeration, preorderEnumeration, remove, remove, removeAllChildren, removeFromParent, setAllowsChildren, setParent, setUserObject
 
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

PLUS_SIGN

public static final int PLUS_SIGN
See Also:
Constant Field Values

PLUSPLUS_SIGN

public static final int PLUSPLUS_SIGN
See Also:
Constant Field Values

MINUS_SIGN

public static final int MINUS_SIGN
See Also:
Constant Field Values

NO_SIGN

public static final int NO_SIGN
See Also:
Constant Field Values

UNDEFINED_SIGN

public static final int UNDEFINED_SIGN
See Also:
Constant Field Values

SIDE_PERMUTATION

public static final int SIDE_PERMUTATION
See Also:
Constant Field Values

EDGE_PERMUTATION

public static final int EDGE_PERMUTATION
See Also:
Constant Field Values

CORNER_PERMUTATION

public static final int CORNER_PERMUTATION
See Also:
Constant Field Values

UNDEFINED_PERMUTATION

public static final int UNDEFINED_PERMUTATION
See Also:
Constant Field Values
Constructor Detail

PermutationNode

public PermutationNode(int layerCount)
Creates a new PermutationNode.


PermutationNode

public PermutationNode(int layerCount,
                       int startpos,
                       int endpos)
Creates a new PermutationNode.

Parameters:
startpos - The start position of the node in the source code.
endpos - The end position of the node in the source code.
Method Detail

getFullTurnCount

public int getFullTurnCount()
Gets the full turn count of the subtree starting at this node.


getQuarterTurnCount

public int getQuarterTurnCount()
Gets the quarter turn count of the subtree starting at this node.

Overrides:
getQuarterTurnCount in class Node

getType

public int getType()

setPermutationSign

public void setPermutationSign(Symbol signSymbol)

addPermItem

public void addPermItem(int type,
                        Symbol signSymbol,
                        Symbol[] faceSymbols)
Throws illegal argument exception if this permutation already has permutation items of a different type.

Parameters:
type - PermutationNode.SIDE, .EDGE, .CORNER
signSymbol - Symbol.PERMUTATION_PLUS, .PMINUS or .PPLUSPLUS or (0 if no sign symbol).
faceSymbols - Array of 1, 2, or 3 entries of Symbol.FACE_R, .PU, .PB, .PL, .PD or .PF.

addPermItem

public void addPermItem(int type,
                        Symbol signSymbol,
                        Symbol[] faceSymbols,
                        int partNumber,
                        int layerCount)
Throws illegal argument exception if this permutation already has permutation items of a different type.

Parameters:
type - PermutationNode.SIDE, .EDGE, .CORNER
signSymbol - Symbol.PERMUTATION_PLUS, .PMINUS or .PPLUSPLUS or (0 if no sign symbol).
faceSymbols - Array of 1, 2, or 3 entries of Symbol.FACE_R, .PU, .PB, .PL, .PD or .PF.
partNumber - A value >= 0 used to disambiguate multiple edge parts and multiple side parts in 4x4 cubes and 5x5 cubes.
layerCount - The number of layers of the cube.

getPermItemCount

public int getPermItemCount()

applyTo

public void applyTo(Cube cube,
                    boolean inverse)
Description copied from class: Node
Applies the symbol represented by this node to the cube.

Overrides:
applyTo in class Node
Parameters:
cube - A cube to be transformed by this symbol.
inverse - If true, the transform will be done in inverse order.

inverse

public void inverse()
Description copied from class: Node
Inverses the subtree starting at this node.

Overrides:
inverse in class Node

reflect

public void reflect()
Description copied from class: Node
Reflects the subtree starting at this node.

Overrides:
reflect in class Node

resolvedEnumeration

public java.util.Enumeration resolvedEnumeration(boolean inverse)
Enumerate this symbol and all of its children. Special operators (i. e. repeat and inverse) are resolved before the children are returned.

Overrides:
resolvedEnumeration in class Node
Parameters:
inverse - Set to true if you wish to get an inverted enumeration.

transform

public void transform(int axis,
                      int layerMask,
                      int angle)
Transforms the node by the given ScriptParser.symbol constant.

Overrides:
transform in class Node

toString

public java.lang.String toString()
Description copied from class: Node
Returns a string representation of this node. Use for debugging only.

Overrides:
toString in class Node

clone

public java.lang.Object clone()
Overrides:
clone in class javax.swing.tree.DefaultMutableTreeNode

writeTokens

public void writeTokens(java.io.PrintWriter w,
                        Notation p,
                        java.util.Map<java.lang.String,MacroNode> macroMap)
                 throws java.io.IOException
Description copied from class: Node
Writes the token(s) represented by the subtree starting at this node. The syntax and the string representations of the tokens are provided by the parser.

Overrides:
writeTokens in class Node
Parameters:
w - This is where the tokens are written to.
p - The notation which provides the tokens.
macroMap - Local macros which are preserved by the translation.
Throws:
java.io.IOException

toResolvedList

public java.util.List toResolvedList()
Returns a String that describes the current permutation of the cube. / public static String toPermutationString(Cube cube, Notation notation) { if (!notation.isSupported(Symbol.PERMUTATION)) { return "---"; } // Retrieve fields from cube int[] cornerLoc = cube.getCornerLocations(); int[] edgeLoc = cube.getEdgeLocations(); int[] sideLoc = cube.getSideLocations(); int[] cornerOrient = cube.getCornerOrientations(); int[] edgeOrient = cube.getEdgeOrientations(); int[] sideOrient = cube.getSideOrientations(); // Local variables Syntax permutationPosition = notation.getSyntax(Symbol.PERMUTATION); StringBuffer buf = new StringBuffer(); boolean[] visitedLocs; int i, j, k, p; int prevOrient; boolean isFirst; String pr = notation.getToken(Symbol.FACE_R); String pu = notation.getToken(Symbol.FACE_U); String pf = notation.getToken(Symbol.FACE_F); String pl = notation.getToken(Symbol.FACE_L); String pd = notation.getToken(Symbol.FACE_D); String pb = notation.getToken(Symbol.FACE_B); // describe the state changes of the corner parts String[] corners = new String[]{ pu + pf + pl, pd + pl + pf, pu + pr + pf, pd + pf + pr, pu + pb + pr, pd + pr + pb, pu + pl + pb, pd + pb + pl }; visitedLocs = new boolean[8]; isFirst = true; for (i = 0; i < 8; i++) { if (!visitedLocs[i]) { if (cornerLoc[i] == i && cornerOrient[i] == 0) { continue; } if (isFirst) { isFirst = false; } else { buf.append(' '); } buf.append(notation.getToken(Symbol.PERMUTATION_BEGIN)); p = buf.length(); buf.append(corners[i]); visitedLocs[i] = true; prevOrient = 0; for (j = 0; cornerLoc[j] != i; j++) { } while (!visitedLocs[j]) { visitedLocs[j] = true; buf.append(notation.getToken(Symbol.PERMUTATION_DELIMITER)); prevOrient = (prevOrient + cornerOrient[j]) % 3; switch (prevOrient) { case 0: buf.append(corners[j]); break; case 2: buf.append(corners[j].charAt(1)); buf.append(corners[j].charAt(2)); buf.append(corners[j].charAt(0)); break; case 1: buf.append(corners[j].charAt(2)); buf.append(corners[j].charAt(0)); buf.append(corners[j].charAt(1)); break; } //buf.append(':'); //buf.append(prevOrient); for (k = 0; cornerLoc[k] != j; k++) { } j = k; } prevOrient = (prevOrient + cornerOrient[i]) % 3; if (prevOrient == 0) { buf.append(notation.getToken(Symbol.PERMUTATION_END)); } else { if (permutationPosition == Syntax.PREFIX) { buf.insert( p - notation.getToken(Symbol.PERMUTATION_BEGIN).length(), notation.getToken((prevOrient == 1) ? Symbol.PERMUTATION_MINUS : Symbol.PERMUTATION_PLUS)); buf.append(notation.getToken(Symbol.PERMUTATION_END)); } else if (permutationPosition == Syntax.PRECIRCUMFIX) { buf.insert( p, notation.getToken((prevOrient == 1) ? Symbol.PERMUTATION_MINUS : Symbol.PERMUTATION_PLUS)); buf.append(notation.getToken(Symbol.PERMUTATION_END)); } else if (permutationPosition == Syntax.POSTCIRCUMFIX) { buf.append( notation.getToken((prevOrient == 1) ? Symbol.PERMUTATION_MINUS : Symbol.PERMUTATION_PLUS)); buf.append(notation.getToken(Symbol.PERMUTATION_END)); } else if (permutationPosition == Syntax.SUFFIX) { buf.append(notation.getToken(Symbol.PERMUTATION_END)); buf.append( notation.getToken((prevOrient == 1) ? Symbol.PERMUTATION_MINUS : Symbol.PERMUTATION_PLUS)); } } } } // describe the state changes of the edge parts String[] edges = new String[]{ pf + pu, pl + pf, pf + pd, pu + pr, pr + pf, pd + pr, pb + pu, pr + pb, pb + pd, pu + pl, pl + pb, pd + pl }; visitedLocs = new boolean[12]; isFirst = true; for (i = 0; i < 12; i++) { if (!visitedLocs[i]) { if (edgeLoc[i] == i && edgeOrient[i] == 0) { continue; } if (isFirst) { if (buf.length() > 0) { buf.append('\n'); } isFirst = false; } else { buf.append(' '); } buf.append(notation.getToken(Symbol.PERMUTATION_BEGIN)); p = buf.length(); buf.append(edges[i]); visitedLocs[i] = true; prevOrient = 0; for (j = 0; edgeLoc[j] != i; j++) { } while (!visitedLocs[j]) { visitedLocs[j] = true; buf.append(notation.getToken(Symbol.PERMUTATION_DELIMITER)); prevOrient ^= edgeOrient[j]; if (prevOrient == 1) { buf.append(edges[j].charAt(1)); buf.append(edges[j].charAt(0)); } else { buf.append(edges[j]); } //buf.append(':'); //buf.append(prevOrient); for (k = 0; edgeLoc[k] != j; k++) { } j = k; } if ((prevOrient ^ edgeOrient[i]) == 0) { buf.append(notation.getToken(Symbol.PERMUTATION_END)); } else { if (permutationPosition == Syntax.PREFIX) { buf.insert( p - notation.getToken(Symbol.PERMUTATION_BEGIN).length(), notation.getToken(Symbol.PERMUTATION_PLUS)); buf.append(notation.getToken(Symbol.PERMUTATION_END)); } else if (permutationPosition == Syntax.PRECIRCUMFIX) { buf.insert(p, notation.getToken(Symbol.PERMUTATION_PLUS)); buf.append(notation.getToken(Symbol.PERMUTATION_END)); } else if (permutationPosition == Syntax.POSTCIRCUMFIX) { buf.append( notation.getToken(Symbol.PERMUTATION_PLUS)); buf.append(notation.getToken(Symbol.PERMUTATION_END)); } else if (permutationPosition == Syntax.SUFFIX) { buf.append(notation.getToken(Symbol.PERMUTATION_END)); buf.append( notation.getToken(Symbol.PERMUTATION_PLUS)); break; } } } } // describe the state changes of the side parts String[] sides = new String[]{ pf, pr, pd, pb, pl, pu }; String[] sideOrients = new String[]{ "", notation.getToken(Symbol.PERMUTATION_MINUS), notation.getToken(Symbol.PERMUTATION_PLUSPLUS), notation.getToken(Symbol.PERMUTATION_PLUS) }; visitedLocs = new boolean[6]; isFirst = true; for (i = 0; i < 6; i++) { if (!visitedLocs[i]) { if (sideLoc[i] == i && sideOrient[i] == 0) { continue; } if (isFirst) { if (buf.length() > 0) { buf.append('\n'); } isFirst = false; } else { buf.append(' '); } buf.append(notation.getToken(Symbol.PERMUTATION_BEGIN)); p = buf.length(); buf.append(sides[i]); visitedLocs[i] = true; prevOrient = 0; for (j = 0; sideLoc[j] != i; j++) { } while (!visitedLocs[j]) { visitedLocs[j] = true; buf.append(notation.getToken(Symbol.PERMUTATION_DELIMITER)); prevOrient = (prevOrient + sideOrient[j]) % 4; if (permutationPosition == Syntax.PREFIX || permutationPosition == Syntax.POSTCIRCUMFIX) { buf.append(sideOrients[prevOrient]); buf.append(sides[j]); } else if (permutationPosition == Syntax.PRECIRCUMFIX || permutationPosition == Syntax.SUFFIX) { buf.append(sides[j]); buf.append(sideOrients[prevOrient]); } //buf.append(':'); //buf.append(prevOrient); for (k = 0; sideLoc[k] != j; k++) { } j = k; } prevOrient = (prevOrient + sideOrient[i]) % 4; if (prevOrient == 0) { buf.append(notation.getToken(Symbol.PERMUTATION_END)); } else { if (permutationPosition == Syntax.PREFIX) { buf.insert( p - notation.getToken(Symbol.PERMUTATION_BEGIN).length(), sideOrients[prevOrient]); buf.append(notation.getToken(Symbol.PERMUTATION_END)); } else if (permutationPosition == Syntax.PRECIRCUMFIX) { buf.insert(p, sideOrients[prevOrient]); buf.append(notation.getToken(Symbol.PERMUTATION_END)); } else if (permutationPosition == Syntax.POSTCIRCUMFIX) { buf.append( sideOrients[prevOrient]); buf.append(notation.getToken(Symbol.PERMUTATION_END)); } else if (permutationPosition == Syntax.SUFFIX) { buf.append(notation.getToken(Symbol.PERMUTATION_END)); buf.append( sideOrients[prevOrient]); } } } } return (buf.length() == 0) ? notation.getToken(Symbol.PERMUTATION_BEGIN) + notation.getToken(Symbol.PERMUTATION_END) : buf.toString(); }

Overrides:
toResolvedList in class Node

(c) Werner Randelshofer.
All rights reserved.