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"); }
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); }
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); }