bool SolveTopCorner_CaseTop(CubeInfo.Cubie cubie, ref List <string> path) { ArrayList steps = new ArrayList(); string[] sides = { "L", "L'", "R", "R'", "F", "F'", "B", "B'" }; string[] down = { "D", "D'", "D2", "" }; string[] D2 = { "D2" }; string[] reverse = { "X" }; steps.Add(sides); steps.Add(D2); steps.Add(reverse); // reverse level0 steps.Add(down); steps.Add(sides); steps.Add(down); steps.Add(reverse); // reverse level0 path = _solver.Search(cubie, _solved, steps, _solver.ScoreSolved); if (path.Count != 0) { _solved.Add(cubie); } return(_solved.Count >= 8); }
bool SolveTopCorners(ref List <string> path) { CubeInfo.Cubie cubie = null; List <CubeInfo.Cubie> topCornerCubes = _cubies.AnalyzeTopCorner(ref cubie, _solved); if (cubie == null) { return(true); // no work to do! } FocusCubie(cubie); _cubies.EnableColor(cubie, true); // case 1: no work to do -> no work to do, return // case 2: cube is in top row, but wrong pos or ori // case 3: cube is in middle row // case 4: cube is in bottom row if (cubie.state == (CubeInfo.POS | CubeInfo.ORI)) { _solved.Add(cubie); return(_solved.Count >= 8); // this hard-codes the order of steps (middle first => 4 cubes, corner next => 8 cubes) } if (cubie.level == CubeInfo.TOP) { return(SolveTopCorner_CaseTop(cubie, ref path)); } else { return(SolveTopCorner_CaseBottom(cubie, ref path)); } }
bool SolveTopCorner_CaseBottom(CubeInfo.Cubie cubie, ref List <string> path) { ArrayList steps = new ArrayList(); string[] down = { "D", "D'", "D2", "" }; string[] sides = { "L", "L'", "R", "R'", "F", "F'", "B", "B'" }; string[] D2 = { "D2" }; string[] reverse = { "X" }; if (_cubies.FacingDown(cubie)) { Debug.Log("FACING DOWN"); steps.Add(down); steps.Add(sides); steps.Add(D2); steps.Add(reverse); } steps.Add(down); steps.Add(sides); steps.Add(down); steps.Add(reverse); path = _solver.Search(cubie, _solved, steps, _solver.ScoreSolved); if (path.Count != 0) { _solved.Add(cubie); } return(_solved.Count >= 8); }
void Test2() { _cubies.Reset(); _cube.turn("F2"); CubeInfo.Cubie cubie = null; List <CubeInfo.Cubie> list = _cubies.FindTopMiddle(); foreach (CubeInfo.Cubie c in list) { if (_cubies.BottomRow(c)) { cubie = c; break; } } List <string> path = new List <string>(); SolveTopMiddle_CaseBottom(cubie, ref path); string s = PathToString(path); Debug.Log("Run Test1: " + s); Debug.Assert(s == "F2"); }
public int ScorePositions(CubeInfo.Cubie cubie, List <CubeInfo.Cubie> constraints) { bool requirements = cubie != null?_cubies.CorrectPos(cubie) : true; for (int i = 0; i < constraints.Count && requirements; i++) { CubeInfo.Cubie info = constraints[i] as CubeInfo.Cubie; if (!_cubies.IsSolved(info)) { requirements = false; } } if (!requirements) { return(0); } int score = 0; for (int i = 0; i < _cubies.GetNumCubes(); i++) { CubeInfo.Cubie info = _cubies.GetCubeInfo(i); if (_cubies.CorrectPos(info)) { score++; } } return(score); }
bool SolveMiddleMiddles(ref List <string> path) { CubeInfo.Cubie cubie = null; List <CubeInfo.Cubie> middleMiddleCubes = _cubies.AnalyzeMiddleMiddle(ref cubie, _solved); if (cubie == null) { return(true); // no work to do! } FocusCubie(cubie); _cubies.EnableColor(cubie, true); // case 1: no work to do -> no work to do, return // case 2: cube is in top row, but wrong pos or ori // case 3: cube is in middle row // case 4: cube is in bottom row if (cubie.state == (CubeInfo.POS | CubeInfo.ORI)) { _solved.Add(cubie); return(_solved.Count >= 8); // this hard-codes the order of steps (middle first => 4 cubes, corner next => 8 cubes) } if (cubie.level == CubeInfo.BOT) { return(SolveMiddleMiddle_CaseBottom(cubie, ref path)); } else { Debug.Log("MiddleMiddle cubie right position; wrong ori -> moving to bottom"); return(SolveMiddleMiddle_CaseMiddle(cubie, ref path)); // move to bottom and then solve } }
void Start() { _cube.init(transform); _cubies.init(transform); _solver.init(_cubies, _cube); if (startState == "Random") { string[] choices = { "F", "F", "F2", "B", "B", "B2", "R", "R", "R2", "L", "L", "L2", "U", "U", "U2", "D", "D", "D2" }; int maxMoves = 10; System.Random random = new System.Random(); for (int i = 0; i < maxMoves; i++) { int idx = random.Next(0, choices.Length); string cmd = choices[idx]; _cube.turn(cmd); Debug.Log(cmd); } } else { char[] delimiterChars = { ' ' }; string[] words = startState.Split(delimiterChars); for (int w = 0; w < words.Length; w++) { string word = words[w]; _cube.turn(word); } } for (int i = 0; i < _cubies.GetNumCubes(); i++) { CubeInfo.Cubie cubie = _cubies.GetCubeInfo(i); if (_cubies.IsCenterCube(i)) { _cubies.EnableColor(cubie, true); } else { _cubies.EnableColor(cubie, false); } } _tasks.Add(new CubeTask(SolveTopMiddle, _cubies.TopMiddleSolved, "top row", "middle cubes")); _tasks.Add(new CubeTask(SolveTopCorners, _cubies.TopCornersSolved, "top row", "corner cubes")); _tasks.Add(new CubeTask(SolveMiddleMiddles, _cubies.MiddleMiddleSolved, "middle row", "middle cubes")); _tasks.Add(new CubeTask(SolveOneCornerPosition, _cubies.BottomOneCornerCorrect, "bottom row", "choose anchor corner")); _tasks.Add(new CubeTask(SolveBottomCornerPositions, _cubies.BottomCornersCorrectPositions, "bottom row", "corner cube positions")); _tasks.Add(new CubeTask(SolveBottomMiddlePositions, _cubies.BottomMiddlesCorrectPositions, "bottom row", "middle cube positions")); _tasks.Add(new CubeTask(SolveBottomCornerOri, _cubies.BottomCornersCorrectOri, "bottom row", "twirl corners")); _tasks.Add(new CubeTask(SolveBottomMiddleOri, _cubies.BottomMiddlesCorrectOri, "bottom row", "flip middles")); }
public List <string> Search(CubeInfo.Cubie c, List <CubeInfo.Cubie> constraints, ArrayList steps, ScoreStateFn scoreFn) { List <string> path = new List <string>(); List <string> best = new List <string>(); int s = Search(c, constraints, steps, 0, scoreFn, ref path, ref best); return(best); }
void FocusCubie(CubeInfo.Cubie cubie) { Debug.Log("FIX CUBIE: " + cubie.id); LookAt camera = Camera.main.GetComponent <LookAt>(); if (camera != null) { camera.SetTarget(cubie.transform); } }
// Check for out of place top middle cubes and pick one to solve // Ignore the cubes in constraints, because we know these are solved already public List <Cubie> AnalyzeTopMiddle(ref CubeInfo.Cubie cubeToFix, List <Cubie> constraints) { int bestScore = 0; cubeToFix = null; List <Cubie> topMiddle = FindTopMiddle(); foreach (Cubie c in topMiddle) { c.score = 0; if (Contains(constraints, c)) { continue; } if (CorrectPos(c)) { c.score += 2; c.state = c.state | POS; } if (CorrectOri(c)) { c.score += 2; c.state = c.state | ORI; } if (TopRow(c)) { c.score += 2; c.level = TOP; } else if (MiddleRow(c)) { c.score += 1; c.level = MID; } else { c.score += 1; c.level = BOT; } if (c.score > bestScore) { bestScore = c.score; cubeToFix = c; } } return(topMiddle); }
bool SolveTopMiddle_CaseMiddle(CubeInfo.Cubie cubie, ref List <string> path) { ArrayList steps = new ArrayList(); string[] level0 = { "U", "U'", "U2", "" }; string[] level1 = { "L", "L'", "R", "R'", "F", "F'", "B", "B'" }; steps.Add(level0); steps.Add(level1); steps.Add(level0); path = _solver.Search(cubie, _solved, steps, _solver.ScoreSolved); if (path.Count != 0) { _solved.Add(cubie); } return(_solved.Count >= 4); }
// return true if the bottom corners are in the correct order public bool BottomCornersSorted() { List <Cubie> bottomCorner = FindBottomCorners(); CubeInfo.Cubie RB = bottomCorner.Find(x => RightBack(x)); CubeInfo.Cubie BL = bottomCorner.Find(x => BackLeft(x)); CubeInfo.Cubie LF = bottomCorner.Find(x => LeftFront(x)); CubeInfo.Cubie FR = bottomCorner.Find(x => FrontRight(x)); List <Cubie> clockwise = new List <Cubie>(4); clockwise.Add(RB); clockwise.Add(BL); clockwise.Add(LF); clockwise.Add(FR); bool sorted = CorrectCornerOrder(clockwise); return(sorted); }
bool SolveOneCornerPosition(ref List <string> path) { CubeInfo.Cubie cubie = null; List <CubeInfo.Cubie> bottom = _cubies.AnalyzeBottomCorners(ref cubie, _solved); if (cubie == null) { return(true); // no work to do } FocusCubie(cubie); _cubies.EnableColor(cubie, true); string[] down = { "D", "D'", "D2", "" }; ArrayList steps = new ArrayList(); steps.Add(down); path = _solver.Search(cubie, _solved, steps, _solver.ScorePositions); return(path.Count > 0); }
bool SolveMiddleMiddle_CaseBottom(CubeInfo.Cubie cubie, ref List <string> path) { ArrayList steps = new ArrayList(); string[] down = { "D", "D'", "D2", "" }; string[] sequences = { "D' L' D L D B D' B'", "D' R' D R D F D' F'", "D' B' D B D R D' R'", "D' F' D F D L D' L'", "D R D' R' D' B' D B", "D F D' F' D' R' D R", "D L D' L' D' F' D F", "D B D' B' D' L' D L" }; // ASN TODO: We know the sequence if we analyze the cube more closely foreach (string seqn in sequences) { steps.Clear(); steps.Add(down); string[] words = seqn.Split(); foreach (string word in words) { string[] tmp = { word }; steps.Add(tmp); } path = _solver.Search(cubie, _solved, steps, _solver.ScoreSolved); if (path.Count > 0) { break; } } if (path.Count != 0) { _solved.Add(cubie); } return(_solved.Count >= 12); }
void Test(string cmd) { _cubies.Reset(); _cube.SortCubeGroups(); string[] words = cmd.Split(); foreach (string word in words) { _cube.turn(word); } CubeInfo.Cubie cubie = null; List <CubeInfo.Cubie> list = _cubies.FindTopCorners(); foreach (CubeInfo.Cubie c in list) { if (_cubies.BottomRow(c)) { cubie = c; break; } } Debug.Assert(cubie != null); List <string> path = new List <string>(); SolveTopCorner_CaseBottom(cubie, ref path); string s = PathToString(path); Debug.Log("Run Test1: " + s); words = s.Split(); foreach (string word in words) { _cube.turn(word); } Debug.Assert(_cubies.IsSolved(cubie)); //Debug.Assert(s == "D' R D R"); }
bool SolveTopMiddle_CaseBottom(CubeInfo.Cubie cubie, ref List <string> path) { ArrayList steps = new ArrayList(); string[] level0 = { "D", "D'", "D2", "" }; string[] level10 = { "L2", "R2", "F2", "B2" }; steps.Add(level0); steps.Add(level10); path = _solver.Search(cubie, _solved, steps, _solver.ScoreSolved); if (path.Count == 0) // try other case { string[] level11 = { "L", "L'", "R", "R'", "F", "F'", "B", "B'" }; string[] level2 = { "U", "U'", "U2", "" }; string[] level3 = { "L", "L'", "R", "R'", "F", "F'", "B", "B'", "" }; steps.Clear(); steps.Add(level0); steps.Add(level11); steps.Add(level2); steps.Add(level3); steps.Add(level3); path = _solver.Search(cubie, _solved, steps, _solver.ScoreSolved); } if (path.Count != 0) { _solved.Add(cubie); } return(_solved.Count >= 4); }
bool SolveTopMiddle(ref List <string> path) { CubeInfo.Cubie cubie = null; List <CubeInfo.Cubie> topMiddleCubes = _cubies.AnalyzeTopMiddle(ref cubie, _solved); if (cubie == null) { return(true); // no work to do! } FocusCubie(cubie); _cubies.EnableColor(cubie, true); // case 1: no work to do -> no work to do, return // case 2: cube is in top row, but wrong pos or ori // case 3: cube is in middle row // case 4: cube is in bottom row if (cubie.state == (CubeInfo.POS | CubeInfo.ORI)) { _solved.Add(cubie); return(_solved.Count >= 4); } if (cubie.level == CubeInfo.TOP) { return(SolveTopMiddle_CaseTop(cubie, ref path)); } else if (cubie.level == CubeInfo.MID) { return(SolveTopMiddle_CaseMiddle(cubie, ref path)); } else { return(SolveTopMiddle_CaseBottom(cubie, ref path)); } }
bool SolveMiddleMiddle_CaseMiddle(CubeInfo.Cubie cubie, ref List <string> path) { if (_cubies.FrontRight(cubie)) { string[] seqn = { "F", "D'", "F'", "D'", "R'", "D", "R" }; path.AddRange(seqn); } else if (_cubies.RightBack(cubie)) { string[] seqn = { "R", "D'", "R'", "D'", "B'", "D", "B" }; path.AddRange(seqn); } else if (_cubies.BackLeft(cubie)) { string[] seqn = { "B", "D'", "B'", "D'", "L'", "D", "L" }; path.AddRange(seqn); } else if (_cubies.LeftFront(cubie)) { string[] seqn = { "L", "D'", "L'", "D'", "F'", "D", "F" }; path.AddRange(seqn); } return(false); }
// Solve for cubie given the passed constraints private int Search(CubeInfo.Cubie c, List <CubeInfo.Cubie> constraints, ArrayList steps, int stepNum, ScoreStateFn scoreFn, ref List <string> path, ref List <string> bestPath) { int score = scoreFn(c, constraints); if (stepNum >= steps.Count) { //Debug.Log(" score " + score + " " + path[0]); if (score > 0) { // bonus for empty moves (e.g. fewer moves is better) foreach (string s in path) { if (s == "") { score += 10; } } //string spath = ""; //foreach (string s in path) spath += s + " "; //Debug.Log("SCORE " + score + " " + spath + " " + path.Count); } bestPath = new List <string>(path); return(score); } string[] turns = (string[])steps[stepNum]; for (int i = 0; i < turns.Length; i++) { List <Transform> list = new List <Transform>(); Vector3 center = new Vector3(0, 0, 0); Vector3 axis = new Vector3(0, 0, 0); float amount = 0.0f; string turn = turns[i]; if (turn != "") { if (turn == "X") { turn = _cube.Reverse((string)path[path.Count - 2]); } _cube.CmdToTurn(turn, out list, out center, out axis, out amount); _cube.turn(list, center, axis, amount); // un-apply move } path.Add(turn); List <string> bestChild = new List <string>(); int tmp = Search(c, constraints, steps, stepNum + 1, scoreFn, ref path, ref bestChild); if (tmp > score) { score = tmp; bestPath = new List <string>(bestChild); } if (turn != "") { _cube.turn(list, center, axis, -amount); // un-apply move } path.RemoveAt(path.Count - 1); } return(score); }
bool SolveBottomMiddleOri(ref List <string> path) { CubeInfo.Cubie cubie = null; List <CubeInfo.Cubie> bottom = _cubies.AnalyzeBottomMiddleOri(ref cubie, _solved); if (cubie == null) { return(true); // no work to do } for (int i = 0; i < _cubies.GetNumCubes(); i++) { CubeInfo.Cubie c = _cubies.GetCubeInfo(i); if (!_cubies.IsCenterCube(i) && !_cubies.BottomRow(c)) { _cubies.EnableColor(c, false); } else { _cubies.EnableColor(c, true); } } foreach (CubeInfo.Cubie c in bottom) { if (!_cubies.IsSolved(c)) { FocusCubie(c); break; } } string[] down = { "D", "D'", "D2", "" }; string[] seqnA = { "F U' D R2 U2 D2 L", "L U' D F2 U2 D2 B", "B U' D L2 U2 D2 R", "R U' D B2 U2 D2 F" }; string[] seqnB = { "L' D2 U2 R2 D' U F'", "B' D2 U2 F2 D' U L'", "R' D2 U2 L2 D' U B'", "F' D2 U2 B2 D' U R'" }; ArrayList steps = new ArrayList(); for (int i = 0; i < seqnA.Length; i++) { steps.Clear(); string[] words = seqnA[i].Split(); foreach (string word in words) { string[] tmp = { word }; steps.Add(tmp); } steps.Add(down); words = seqnB[i].Split(); foreach (string word in words) { string[] tmp = { word }; steps.Add(tmp); } steps.Add(down); path = _solver.Search(cubie, _solved, steps, _solver.ScoreSolved); if (path.Count > 0) { break; } } return(path.Count > 0); }
bool SolveBottomCornerOri(ref List <string> path) { CubeInfo.Cubie cubie = null; List <CubeInfo.Cubie> bottom = _cubies.AnalyzeBottomCornerOri(ref cubie, _solved); if (cubie == null) { return(true); // no work to do } for (int i = 0; i < _cubies.GetNumCubes(); i++) { if (!_cubies.IsCenterCube(i)) { _cubies.EnableColor(_cubies.GetCubeInfo(i), false); } } foreach (CubeInfo.Cubie c in bottom) { if (_cubies.IsSolved(c)) { _cubies.EnableColor(c, true); FocusCubie(c); } } string[] down = { "D", "D'", "D2", "" }; string[] seqnA = { "B' U B L U L'", "R' U R B U B'", "F' U F R U R'", "L' U L F U F'" }; string[] seqnB = { "L U' L' B' U' B", "B U' B' R' U' R", "R U' R' F' U' F", "F U' F' L' U' L" }; ArrayList steps = new ArrayList(); for (int i = 0; i < seqnA.Length; i++) { steps.Clear(); string[] words = seqnA[i].Split(); foreach (string word in words) { string[] tmp = { word }; steps.Add(tmp); } steps.Add(down); words = seqnB[i].Split(); foreach (string word in words) { string[] tmp = { word }; steps.Add(tmp); } steps.Add(down); path = _solver.Search(cubie, _solved, steps, _solver.ScoreSolved); if (path.Count > 0) { break; } } return(path.Count > 0); }