Example #1
0
    public static void IGT(int delay, string path)
    {
        MakeSave();
        IGTResults res = Gsc.IGTCheckParallel(MultiThread.MakeThreads <Gold>(8), 120, new GscIntroSequence(delay, GscStrat.GfSkip, GscStrat.TitleSkip, GscStrat.Continue), 60, gb => gb.Execute(path) == gb.OverworldLoopAddress);

        Console.WriteLine(res.TotalSuccesses + " (RNG: " + res.RNGSuccesses(10) + ")");
    }
Example #2
0
    public static void Start()
    {
        Yellow[] gbs = MultiThread.MakeThreads <Yellow>(8, "baseSaves/yellow_moon_backup.sav");
        Yellow   gb  = gbs[0];

        gb.Show();
        new RbyIntroSequence().Execute(gb);

        RbyMap map1 = gb.Maps[60];
        RbyMap map2 = gb.Maps[61];

        Pathfinding.GenerateEdges <RbyMap, RbyTile>(gb, 0, map2[12, 9], Action.Up | Action.Down | Action.Left | Action.Right | Action.A);

        map1[21, 16].GetEdge(0, Action.Down).NextTile  = map2[21, 17];
        map1[20, 17].GetEdge(0, Action.Right).NextTile = map2[21, 17];

        for (int x = 0xd; x <= 0x12; x++)
        {
            for (int y = 0x10; y <= 0x11; y++)
            {
                map1[x, y].RemoveEdge(0, Action.A);
                map1[x, y].RemoveEdge(0, Action.Down);
            }
        }

        for (int x = 0xd; x <= 0x12; x++)
        {
            for (int y = 0x10; y <= 0x11; y++)
            {
                map1[x, y].RemoveEdge(0, Action.A);
                map1[x, y].RemoveEdge(0, Action.Down);
            }
        }

        for (int x = 0x11; x <= 0x17; x++)
        {
            map2[x, 0x1f].RemoveEdge(0, Action.A);
        }

        IGTResults initialState = Yellow.IGTCheckParallel(gbs, new RbyIntroSequence(), 60);

        StreamWriter writer = new StreamWriter("moon.txt");

        writer.AutoFlush = true;

        DFParameters <Yellow, RbyMap, RbyTile> parameters = new DFParameters <Yellow, RbyMap, RbyTile>()
        {
            PruneAlreadySeenStates = true,
            MaxCost       = 20,
            NoEncounterSS = 60,
            RNGSS         = 56,
            EndTiles      = new RbyTile[] { map2[12, 9], },
            FoundCallback = state => writer.WriteLine(state.Log),
            EndEdgeSet    = 0,
        };

        DepthFirstSearch.StartSearch(gbs, parameters, gb.Tile, 0, initialState);
    }
Example #3
0
    public static IGTResults IGTCheckParallel <Gb>(Gb[] gbs, int timesec, GscIntroSequence intro, int numIgts, Func <Gb, bool> fn = null, int ss = 0, int igtOffset = 0) where Gb : Gsc
    {
        gbs[0].SetTimeSec(timesec);
        intro.ExecuteUntilIGT(gbs[0]);
        byte[]     igtState    = gbs[0].SaveState();
        IGTResults introStates = new IGTResults(numIgts);

        MultiThread.For(numIgts, gbs, (gb, i) => {
            introStates[i] = gb.MakeIGTState(intro, igtState, i + igtOffset);
        });

        return(IGTCheckParallel(gbs, introStates, x => fn == null || fn((Gb)x), ss));
    }
Example #4
0
    public IGTResults IGTCheck(int timesec, GscIntroSequence intro, int numIgts, Func <bool> fn = null, int ss = 0, int igtOffset = 0)
    {
        SetTimeSec(timesec);
        intro.ExecuteUntilIGT(this);
        byte[]     igtState    = SaveState();
        IGTResults introStates = new IGTResults(numIgts);

        for (int i = 0; i < numIgts; i++)
        {
            introStates[i] = MakeIGTState(intro, igtState, i + igtOffset);
        }

        return(IGTCheck(introStates, fn, ss));
    }
Example #5
0
    static void Cherrygrove(Gold[] gbs, Action[] path, byte[][] states, GscTile startTile)
    {
        long cherryPathsFound          = 0;
        long numSeenPaths              = 0;
        HashSet <(int, int, int)> rngs = new HashSet <(int, int, int)>();

        while (numSeenPaths < 30)
        {
            GC.Collect();
            Console.WriteLine("Searching for cherrygrove path (" + cherryPathsFound + ")...");
            var ret = RandomPathSearch.StartSearch(gbs,
                                                   new RandomSearchParameters <GscTile>()
            {
                StateList = new List <byte[][]>()
                {
                    states
                },
                ClusterSize       = 1,
                SS                = 60,
                NumPathsToFind    = 1,
                StartEdgeSet      = 0,
                StartTile         = startTile,
                EndTiles          = new GscTile[] { r30[12, 46], r30[13, 46] },
                ExecutionCallback = (gb, actions) => gb.Execute(actions) == gb.OverworldLoopAddress,
            }).First();

            cherryPathsFound++;
            Action[]   actions = ret.Actions;
            IGTResults results = ret.Results[0];
            (int, int, int)rng = (results.MostCommonHRA, results.MostCommonHRS, results.MostCommonDivider);
            Action[] concatPath = path.Concat(actions).ToArray();
            cherrygroveWriter.WriteLine(ActionFunctions.ActionsToPath(concatPath));
            cherrygroveWriter.Flush();
            if (!rngs.Add(rng))
            {
                numSeenPaths++;
                continue;
            }
            else
            {
                numSeenPaths = 0;
            }
            gbs[0].LoadState(results.FirstState);
            End(gbs, concatPath, results.States, gbs[0].Tile);
        }
    }
Example #6
0
    private static void ParallelSearch <Gb, T>(ConcurrentBag <RandomPathResult> list, Gb gb, RandomSearchParameters <T> parameters, ref int pathsFound) where Gb : GameBoy
        where T : Tile <T>
    {
        Random random    = new Random();
        int    igtFrames = parameters.StateList[0].Length;

        IGTResults[] results = new IGTResults[parameters.ClusterSize];
        int          statesIndex;
        int          successes;

        while (pathsFound < parameters.NumPathsToFind)
        {
            Action[] actions = GenerateRandomPath(random, parameters.StartEdgeSet, parameters.StartTile, parameters.EndTiles).ToArray();
            statesIndex = random.Next(parameters.StateList.Count - parameters.ClusterSize + 1);
            successes   = igtFrames * parameters.ClusterSize;

            for (int i = 0; i < parameters.ClusterSize && successes >= parameters.SS; i++)
            {
                results[i] = gb.IGTCheck(parameters.StateList[statesIndex + i], gb => parameters.ExecutionCallback(gb, actions), parameters.SS, successes);
                successes -= results[i].TotalFailures;
            }

            if (successes >= parameters.SS)
            {
                if (parameters.FoundCallback != null)
                {
                    parameters.FoundCallback(statesIndex, actions, successes);
                }
                if (parameters.NumPathsToFind > 0)
                {
                    Interlocked.Increment(ref pathsFound);
                    list.Add(new RandomPathResult {
                        StatesIndex = statesIndex,
                        Actions     = actions,
                        Results     = results,
                    });
                }
            }
        }
    }
Example #7
0
    public static void StartSearch <Gb, T>(Gb[] gbs, DFParameters <Gb, T> parameters, T startTile, int startEdgeSet, byte[][] states) where Gb : GameBoy
        where T : Tile <T>
    {
        IGTResults initialState = new IGTResults(states.Length);

        for (int i = 0; i < states.Length; i++)
        {
            initialState[i]         = new IGTState();
            initialState[i].State   = states[i];
            initialState[i].HRA     = -1;
            initialState[i].HRS     = -1;
            initialState[i].Divider = -1;
        }

        RecursiveSearch(gbs, parameters, new DFState <T> {
            Tile           = startTile,
            EdgeSet        = startEdgeSet,
            WastedFrames   = 0,
            Log            = parameters.LogStart,
            BlockedActions = Action.A,
            IGT            = initialState,
        }, new HashSet <int>());
    }
Example #8
0
    static void R29(Gold[] gbs, byte[][] states, GscTile startTile)
    {
        HashSet <(int, int, int)> rngs = new HashSet <(int, int, int)>();

        while (true)
        {
            Console.WriteLine("Searching for r29 path...");
            var ret = RandomPathSearch.StartSearch(gbs,
                                                   new RandomSearchParameters <GscTile>()
            {
                StateList = new List <byte[][]>()
                {
                    states
                },
                ClusterSize       = 1,
                SS                = 60,
                NumPathsToFind    = 1,
                StartEdgeSet      = 0,
                StartTile         = startTile,
                EndTiles          = new GscTile[] { cherrygrove[33, 7] },
                ExecutionCallback = (gb, action) => gb.Execute(action) == gb.OverworldLoopAddress,
            }).First();

            Action[]   actions = ret.Actions;
            IGTResults results = ret.Results[0];
            (int, int, int)rng = (results.MostCommonHRA, results.MostCommonHRS, results.MostCommonDivider);
            r29Writer.WriteLine(ActionFunctions.ActionsToPath(ret.Actions));
            r29Writer.Flush();
            if (!rngs.Add(rng))
            {
                continue;
            }
            gbs[0].LoadState(results.FirstState);
            Cherrygrove(gbs, ret.Actions, results.States, gbs[0].Tile);
        }
    }
Example #9
0
    public static string CleanUpPathParallel <Gb>(Gb[] gbs, IGTResults initialStates, int ss, params Action[] path) where Gb : Gsc
    {
        List <int> aPressIndices = new List <int>();

        for (int i = 0; i < path.Length; i++)
        {
            if ((path[i] & Action.A) > 0)
            {
                aPressIndices.Add(i);
            }
        }

        foreach (int index in aPressIndices)
        {
            path[index] &= ~Action.A;
            int successes = Gsc.IGTCheckParallel(gbs, initialStates, gb => gb.Execute(path) == gb.SYM["OWPlayerInput"]).TotalSuccesses;
            if (successes < ss)
            {
                path[index] |= Action.A;
            }
        }

        return(ActionFunctions.ActionsToPath(path));
    }
Example #10
0
    public static void StartSearch(int numThreads)
    {
        bool[]   threadsRunning = new bool[numThreads];
        Thread[] threads        = new Thread[numThreads];
        Gold     dummyGb        = new Gold();
        GscMap   map            = dummyGb.Maps[6149];

        map.Sprites.Remove(5, 3); // Remove police officer (https://gunnermaniac.com/pokeworld2?map=6149#5/3)
        Pathfinding.GenerateEdges <GscMap, GscTile>(dummyGb, 0, map[7, 5], Action.Right | Action.Down | Action.StartB);
        Pathfinding.GenerateEdges <GscMap, GscTile>(dummyGb, 1, map[7, 4], Action.StartB);

        map[4, 5].RemoveEdge(0, Action.Down);
        map[4, 5].RemoveEdge(0, Action.Down | Action.A); // Don't walk into cutscene
        map[5, 5].RemoveEdge(0, Action.Down);
        map[5, 5].RemoveEdge(0, Action.Down | Action.A); // ^
        map[7, 4].RemoveEdge(0, Action.Right);
        map[7, 4].RemoveEdge(0, Action.Right | Action.A);
        map[7, 5].RemoveEdge(0, Action.Right);
        map[7, 5].RemoveEdge(0, Action.Right | Action.A);
        map[4, 2].RemoveEdge(0, Action.Down | Action.A);
        map[5, 3].RemoveEdge(0, Action.Down | Action.A);

        map[7, 5].AddEdge(0, new Edge <GscMap, GscTile>()
        {
            Action      = Action.Up,
            NextTile    = map[7, 4],
            NextEdgeset = 1,
            Cost        = 0,
        });

        GscTile[] startTiles   = { map[4, 2], map[4, 3], map[4, 4], map[5, 3], map[5, 4] };
        byte[]    startHours   = { 10, 8, 2, 18 };
        byte[]    startMinutes = { 51, 59 };
        byte[]    audios       = { 0xc1, 0xe1 };

        int numSavesCompleted = 0;

        Writer = new StreamWriter("gold_toto_" + DateTime.Now.Ticks + ".txt");
        int numSaves = startTiles.Length * startHours.Length * startMinutes.Length * 2 * 2 * 8 * 2 * 10;

        Console.WriteLine(numThreads + " threads, " + (numSaves) + " saves (" + (float)numSaves / (float)numThreads + " iterations)");
        foreach (GscTile tile in startTiles)
        {
            foreach (byte hour in startHours)
            {
                foreach (byte minute in startMinutes)
                {
                    for (byte momStep = 0; momStep <= 1; momStep++)
                    {
                        foreach (byte audio in audios)
                        {
                            for (byte frameType = 0; frameType <= 7; frameType++)
                            {
                                for (byte menuAccount = 0; menuAccount <= 1; menuAccount++)
                                {
                                    for (byte igt = 0; igt < 60; igt += 6)
                                    {
                                        int threadIndex;
                                        while ((threadIndex = Array.IndexOf(threadsRunning, false)) == -1)
                                        {
                                            Thread.Sleep(50);
                                        }
                                        threadsRunning[threadIndex] = true;
                                        new Thread(parameter => {
                                            (int, (GscTile, byte, byte, byte, byte, byte, byte, byte))data = ((int, (GscTile, byte, byte, byte, byte, byte, byte, byte)))parameter;
                                            (GscTile tile, byte hour, byte minute, byte momStep, byte audio, byte frameType, byte menuAccount, byte igt)state = data.Item2;
                                            Gold gb;
                                            lock (startTiles) {
                                                MakeSave(state.tile.X, state.tile.Y, state.hour, state.minute, state.momStep, state.audio, state.frameType, state.menuAccount, state.igt);
                                                gb = new Gold("roms/gold_toto_temp.sav");
                                                gb.SetTimeSec(120);
                                                gb.Hold(Joypad.Left, 0x100);
                                            }
                                            GscStrat.GfSkip.Execute(gb);
                                            GscStrat.TitleSkip.Execute(gb);
                                            byte[] mmbackState = gb.SaveState();
                                            for (int mmBack = 0; mmBack <= 3; mmBack++)
                                            {
                                                GscStrat.Continue.Execute(gb);
                                                byte[] fsbackState = gb.SaveState();
                                                for (int fsBack = 0; fsBack <= 3; fsBack++)
                                                {
                                                    gb.Hold(Joypad.Left, "GetJoypad");
                                                    gb.AdvanceFrame(Joypad.Left);
                                                    byte[] delayState = gb.SaveState();
                                                    for (int delay = 0; delay <= MaxCost; delay++)
                                                    {
                                                        int introCost = mmBack * 83 + fsBack * 101 + delay;
                                                        if (introCost > MaxCost)
                                                        {
                                                            break;
                                                        }
                                                        gb.Hold(Joypad.A, "OWPlayerInput");
                                                        DFParameters <Gold, GscMap, GscTile> parameters = new DFParameters <Gold, GscMap, GscTile>()
                                                        {
                                                            NoEncounterSS          = 1,
                                                            PruneAlreadySeenStates = false,
                                                            MaxCost  = MaxCost - introCost,
                                                            LogStart = string.Format("(x={0}, y={1}, h={2}, m={3}, momStep={4}, audio={5:x02}, frameType={6}, menuAccount={7}, igt={8}, mmback={9}, fsback={10}, delay={11}) ",
                                                                                     state.tile.X, state.tile.Y, state.hour, state.minute, state.momStep, state.audio, state.frameType, state.menuAccount, state.igt, mmBack, fsBack, delay),
                                                            EndTiles      = new GscTile[] { map[7, 4] },
                                                            EndEdgeSet    = 1,
                                                            FoundCallback = state => EvaluateTototdile(gb, state),
                                                        };
                                                        IGTResults results = new IGTResults(1);
                                                        results[0]         = new IGTState(gb, true, 0);
                                                        DepthFirstSearch.StartSearch(new Gold[] { gb }, parameters, tile, 0, results);
                                                        gb.LoadState(delayState);
                                                        gb.AdvanceFrame(Joypad.Left);
                                                        delayState = gb.SaveState();
                                                    }
                                                    gb.LoadState(fsbackState);
                                                    GscStrat.FsBack.Execute(gb);
                                                    GscStrat.Continue.Execute(gb);
                                                    fsbackState = gb.SaveState();
                                                }
                                                gb.LoadState(mmbackState);
                                                GscStrat.MmBack.Execute(gb);
                                                GscStrat.TitleSkip.Execute(gb);
                                                mmbackState = gb.SaveState();
                                            }
                                            Interlocked.Increment(ref numSavesCompleted);
                                            Console.WriteLine("Completed save " + numSavesCompleted + "/" + numSaves);
                                            threadsRunning[threadIndex] = false;
                                        }).Start((threadIndex, (tile, hour, minute, momStep, audio, frameType, menuAccount, igt)));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        while (true)
        {
            Thread.Sleep(10000);
        }
    }
Example #11
0
    private static void RecursiveSearch <Gb, M, T>(Gb[] gbs, DFParameters <Gb, M, T> parameters, DFState <M, T> state, HashSet <int> seenStates) where Gb : PokemonGame
        where M : Map <M, T>
        where T : Tile <M, T>
    {
        if (parameters.EndTiles != null && state.EdgeSet == parameters.EndEdgeSet && parameters.EndTiles.Any(t => t.X == state.Tile.X && t.Y == state.Tile.Y))
        {
            if (parameters.FoundCallback != null)
            {
                parameters.FoundCallback(state);
            }
        }

        if (parameters.PruneAlreadySeenStates && !seenStates.Add(state.GetHashCode()))
        {
            return;
        }

        foreach (Edge <M, T> edge in state.Tile.Edges[state.EdgeSet])
        {
            if (state.WastedFrames + edge.Cost > parameters.MaxCost)
            {
                continue;
            }
            if ((state.BlockedActions & edge.Action) > 0)
            {
                continue;
            }
            if (edge.Action == Action.A && state.APressCounter > 0)
            {
                continue;
            }

            IGTResults results = PokemonGame.IGTCheckParallel <Gb>(gbs, state.IGT, gb => gb.Execute(edge.Action) == gb.OverworldLoopAddress, parameters.NoEncounterSS);

            DFState <M, T> newState = new DFState <M, T>()
            {
                Tile         = edge.NextTile,
                EdgeSet      = edge.NextEdgeset,
                Log          = state.Log + edge.Action.LogString() + " ",
                IGT          = results,
                WastedFrames = state.WastedFrames + edge.Cost,
            };

            int noEncounterSuccesses = results.TotalSuccesses;
            if (noEncounterSuccesses >= parameters.NoEncounterSS)
            {
                int rngSuccesses = results.RNGSuccesses(0x9);
                if (rngSuccesses >= parameters.RNGSS)
                {
                    newState.APressCounter = edge.Action == Action.A ? 2 : Math.Max(state.APressCounter - 1, 0);

                    Action blockedActions = state.BlockedActions;
                    if ((edge.Action & Action.A) > 0)
                    {
                        blockedActions |= Action.A;
                    }
                    else
                    {
                        blockedActions &= ~(Action.A | Action.StartB);
                    }
                    newState.BlockedActions = blockedActions;

                    RecursiveSearch(gbs, parameters, newState, seenStates);
                }
            }
        }
    }
Example #12
0
 public static void StartSearch <Gb, M, T>(Gb[] gbs, DFParameters <Gb, M, T> parameters, T startTile, int startEdgeSet, IGTResults initialState) where Gb : PokemonGame
     where M : Map <M, T>
     where T : Tile <M, T>
 {
     RecursiveSearch(gbs, parameters, new DFState <M, T> {
         Tile          = startTile,
         EdgeSet       = startEdgeSet,
         WastedFrames  = 0,
         Log           = parameters.LogStart,
         APressCounter = 1,
         IGT           = initialState,
     }, new HashSet <int>());
 }
Example #13
0
    private static void RecursiveSearch <Gb, T>(Gb[] gbs, DFParameters <Gb, T> parameters, DFState <T> state, HashSet <int> seenStates) where Gb : GameBoy
        where T : Tile <T>
    {
        if (parameters.EndTiles != null && state.EdgeSet == parameters.EndEdgeSet && parameters.EndTiles.Any(t => t.X == state.Tile.X && t.Y == state.Tile.Y))
        {
            if (parameters.FoundCallback != null)
            {
                parameters.FoundCallback(state);
            }
            else
            {
                Console.WriteLine(state.Log);
            }
        }

        if (parameters.PruneAlreadySeenStates && !seenStates.Add(state.GetHashCode()))
        {
            return;
        }

        byte[][] states = state.IGT.States;

        foreach (Edge <T> edge in state.Tile.Edges[state.EdgeSet])
        {
            if (state.WastedFrames + edge.Cost > parameters.MaxCost)
            {
                continue;
            }
            if ((state.BlockedActions & edge.Action) > 0)
            {
                continue;
            }

            IGTResults results = GameBoy.IGTCheckParallel <Gb>(gbs, states, gb => gb.Execute(edge.Action) == gb.OverworldLoopAddress, parameters.EncounterCallback == null ? parameters.NoEncounterSS : 0);

            DFState <T> newState = new DFState <T>()
            {
                Tile         = edge.NextTile,
                EdgeSet      = edge.NextEdgeset,
                Log          = state.Log + edge.Action.LogString() + " ",
                IGT          = results,
                WastedFrames = state.WastedFrames + edge.Cost,
            };

            int noEncounterSuccesses = results.TotalSuccesses;
            if (parameters.EncounterCallback != null)
            {
                int encounterSuccesses = results.TotalFailures;
                for (int i = 0; i < results.NumIGTFrames && encounterSuccesses >= parameters.EncounterSS; i++)
                {
                    gbs[0].LoadState(results.States[i]);
                    if (parameters.EncounterCallback(gbs[0]))
                    {
                        encounterSuccesses++;
                    }
                }

                if (encounterSuccesses >= parameters.EncounterSS)
                {
                    if (parameters.FoundCallback != null)
                    {
                        parameters.FoundCallback(newState);
                    }
                    else
                    {
                        Console.WriteLine(state.Log);
                    }
                }
            }

            if (noEncounterSuccesses >= parameters.NoEncounterSS)
            {
                Action blockedActions = state.BlockedActions;

                if (edge.Action == Action.A)
                {
                    blockedActions |= Action.StartB;
                }
                if ((edge.Action & Action.A) > 0)
                {
                    blockedActions |= Action.A;
                }
                else
                {
                    blockedActions &= ~(Action.A | Action.StartB);
                }

                newState.BlockedActions = blockedActions;
                RecursiveSearch(gbs, parameters, newState, seenStates);
            }
        }
    }