Example #1
0
        public static GraphContainer Generate(GenerateParameters parameters)
        {
            parameters.Seed = parameters.Seed > -1 ? parameters.Seed : new Random((int)DateTime.Now.Ticks).Next();

            _maxDepth      = parameters.MaxDepth;
            _maxBranches   = parameters.MaxBranches;
            _maxIterations = parameters.MaxIterations;
            _skipOdds      = parameters.SkipOdds;

            _rng = new Random(parameters.Seed);

            PuzzleGoal.ResetIdCounter();

            var last = new PuzzleGoal("Last Puzzle", "", new List <PuzzleGoal>()
            {
                new PuzzleGoal("End Game")
            });

            var allPuzzles = GenerateGoals(nextPuzzle: last);

            var first = new PuzzleGoal("First puzzle", "", allPuzzles[allPuzzles.Count]);
            var start = new PuzzleStart(first);

            var container = Create();
            var graph     = container.CreateGraph(start);

            graph.Rename();
            graph.Position();

            if (parameters.DoSort)
            {
                graph.Sort(maxIterations: _maxIterations);
            }
            if (parameters.DoSwap)
            {
                graph.Swap(maxIterations: _maxIterations);
            }
            if (parameters.DoSort)
            {
                graph.Sort(direction: -1, maxIterations: _maxIterations);
            }

            if (parameters.DoCompressY)
            {
                graph.CompressY();
            }

            if (parameters.DoCompressX)
            {
                graph.CompressX();
            }
            if (parameters.DoCompressX)
            {
                graph.CompressX(direction: -1);
            }

            graph.Plot();

            return(container);
        }
Example #2
0
        private static bool IntersectCheckY(PuzzleGoal nextPuzzle, int newY, PuzzleGoal testPuzzle, int direction = 1, PuzzleGoal goal = null)
        {
            bool intersects = (testPuzzle.Position.y == newY &&
                               testPuzzle.Position.x == nextPuzzle.Position.x);

            if (testPuzzle.Result == null)
            {
                return(intersects);
            }

            intersects |= (testPuzzle.Position.y <= newY &&
                           testPuzzle.Position.x < nextPuzzle.Position.x &&
                           testPuzzle.Result.NextPuzzles.Where(x => (x.Position.x * direction) >= 0).Any(x => x.Position.y == newY && (x.Position.x * direction) > (nextPuzzle.Position.x * direction)));

            intersects |= (testPuzzle.Position.x == nextPuzzle.Position.x &&
                           testPuzzle.Position.y < nextPuzzle.Position.y &&
                           testPuzzle.Result.NextPuzzles.Where(x => (x.Position.x * direction) >= 0).Any(x => x.Position.y == newY && (x.Position.x * direction) < (nextPuzzle.Position.x * direction)));

            intersects |= (testPuzzle.Position.y == newY &&
                           testPuzzle.Position.x < nextPuzzle.Position.x &&
                           testPuzzle.Result.NextPuzzles.Where(x => (x.Position.x * direction) >= 0).Any(x => x.Position.y > newY && x.Position.x == nextPuzzle.Position.x));

            intersects |= goal != null &&
                          (goal.Position.y <testPuzzle.Position.y &&
                                            goal.Position.x> nextPuzzle.Position.x &&
                           testPuzzle.Position.x == goal.Position.x &&
                           testPuzzle.Position.y <= nextPuzzle.Position.y);

            return(intersects);
        }
Example #3
0
        public static void Rename(this Graph graph, PuzzleGoal goal = null)
        {
            if (goal == null)
            {
                _renameCount = 1;
            }

            goal ??= graph.PuzzleStart;

            if (!goal.Renamed && goal.Title.StartsWith("Puzzle"))
            {
                goal.Title   = $"Puzzle {_renameCount++}";
                goal.Renamed = true;
            }

            if (goal.Result == null)
            {
                return;
            }

            foreach (var next in goal.Result.NextPuzzles.Reverse <PuzzleGoal>())
            {
                graph.Rename(next);
            }
        }
Example #4
0
        public static void Plot(this Graph graph, PuzzleGoal goal = null)
        {
            goal ??= graph.PuzzleStart;

            if (goal.Plotted)
            {
                return;
            }

            goal.Plotted = true;

            graph.AddNode(goal.Id, goal.Title)
            .AddGraphics(goal.Position, nodeWidth, nodeHeight)
            .AddLabelGraphics(goal.Title);

            if (goal.Result == null)
            {
                return;
            }

            var currentId       = goal.Id;
            var currentPosition = (goal.Position.x, goal.Position.y);

            if (!string.IsNullOrEmpty(goal.Result.PrizeName))
            {
                currentPosition = (goal.Position.x, goal.Position.y + (yStep / 2));
                currentId       = goal.Id + 1;

                graph.AddNode(currentId, goal.Result.PrizeName)
                .AddGraphics(currentPosition, nodeWidth, nodeHeight / 2, true)
                .AddLabelGraphics(goal.Result.PrizeName);

                graph.AddEdge(goal.Id, currentId)
                .AddEdgeGraphics()
                .AddLine();
            }

            foreach (var nextPuzzle in goal.Result.NextPuzzles)
            {
                graph.Plot(nextPuzzle);
            }

            var points = new List <(double, double)>();
            var index  = 0;

            foreach (var nextPuzzle in goal.Result.NextPuzzles.Reverse <PuzzleGoal>())
            {
                points.Add(nextPuzzle.Position);
            }

            foreach (var nextPuzzle in goal.Result.NextPuzzles.Reverse <PuzzleGoal>())
            {
                graph.AddEdge(currentId, nextPuzzle.Id)
                .AddEdgeGraphics()
                .AddLine()
                .AddPoints(currentPosition, points, index++, nextPuzzle.Id);
            }
        }
Example #5
0
        public static bool DoSort(this Graph graph, PuzzleGoal goal = null, int direction = 1)
        {
            goal ??= graph.PuzzleStart;

            var shifted = false;

            if (goal.Result == null)
            {
                return(false);
            }

            foreach (var nextPuzzle in goal.Result.NextPuzzles.Where(x => (x.Position.x * direction) >= 0))
            {
                foreach (var testPuzzle in _plottedGoals.Values)
                {
                    if (goal.Id == testPuzzle.Id)
                    {
                        continue;
                    }
                    if (nextPuzzle.Id == testPuzzle.Id)
                    {
                        continue;
                    }

                    if (IntersectCheckX(nextPuzzle, nextPuzzle.Position.x, testPuzzle, direction))
                    {
                        shifted = true;
                        graph.ShiftY(nextPuzzle);
                        break;
                    }

                    if (IntersectCheckX(nextPuzzle, nextPuzzle.Position.x, testPuzzle, direction, goal))
                    {
                        shifted = true;
                        graph.ShiftY(goal);
                        break;
                    }

                    if (IntersectCheckY(nextPuzzle, nextPuzzle.Position.y, testPuzzle, direction))
                    {
                        shifted = true;
                        graph.ShiftX(nextPuzzle, direction);
                        break;
                    }

                    if (IntersectCheckY(nextPuzzle, nextPuzzle.Position.y, testPuzzle, direction, goal))
                    {
                        shifted = true;
                        graph.ShiftX(goal, direction);
                        break;
                    }
                }

                shifted |= graph.DoSort(nextPuzzle, direction);
            }

            return(shifted);
        }
Example #6
0
        public static void SwapX(this Graph graph, PuzzleGoal goal)
        {
            _plottedPositions[goal.Position.y].Remove(goal.Position.x);

            goal.Position = (-goal.Position.x, goal.Position.y);

            _plottedPositions[goal.Position.y][goal.Position.x] = goal.Id;

            goal.Swapped = true;
        }
Example #7
0
        public static void Position(this Graph graph, PuzzleGoal goal = null, int x = xStart, int y = yStart, PuzzleGoal start = null)
        {
            goal ??= graph.PuzzleStart;

            if (start is null)
            {
                graph.Initialise();
            }

            start ??= goal;

            if (!_plottedPositions.ContainsKey(y))
            {
                _plottedPositions.Add(y, new Dictionary <int, int>());
            }

            _plottedPositions[y][x] = goal.Id;

            goal.Position = (x, y);

            _plottedGoals[goal.Id] = goal;

            if (goal.Result != null)
            {
                foreach (var nextPuzzle in goal.Result.NextPuzzles)
                {
                    if (!_plottedGoals.ContainsKey(nextPuzzle.Id))
                    {
                        _plottedGoals[nextPuzzle.Id] = nextPuzzle;

                        var keys = _plottedPositions.Keys.Where(f => f == y + yStep);

                        foreach (var key in keys)
                        {
                            while (_plottedPositions[key].ContainsKey(x))
                            {
                                x += xStep;
                            }
                        }

                        foreach (var node in _plottedGoals.Values.Where(x => Math.Sign(x.Position.x) > 0 && x.Id != goal.Id))
                        {
                            var intersects = IntersectCheckX(goal, x, node);

                            if (intersects)
                            {
                                x += xStep;
                            }
                        }

                        graph.Position(nextPuzzle, x, y + yStep, start);
                    }
                }
            }
        }
Example #8
0
        public static void ShiftY(this Graph graph, PuzzleGoal goal)
        {
            if (goal == null)
            {
                return;
            }

            if (_plottedPositions.ContainsKey(goal.Position.y))
            {
                _plottedPositions[goal.Position.y].Remove(goal.Position.x);

                if (!_plottedPositions[goal.Position.y].Any())
                {
                    _plottedPositions.Remove(goal.Position.y);
                }
            }

            PuzzleGoal existing = null;

            var newY = Math.Min(_plottedPositions.Keys.Max(), goal.Position.y) + yStep;

            goal.Position = (goal.Position.x, newY);

            if (_plottedPositions.ContainsKey(goal.Position.y) &&
                _plottedPositions[goal.Position.y].ContainsKey(goal.Position.x) &&
                _plottedPositions[goal.Position.y][goal.Position.x] > 0)
            {
                existing = _plottedGoals[_plottedPositions[goal.Position.y][goal.Position.x]];
                graph.ShiftY(existing);
            }

            if (!_plottedPositions.ContainsKey(goal.Position.y))
            {
                _plottedPositions.Add(goal.Position.y, new Dictionary <int, int>());
            }

            _plottedPositions[goal.Position.y][goal.Position.x] = goal.Id;

            if (goal.Result == null)
            {
                return;
            }

            foreach (var next in goal.Result.NextPuzzles.Reverse <PuzzleGoal>())
            {
                if (next != existing)
                {
                    graph.ShiftY(next);
                }
            }
        }
Example #9
0
        public static bool DoCompressX(this Graph graph, PuzzleGoal goal, int direction = 1)
        {
            var intersects = false;
            var newX       = goal.Position.x;

            if (goal.Title == "Puzzle 2")
            {
                return(false);
            }

            do
            {
                newX = newX - (direction * xStep);

                if (newX == 0)
                {
                    return(false);
                }

                if (goal.Result != null)
                {
                    foreach (var node in _plottedGoals.Values.Where(x => (x.Position.x == 0 || Math.Sign(x.Position.x) == direction) && x.Id != goal.Id))
                    {
                        intersects = IntersectCheckX(goal, newX, node);

                        if (intersects)
                        {
                            break;
                        }
                    }
                }

                if (!intersects)
                {
                    _plottedPositions[goal.Position.y].Remove(goal.Position.x);

                    goal.Position = (newX, goal.Position.y);

                    _plottedPositions[goal.Position.y][goal.Position.x] = goal.Id;

                    return(true);
                }
            }while (true);
        }
Example #10
0
        public static void ShiftX(this Graph graph, PuzzleGoal goal, int direction = 1)
        {
            if (_plottedPositions.ContainsKey(goal.Position.y))
            {
                _plottedPositions[goal.Position.y].Remove(goal.Position.x);
            }

            var newX = goal.Position.x + (direction * xStep);

            goal.Position = (newX, goal.Position.y);

            if (_plottedPositions.ContainsKey(goal.Position.y) &&
                _plottedPositions[goal.Position.y].ContainsKey(goal.Position.x) &&
                _plottedPositions[goal.Position.y][goal.Position.x] > 0)
            {
                var existing = _plottedGoals[_plottedPositions[goal.Position.y][goal.Position.x]];
                graph.ShiftX(existing, direction);
            }

            _plottedPositions[goal.Position.y][goal.Position.x] = goal.Id;
        }
Example #11
0
        public static bool DoCompressYShift(int rowKey, PuzzleGoal goal)
        {
            _plottedPositions[rowKey].Remove(goal.Position.x);

            goal.Position = (goal.Position.x, goal.Position.y - yStep);

            if (!_plottedPositions.ContainsKey(goal.Position.y))
            {
                _plottedPositions.Add(goal.Position.y, new Dictionary <int, int>());
            }

            _plottedPositions[goal.Position.y][goal.Position.x] = goal.Id;

            if (!_plottedPositions[rowKey].Any())
            {
                _plottedPositions.Remove(rowKey);
                return(true);
            }

            return(false);
        }
Example #12
0
        public static GraphContainer CreateDigGraph()
        {
            var end = new PuzzleGoal("End Game");

            var killGuard = new PuzzleGoal("Kill guard", "Save everyone", end);

            var openEye = new PuzzleGoal("Open eye", "Guard", killGuard);

            var completeStrangeDevice = new PuzzleGoal("Complete strange device", "Powered eye", openEye);

            var crystal = new PuzzleGoal("Crystal", "Crystal", completeStrangeDevice, hidden: true);
            var eyePart = new PuzzleGoal("Eye part", "Eye part", completeStrangeDevice, hidden: true);

            var fixCrystalMachine = new PuzzleGoal("Fix crystal machine", "", new List <PuzzleGoal> {
                crystal, eyePart
            });

            var useMapPanel = new PuzzleGoal("Use map panel", "Eye part", fixCrystalMachine);

            var persuadeCreature = new PuzzleGoal("Persuade creature", "Creator's engraving", useMapPanel);

            var reviveCreature = new PuzzleGoal("Revive creature", "", persuadeCreature);

            var completeEnergyLines = new PuzzleGoal("Complete energy lines", "Completed eye", openEye);

            var activateLightBridge = new PuzzleGoal("Activate light bridge", "Light bridge", completeEnergyLines);

            var accessCathedralSpire1 = new PuzzleGoal("Access cathedral spire", "Access cathedral spire", persuadeCreature, hidden: true);
            var accessCathedralSpire2 = new PuzzleGoal("Access cathedral spire", "Access cathedral spire", activateLightBridge, hidden: true);

            var completeAlcove = new PuzzleGoal("Complete alcove", "", new List <PuzzleGoal> {
                accessCathedralSpire1, accessCathedralSpire2
            });

            var freeBrink = new PuzzleGoal("Free brink", "Brink freed", completeAlcove);

            var fourPlates   = new PuzzleGoal("Four plates", "Four plates", completeAlcove, hidden: true);
            var brinkTrapped = new PuzzleGoal("Brink trapped", "Brink trapped", freeBrink, hidden: true);

            var collectFourPlates = new PuzzleGoal("Collect four plates", "", new List <PuzzleGoal> {
                fourPlates, brinkTrapped
            });

            var accessHiddenIsland = new PuzzleGoal("Access hidden island", "Plate", collectFourPlates);

            var crystals = new PuzzleGoal("", "Crystals", reviveCreature, hidden: true);
            var tablet   = new PuzzleGoal("", "Tablet", accessHiddenIsland, hidden: true);

            var saveRobbins = new PuzzleGoal("Save robbins", "", new List <PuzzleGoal> {
                crystals, tablet
            });

            var distractMonster = new PuzzleGoal("Distract monster", "Rock by waterfall", saveRobbins);

            var recruitBrink = new PuzzleGoal("Recruit brink", "Brink in position", distractMonster);

            var distractBrink = new PuzzleGoal("Distract brink", "Stolen crystals", recruitBrink);

            var reviveCreature2 = new PuzzleGoal("Revive creature", "Flashlight", distractBrink);

            var openPyramid = new PuzzleGoal("Open pyramid", "Crystal", reviveCreature2);

            var openDoor = new PuzzleGoal("Open door", "Access door", openPyramid);

            var killGuard2 = new PuzzleGoal("Kill guard", "Access door", openDoor);

            var moveSlab = new PuzzleGoal("Move slab", "Crystal", killGuard2);

            var revealPassage = new PuzzleGoal("Reveal passage", "", moveSlab);

            var mapPanel = new PuzzleGoal("Map panel", "Discover secret under tomb", moveSlab);

            var activateLightBridge2 = new PuzzleGoal("Activate light bridge", "Light bridge", completeEnergyLines);

            var turnOnLights = new PuzzleGoal("Turn on lights", "Light source under earth", revealPassage);

            var openShutter = new PuzzleGoal("Open shutter", "Let light through", revealPassage);

            var alignMoons = new PuzzleGoal("Align moons", "Light slab", moveSlab);

            var accessMapSpire1 = new PuzzleGoal("", "Access map spire", mapPanel, hidden: true);
            var accessMapSpire2 = new PuzzleGoal("", "Access map spire", activateLightBridge2, hidden: true);

            var openMishapedDoor = new PuzzleGoal("Open mishaped door", "", new List <PuzzleGoal> {
                accessMapSpire1, accessMapSpire2
            });

            var fixOpenDoor1 = new PuzzleGoal("", "Sceptres", alignMoons, hidden: true);
            var fixOpenDoor2 = new PuzzleGoal("", "Plate", collectFourPlates, hidden: true);
            var fixOpenDoor3 = new PuzzleGoal("", "Green rod", openMishapedDoor, hidden: true);

            var fixOpenDoor = new PuzzleGoal("Fix/Open door", "", new List <PuzzleGoal> {
                fixOpenDoor1, fixOpenDoor2, fixOpenDoor3
            });

            var findRatsLair = new PuzzleGoal("Find rat's lair", "Door piece", fixOpenDoor);

            var bugRat = new PuzzleGoal("Bug rat", "Alien device", findRatsLair);

            var fashionTrap = new PuzzleGoal("Fashion trap", "Rat", bugRat);

            var activateLightBridge3 = new PuzzleGoal("Activate light bridge", "Light bridge", completeEnergyLines);

            var discoverChamber = new PuzzleGoal("Discover chamber", "", new List <PuzzleGoal> {
                turnOnLights, openShutter
            });

            var digOutPlate = new PuzzleGoal("Dig out plate", "", discoverChamber);

            var shovel            = new PuzzleGoal("Shovel", "Shovel", digOutPlate, hidden: true);
            var accessLightBridge = new PuzzleGoal("Access light bridge", "Access light bridge", activateLightBridge2, hidden: true);

            var accessTombSpire = new PuzzleGoal("Access tomb spire", "", new List <PuzzleGoal> {
                shovel, accessLightBridge
            });

            var openStarDoor = new PuzzleGoal("Open Star door", "Access tram", accessTombSpire);

            var energiseCrystals = new PuzzleGoal("Energise crystals", "Power tram", accessTombSpire);

            var passAirlock = new PuzzleGoal("Pass airlock", "Access command centre", energiseCrystals);

            var openReturnPath = new PuzzleGoal("Open return path");

            var jumpGap1 = new PuzzleGoal("", "Blue rod", energiseCrystals, hidden: true);
            var jumpGap2 = new PuzzleGoal("", "Rod", openShutter, hidden: true);
            var jumpGap3 = new PuzzleGoal("", "Shovel", openReturnPath, hidden: true);
            var jumpGap4 = new PuzzleGoal("", "Panel cover", fixOpenDoor, hidden: true);
            var jumpGap5 = new PuzzleGoal("", "Access cave", findRatsLair, hidden: true);
            var jumpGap6 = new PuzzleGoal("", "Trap parts", fashionTrap, hidden: true);
            var jumpGap7 = new PuzzleGoal("", "Access lightbridge", activateLightBridge3, hidden: true);

            var jumpGap = new PuzzleGoal("Jump gap", "", new List <PuzzleGoal> {
                jumpGap1, jumpGap2, jumpGap3, jumpGap4, jumpGap5, jumpGap6, jumpGap7
            });

            var openDiamondDoor = new PuzzleGoal("Open diamond door", "Access planetarium spire", jumpGap);

            var orangeRod = new PuzzleGoal("", "Orange rod", openDiamondDoor, hidden: true);
            var plate2    = new PuzzleGoal("", "Plate", collectFourPlates, hidden: true);

            var killMonsterToAccessWater = new PuzzleGoal("Kill monster to access water", "", new List <PuzzleGoal> {
                orangeRod, plate2
            });

            var reviveBoobyTrapTurtle = new PuzzleGoal("Revive/boobytrap turtle", "Boobytrapped turtle", killMonsterToAccessWater);

            var openWeakenedDoor = new PuzzleGoal("Open weakened door", "Canister", reviveBoobyTrapTurtle);

            var reviveBrink = new PuzzleGoal("Revive Brink", "", openWeakenedDoor);

            var activateLightBridge4 = new PuzzleGoal("Activate light bridge", "Light bridge", completeEnergyLines);

            var openTriangleDoor1 = new PuzzleGoal("", "Red rod", openStarDoor, hidden: true);
            var openTriangleDoor2 = new PuzzleGoal("", "Red rod", mapPanel, hidden: true);
            var openTriangleDoor3 = new PuzzleGoal("", "Glowing crystals", reviveBrink, hidden: true);
            var openTriangleDoor4 = new PuzzleGoal("", "Fossil", reviveBoobyTrapTurtle, hidden: true);
            var openTriangleDoor5 = new PuzzleGoal("", "Access museum spire", activateLightBridge4, hidden: true);

            var openTriangleDoor = new PuzzleGoal("Jump gap", "Panel cover", new List <PuzzleGoal> {
                openTriangleDoor1, openTriangleDoor2, openTriangleDoor3, openTriangleDoor4, openTriangleDoor5
            });

            var powerMishapedDoorPanel = new PuzzleGoal("Power mishaped door panel", "Powered door", openMishapedDoor);

            var restorePower1 = new PuzzleGoal("", "Power doors", openTriangleDoor, hidden: true);
            var restorePower2 = new PuzzleGoal("", "Revealed power line", powerMishapedDoorPanel, hidden: true);

            var restorePower = new PuzzleGoal("Restore Power", "", new List <PuzzleGoal> {
                restorePower1, restorePower2
            });

            var removeDoorPanel = new PuzzleGoal("Remove door panel", "Broken controls", powerMishapedDoorPanel);

            var plate1            = new PuzzleGoal("Plate", "Plate", collectFourPlates, hidden: true);
            var blueCrystal       = new PuzzleGoal("Blue crystal", "Blue crystal", turnOnLights, hidden: true);
            var accessTunnel      = new PuzzleGoal("Access tunnel", "Access tunnel", passAirlock, hidden: true);
            var purpleRod         = new PuzzleGoal("Purple rod", "Purple rod", openTriangleDoor, hidden: true);
            var accessPowerSource = new PuzzleGoal("Access power source", "Access power source", restorePower, hidden: true);
            var accessNexus       = new PuzzleGoal("Access nexus", "Access nexus", removeDoorPanel, hidden: true);

            var findNexus = new PuzzleGoal("Find Nexus", "", new List <PuzzleGoal> {
                plate1, blueCrystal, accessTunnel, purpleRod, accessPowerSource, accessNexus
            });

            var goldRod         = new PuzzleGoal("Gold rod", "Gold rod", openPyramid, hidden: true);
            var goldEngravedRod = new PuzzleGoal("Gold engraved rod", "Gold engraved rod", openDoor, hidden: true);
            var hole            = new PuzzleGoal("Hole", "Hole", findNexus, hidden: true);
            var wire            = new PuzzleGoal("Wire", "Wire", powerMishapedDoorPanel, hidden: true);

            var pullWire = new PuzzleGoal("Pull wire", "", new List <PuzzleGoal> {
                goldRod, goldEngravedRod, hole, wire
            });

            var findSmallMound = new PuzzleGoal("Find small mound", "Bracelet", bugRat);

            var tusk    = new PuzzleGoal("Tusk", "Tusk", removeDoorPanel, hidden: true);
            var jawBone = new PuzzleGoal("Jawbone", "Jawbone", freeBrink, hidden: true);

            var digGrave = new PuzzleGoal("Dig grave", "", new List <PuzzleGoal> {
                tusk, jawBone
            });

            var accessWreck = new PuzzleGoal("Access wreck", "Access wreck", pullWire, hidden: true);
            var alienDevice = new PuzzleGoal("Alien device", "Alien device", findSmallMound, hidden: true);
            var shovel2     = new PuzzleGoal("Shovel", "Shovel", digGrave, hidden: true);

            var travelToAlienPlanet = new PuzzleGoal("Travel to alien planet", "", new List <PuzzleGoal> {
                accessWreck, alienDevice, shovel2
            });

            var accessAsteroidInterior = new PuzzleGoal("Access asteroid interior", "Metal plates", travelToAlienPlanet);

            var plantBombAlpha = new PuzzleGoal("Plant bomb alpha", "", accessAsteroidInterior);
            var plantBombBeta  = new PuzzleGoal("Plant bomb beta", "", accessAsteroidInterior);

            var releasePigA1 = new PuzzleGoal("", "Bomb", plantBombAlpha, hidden: true);
            var releasePigA2 = new PuzzleGoal("", "Digger", plantBombAlpha, hidden: true);
            var releasePigA3 = new PuzzleGoal("", "Arming key", plantBombAlpha, hidden: true);

            var releasePigB1 = new PuzzleGoal("", "Bomb", plantBombBeta, hidden: true);
            var releasePigB2 = new PuzzleGoal("", "Shovel", plantBombBeta, hidden: true);
            var releasePigB3 = new PuzzleGoal("", "Arming key", plantBombBeta, hidden: true);

            var releasePig = new PuzzleGoal("Release pig", "", new List <PuzzleGoal> {
                releasePigA1, releasePigA2, releasePigA3, releasePigB1, releasePigB2, releasePigB3
            });


            var theDigBegins = new PuzzleGoal("The Dig begins", "", releasePig);

            var start = new PuzzleStart(theDigBegins);

            var container = GraphContainer.Create();
            var graph     = container.CreateGraph(start);

            graph.Position();
            graph.Rename();

            graph.Sort();
            graph.Swap(maxIterations: 10);
            graph.Sort(direction: -1);

            graph.DoCompressY();

            graph.CompressX();
            graph.CompressX(direction: -1);

            graph.Plot();

            return(container);
        }
Example #13
0
        private static Dictionary <int, List <PuzzleGoal> > GenerateGoals(
            int depth             = 1,
            PuzzleGoal nextPuzzle = null,
            Dictionary <int, List <PuzzleGoal> > allPuzzles = null)
        {
            allPuzzles ??= new Dictionary <int, List <PuzzleGoal> >();

            if (depth > _maxDepth)
            {
                return(allPuzzles);
            }

            if (!allPuzzles.ContainsKey(depth))
            {
                allPuzzles.Add(depth, new List <PuzzleGoal>());
            }

            var branches = _rng.Next(1, _maxBranches);

            for (var branch = 1; branch <= branches; branch++)
            {
                PuzzleGoal puzzle;

                if (nextPuzzle != null)
                {
                    nextPuzzle.Linked = true;
                    puzzle            = new PuzzleGoal($"Puzzle {++_puzzleCount}", $"Item {_puzzleCount}", nextPuzzle);
                }
                else
                {
                    var nextPuzzles = new List <PuzzleGoal>();

                    if (depth > 1)
                    {
                        var pickRandom = _rng.Next(0, _skipOdds);

                        if (pickRandom == 0)
                        {
                            var randomDepth = _rng.Next(1, depth - 1);
                            var inBranches  = _rng.Next(1, Math.Min(allPuzzles[randomDepth].Count, _maxBranches));

                            for (var inBranch = 0; inBranch < inBranches; inBranch++)
                            {
                                var randomPuzzleIndex = _rng.Next(0, allPuzzles[randomDepth].Count - 1);

                                allPuzzles[randomDepth][randomPuzzleIndex].Linked = true;
                                nextPuzzles.Add(allPuzzles[randomDepth][randomPuzzleIndex]);
                            }
                        }
                        else
                        {
                            var inBranches = _rng.Next(1, Math.Min(allPuzzles[depth - 1].Count, _maxBranches));

                            for (var inBranch = 0; inBranch < inBranches; inBranch++)
                            {
                                var randomPuzzleIndex = _rng.Next(0, allPuzzles[depth - 1].Count - 1);

                                allPuzzles[depth - 1][randomPuzzleIndex].Linked = true;
                                nextPuzzles.Add(allPuzzles[depth - 1][randomPuzzleIndex]);
                            }
                        }
                    }

                    puzzle = new PuzzleGoal($"Puzzle {++_puzzleCount}", $"Item {_puzzleCount}", nextPuzzles);
                }

                allPuzzles[depth].Add(puzzle);
            }

            allPuzzles = GenerateGoals(depth + 1, allPuzzles: allPuzzles);

            for (var i = depth - 1; i < depth && depth > 1; i++)
            {
                var unLinked = allPuzzles[i].Where(x => !x.Linked).ToList();

                foreach (var puzzle in unLinked)
                {
                    var randomParent = _rng.Next(0, allPuzzles[depth].Count - 1);
                    allPuzzles[depth][randomParent].Result.NextPuzzles.Add(puzzle);
                }
            }

            return(allPuzzles);
        }
Example #14
0
        public static bool DoSwap(this Graph graph, PuzzleGoal goal = null)
        {
            goal ??= graph.PuzzleStart;

            if (goal.Result == null || goal.Position.x <= 0)
            {
                return(false);
            }

            var swapped = false;

            foreach (var nextPuzzle in goal.Result.NextPuzzles)
            {
                if (!goal.Swapped && goal.Position.x != 0)
                {
                    var swappable = false;

                    foreach (var node in _plottedGoals.Select(x => x.Value))
                    {
                        if (node.Result == null)
                        {
                            continue;
                        }

                        foreach (var result in node.Result.NextPuzzles)
                        {
                            if (result == goal && node.Position.x == 0)
                            {
                                swappable = true;
                            }
                        }
                    }

                    if (!swappable)
                    {
                        continue;
                    }

                    foreach (var node in _plottedGoals.Select(x => x.Value))
                    {
                        var intersects = (node.Position.x == goal.Position.x &&
                                          node.Position.y > goal.Position.y &&
                                          goal.Result.NextPuzzles.Any(x => x.Position.x <node.Position.x && x.Position.y> node.Position.y));

                        if (intersects)
                        {
                            swapped = true;
                            graph.SwapX(goal);
                            break;
                        }
                    }

                    if (swapped)
                    {
                        break;
                    }

                    for (var y = 0; y <= nextPuzzle.Position.y; y += yStep)
                    {
                        if (!_plottedPositions.ContainsKey(y))
                        {
                            continue;
                        }

                        var nodes = _plottedPositions[y].Where(x => x.Key >= 0 && x.Key < goal.Position.x).ToList();

                        foreach (var node in nodes)
                        {
                            var source = _plottedGoals[node.Value];
                            if (source != nextPuzzle && source.Result != null)
                            {
                                foreach (var target in source.Result.NextPuzzles)
                                {
                                    if (target.Position.y > nextPuzzle.Position.y)
                                    {
                                        swapped = true;
                                        graph.SwapX(goal);
                                        break;
                                    }
                                }
                            }

                            if (swapped)
                            {
                                break;
                            }
                        }

                        if (swapped)
                        {
                            break;
                        }
                    }
                }

                if (swapped)
                {
                    break;
                }

                if (!nextPuzzle.Swapped && goal.Position.x < 0)
                {
                    swapped = true;
                    graph.SwapX(nextPuzzle);
                    break;
                }

                if (swapped)
                {
                    break;
                }
            }

            return(swapped);
        }