Skip to content

Commit

Permalink
Fixing search algorithm bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
AthenaADP committed Aug 25, 2019
1 parent ba34115 commit cd96a8a
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 32 deletions.
52 changes: 48 additions & 4 deletions Armor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,17 +389,24 @@ unsigned GetTier( const unsigned hr )
return hr > 5 ? 1 : 0;
}

bool Armor::MatchesQuery( Query^ query, const bool allow_full )
bool Armor::MeetsRequirements( Query^ query, const bool allow_full )
{
//check requirements
if( !query->include_arena && this->arena ||
!query->allow_lower_tier && GetTier( this ) < GetTier( query->hr ) ||
gender != Gender::BOTH_GENDERS && gender != query->gender ||
this->dlc_disabled ||
this->dlc_disabled ||
!allow_full && this->full_set ||
query->hr < this->hr )
return false;

return true;
}

bool Armor::MatchesQuery( Query^ query, const bool allow_full )
{
if( !MeetsRequirements( query, allow_full ) )
return false;

//check for relevant skills
total_relevant_skill_points = 0;
for each( AbilityPair^ ap in abilities )
Expand All @@ -408,7 +415,7 @@ bool Armor::MatchesQuery( Query^ query, const bool allow_full )
total_relevant_skill_points += ap->amount;
}

return total_relevant_skill_points > 0;
return total_relevant_skill_points > 0 || total_slots > 0;
}

bool Armor::IsBetterAtNonSkills( Armor^ other )
Expand Down Expand Up @@ -464,6 +471,43 @@ bool Armor::IsBetterThan( Armor^ other, List_t< Ability^ >^ rel_abilities )
return total_relevant_points > other_total_relevant_points || ( !somewhat_worse && this->IsBetterAtNonSkills( other ) );
}

bool Armor::IsStrictlyBetterThan( Armor^ other )
{
if( this->full_set || other->full_set )
return false;

if( this->total_slots < other->total_slots ||
this->highest_slot_level < other->highest_slot_level ||
this->total_slot_level < other->total_slot_level ||
this->slot_product < other->slot_product )
return false;

if( SpecificAbility::nonelemental_boost->relevant && this->has_free_element && !other->has_free_element )
return false;

int total_relevant_points = 0, other_total_relevant_points = 0;

for each( AbilityPair^ ap in abilities )
{
int my_skill_at = this->GetSkillAt( ap->ability );
int other_skill_at = other->GetSkillAt( ap->ability );

if( my_skill_at < other_skill_at )
return false;
}

for each( AbilityPair^ ap in other->abilities )
{
int my_skill_at = this->GetSkillAt( ap->ability );
int other_skill_at = other->GetSkillAt( ap->ability );

if( my_skill_at < other_skill_at )
return false;
}

return true;
}

unsigned Armor::GetSkillAt( Ability^ ability )
{
for each( AbilityPair^ apair in abilities )
Expand Down
2 changes: 2 additions & 0 deletions Armor.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ ref struct Armor : public AdvancedSearchOptions

bool IsBetterThan( Armor^ other, List_t< Ability^ >^ rel_abilities );
bool IsBetterAtNonSkills( Armor^ other );
bool IsStrictlyBetterThan( Armor^ other );
unsigned GetSkillAt( Ability^ ability );

bool MatchesQuery( Query^ query, const bool allow_full );
bool MeetsRequirements( Query^ query, const bool allow_full );

bool ContainsAnyAbility( List_t< Ability^ >% to_search );

Expand Down
22 changes: 15 additions & 7 deletions Form1.h
Original file line number Diff line number Diff line change
Expand Up @@ -1904,15 +1904,22 @@ namespace MHWASS

for( int p = 0; p < int( Armor::ArmorType::NumArmorTypes ); ++p )
{
List_t< String^ > old, nnu;
for each( Armor^ a in query->rel_armor[ p ] )
old.Add( a->name );

query->rel_armor[ p ]->Clear();
List_t< Armor^ >^ ilist = query->inf_armor[ p ];
query->inf_armor[ p ] = gcnew List_t< Armor^ >();
for( int i = 0; i < ilist->Count; ++i )
/*for( int i = 0; i < ilist->Count; ++i )
{
if( !ilist[ i ]->force_disable )
AddToList( query->rel_armor[ p ], ilist[ i ], %query->rel_abilities, query->inf_armor[ p ], false );
}
}*/

data->GetRelevantArmors( query, query->rel_armor[ p ], Armor::static_armors[ p ], query->inf_armor[ p ], true );
for each( Armor^ a in query->rel_armor[ p ] )
nnu.Add( a->name );
#ifdef _DEBUG
for( int i = 0; i < ilist->Count; ++i )
{
Expand Down Expand Up @@ -2105,18 +2112,19 @@ namespace MHWASS

System::Text::StringBuilder sb( solutions->Count * 1024 );

if( last_result ) sb.Append( last_result );
if( last_result )
sb.Append( last_result );

System::String^ dash = L"-----------------";
int count = 0;
for each( Solution^ solution in solutions )
{
if( ++count > MAX_LIMIT )
break;

if( solution->HasDLCDisabledArmor() )
continue;

if( ++count > MAX_LIMIT )
break;

sb.Append( endl );
result_offsets.Add( ++offset );

Expand Down Expand Up @@ -2245,7 +2253,7 @@ namespace MHWASS
final_solutions.AddRange( solutions );

System::Text::StringBuilder sb2;
sb2.Append( StartString( SolutionsFound ) )->AppendLine( Convert::ToString( final_solutions.Count ) );
sb2.Append( StartString( SolutionsFound ) )->AppendLine( Convert::ToString( count ) );

if( solutions->Count > MAX_LIMIT )
{
Expand Down
48 changes: 28 additions & 20 deletions LoadedData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,27 +113,25 @@ void AddToList( List_t< Decoration^ >^ list, Decoration^ item, List_t< Ability^
list->Add( item );
}

void AddToList( List_t< Armor^ >^ list, Armor^ armor, List_t< Ability^ >^ rel_abilities, List_t< Armor^ >^ inf_armor, const bool adv )
void AddToList( List_t< Armor^ >^ list, Armor^ armor, List_t< Ability^ >^ rel_abilities, List_t< Armor^ >^ inf_armor, const bool check_disabled )
{
if( adv && armor->force_disable )
if( check_disabled && armor->force_disable )
return;

#ifdef _DEBUG
const bool test = armor->name->StartsWith( L"Kaiser" );
#endif
//#ifdef _DEBUG
// const bool test = armor->name->StartsWith( L"Kaiser" );
//#endif

const bool may_remove_self = !adv/* || !armor->force_enable*/;
for( int i = 0; i < list->Count; ++i )
{
if( armor->IsBetterThan( list[ i ], rel_abilities ) )
{
const bool may_remove = !adv/* || !list[ i ]->force_enable*/;
if( may_remove && !list[ i ]->IsBetterThan( armor, rel_abilities ) )
if( !list[ i ]->IsBetterThan( armor, rel_abilities ) )
{
list->Remove( list[ i-- ] );
}
}
else if( may_remove_self && list[ i ]->IsBetterThan( armor, rel_abilities ) )
else if( list[ i ]->IsBetterThan( armor, rel_abilities ) )
{
if( inf_armor )
{
Expand All @@ -147,28 +145,30 @@ void AddToList( List_t< Armor^ >^ list, Armor^ armor, List_t< Ability^ >^ rel_ab
inf_armor->Add( armor );
}

bool IsBonusArmor( Armor^ a )
bool IsBonusArmor( Armor^ a, Query^ query )
{
return a->total_slots >= 2 && a->highest_slot_level > 1 && a->abilities.Count > 0;
return a->MeetsRequirements( query, false ) && a->total_slots >= 2 && a->highest_slot_level > 1 && a->abilities.Count > 0;
}

int CompareArmorByIndex( Armor^ a, Armor^ b )
{
return a->index < b->index ? -1 : b->index < a->index ? 1 : 0;
}

void GetRelevantArmors( Query^ query, List_t< Armor^ >^ rel_armor, List_t< Armor^ >^ list, List_t< Armor^ >^ inf_armor )
void LoadedData::GetRelevantArmors( Query^ query, List_t< Armor^ >^ rel_armor, List_t< Armor^ >^ list, List_t< Armor^ >^ inf_armor, const bool check_disabled )
{
List_t< Armor^ > bonus_armor;

for each( Armor^ armor in list )
{
//const bool test = armor->name->StartsWith( L"Kulve" );

armor->relevant = false;
if( armor->MatchesQuery( query, false ) )
{
AddToList( rel_armor, armor, %query->rel_abilities, inf_armor, false );
}
else if( IsBonusArmor( armor ) )
else if( IsBonusArmor( armor, query ) && !( check_disabled && armor->force_disable ) )
bonus_armor.Add( armor );
}

Expand All @@ -177,10 +177,9 @@ void GetRelevantArmors( Query^ query, List_t< Armor^ >^ rel_armor, List_t< Armor
for( int i = 0; i < rel_armor->Count; ++i )
{
Armor^ alpha = rel_armor[ i ]->alpha_version;
if( alpha && alpha->total_relevant_skill_points > 0 && !Utility::Contains( inf_armor, alpha ) )
if( alpha && alpha->total_relevant_skill_points > 0 && !alpha->dlc_disabled && !( check_disabled && alpha->force_disable ) && !Utility::Contains( inf_armor, alpha ) )
{
inf_armor->Insert( i, alpha );
++i;
inf_armor->Add( alpha );
}
}
}
Expand All @@ -200,7 +199,7 @@ void GetRelevantArmors( Query^ query, List_t< Armor^ >^ rel_armor, List_t< Armor
{
Armor^ a = inf_armor[ i ];
if( a->total_relevant_skill_points == 0 &&
!IsBonusArmor( a ) &&
!IsBonusArmor( a, query ) &&
a->total_slots < 3 &&
a->total_slots <= max_num_slots &&
a->highest_slot_level <= max_slot_level &&
Expand All @@ -210,12 +209,21 @@ void GetRelevantArmors( Query^ query, List_t< Armor^ >^ rel_armor, List_t< Armor
inf_armor->RemoveAt( i-- );
}

for each( Armor^ armor in rel_armor )
{
for( int i = 0; i < inf_armor->Count; ++i )
{
if( inf_armor[ i ]->total_relevant_skill_points == 0 && !IsBonusArmor( inf_armor[ i ], query ) && armor->IsStrictlyBetterThan( inf_armor[ i ] ) )
inf_armor->RemoveAt( i-- );
}
}

if( bonus_armor.Count > 0 )
{
inf_armor->AddRange( %bonus_armor );

inf_armor->Sort( gcnew Comparison< Armor^ >( CompareArmorByIndex ) );
}

inf_armor->Sort( gcnew Comparison< Armor^ >( CompareArmorByIndex ) );
}

void GetRelevantDecorations( Query^ query )
Expand Down Expand Up @@ -288,7 +296,7 @@ void LoadedData::GetRelevantData( Query^ query )
//get relevant armors
for( int i = 0; i < int( Armor::ArmorType::NumArmorTypes ); ++i )
{
GetRelevantArmors( query, query->rel_armor[ i ], Armor::static_armors[ i ], query->inf_armor[ i ] );
GetRelevantArmors( query, query->rel_armor[ i ], Armor::static_armors[ i ], query->inf_armor[ i ], false );

query->rel_armor[ i ]->TrimExcess();
}
Expand Down
2 changes: 2 additions & 0 deletions LoadedData.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ ref class LoadedData
void LoadDataFiles();

void GetRelevantData( Query^ query );

void GetRelevantArmors( Query^ query, List_t< Armor^ >^ rel_armor, List_t< Armor^ >^ list, List_t< Armor^ >^ inf_armor, const bool check_disabled );
};
2 changes: 1 addition & 1 deletion Solution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ void Solution::FindArmorSwaps( Query^ query )
//search unused armors for potential swaps
for each( Armor^ other_armor in query->inf_armor[ armor_type ] )
{
if( other_armor->force_disable )
if( other_armor->force_disable || other_armor->relevant || other_armor->dlc_disabled )
continue;

if( other_armor->total_slots + other_armor->total_relevant_skill_points < total_required )
Expand Down

0 comments on commit cd96a8a

Please sign in to comment.