ch.randelshofer.rubik.parser
Class PermutationNode
java.lang.Object
javax.swing.tree.DefaultMutableTreeNode
ch.randelshofer.rubik.parser.Node
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
| 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 |
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
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.
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, .CORNERsignSymbol - 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, .CORNERsignSymbol - 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