public BaseSolver(Cube cube) { this.Cube = cube; this.Turns = new List<Turn>(); this.Description = new List<string>(); Clear(); }
/// <summary> /// This test shows that either the cube is solved and had no parity OR the UF BD cubies are swapped and it had parity /// </summary> /// <param name="solver"></param> /// <param name="cube"></param> /// <returns></returns> static int GetState(SolverM2 solver, Cube cube) { var state = cube.IsSolved() ? StateSolved : StateNotSolved; state += (solver.HasParity ? StateHasParity : 0); var cubie = cube[Sticker.sUF]; if (cubie.Type != Sticker.sUF) { state += StateUFBDSwapped; } return state; }
static void M2Stats() { var totalSolves = 1000; var cube = new Cube(); var solver = new SolverM2(cube); var states = new Dictionary<int, int>(); for (int i = 0; i < totalSolves; ++i) { cube.Reset(); var seed = DateTime.Now.Ticks; var scrambleSequence = cube.Scramble(20+(int)(seed % 20), (int)seed); cube.Apply(scrambleSequence); solver.Solve(SolverM2.M2SolveMode.CornersParityEdges); var state = GetState(solver, cube); if (states.ContainsKey(state)) { states[state]++; } else { states[state] = 1; } //if (state != 0 && state != 1 && state != 11 && state != 19) //{ // Console.WriteLine("FAIL"); // Console.WriteLine("Seed: {0}", seed); // Console.Write("Seq: "); // foreach (var turn in scrambleSequence) // { // Console.Write(turn); Console.Write(" "); // } // Console.WriteLine(); // Console.WriteLine("Parity: {0}", solver.HasParity ? "yes" : "no"); // solver.Describe(); // break; //} } Console.WriteLine(); Console.WriteLine("STATS"); foreach (int key in states.Keys) { Console.WriteLine("Key {0} = {1} times", key, states[key]); } }
public SolverClassic(Cube cube) : base(cube) { }
public static void Fix(Cube cube, Sticker[] allStickers, Sticker bufferPosition, Action<OSticker> addStickerSequence) { Sticker? cycleHead = null; var stickersLeft = new List<Sticker>(allStickers); OSticker? next = null; bool atCycleHead = true; do { if (next.HasValue) { if (cycleHead.HasValue || next.Value.Sticker() != bufferPosition) { addStickerSequence(next.Value); } if ( (!cycleHead.HasValue && next.Value.Sticker() == bufferPosition) || (cycleHead.HasValue && !atCycleHead && next.Value.Sticker() == cycleHead.Value)) { if (stickersLeft.Count() == 0) { break; } // Find new path start cycleHead = null; do { if (cycleHead.HasValue) { stickersLeft.Remove(next.Value.Sticker()); if (stickersLeft.Count() == 0) { break; } } cycleHead = stickersLeft.First(); atCycleHead = true; next = cycleHead.Value.PrimarySticker(); } while (cube[next.Value.Sticker()].Type == cycleHead && cube[next.Value.Sticker()].IsCorrect); if (stickersLeft.Count() == 0) { break; } continue; } } else { next = bufferPosition.PrimarySticker(); } atCycleHead = false; stickersLeft.Remove(next.Value.Sticker()); next = cube[next.Value]; //var nextCubie = cube[next.Value.Sticker()]; //next = nextCubie.Oriented(next.Value); } while (true); }
public SolverM2(Cube cube) : base(cube) { }
static void TestMinMaxSteps() { var totalSolves = 3000; var cube = new Cube(); var solver = new SolverClassic(cube); var maxSteps = 0; var minSteps = 100000; var stepAverage = 0; Console.WriteLine("Performing {0} solves using {1}", totalSolves, solver); for (int i = 0; i < totalSolves; ++i) { cube.Reset(); var seed = DateTime.Now.Ticks; var scrambleSequence = cube.Scramble(25, (int)seed); cube.Apply(scrambleSequence); solver.Solve(); var steps = solver.TotalStepsWithoutParity; if (steps < minSteps) { minSteps = steps; } if (steps > maxSteps) { maxSteps = steps; } stepAverage += steps; if (i % 100 == 0) { Console.WriteLine(i); } } Console.WriteLine("Minimum number of steps in a solve: {0}", minSteps); Console.WriteLine("Maximum number of steps in a solve: {0}", maxSteps); Console.WriteLine("Average number of steps in a solve: {0:N2}", stepAverage / totalSolves); }
static void TestSolve(Func<Cube, ISolver> solverCreator) { var totalSolves = 100; var cube = new Cube(); var solver = solverCreator(cube); Console.WriteLine("Performing {0} solves using {1}", totalSolves, solver); for (int i = 0; i < totalSolves; ++i) { cube.Reset(); var seed = DateTime.Now.Ticks; var scrambleSequence = cube.Scramble(4+(int)(seed % 4), (int)seed); cube.Apply(scrambleSequence); solver.Solve(); if (!cube.IsSolved()) { Console.WriteLine("Not solved (seed={0})!", seed); Console.Write("Seq: "); foreach (var turn in scrambleSequence) { Console.Write(turn); Console.Write(" "); } Console.WriteLine(); solver.Describe(); break; } if (i % 100 == 0) { Console.WriteLine(i); } } }
/// <summary> /// This test shows that the cubie opposite the buffer (UB) always contains the right cubie rotated right! /// </summary> /// <param name="solver"></param> /// <param name="cube"></param> /// <returns></returns> static int GetStateOppositeBufferTest(SolverM2 solver, Cube cube) { var cubie = cube[Sticker.sUB]; if (cubie.Type == Sticker.sUB && !cubie.IsCorrect) { return StateBufferRotated; } else if (cubie.Type != Sticker.sUB) { return StateBufferWrong; } else return StateBufferOK; }
/// <summary> /// This test shows that the UF cubie is either correct or contains the DB cubie. either is 50-50 /// </summary> /// <param name="solver"></param> /// <param name="cube"></param> /// <returns></returns> static int GetStateUFTest(SolverM2 solver, Cube cube) { var cubie = cube[Sticker.sUF]; if (cubie.Type == Sticker.sUF && !cubie.IsCorrect) { return StateBufferRotated; } else if (cubie.Type != Sticker.sUF) { return (int)cubie.Type; } else return StateBufferOK; }
/// <summary> /// This test shows that when the DB cubie is not correct (that is contains the UF cubie) this cubie is always oriented 98 (rotated twice around x-axis) /// </summary> /// <param name="solver"></param> /// <param name="cube"></param> /// <returns></returns> static int GetStateDBOrientationTest(SolverM2 solver, Cube cube) { var cubie = cube[Sticker.sDB]; if (cubie.Type == Sticker.sDB && !cubie.IsCorrect) { return StateBufferRotated; } else if (cubie.Type != Sticker.sDB) { return (int)cubie.Orientation; } else return StateBufferOK; }