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