2

我正在用 C# 创建一个解决魔方问题的项目。它将魔方的当前状态作为输入,并输出一系列动作以执行使用指定符号解魔方。

Cube 由 6 个长度为 9 的字符串数组组成:

private string[,] CubeState = new string[6,9] {
    { "WHITE", "WHITE", "WHITE", "WHITE", "WHITE", "WHITE", "WHITE", "WHITE", "WHITE"},
    { "BLUE", "BLUE", "BLUE", "BLUE", "BLUE", "BLUE", "BLUE", "BLUE", "BLUE"},
    { "RED", "RED", "RED", "RED", "RED", "RED", "RED", "RED", "RED"},
    { "GREEN", "GREEN", "GREEN", "GREEN", "GREEN", "GREEN", "GREEN", "GREEN", "GREEN"},
    { "ORANGE", "ORANGE", "ORANGE", "ORANGE", "ORANGE", "ORANGE", "ORANGE", "ORANGE", "ORANGE"},
    { "YELLOW", "YELLOW", "YELLOW", "YELLOW", "YELLOW", "YELLOW", "YELLOW", "YELLOW", "YELLOW" } };

我创建了一个 excel 电子表格来代表每个面孔二维立方体的表示

你可以把它想象成一个折叠在一起形成立方体的网。

由于我使用的是控制台应用程序而不是 Windows 窗体应用程序,因此我必须通过将每个面写入彼此下方的控制台来表示立方体。我使用以下方法执行此操作PrintCube()

public void PrintCube()
    {
        for (int i = 0; i < 6; i++)
        {
            for (int j = 0; j < 9; j++)
            {
                Console.Write("--" + CubeState[i,j]);

                if (j % 3 == 2 && j != 0)
                {
                    Console.Write("\r\n");
                }
            }

            Console.WriteLine("\r\n");
        }
    }

这使得求解立方体的标准输出如下:

求解立方体输出

目前,我正处于编码可以在立方体上执行的每个不同动作的阶段,但我遇到了障碍。

下面是执行操作的代码:

public void PerformOperation(CubeOperations operation)
{
    string[,] newCubeState = CubeState;
    string tempString;

    switch (operation)
    {
        case CubeOperations.F:
            for (int i = 6; i < 9; i++)
            {
                // Test 1
                tempString = CubeState[4, (3 * (i - 6)) + 2];
                newCubeState[4, (3 * (i - 6)) + 2] = CubeState[3, i - 6];   //258  012
                newCubeState[3, i - 6] = CubeState[2, 3 * (i - 6)];         //012  036
                newCubeState[2, 3 * (i - 6)] = CubeState[1, i];             //036  678
                newCubeState[1, i] = tempString;                            //678  258
                // Test 2
                /*newCubeState[1, i] = CubeState[4, i];
                newCubeState[2, i] = CubeState[1, i];
                newCubeState[3, i] = CubeState[2, i];
                newCubeState[4, i] = CubeState[3, i];*/
            }

            RotateFaceRight(newCubeState, Rubiks_Cube_Solver.CubeCenters.WHITE);
        break;

        case CubeOperations.R:
            for (int i = 2; i < 9; i += 3)
            {
                // Test 1
                tempString = CubeState[3, i];
                newCubeState[3, i] = CubeState[5, 8 - i];        //258  630
                newCubeState[5, i - 2] = CubeState[1, 10 - i];   //036  852
                newCubeState[1, i] = CubeState[0, i];            //258  258
                newCubeState[0, i] = tempString;                 //258  258
                // Test 2
                /*newCubeState[0, i] = CubeState[3, i];
                newCubeState[1, i] = CubeState[0, i];
                newCubeState[5, i] = CubeState[1, i - 2];
                newCubeState[3, i - 2] = CubeState[5, i];*/
            }

            RotateFaceRight(newCubeState, Rubiks_Cube_Solver.CubeCenters.RED);
            break;

        case CubeOperations.U:
            break;

        case CubeOperations.L:
            break;

        case CubeOperations.B:
            break;

        case CubeOperations.D:
            break;

        case CubeOperations.FPRIME:
            break;

        case CubeOperations.RPRIME:
            break;

        case CubeOperations.UPRIME:
            break;

        case CubeOperations.LPRIME:
            break;

        case CubeOperations.BPRIME:
            break;

        case CubeOperations.DPRIME:
            break;

        case CubeOperations.F2:
            break;

        case CubeOperations.R2:
            break;

        case CubeOperations.U2:
            break;

        case CubeOperations.L2:
            break;

        case CubeOperations.B2:
            break;

        case CubeOperations.D2:
            break;
        default:
            break;
    }

    CubeState = newCubeState;
}

我正在按顺序对操作进行编码,因此,到目前为止,我只完成了F操作,但我一生都无法弄清楚我在R操作上哪里出错了。

在魔方符号中,我们看到对已解出的立方体的操作R,从白色面朝外,蓝色面朝上,表示以下运动:

  • 握住立方体,白色面朝外,蓝色面朝上。

  • 将红色面顺时针旋转 90 度,使白色面的右侧移到蓝色面上,绿色移到白色上,黄色移到绿色上,蓝色移到黄色上。

执行这两个步骤会导致R操作。

要了解我们需要在代码中做什么才能实现这一点,让我们回到 excel 电子表格。 二维立方体的表示

从白边开始,我们可以看到我们必须改变:

  1. 白面的索引2、5和 8绿面的索引2、5 和 8 。
  2. 脸的索引2、5和 8 分别对应白脸的索引*2、5 和 8*
  3. 然而,当我们到达黄色面时,由于网络中的面必须“翻转”来连接橙色、蓝色、绿色和红色的面,我们必须更改索引0、3 和 6。这些分别更改为蓝色面上的索引 8、5和 2 。如果您面前有一个立方体,则更容易思考为什么这是真的
  4. 绿面上,我们将索引2、5 和 8更改为面上的索引 6、3和 0。同样,这是因为我们如何解释网络。

放大 Operation R的代码,我们可以看到我是如何实现这一点的:

case CubeOperations.R:
    for (int i = 2; i < 9; i += 3)
    {
        //Test 1
        tempString = CubeState[3, i];
        newCubeState[3, i] = CubeState[5, 8 - i];       //258  630
        newCubeState[5, i - 2] = CubeState[1, 10 - i];  //036  852
        newCubeState[1, i] = CubeState[0, i];           //258  258
        newCubeState[0, i] = tempString;                //258  258
        // Test 2
        /*newCubeState[0, i] = CubeState[3, i];
        newCubeState[1, i] = CubeState[0, i];
        newCubeState[5, i] = CubeState[1, i - 2];
        newCubeState[3, i - 2] = CubeState[5, i];*/
    }

我在每一行旁边都有注释,说明发生了变化,其中//258 630表示由newCubeState索引2、5 和 8表示的面部分别更改为由CubeState索引 6、3和 0表示的面部。

从上面的二维数组可以看出,第一个索引表示人脸变为[0] = "WHITE", [1] = "BLUE", [2] = "RED",[3] = "GREEN" , [4] = "橙色", [5] = "黄色"

知道了这一点,我们可以这样解释我的代码:

  • 首先,绿色面上的第 2 个索引成为黄色面上的第 6 个索引。[绿色 -> 黄色]

  • 二、黄脸第0个索引变成第8个索引[YELLOW -> BLUE]

  • 第三,脸的第二个索引变成白脸第二个索引。[蓝色 -> 白色]

  • 第四,白面的第二个索引变成了绿面的第二个索引。[白色-> 绿色]

请注意,由于某些奇怪的原因,即使它们是完全独立的变量,它似乎会影响CubeState[x,y]我设置的时间newCubeState[i,j] = CubeState[x, y],因此,我需要在更改之前使用索引,这导致需要临时变量tempString,但是,这不是手头的问题在这里。

  • 第五,绿面上的第 5 个索引变成了黄面上的第 3 个索引。[绿色 -> 黄色]

  • 六、黄面第3个索引变成第5个索引[YELLOW -> BLUE]

  • 第七,脸的第5个索引变成了白脸的第 5 个索引。[蓝色 -> 白色]

  • 第八,白面的第5个索引变成了绿面的第 5 个索引。[白色-> 绿色]

  • 第九,绿面上的第8 个索引变成了黄面上的第 0个索引。[绿色 -> 黄色]

  • 十、黄面第6个索引变成第2个索引[YELLOW -> BLUE]

  • 第十一,脸的第8个索引变成了白脸的第8个索引。[蓝色 -> 白色]

  • 第十二,白面的第8个索引变成了绿面的第 8 个索引。[白色-> 绿色]

这应该会产生以下输出:


白 - 白 - 绿

白 - 白 - 绿

白 - 白 - 绿  

 

蓝色 - 蓝色 - 白色

蓝色 - 蓝色 - 白色

蓝色 - 蓝色 - 白色  

 

红 - 红 - 红

红 - 红 - 红

红 - 红 - 红  

 

绿色 - 绿色 - 黄色

绿色 - 绿色 - 黄色

绿色 - 绿色 - 黄色  

 

橙色 - 橙色 - 橙色

橙色 - 橙色 - 橙色

橙色 - 橙色 - 橙色  

 

蓝色 - 黄色 - 黄色

蓝色 - 黄色 - 黄色

蓝色 - 黄色 - 黄色


但是,我们看到情况并非如此:

执行正确的操作

出于某种奇怪的原因,我们看到第3面的第 8 个索引( GREEN)变成了BLUE而不是YELLOW,以及第5面的第 6 个索引( YELLOW)变成了WHITE而不是BLUE

我不知道为什么会发生这种情况,我将非常感谢您的帮助。

它不应该引起任何问题,但这是我的RotateFaceRight()方法:

private void RotateFaceRight(string[,] cube, CubeCenters faceCenterColour)
{
    string[] face = new string[9];
    int faceNumber = (int)faceCenterColour;

    for (int i = 0; i < 9; i++)
    {
        face[i] = cube[(int)faceCenterColour, i];
    }

    /*
     * 012  ->  630
     * 345  ->  741
     * 678  ->  852
     */

    cube[faceNumber, 0] = face[6];
    cube[faceNumber, 1] = face[3];
    cube[faceNumber, 2] = face[0];
    cube[faceNumber, 3] = face[7];
    cube[faceNumber, 4] = face[4];
    cube[faceNumber, 5] = face[1];
    cube[faceNumber, 6] = face[8];
    cube[faceNumber, 7] = face[5];
    cube[faceNumber, 8] = face[2];
}

我的其余代码在这里:

立方体.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Rubiks_Cube_Solver
{
    class Cube
    {

        private string[,] CubeState = new string[6, 9] {
            { "WHITE", "WHITE", "WHITE", "WHITE", "WHITE", "WHITE", "WHITE", "WHITE", "WHITE"},
            { "BLUE", "BLUE", "BLUE", "BLUE", "BLUE", "BLUE", "BLUE", "BLUE", "BLUE"},
            { "RED", "RED", "RED", "RED", "RED", "RED", "RED", "RED", "RED"},
            { "GREEN", "GREEN", "GREEN", "GREEN", "GREEN", "GREEN", "GREEN", "GREEN", "GREEN"},
            { "ORANGE", "ORANGE", "ORANGE", "ORANGE", "ORANGE", "ORANGE", "ORANGE", "ORANGE", "ORANGE"},
            { "YELLOW", "YELLOW", "YELLOW", "YELLOW", "YELLOW", "YELLOW", "YELLOW", "YELLOW", "YELLOW" } };

        private readonly string[] CubeCenters = new string[] { "WHITE", "BLUE", "RED", "GREEN", "ORANGE", "YELLOW" };
        private readonly string[] CubeSides = new string[] { "FRONT", "TOP", "RIGHT", "BOTTOM", "LEFT", "BACK" };



        public Cube()
        {

        }


        public void PerformOperation(CubeOperations operation)
        {
            string[,] newCubeState = CubeState;
            string tempString;

            switch (operation)
            {

                //Console.WriteLine("{0} -> {1}\nOld Face: {2} Old Item: {3}\nNew Face: {4} New Item: {5}\n\n", newCubeState[3, i], CubeState[5, 8 - i], 5, (8 - i), 3, (i));

                case CubeOperations.F:
                    for (int i = 6; i < 9; i++)
                    {
                        // Test 1
                        tempString = CubeState[4, (3 * (i - 6)) + 2];
                        newCubeState[4, (3 * (i - 6)) + 2] = CubeState[3, i - 6];   //258  012
                        newCubeState[3, i - 6] = CubeState[2, 3 * (i - 6)];         //012  036
                        newCubeState[2, 3 * (i - 6)] = CubeState[1, i];             //036  678
                        newCubeState[1, i] = tempString;                            //678  258
                        // Test 2
                        /*newCubeState[1, i] = CubeState[4, i];
                        newCubeState[2, i] = CubeState[1, i];
                        newCubeState[3, i] = CubeState[2, i];
                        newCubeState[4, i] = CubeState[3, i];*/
                    }

                    RotateFaceRight(newCubeState, Rubiks_Cube_Solver.CubeCenters.WHITE);
                    break;

                case CubeOperations.R:
                    for (int i = 2; i < 9; i += 3)
                    {
                        // Test 1
                        tempString = CubeState[3, i];
                        newCubeState[3, i] = CubeState[5, 8 - i];       //258  630
                        newCubeState[5, i - 2] = CubeState[1, 10 - i];  //036  852
                        newCubeState[1, i] = CubeState[0, i];           //258  258
                        newCubeState[0, i] = tempString;                //258  258
                        // Test 2
                        /*newCubeState[0, i] = CubeState[3, i];
                        newCubeState[1, i] = CubeState[0, i];
                        newCubeState[5, i] = CubeState[1, i - 2];
                        newCubeState[3, i - 2] = CubeState[5, i];*/
                    }

                    RotateFaceRight(newCubeState, Rubiks_Cube_Solver.CubeCenters.RED);
                    break;

                case CubeOperations.U:
                    for (int i = 0; i < 3; i++)
                    {
                        // Test 1
                        tempString = CubeState[4, i];
                        newCubeState[4, i] = CubeState[0, i];   //012  012
                        newCubeState[0, i] = CubeState[2, i];   //012  012
                        newCubeState[2, i] = CubeState[5, i];   //012  012
                        newCubeState[5, i] = tempString;        //012  012
                        // Test 2
                        /*newCubeState[0, i] = CubeState[2, i];
                        newCubeState[2, i] = CubeState[5, i];
                        newCubeState[5, i] = CubeState[4, i];
                        newCubeState[4, i] = CubeState[0, i];*/
                    }

                    RotateFaceRight(newCubeState, Rubiks_Cube_Solver.CubeCenters.BLUE);
                    break;

                case CubeOperations.L:
                    for (int i = 0; i < 7; i += 3)
                    {
                        // Test 1
                        tempString = CubeState[0, i];
                        newCubeState[0, i] = CubeState[1, i];       //036  036
                        newCubeState[1, i] = CubeState[5, i + 2];   //036  258
                        newCubeState[5, i + 2] = CubeState[3, i];   //258  036
                        newCubeState[3, i] = tempString;            //036  036
                        // Test 2
                        /*newCubeState[0, i] = CubeState[1, i];
                        newCubeState[1, i] = CubeState[5, i];
                        newCubeState[5, i] = CubeState[3, i];
                        newCubeState[3, i] = CubeState[0, i];*/
                    }

                    RotateFaceRight(newCubeState, Rubiks_Cube_Solver.CubeCenters.ORANGE);
                    break;

                case CubeOperations.B:
                    for (int i = 0; i < 3; i++)
                    {
                        // Test 1
                        tempString = CubeState[1, i];
                        newCubeState[1, i] = CubeState[2, (i * 3) + 2];     //012  258
                        newCubeState[2, (i * 3) + 2] = CubeState[3, i + 6]; //258  678
                        newCubeState[3, i + 6] = CubeState[4, (i * 3)];     //678  036
                        newCubeState[4, (i * 3)] = tempString;              //036  012
                        // Test 2
                        /*newCubeState[1, i] = CubeState[2, i];
                        newCubeState[2, i] = CubeState[3, i];
                        newCubeState[3, i] = CubeState[4, i];
                        newCubeState[4, i] = CubeState[1, i];*/
                    }

                    RotateFaceRight(newCubeState, Rubiks_Cube_Solver.CubeCenters.YELLOW);
                    break;

                case CubeOperations.D:
                    for (int i = 6; i < 9; i++)
                    {
                        // Test 1
                        tempString = CubeState[2, i];
                        newCubeState[2, i] = CubeState[0, i];     //678  678
                        newCubeState[0, i] = CubeState[4, i];     //678  678
                        newCubeState[4, i] = CubeState[5, i];     //678  678
                        newCubeState[5, i] = tempString;          //678  678
                        // Test 2
                        /*newCubeState[0, i] = CubeState[4, i];
                        newCubeState[2, i] = CubeState[0, i];
                        newCubeState[5, i] = CubeState[2, i];
                        newCubeState[4, i] = CubeState[5, i];*/
                    }

                    RotateFaceRight(newCubeState, Rubiks_Cube_Solver.CubeCenters.GREEN);
                    break;

                case CubeOperations.FPRIME:
                    break;

                case CubeOperations.RPRIME:
                    break;

                case CubeOperations.UPRIME:
                    break;

                case CubeOperations.LPRIME:
                    break;

                case CubeOperations.BPRIME:
                    break;

                case CubeOperations.DPRIME:
                    break;

                case CubeOperations.F2:
                    break;

                case CubeOperations.R2:
                    break;

                case CubeOperations.U2:
                    break;

                case CubeOperations.L2:
                    break;

                case CubeOperations.B2:
                    break;

                case CubeOperations.D2:
                    break;
                default:
                    break;
            }

            CubeState = newCubeState;
        }


        private void RotateFaceRight(string[,] cube, CubeCenters faceCenterColour)
        {
            string[] face = new string[9];
            int faceNumber = (int)faceCenterColour;

            for (int i = 0; i < 9; i++)
            {
                face[i] = cube[(int)faceCenterColour, i];
            }

            /*
             * 012  ->  630
             * 345  ->  741
             * 678  ->  852
             */

            cube[faceNumber, 0] = face[6];
            cube[faceNumber, 1] = face[3];
            cube[faceNumber, 2] = face[0];
            cube[faceNumber, 3] = face[7];
            cube[faceNumber, 4] = face[4];
            cube[faceNumber, 5] = face[1];
            cube[faceNumber, 6] = face[8];
            cube[faceNumber, 7] = face[5];
            cube[faceNumber, 8] = face[2];
        }


        public void PrintCube()
        {
            for (int i = 0; i < 6; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    Console.Write("--" + CubeState[i, j]);

                    if (j % 3 == 2 && j != 0)
                    {
                        Console.Write("\r\n");
                    }
                }

                Console.WriteLine("\r\n");
            }
        }

    }
}

CubeCenters.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Rubiks_Cube_Solver
{
    enum CubeCenters
    {
        WHITE,
        BLUE,
        RED,
        GREEN,
        ORANGE,
        YELLOW
    }
}

CubeOperations.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Rubiks_Cube_Solver
{
    enum CubeOperations
    {
        F,
        R,
        U,
        L,
        B,
        D,
        FPRIME,
        RPRIME,
        UPRIME,
        LPRIME,
        BPRIME,
        DPRIME,
        F2,
        R2,
        U2,
        L2,
        B2,
        D2
    }
}

程序.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Rubiks_Cube_Solver
{
    class Program
    {
        static void Main(string[] args)
        {
            Cube cube = new Cube();
            cube.PerformOperation(CubeOperations.R);
            cube.PrintCube();

            Console.ReadLine();
        }
    }
}
4

0 回答 0