Skip to content
Merged
4 changes: 4 additions & 0 deletions SerialPrograms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2222,6 +2222,8 @@ file(GLOB MAIN_SOURCES
Source/PokemonSwSh/Programs/RNG/PokemonSwSh_BasicRNG.h
Source/PokemonSwSh/Programs/RNG/PokemonSwSh_CramomaticRNG.cpp
Source/PokemonSwSh/Programs/RNG/PokemonSwSh_CramomaticRNG.h
Source/PokemonSwSh/Programs/RNG/PokemonSwSh_DailyHighlightRNG.cpp
Source/PokemonSwSh/Programs/RNG/PokemonSwSh_DailyHighlightRNG.h
Source/PokemonSwSh/Programs/RNG/PokemonSwSh_SeedFinder.cpp
Source/PokemonSwSh/Programs/RNG/PokemonSwSh_SeedFinder.h
Source/PokemonSwSh/Programs/ShinyHuntAutonomous/PokemonSwSh_ShinyHuntAutonomous-BerryTree.cpp
Expand Down Expand Up @@ -2260,6 +2262,8 @@ file(GLOB MAIN_SOURCES
Source/PokemonSwSh/Programs/ShinyHuntUnattended/PokemonSwSh_ShinyHuntUnattended-SwordsOfJustice.h
Source/PokemonSwSh/Programs/TestPrograms/PokemonSwSh_ShinyEncounterTester.cpp
Source/PokemonSwSh/Programs/TestPrograms/PokemonSwSh_ShinyEncounterTester.h
Source/PokemonSwSh/Resources/PokemonSwSh_DailyHighlightDatabase.cpp
Source/PokemonSwSh/Resources/PokemonSwSh_DailyHighlightDatabase.h
Source/PokemonSwSh/Resources/PokemonSwSh_MaxLairDatabase.cpp
Source/PokemonSwSh/Resources/PokemonSwSh_MaxLairDatabase.h
Source/PokemonSwSh/Resources/PokemonSwSh_NameDatabase.cpp
Expand Down
16 changes: 16 additions & 0 deletions SerialPrograms/Source/Pokemon/Pokemon_Xoroshiro128Plus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,22 @@ std::vector<bool> Xoroshiro128Plus::generate_last_bit_sequence(size_t max_advanc
return sequence;
}


std::pair<bool, uint64_t> Xoroshiro128Plus::advances_to_state(Xoroshiro128PlusState other_state, uint64_t max_advances) {
Xoroshiro128Plus temp_rng(get_state());
uint64_t advances = 0;

while (advances <= max_advances) {
Xoroshiro128PlusState temp_state = temp_rng.get_state();
if (temp_state.s0 == other_state.s0 && temp_state.s1 == other_state.s1) {
return { true, advances };
}
temp_rng.next();
advances++;
}
return { false, advances };
}

// The generic solution to the system of equations to calculate the initial state from the last bits of 128 consecutive Xoroshiro128+ results.
uint64_t Xoroshiro128Plus::last_bits_reverse_matrix[128][2] = {
/*s0 bit 0*/ {0b0101001100100001111011111110111001010011111110101011100011001101, 0b0111010111110111000101010100001111101001111001011111001011010111} ,
Expand Down
7 changes: 7 additions & 0 deletions SerialPrograms/Source/Pokemon/Pokemon_Xoroshiro128Plus.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ class Xoroshiro128Plus{
Xoroshiro128PlusState get_state();
std::vector<bool> generate_last_bit_sequence(size_t max_advances);

// Calculates how many advances are required to reach the given state.
// The given state must be reachable within max_advances advances.
// Returns a pair:
// first: true if the state is reachable within max_advances, false otherwise
// second: the number of advances required (if first is true)
std::pair<bool, uint64_t> advances_to_state(Xoroshiro128PlusState other_state, uint64_t max_advances = 100000);

static Xoroshiro128Plus xoroshiro128plus_from_last_bits(std::pair<uint64_t, uint64_t> last_bits);


Expand Down
4 changes: 3 additions & 1 deletion SerialPrograms/Source/PokemonSwSh/PokemonSwSh_Panels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
#include "Programs/OverworldBot/PokemonSwSh_ShinyHuntAutonomous-Overworld.h"

#include "Programs/RNG/PokemonSwSh_CramomaticRNG.h"
#include "Programs/RNG/PokemonSwSh_DailyHighlightRNG.h"
#include "Programs/RNG/PokemonSwSh_SeedFinder.h"

#include "Programs/PokemonSwSh_SynchronizedSpinning.h"
Expand Down Expand Up @@ -200,7 +201,8 @@ std::vector<PanelEntry> PanelListFactory::make_panels() const{
ret.emplace_back(make_single_switch_program<ShinyHuntUnattendedIoATrade_Descriptor, ShinyHuntUnattendedIoATrade>());

if (PreloadSettings::instance().DEVELOPER_MODE){
// ret.emplace_back("---- Untested/Beta/WIP ----");
ret.emplace_back("---- Untested/Beta/WIP ----");
ret.emplace_back(make_single_switch_program<DailyHighlightRNG_Descriptor, DailyHighlightRNG>());
}
if (PreloadSettings::instance().DEVELOPER_MODE){
ret.emplace_back("---- Developer Tools ----");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ Xoroshiro128PlusState find_rng_state(
return rng.get_state();
}


Xoroshiro128PlusState refind_rng_state(
VideoStream& stream,
ProControllerContext& context,
Expand All @@ -75,6 +74,18 @@ Xoroshiro128PlusState refind_rng_state(
size_t max_advances,
bool save_screenshots,
bool log_image_values
) {
return refind_rng_state_and_animations(stream, context, last_known_state, min_advances, max_advances, save_screenshots, log_image_values).first;
}

std::pair<Xoroshiro128PlusState, uint64_t> refind_rng_state_and_animations(
VideoStream& stream,
ProControllerContext& context,
Xoroshiro128PlusState last_known_state,
size_t min_advances,
size_t max_advances,
bool save_screenshots,
bool log_image_values
)
{
Xoroshiro128Plus rng(last_known_state.s0, last_known_state.s1);
Expand Down Expand Up @@ -140,7 +151,7 @@ Xoroshiro128PlusState refind_rng_state(
stream.log("RNG: state[0] = " + tostr_hex(rng.get_state().s0));
stream.log("RNG: state[1] = " + tostr_hex(rng.get_state().s1));

return rng.get_state();
return { rng.get_state(), sequence.size() };
}


Expand Down Expand Up @@ -169,6 +180,18 @@ void do_rng_advances(
pbf_wait(context, 1000ms);
}

Xoroshiro128PlusState predict_state_after_menu_close(Xoroshiro128PlusState current_state, uint8_t num_npcs) {
Xoroshiro128Plus rng(current_state);

for (size_t i = 0; i < num_npcs; i++) {
rng.nextInt(91);
}
rng.next();
rng.nextInt(61);

return rng.get_state();
}


}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "NintendoSwitch/Controllers/NintendoSwitch_ProController.h"
#include "Pokemon/Pokemon_Xoroshiro128Plus.h"


namespace PokemonAutomation{
namespace NintendoSwitch{
namespace PokemonSwSh{
Expand All @@ -33,6 +34,20 @@ Xoroshiro128PlusState refind_rng_state(
bool log_values
);

// Performs Orbeetle attack animations until only one possible state is left.
// Returns a pair:
// first: current RNG state
// second: the number of animations required to find the state
std::pair<Xoroshiro128PlusState, uint64_t> refind_rng_state_and_animations(
VideoStream& stream,
ProControllerContext& context,
Xoroshiro128PlusState last_known_state,
size_t min_advances,
size_t max_advances,
bool save_screenshots,
bool log_values
);

void do_rng_advances(
VideoStream& stream, ProControllerContext& context,
Xoroshiro128Plus& rng,
Expand All @@ -41,6 +56,8 @@ void do_rng_advances(
Milliseconds release_duration
);

Xoroshiro128PlusState predict_state_after_menu_close(Xoroshiro128PlusState current_state, uint8_t num_npcs);



}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,13 +194,9 @@ CramomaticTarget CramomaticRNG::calculate_target(SingleSwitchProgramEnvironment&
// priority_advances only starts counting up after the first good result is found
while (priority_advances <= MAX_PRIORITY_ADVANCES){
// calculate the result for the current temp_rng state
Xoroshiro128Plus temp_rng(rng.get_state());
Xoroshiro128PlusState temp_state = predict_state_after_menu_close(rng.get_state(), NUM_NPCS);
Xoroshiro128Plus temp_rng(temp_state);

for (size_t i = 0; i < NUM_NPCS; i++){
temp_rng.nextInt(91);
}
temp_rng.next();
temp_rng.nextInt(60);

/*uint64_t item_roll =*/ temp_rng.nextInt(4);
uint64_t ball_roll = temp_rng.nextInt(100);
Expand Down
Loading
Loading