コード例 #1
0
    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);
    }
コード例 #2
0
    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));
        }
    }
コード例 #3
0
    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);
    }
コード例 #4
0
    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");
    }
コード例 #5
0
ファイル: CubeTaskSolver.cs プロジェクト: alinen/cube
    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);
    }
コード例 #6
0
    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
        }
    }
コード例 #7
0
    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"));
    }
コード例 #8
0
ファイル: CubeTaskSolver.cs プロジェクト: alinen/cube
    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);
    }
コード例 #9
0
    void FocusCubie(CubeInfo.Cubie cubie)
    {
        Debug.Log("FIX CUBIE: " + cubie.id);
        LookAt camera = Camera.main.GetComponent <LookAt>();

        if (camera != null)
        {
            camera.SetTarget(cubie.transform);
        }
    }
コード例 #10
0
    // 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);
    }
コード例 #11
0
    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);
    }
コード例 #12
0
    // 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);
    }
コード例 #13
0
    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);
    }
コード例 #14
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);
    }
コード例 #15
0
    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");
    }
コード例 #16
0
    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);
    }
コード例 #17
0
    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));
        }
    }
コード例 #18
0
 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);
 }
コード例 #19
0
ファイル: CubeTaskSolver.cs プロジェクト: alinen/cube
    // 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);
    }
コード例 #20
0
    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);
    }
コード例 #21
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);
    }