public static void StartSearch(int numThreads, int minDelay, int maxDelay) { Console.WriteLine("Buffered=" + Buffered + ", Overflow=" + Overflow); List <byte[][]> stateList = new List <byte[][]>(); MakeSave(); Gold gb = new Gold(true); List <GscTile> endTiles = new List <GscTile>() { r29[38, 16] }; gb.SetTimeSec(120); for (int i = 0; i <= (maxDelay - minDelay); i++) { stateList.Add(new byte[60][]); } new GscIntroSequence(GscStrat.GfSkip, GscStrat.TitleSkip, GscStrat.Continue).ExecuteUntilIGT(gb); gb.AdvanceFrames(minDelay, Joypad.Left); byte[] state = gb.SaveState(); for (int i = 0; i < stateList.Count(); i++) { for (int igt = 0; igt < 60; igt++) { gb.LoadState(state); gb.CpuWrite("wGameTimeFrames", (byte)igt); gb.AdvanceFrames(i, Joypad.Left); gb.Hold(Joypad.A, "OWPlayerInput"); stateList[i][igt] = gb.SaveState(); } } RandomPathSearch.StartSearch <Gold, GscTile>(numThreads, new RandomSearchParameters <GscTile>() { StateList = stateList, ClusterSize = 1, SS = 60, NumPathsToFind = int.MaxValue, StartEdgeSet = 0, StartTile = gb.Tile, EndTiles = endTiles.ToArray(), ExecutionCallback = (gb, actions) => gb.Execute(actions) == gb.OverworldLoopAddress, FoundCallback = (stateIndex, actions, successes) => { lock (startWriter) { startWriter.WriteLine(successes + " " + stateIndex + " " + ActionFunctions.ActionsToPath(actions)); startWriter.Flush(); } }, }); }
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); } }
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); } }