我正在开发一个应用程序,以在给定特定起始结构的情况下,找到拼图立方体的可能解决方案的数量。
我把所有独特的解决方案都存储在内存中,我将把给定的结构与之进行比较,以确定有多少解决方案是可能的。
为了做到这一点,我必须将立方体绕每个面旋转90度,4次,以便检查所有可能的方向。我稍后会考虑反思。
对于立方体,有6个面,4个旋转,总共进行24次操作。
我很难实现一个有效的算法,因为绕一个轴的旋转相当于绕另一个2轴的旋转。
例如:绕x轴旋转产生与绕y轴然后绕z轴旋转相同的方向。因此,我当前的实现需要64个操作,这是多余的,因为我多次检查同一方向。
应用图像
当前算法:
public static int getPossibleSolutionCount(Map<PieceIndex, Piece> pieces)
{
int count = 0;
for (Solution s : solutions)
{
for (int z = 0; z < 4; z++)
{
for (int x = 0; x < 4; x++)
{
for (int y = 0; y < 4; y++)
{
if (s.isDerrivedFrom(pieces))
{
count++;
}
//all rotation calls rotate the piece / structure byt 90 degrees
pieces.values().forEach(piece -> piece.rotate(GameObject.Axis.Y_AXIS));
}
pieces.values().forEach(piece -> piece.rotate(GameObject.Axis.X_AXIS));
}
pieces.values().forEach(piece -> piece.rotate(GameObject.Axis.Z_AXIS));
}
}
return count;
}
我如何改进这一点,使我不会重复相同的方向,即我只能检查24次迭代,而不是64次。
24个旋转中的每一个都可以通过哪一面朝上(6种可能性)和哪一面向左(每个朝上的面有4种可能性)来唯一识别。
一个外环来确定向上的面,然后一个内环来确定向左的面似乎很容易。考虑到你的轮调需要的论据,我可能会这样做:
// Rotating around these axes in sequence will bring each face in turn
// to the top
private static GameObject.AXIS ROTATION_PATH = new GameObject.AXIS[] {
GameObject.AXIS.X_AXIS,
GameObject.AXIS.X_AXIS,
GameObject.AXIS.Z_AXIS,
GameObject.AXIS.X_AXIS,
GameObject.AXIS.X_AXIS,
GameObject.AXIS.Z_AXIS
};
public static int getPossibleSolutionCount(Map<PieceIndex, Piece> pieces)
{
int count = 0;
for (GameObject.AXIS path_axis: ROTATION_PATH)
{
for (int y = 0; y < 4; y++)
{
for (Solution s : solutions)
{
if (s.isDerivedFrom(pieces))
{
count++;
}
}
pieces.values().forEach(piece -> piece.rotate(GameObject.Axis.Y_AXIS));
}
pieces.values().forEach(piece -> piece.rotate(path_axis));
}
return count;
}
希望你能看到它应该如何工作。我假设了轴指向的方向和物体旋转的方向,所以如果ROTATION_PATH没有为你做它应该做的事情,那么就相应地调整它。