Commit 497e633d authored by Bošániová Monika's avatar Bošániová Monika
Browse files

Kociemba library added, buttos fixed

parent e2263594
......@@ -39,3 +39,12 @@ sysinfo.txt
# Crashlytics generated file
Assets/StreamingAssets/crashlytics-build.properties
# Ignore Tables folder and contents.
/Tables
/Tables/*
# Ignore meta files
/.vs
/.vs/*
*.meta
using System;
namespace Kociemba
{
internal class CoordCube
{
internal const short N_TWIST = 2187; // 3^7 possible corner orientations
internal const short N_FLIP = 2048; // 2^11 possible edge flips
internal const short N_SLICE1 = 495; // 12 choose 4 possible positions of FR,FL,BL,BR edges
internal const short N_SLICE2 = 24; // 4! permutations of FR,FL,BL,BR edges in phase2
internal const short N_PARITY = 2; // 2 possible corner parities
internal const short N_URFtoDLF = 20160; // 8!/(8-6)! permutation of URF,UFL,ULB,UBR,DFR,DLF corners
internal const short N_FRtoBR = 11880; // 12!/(12-4)! permutation of FR,FL,BL,BR edges
internal const short N_URtoUL = 1320; // 12!/(12-3)! permutation of UR,UF,UL edges
internal const short N_UBtoDF = 1320; // 12!/(12-3)! permutation of UB,DR,DF edges
internal const short N_URtoDF = 20160; // 8!/(8-6)! permutation of UR,UF,UL,UB,DR,DF edges in phase2
internal const int N_URFtoDLB = 40320; // 8! permutations of the corners
internal const int N_URtoBR = 479001600; // 8! permutations of the corners
internal const short N_MOVE = 18;
// All coordinates are 0 for a solved cube except for UBtoDF, which is 114
internal short twist;
internal short flip;
internal short parity;
internal short FRtoBR;
internal short URFtoDLF;
internal short URtoUL;
internal short UBtoDF;
internal int URtoDF;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Generate a CoordCube from a CubieCube
internal CoordCube(CubieCube c, DateTime startTime, string currentTime, out string info)
{
info = currentTime;
twist = c.getTwist();
flip = c.getFlip();
parity = c.cornerParity();
FRtoBR = c.getFRtoBR();
URFtoDLF = c.getURFtoDLF();
URtoUL = c.getURtoUL();
UBtoDF = c.getUBtoDF();
URtoDF = c.getURtoDF();// only needed in phase2
info += "[ Finished Initialiation: " + String.Format(@"{0:mm\:ss\.ffff}", (DateTime.Now - startTime)) + " ] ";
}
// A move on the coordinate level
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
internal virtual void move(int m)
{
twist = twistMove[twist, m];
flip = flipMove[flip, m];
parity = parityMove[parity][m];
FRtoBR = FRtoBR_Move[FRtoBR, m];
URFtoDLF = URFtoDLF_Move[URFtoDLF, m];
URtoUL = URtoUL_Move[URtoUL, m];
UBtoDF = UBtoDF_Move[UBtoDF, m];
if (URtoUL < 336 && UBtoDF < 336) // updated only if UR,UF,UL,UB,DR,DF
{
// are not in UD-slice
URtoDF = MergeURtoULandUBtoDF[URtoUL, UBtoDF];
}
}
// ******************************************Phase 1 move tables*****************************************************
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Move table for the twists of the corners
// twist < 2187 in phase 2.
// twist = 0 in phase 2.
internal static short[,] twistMove = CoordCubeTables.twist;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Move table for the flips of the edges
// flip < 2048 in phase 1
// flip = 0 in phase 2.
internal static short[,] flipMove = CoordCubeTables.flip;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Parity of the corner permutation. This is the same as the parity for the edge permutation of a valid cube.
// parity has values 0 and 1
internal static short[][] parityMove = new short[][]
{
new short[] {1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1},
new short[] {0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0}
};
// ***********************************Phase 1 and 2 movetable********************************************************
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Move table for the four UD-slice edges FR, FL, Bl and BR
// FRtoBRMove < 11880 in phase 1
// FRtoBRMove < 24 in phase 2
// FRtoBRMove = 0 for solved cube
internal static short[,] FRtoBR_Move = CoordCubeTables.FRtoBR;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Move table for permutation of six corners. The positions of the DBL and DRB corners are determined by the parity.
// URFtoDLF < 20160 in phase 1
// URFtoDLF < 20160 in phase 2
// URFtoDLF = 0 for solved cube.
internal static short[,] URFtoDLF_Move = CoordCubeTables.URFtoDLF;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Move table for the permutation of six U-face and D-face edges in phase2. The positions of the DL and DB edges are
// determined by the parity.
// URtoDF < 665280 in phase 1
// URtoDF < 20160 in phase 2
// URtoDF = 0 for solved cube.
internal static short[,] URtoDF_Move = CoordCubeTables.URtoDF;
// **************************helper move tables to compute URtoDF for the beginning of phase2************************
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Move table for the three edges UR,UF and UL in phase1.
internal static short[,] URtoUL_Move = CoordCubeTables.URtoUL;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Move table for the three edges UB,DR and DF in phase1.
internal static short[,] UBtoDF_Move = CoordCubeTables.UBtoDF;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Table to merge the coordinates of the UR,UF,UL and UB,DR,DF edges at the beginning of phase2
internal static short[,] MergeURtoULandUBtoDF = CoordCubeTables.MergeURtoULandUBtoDF;
// ****************************************Pruning tables for the search*********************************************
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Pruning table for the permutation of the corners and the UD-slice edges in phase2.
// The pruning table entries give a lower estimation for the number of moves to reach the solved cube.
internal static sbyte[] Slice_URFtoDLF_Parity_Prun = CoordCubeTables.Slice_URFtoDLF_Parity_Prun;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Pruning table for the permutation of the edges in phase2.
// The pruning table entries give a lower estimation for the number of moves to reach the solved cube.
internal static sbyte[] Slice_URtoDF_Parity_Prun = CoordCubeTables.Slice_URtoDF_Parity_Prun;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Pruning table for the twist of the corners and the position (not permutation) of the UD-slice edges in phase1
// The pruning table entries give a lower estimation for the number of moves to reach the H-subgroup.
internal static sbyte[] Slice_Twist_Prun = CoordCubeTables.Slice_Twist_Prun;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Pruning table for the flip of the edges and the position (not permutation) of the UD-slice edges in phase1
// The pruning table entries give a lower estimation for the number of moves to reach the H-subgroup.
internal static sbyte[] Slice_Flip_Prun = CoordCubeTables.Slice_Flip_Prun;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Set pruning value in table. Two values are stored in one byte.
internal static void setPruning(sbyte[] table, int index, sbyte value)
{
if ((index & 1) == 0)
{
table[index / 2] &= unchecked((sbyte)(0xf0 | value));
}
else
{
table[index / 2] &= (sbyte)(0x0f | (value << 4));
}
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Extract pruning value
internal static sbyte getPruning(sbyte[] table, int index)
{
if ((index & 1) == 0)
{
return (sbyte)(table[index / 2] & 0x0f);
}
else
{
return (sbyte)((int)((uint)(table[index / 2] & 0xf0) >> 4));
}
}
}
public static class CoordCubeTables
{
// Movement
public static readonly short[,] twist = Tools.DeserializeTable("twist");
public static readonly short[,] flip = Tools.DeserializeTable("flip");
public static readonly short[,] FRtoBR = Tools.DeserializeTable("FRtoBR");
public static readonly short[,] URFtoDLF = Tools.DeserializeTable("URFtoDLF");
public static readonly short[,] URtoDF = Tools.DeserializeTable("URtoDF");
public static readonly short[,] URtoUL = Tools.DeserializeTable("URtoUL");
public static readonly short[,] UBtoDF = Tools.DeserializeTable("UBtoDF");
public static readonly short[,] MergeURtoULandUBtoDF = Tools.DeserializeTable("MergeURtoULandUBtoDF");
//Prune
public static readonly sbyte[] Slice_URFtoDLF_Parity_Prun = Tools.DeserializeSbyteArray("Slice_URFtoDLF_Parity_Prun");
public static readonly sbyte[] Slice_URtoDF_Parity_Prun = Tools.DeserializeSbyteArray("Slice_URtoDF_Parity_Prun");
public static readonly sbyte[] Slice_Twist_Prun = Tools.DeserializeSbyteArray("Slice_Twist_Prun");
public static readonly sbyte[] Slice_Flip_Prun = Tools.DeserializeSbyteArray("Slice_Flip_Prun");
}
}
This diff is collapsed.
This diff is collapsed.
namespace Kociemba
{
/**
* <pre>
* The names of the facelet positions of the cube
* |************|
* |*U1**U2**U3*|
* |************|
* |*U4**U5**U6*|
* |************|
* |*U7**U8**U9*|
* |************|
* ************|************|************|************|
* *L1**L2**L3*|*F1**F2**F3*|*R1**R2**F3*|*B1**B2**B3*|
* ************|************|************|************|
* *L4**L5**L6*|*F4**F5**F6*|*R4**R5**R6*|*B4**B5**B6*|
* ************|************|************|************|
* *L7**L8**L9*|*F7**F8**F9*|*R7**R8**R9*|*B7**B8**B9*|
* ************|************|************|************|
* |************|
* |*D1**D2**D3*|
* |************|
* |*D4**D5**D6*|
* |************|
* |*D7**D8**D9*|
* |************|
* </pre>
*
*A cube definition string "UBL..." means for example: In position U1 we have the U-color, in position U2 we have the
* B-color, in position U3 we have the L color etc. according to the order U1, U2, U3, U4, U5, U6, U7, U8, U9, R1, R2,
* R3, R4, R5, R6, R7, R8, R9, F1, F2, F3, F4, F5, F6, F7, F8, F9, D1, D2, D3, D4, D5, D6, D7, D8, D9, L1, L2, L3, L4,
* L5, L6, L7, L8, L9, B1, B2, B3, B4, B5, B6, B7, B8, B9 of the enum constants.
*/
public enum Facelet
{
U1, U2, U3, U4, U5, U6, U7, U8, U9, R1, R2, R3, R4, R5, R6, R7, R8, R9, F1, F2, F3, F4, F5, F6, F7, F8, F9, D1, D2, D3, D4, D5, D6, D7, D8, D9, L1, L2, L3, L4, L5, L6, L7, L8, L9, B1, B2, B3, B4, B5, B6, B7, B8, B9
}
//++++++++++++++++++++++++++++++ Names the colors of the cube facelets ++++++++++++++++++++++++++++++++++++++++++++++++
public enum CubeColor
{
U, R, F, D, L, B
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//The names of the corner positions of the cube. Corner URF e.g., has an U(p), a R(ight) and a F(ront) facelet
public enum Corner
{
URF, UFL, ULB, UBR, DFR, DLF, DBL, DRB
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Then names of the edge positions of the cube. Edge UR e.g., has an U(p) and R(ight) facelet.
public enum Edge
{
UR, UF, UL, UB, DR, DF, DL, DB, FR, FL, BL, BR
}
}
using System;
namespace Kociemba
{
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Cube on the facelet level
public class FaceCube
{
public CubeColor[] f = new CubeColor[54];
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Map the corner positions to facelet positions. cornerFacelet[URF.ordinal()][0] e.g. gives the position of the
// facelet in the URF corner position, which defines the orientation.<br>
// cornerFacelet[URF.ordinal()][1] and cornerFacelet[URF.ordinal()][2] give the position of the other two facelets
// of the URF corner (clockwise).
public static Facelet[][] cornerFacelet = new Facelet[][] {
new Facelet[] { Facelet.U9, Facelet.R1, Facelet.F3 },
new Facelet[] { Facelet.U7, Facelet.F1, Facelet.L3 },
new Facelet[] { Facelet.U1, Facelet.L1, Facelet.B3 },
new Facelet[] { Facelet.U3, Facelet.B1, Facelet.R3 },
new Facelet[] { Facelet.D3, Facelet.F9, Facelet.R7 },
new Facelet[] { Facelet.D1, Facelet.L9, Facelet.F7 },
new Facelet[] { Facelet.D7, Facelet.B9, Facelet.L7 },
new Facelet[] { Facelet.D9, Facelet.R9, Facelet.B7 }
};
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Map the edge positions to facelet positions. edgeFacelet[UR.ordinal()][0] e.g. gives the position of the facelet in
// the UR edge position, which defines the orientation.<br>
// edgeFacelet[UR.ordinal()][1] gives the position of the other facelet
public static Facelet[][] edgeFacelet = new Facelet[][]{
new Facelet[] { Facelet.U6, Facelet.R2 },
new Facelet[] { Facelet.U8, Facelet.F2 },
new Facelet[] { Facelet.U4, Facelet.L2 },
new Facelet[] { Facelet.U2, Facelet.B2 },
new Facelet[] { Facelet.D6, Facelet.R8 },
new Facelet[] { Facelet.D2, Facelet.F8 },
new Facelet[] { Facelet.D4, Facelet.L8 },
new Facelet[] { Facelet.D8, Facelet.B8 },
new Facelet[] { Facelet.F6, Facelet.R4 },
new Facelet[] { Facelet.F4, Facelet.L6 },
new Facelet[] { Facelet.B6, Facelet.L4 },
new Facelet[] { Facelet.B4, Facelet.R6 }
};
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Map the corner positions to facelet CubeColors.
public static CubeColor[][] cornerColor = new CubeColor[][]{
new CubeColor[] { CubeColor.U, CubeColor.R, CubeColor.F },
new CubeColor[] { CubeColor.U, CubeColor.F, CubeColor.L },
new CubeColor[] { CubeColor.U, CubeColor.L, CubeColor.B },
new CubeColor[] { CubeColor.U, CubeColor.B, CubeColor.R },
new CubeColor[] { CubeColor.D, CubeColor.F, CubeColor.R },
new CubeColor[] { CubeColor.D, CubeColor.L, CubeColor.F },
new CubeColor[] { CubeColor.D, CubeColor.B, CubeColor.L },
new CubeColor[] { CubeColor.D, CubeColor.R, CubeColor.B }
};
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Map the edge positions to facelet CubeColors.
public static CubeColor[][] edgeColor = new CubeColor[][]{
new CubeColor[] { CubeColor.U, CubeColor.R },
new CubeColor[] { CubeColor.U, CubeColor.F },
new CubeColor[] { CubeColor.U, CubeColor.L },
new CubeColor[] { CubeColor.U, CubeColor.B },
new CubeColor[] { CubeColor.D, CubeColor.R },
new CubeColor[] { CubeColor.D, CubeColor.F },
new CubeColor[] { CubeColor.D, CubeColor.L },
new CubeColor[] { CubeColor.D, CubeColor.B },
new CubeColor[] { CubeColor.F, CubeColor.R },
new CubeColor[] { CubeColor.F, CubeColor.L },
new CubeColor[] { CubeColor.B, CubeColor.L },
new CubeColor[] { CubeColor.B, CubeColor.R }
};
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public FaceCube()
{
string s = "UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB";
for (int i = 0; i < 54; i++)
{
CubeColor col = (CubeColor)Enum.Parse(typeof(CubeColor), s[i].ToString());
f[i] = col;
}
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Construct a facelet cube from a string
public FaceCube(string cubeString)
{
for (int i = 0; i < cubeString.Length; i++)
{
CubeColor col = (CubeColor)Enum.Parse(typeof(CubeColor), cubeString[i].ToString());
f[i] = col;
}
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Gives string representation of a facelet cube
public string to_fc_String()
{
string s = "";
for (int i = 0; i < 54; i++)
s += f[i].ToString();
return s;
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Gives CubieCube representation of a faceletcube
public CubieCube toCubieCube()
{
byte ori;
CubieCube ccRet = new CubieCube();
for (int i = 0; i < 8; i++)
ccRet.cp[i] = Corner.URF;// invalidate corners
for (int i = 0; i < 12; i++)
ccRet.ep[i] = Edge.UR;// and edges
CubeColor col1, col2;
foreach (Corner i in (Corner[])Enum.GetValues(typeof(Corner)))
{
// get the CubeColors of the cubie at corner i, starting with U/D
for (ori = 0; ori < 3; ori++)
if (f[(int)cornerFacelet[(int)i][ori]] == CubeColor.U || f[(int)cornerFacelet[(int)i][ori]] == CubeColor.D)
break;
col1 = f[(int)cornerFacelet[(int)i][(ori + 1) % 3]];
col2 = f[(int)cornerFacelet[(int)i][(ori + 2) % 3]];
foreach (Corner j in (Corner[])Enum.GetValues(typeof(Corner)))
{
if (col1 == cornerColor[(int)j][1] && col2 == cornerColor[(int)j][2])
{
// in cornerposition i we have cornercubie j
ccRet.cp[(int)i] = j;
ccRet.co[(int)i] = (byte)(ori % 3);
break;
}
}
}
foreach (Edge i in (Edge[])Enum.GetValues(typeof(Edge)))
foreach (Edge j in (Edge[])Enum.GetValues(typeof(Edge)))
{
if (f[(int)edgeFacelet[(int)i][0]] == edgeColor[(int)j][0]
&& f[(int)edgeFacelet[(int)i][1]] == edgeColor[(int)j][1])
{
ccRet.ep[(int)i] = j;
ccRet.eo[(int)i] = 0;
break;
}
if (f[(int)edgeFacelet[(int)i][0]] == edgeColor[(int)j][1]
&& f[(int)edgeFacelet[(int)i][1]] == edgeColor[(int)j][0])
{
ccRet.ep[(int)i] = j;
ccRet.eo[(int)i] = 1;
break;
}
}
return ccRet;
}
//public Cube toCube()
//{
// byte ori;
// Cube ccRet = new Cube();
// for (int i = 0; i < 8; i++)
// ccRet.cp[i] = Corner.URF;// invalidate corners
// for (int i = 0; i < 12; i++)
// ccRet.ep[i] = Edge.UR;// and edges
// CubeColor col1, col2;
// foreach (Corner i in (Corner[])Enum.GetValues(typeof(Corner)))
// {
// // get the CubeColors of the cubie at corner i, starting with U/D
// for (ori = 0; ori < 3; ori++)
// if (f[(int)cornerFacelet[(int)i][ori]] == CubeColor.U || f[(int)cornerFacelet[(int)i][ori]] == CubeColor.D)
// break;
// col1 = f[(int)cornerFacelet[(int)i][(ori + 1) % 3]];
// col2 = f[(int)cornerFacelet[(int)i][(ori + 2) % 3]];
// foreach (Corner j in (Corner[])Enum.GetValues(typeof(Corner)))
// {
// if (col1 == cornerColor[(int)j][1] && col2 == cornerColor[(int)j][2])
// {
// // in cornerposition i we have cornercubie j
// ccRet.cp[(int)i] = j;
// ccRet.co[(int)i] = (byte)(ori % 3);
// break;
// }
// }
// }
// foreach (Edge i in (Edge[])Enum.GetValues(typeof(Edge)))
// foreach (Edge j in (Edge[])Enum.GetValues(typeof(Edge)))
// {
// if (f[(int)edgeFacelet[(int)i][0]] == edgeColor[(int)j][0]
// && f[(int)edgeFacelet[(int)i][1]] == edgeColor[(int)j][1])
// {
// ccRet.ep[(int)i] = j;
// ccRet.eo[(int)i] = 0;
// break;
// }
// if (f[(int)edgeFacelet[(int)i][0]] == edgeColor[(int)j][1]
// && f[(int)edgeFacelet[(int)i][1]] == edgeColor[(int)j][0])
// {
// ccRet.ep[(int)i] = j;
// ccRet.eo[(int)i] = 1;
// break;
// }
// }
// return ccRet;
//}
}
}
using System;
namespace Kociemba
{
public class Search
{
internal static int[] ax = new int[31]; // The axis of the move
internal static int[] po = new int[31]; // The power of the move
internal static int[] flip = new int[31]; // phase1 coordinates
internal static int[] twist = new int[31];
internal static int[] slice = new int[31];
internal static int[] parity = new int[31]; // phase2 coordinates
internal static int[] URFtoDLF = new int[31];
internal static int[] FRtoBR = new int[31];
internal static int[] URtoUL = new int[31];
internal static int[] UBtoDF = new int[31];
internal static int[] URtoDF = new int[31];
internal static int[] minDistPhase1 = new int[31]; // IDA* distance do goal estimations
internal static int[] minDistPhase2 = new int[31];
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// generate the solution string from the array data
internal static string solutionToString(int length)
{
string s = "";
for (int i = 0; i < length; i++)
{
switch (ax[i])
{
case 0:
s += "U";
break;
case 1:
s += "R";
break;
case 2:
s += "F";
break;
case 3:
s += "D";
break;
case 4:
s += "L";
break;
case 5:
s += "B";
break;
}
switch (po[i])
{
case 1:
s += " ";
break;
case 2:
s += "2 ";
break;
case 3:
s += "' ";
break;
}
}
return s;
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// generate the solution string from the array data including a separator between phase1 and phase2 moves
internal static string solutionToString(int length, int depthPhase1)
{
string s = "";
for (int i = 0; i < length; i++)
{
switch (ax[i])
{
case 0:
s += "U";
break;
case 1:
s += "R";
break;
case 2:
s += "F";
break;
case 3:
s += "D";
break;
case 4:
s += "L";
break;
case 5:
s += "B";
break;
}