Example #1
0
    private void Init()
    {
        eSymmetryMode = ESymmetry.EOff;

        cs_Charges = Resources.Load <ComputeShader>("Shaders/cs_Charges");

        meshFilter   = GetComponent <MeshFilter>();
        meshRenderer = GetComponent <MeshRenderer>();
        meshCollider = GetComponent <MeshCollider>();
        if (meshFilter == null)
        {
            meshFilter = gameObject.AddComponent <MeshFilter>();
        }
        if (meshRenderer == null)
        {
            meshRenderer = gameObject.AddComponent <MeshRenderer>();
        }
        if (meshCollider == null)
        {
            meshCollider = gameObject.AddComponent <MeshCollider>();
        }
        mesh = meshFilter.sharedMesh;
        if (mesh == null)
        {
            mesh                  = new Mesh();
            mesh.indexFormat      = UnityEngine.Rendering.IndexFormat.UInt32;
            meshFilter.sharedMesh = mesh;
        }
        int x = Meta_CellEditor.SCULPTING.GRID.DIMENSION.X;
        int y = Meta_CellEditor.SCULPTING.GRID.DIMENSION.Y;
        int z = Meta_CellEditor.SCULPTING.GRID.DIMENSION.Z;

        meshGenerator = new MeshGenerator(mesh, new Vector3Int(x, y, z), transform, false);
        if (meshCollider.sharedMesh == null)
        {
            meshCollider.sharedMesh = mesh;
        }
        // force update
        meshCollider.enabled  = false;
        meshCollider.enabled  = true;
        meshRenderer.material = Resources.Load <Material>("Material/Shader Graphs_s_cell");
    }
Example #2
0
    private List <Node_CellEditor> GetSymmetryNodes(ESymmetry _eSymmetry)
    {
        List <Node_CellEditor> ret       = new List <Node_CellEditor>();
        Stack <ENodePosition>  positions = new Stack <ENodePosition>();

        positions.Push(ePositionToParent);
        Node_CellEditor center   = parentNode;
        int             children = center.GetChildCount();

        //find the center of symmetry
        if (Designer_CellEditor.HasSymmetryNode())
        {
            while (center.eType != ENodeType.EBase && !center.symmetryNode)
            {
                positions.Push(center.ePositionToParent);
                center   = center.parentNode;
                children = center.GetChildCount();
            }

            //if the base is reached withou finding the symmetry node, stop
            if (!center.symmetryNode)
            {
                return(ret);
            }
        }
        else
        {
            while (center.eType != ENodeType.EBase)
            {
                positions.Push(center.ePositionToParent);
                center   = center.parentNode;
                children = center.GetChildCount();
            }
        }
        //if the symmetry node has only one child, stop
        if (children == 1)
        {
            return(ret);
        }


        //now we have the center of symmetry
        //iterater over all the steps it took to get here, but backwards

        if (_eSymmetry == ESymmetry.EMirror || _eSymmetry == ESymmetry.EPointMirror)
        {
            ENodePosition curPos;
            curPos = positions.Pop();
            while (positions.Count != 0 && center != null)
            {
                curPos = UTIL_CellEditor.GetOppositePosition(curPos);
                center = center.GetChild(curPos);
            }

            if (center != null)
            {
                ret.Add(center);
            }
        }
        else if (_eSymmetry == ESymmetry.EPoint)
        {
            //F**K!
        }



        return(ret);
    }
Example #3
0
        public Puzzle GeneratePuzzle(EDifficulty difficulty, ESymmetry symmetry = ESymmetry.NONE)
        {
            // Random symmetry if so desired
            if (symmetry == ESymmetry.RANDOM)
            {
                switch (random.Next(5))
                {
                case 0: symmetry = ESymmetry.NONE; break;

                case 1: symmetry = ESymmetry.ROTATE90; break;

                case 2: symmetry = ESymmetry.ROTATE180; break;

                case 3: symmetry = ESymmetry.MIRROR; break;

                case 4: symmetry = ESymmetry.FLIP; break;
                }
            }

            Stopwatch stopwatch = TrackTiming ? new Stopwatch() : null;

            if (TrackTiming)
            {
                stopwatch.Start();
            }

            // Create an empty puzzle
            var puzzle = new Puzzle();

            // Solve all the way. This invents a puzzle and returns it completely solved.
            // Do not keep stats
            puzzle = Solve(puzzle, uint.MaxValue, false);

            var solveTime = TrackTiming ? stopwatch.Elapsed : TimeSpan.MinValue;

            Trace(ESev.Important, "Solved puzzle:");
            Trace(ESev.Important, Print(puzzle, EPrintStyle.READABLE));

            // Optimization: When not using symmetry to unmark multiple cells,
            // unmark all the cells that were found through logic instead of guessed
            if (symmetry == ESymmetry.NONE)
            {
                //    // Rollback any square for which it is obvious that
                //    // the square doesn't contribute to a unique solution
                //    // (ie, squares that were filled by logic rather
                //    // than by guess)
                //    rollbackNonGuesses();
            }

            // Create a position randomizer
            var randomizer = new PositionRandomizer(random);

            // Try removing a 1,2 or 4 values at a time (depending on symmetry).
            // Put them back if the puzzle does not have a unique solution anymore.
            var    positions    = new List <Position>();
            var    savedCells   = new List <uint>();
            Puzzle solvedPuzzle = null;

            foreach (var posInOrder in Position.AllPositions)
            {
                // Get randomized position
                positions.Clear();
                savedCells.Clear();
                positions.Add(randomizer[posInOrder]);

                // Add whatever the symmetry requires
                switch (symmetry)
                {
                case ESymmetry.ROTATE90:
                    positions.Add(positions[0].Opposite);
                    positions.Add(positions[0].VerticalFlip);
                    positions.Add(positions[0].HorizontalFlip);
                    break;

                case ESymmetry.ROTATE180:
                    positions.Add(positions[0].Opposite);
                    break;

                case ESymmetry.FLIP:
                    positions.Add(positions[0].VerticalFlip);
                    break;

                case ESymmetry.MIRROR:
                    positions.Add(positions[0].HorizontalFlip);
                    break;
                }

                // Save the values and remove them from the puzzle
                foreach (var pos in positions)
                {
                    savedCells.Add(puzzle.Givens[pos.Cell]);
                    puzzle.Givens[pos.Cell] = 0;
                }

                // See if we can solve in one, and keep track of the stats so that we can assess the difficulty
                bool putValuesBack   = false;
                var  tmpSolvedPuzzle = Solve(puzzle, difficulty == EDifficulty.EXPERT ? 1u : 0u, true);
                if (tmpSolvedPuzzle == null)
                {
                    // Nope, put the values back
                    putValuesBack = true;
                    Trace(ESev.Interesting, $"Put back {savedCells.Count} values");
                }
                else
                {
                    Trace(ESev.Interesting, $"Desired difficulty {difficulty}, after hollowing out: {tmpSolvedPuzzle.Statistics.Difficulty} pos {posInOrder}");

                    // See if we made the puzzle too difficult
                    if (tmpSolvedPuzzle.Statistics.Difficulty > difficulty)
                    {
                        // Yes, put the values back
                        putValuesBack = true;
                        Trace(ESev.Interesting, "Put back {savedCells.Count} values");
                    }
                }

                if (putValuesBack)
                {
                    // put back in reverse order, as some cells may be identical
                    for (int p = positions.Count - 1; p >= 0; p--)
                    {
                        puzzle.Givens[positions[p].Cell] = savedCells[p];
                    }
                }
                else
                {
                    solvedPuzzle = tmpSolvedPuzzle;
                }
            }

            var hollowOutTime = TrackTiming ? stopwatch.Elapsed : TimeSpan.MinValue;

            if (TrackTiming)
            {
                var statsTime = stopwatch.Elapsed;
                stopwatch.Stop();
                Console.WriteLine($"Solve time: {solveTime.Milliseconds}ms, Hollow out time: {hollowOutTime.Milliseconds}ms, stat time: {statsTime.Milliseconds}, symmetry {symmetry}, difficulty {solvedPuzzle.Statistics.Difficulty}");
            }

            Trace(ESev.Important, "Final puzzle:");
            Trace(ESev.Important, Print(puzzle, EPrintStyle.READABLE));

            // Update stats
            puzzle.Statistics = solvedPuzzle.Statistics;

            return(puzzle);
        }