ルービック キューブを解く C# でプロジェクトを作成しています。ルービック キューブの現在の状態を入力として受け取り、指定された表記法を使用して立方体を解くために実行する一連の動きを出力します。
Cube は、長さ 9 の 6 つの文字列配列の配列で表されます。
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 度ねじって、白い面の右側が青い面に、緑が白に、黄色が緑に、青が黄色に移動するようにします。
これら 2 つの手順を実行すると、R操作が実行されます。
これを行うためにコードで何をする必要があるかを確認するために、Excel スプレッドシートに戻りましょう。
白い面から始めて、変更する必要があることがわかります。
- ホワイトフェイスのインデックス2、5、8からグリーンフェイスのインデックス2、5、8まで。
- ブルーフェイスのインデックス2、5、8からホワイトフェイスのインデックス*2、5、8*まで
- ただし、黄色の面に到達すると、ネット内の面が「反転」してオレンジ、青、緑、および赤の面を接続する必要があるため、インデックス0、3、および 6を変更する必要があります。これらはそれぞれ、青の文字盤でインデックス 8、5 、および 2に変わります。目の前に立方体があるとなぜそうなのか考えやすい
- 緑の面では、インデックス 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 、および 8CubeState
が、それぞれインデックス 6、3 、および 0 で示される面にあったものに変更されたことを示します。
上記の 2 次元配列からわかるように、最初のインデックスは、[0] = "WHITE"、[1] = "BLUE"、[2] = "RED"、[3] = "GREEN"になる面を表していることがわかります。 、[4] =「オレンジ」、[5] =「イエロー」
これを知っていれば、コードを次のように解釈できます。
まず、グリーン面の2番目のインデックスがイエロー面の6番目のインデックスになります。[緑→黄]
次に、イエローフェイスの0 番目のインデックスがブルーフェイスの8 番目のインデックスになる[YELLOW -> BLUE]
3 つ目は、ブルーフェイスの 2 番目のインデックスがホワイト フェイスの2番目のインデックスになります。[青→白]
4つ目は、ホワイトフェイスの2番目のインデックスがグリーンフェイスの2番目のインデックスになります。【白→緑】
いくつかの奇妙な理由で、それらは完全に別の変数ですが、CubeState[x,y]
設定したときに影響するように見えることに注意してください。そのため、newCubeState[i,j] = CubeState[x, y]
変更する前にインデックスを使用する必要があり、一時変数が必要になりますtempString
が、そうではありませんここで当面の問題。
5 つ目は、グリーン面の5 番目のインデックスが、イエロー面の3 番目のインデックスになります。[緑→黄]
第六に、イエローフェイスの3番目のインデックスは、ブルーフェイスの5番目のインデックスになります[YELLOW -> BLUE]
7番目、ブルーフェイスの5番目のインデックスは、ホワイトフェイスの5番目のインデックスになります。[青→白]
8番目に、ホワイトフェイスの5番目のインデックスは、グリーンフェイスの5番目のインデックスになります。【白→緑】
グリーン面の9番目、8番目のインデックスは、イエロー面の0番目のインデックスになります。[緑→黄]
イエローフェイスの10番目、6番目のインデックスがブルーフェイスの2番目のインデックスになる[YELLOW -> BLUE]
11 番目、青文字盤の 8 番目のインデックスは、白文字盤の8番目のインデックスになります。[青→白]
12番目、ホワイトフェイスの8番目のインデックスは、グリーンフェイスの8番目のインデックスになります。【白→緑】
これにより、次の出力が得られるはずです。
白 - 白 - 緑
白 - 白 - 緑
白 - 白 - 緑
青 - 青 - 白
青 - 青 - 白
青 - 青 - 白
赤 - 赤 - 赤
赤 - 赤 - 赤
赤 - 赤 - 赤
緑 - 緑 - 黄
緑 - 緑 - 黄
緑 - 緑 - 黄
オレンジ - オレンジ - オレンジ
オレンジ - オレンジ - オレンジ
オレンジ - オレンジ - オレンジ
青 - 黄 - 黄
青 - 黄 - 黄
青 - 黄 - 黄
ただし、そうではないことがわかります。
何らかの奇妙な理由で、 3 番目の面 ( GREEN )の8 番目のインデックスがYELLOWではなくBLUEになり、 5 番目の面 ( YELLOW )の6 番目のインデックスがBLUEではなくWHITEになることがわかります。
なぜこれが起こるのかわかりません。これについて助けていただければ幸いです。
問題が発生することはありませんが、私の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];
}
私のコードの残りの部分はここにあります:
Cube.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
}
}
Program.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();
}
}
}