java - 魔方旋转算法

标签 java algorithm rubiks-cube

我目前正在完成一项构建功能性魔方的作业。该程序不需要 GUI。但它必须模拟具有旋转行为的 3 X 3 立方体,并提供立方体的图形表示(我将使用平面字母结构)。我的代码有一个用于构成面的面的类(另一个类),然后有一个包含旋转方法的立方体类。

我在创建/选择要使用的算法来准确模拟立方体和所有可能的旋转时遇到问题。我在该站点上找到了一个解决方案,引用了一篇论文,该论文提出了 7 种不同的方法(下面的链接)。但哪种方法最直观/最容易编写代码?更重要的是,哪个最适合下面概述的行为(在伪代码中)?

我无法理解如何使用任何方法同时解释每个面的变化,尤其是在考虑面旋转行为(与行和列相对)时。

How would you represent a Rubik's Cube in code?

Rotation Pseudocode: 

map each cube numbers 1-54, faces 1 – 4 are 1 – 36 while top face is 37 - 45 and bottom is 46 – 54
1 turn: clockwise = +9
1 turn: counterclockwise = -9 loops back to 45
1 turn: up = + 37
1 turn: down = -37 loops back to 46
2 turns: clockwise = +9(2)
2 turns: counterclockwise = -9(2)
2 turns: up = +37(2)
2 turns: down = -37(2)
3 turns: clockwise = +9(3)
3 turns: counterclockwise = -9(3)
3 turns: up = +37(3)
3 turns: down = -37(3)

此伪代码不考虑面部变化。

有没有比我的伪代码建议的方法更好/更简单的方法?我如何解释面部变化?

示例:(正面,顺时针旋转 1 圈)

123    741
456    852
789    963

注意:我倾向于 54 元素 vector ,但不确定如何操作它。

此外,这是我的第一个问题,如果有什么问题请告诉我(信息不足、信息过多、主题错误等)

谢谢!

注意:这是我正在使用的代码。

方面类:

public class Facets {

    public Color color;


    public Facets(Color color){
    }


    public enum Color {

        B, G, R, Y, O, P


}

    public String getName(){
        return this.color.name();
    }

}

面部类:

import java.util.Arrays;

public class Face {


    public Facets[] face;

    /*public Face(Facets.Color color, Facets.Color[] array){
        face = new Facets[9];
        for(int i = 0; i < face.length; i++){
            face[i] = new Facets(array[i]);
            face[i] = new Facets(color);

        }
    }*/

    public Face(Facets.Color color){
        face = new Facets[9];
        for(int i = 0; i < face.length; i++){
            face[i] = new Facets(color);
        }
    }

    public Face(Facets.Color[] array){
        face = new Facets[9];
        for (int i = 0; i < face.length; i++){
            face[i] = new Facets(array[i]);
            //face[i] = face[i].toString();
        }
    }


    //Returns a textual representation of Face  
    public String printFace(){
        StringBuilder faceString = new StringBuilder();

        for(Facets f: face){
            faceString.append(f.getName()); 
            System.out.println(f.toString());
        }
        return faceString.toString();

}

    public static void main(String[] args){
        Face face = new Face(Facets.Color.B);
        System.out.println(face.toString());
    }
}

立方体类:

public class Cube {

    public Cube(Face front, Face right, Face back, Face left, Face top, Face bottom){

    }

    public Cube createCube(){


    }

    public Cube rotate(int row, int column, String direction, int turns){
        /*Turns must be between 0 - 4
Row must be 1 or 2, column must be 1 or 2, direction must be clockwise, counterclockwise, up or down (0 means no turn, 1 is top row or left column; 2 is bottom row or right column)
*/

    }

    public int turns(){

    }

    public Cube row(){

    }

    public Cube column(){

    }

    public Cube clockwise(){

    }

    public Cube counterClockwise(){

    }

    public Cube up(){

    }

    public Cube down(){

    }

    public Cube random(Cube cube){

    }

    public Cube configuration(Cube cube){

    }



}

魔方:

public class RubiksCube {

    public RubiksCube(Cube cube){

    }

    public RubiksCube(Face front, Face rightOfFront, Face back, Face leftOfFront, Face top, Face bottom){

    }


    //calls face and colors and initializes the arrays into a object
    //default config: solid color on each side so each array, representing a face, is set to a solid color
    public void createNewCube(){

    }


    public void rotation(Cube cube, int row, int column, String direction, int turns){

    }

    public Cube configuration(Cube cube){//should return 6 Faces? or cube?

        return cube;

    }

}

最佳答案

想想哪种数据结构最容易让您将立方体概念化。您提供的链接中的不同解决方案各有利弊。你可以有一个更简洁的结构(即五个整数表示),它占用更少的内存并优化性能。但是,如果您是这个问题的新手,那么这种表示可能很难处理。另一方面是面向对象的表示,它模拟了大多数人对魔方的看法。对于刚接触魔方的人来说,这可能是最好的方法。

在您拥有对您有意义的数据结构之后,请考虑可以对多维数据集执行的不同操作。您可以在改变数据状态的函数中捕获这些移动中的每一个。如果你有一个真正的魔方可以玩,弄清楚所有不同的转弯是什么以及它们如何改变魔方的值。然后尝试在它们自己的功能中对它们进行建模。也就是说,顶部转弯会导致六个面孔中的五个发生变化,对吧。这将导致其中四张面孔接收到他们邻居的顶行。它也会导致顶面发生变化。底面不会受到影响。

如果您对复杂性感到不知所措,请尝试将您的问题分解为更小的问题。也许您可以尝试为 2 x 2 而不是 3 x 3 的魔方编写一个表示。一旦您掌握了较小的问题,就返回到较大的问题。

关于java - 魔方旋转算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41840439/

相关文章:

algorithm - 找到带来最大利润的组合

python - 如何在OpenCV2中将阈值分成正方形?

java - 什么是 JDBC 中的序数绑定(bind)和命名绑定(bind)

算法 - 在整数序列中找到第一个缺失的整数

Java 插件框架 (JPF) 和 SystemClassLoader

java - 算法的时间复杂度取决于增量/减量步长部分,而不是实际输入大小?

java - 最简单的魔方编码算法?

java - 隐藏魔方内部接线

java - 跟踪类(class)中已租用和可用的汽车数量

java - JPA 中的哪些操作绕过持久性上下文/缓存并直接在数据库中调用?