Skip to content

Commit 1a63abc

Browse files
author
Gin
committed
refactor Home sorting code
1 parent 6599616 commit 1a63abc

File tree

7 files changed

+240
-180
lines changed

7 files changed

+240
-180
lines changed

SerialPrograms/Source/PokemonHome/Options/PokemonHome_BoxSortingTable.cpp renamed to SerialPrograms/Source/Pokemon/Options/Pokemon_BoxSortingTable.cpp

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,20 @@
44
*
55
*/
66

7-
#include "PokemonHome_BoxSortingTable.h"
7+
#include "Pokemon_BoxSortingTable.h"
88

99
namespace PokemonAutomation{
10-
namespace NintendoSwitch{
11-
namespace PokemonHome{
12-
13-
14-
const EnumDropdownDatabase<BoxSortingSortType>& BallType_Database(){
15-
static const EnumDropdownDatabase<BoxSortingSortType> database({
16-
{BoxSortingSortType::NationalDexNo, "dex", "National Dex Number"},
17-
{BoxSortingSortType::Shiny, "shiny", "Shiny"},
18-
{BoxSortingSortType::Gigantamax, "gigantamax", "Gigantamax"},
19-
{BoxSortingSortType::Alpha, "alpha", "Alpha"},
20-
{BoxSortingSortType::Ball_Slug, "ball_slug", "Ball Type"},
21-
{BoxSortingSortType::Gender, "gender", "Gender (Male, Female, Genderless)"},
10+
namespace Pokemon{
11+
12+
13+
const EnumDropdownDatabase<SortingRuleType>& BallType_Database(){
14+
static const EnumDropdownDatabase<SortingRuleType> database({
15+
{SortingRuleType::NationalDexNo, "dex", "National Dex Number"},
16+
{SortingRuleType::Shiny, "shiny", "Shiny"},
17+
{SortingRuleType::Gigantamax, "gigantamax", "Gigantamax"},
18+
{SortingRuleType::Alpha, "alpha", "Alpha"},
19+
{SortingRuleType::Ball_Slug, "ball_slug", "Ball Type"},
20+
{SortingRuleType::Gender, "gender", "Gender (Male, Female, Genderless)"},
2221
});
2322
return database;
2423
}
@@ -27,7 +26,7 @@ const EnumDropdownDatabase<BoxSortingSortType>& BallType_Database(){
2726

2827
BoxSortingRow::BoxSortingRow(EditableTableOption& parent_table)
2928
: EditableTableRow(parent_table)
30-
, sort_type(BallType_Database(), LockMode::LOCK_WHILE_RUNNING, BoxSortingSortType::NationalDexNo)
29+
, sort_type(BallType_Database(), LockMode::LOCK_WHILE_RUNNING, SortingRuleType::NationalDexNo)
3130
, reverse(LockMode::LOCK_WHILE_RUNNING, false)
3231
{
3332
PA_ADD_OPTION(sort_type);
@@ -50,12 +49,12 @@ BoxSortingTable::BoxSortingTable(std::string label)
5049
{}
5150

5251

53-
std::vector<BoxSortingSelection> BoxSortingTable::preferences() const{
52+
std::vector<SortingRule> BoxSortingTable::preferences() const{
5453
std::vector<std::unique_ptr<BoxSortingRow>> table = copy_snapshot();
55-
std::vector<BoxSortingSelection> selections;
54+
std::vector<SortingRule> selections;
5655
for (const std::unique_ptr<BoxSortingRow>& row : table){
57-
BoxSortingSelection selection;
58-
selection.sort_type = BoxSortingSortType(row->sort_type.current_value());
56+
SortingRule selection;
57+
selection.sort_type = SortingRuleType(row->sort_type.current_value());
5958
selection.reverse = row->reverse.current_value();
6059

6160
selections.emplace_back(selection);
@@ -86,14 +85,5 @@ std::vector<std::unique_ptr<EditableTableRow>> BoxSortingTable::make_defaults(){
8685

8786

8887

89-
90-
91-
92-
93-
94-
95-
96-
97-
}
9888
}
9989
}

SerialPrograms/Source/PokemonHome/Options/PokemonHome_BoxSortingTable.h renamed to SerialPrograms/Source/Pokemon/Options/Pokemon_BoxSortingTable.h

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
1-
/* Cram-o-matic Table
1+
/* Box Sorting Table
22
*
33
* From: https://github.com/PokemonAutomation/
44
*
55
*/
66

7-
#ifndef PokemonAutomation_PokemonHome_BoxSortingTable_H
8-
#define PokemonAutomation_PokemonHome_BoxSortingTable_H
7+
#ifndef PokemonAutomation_Pokemon_BoxSortingTable_H
8+
#define PokemonAutomation_Pokemon_BoxSortingTable_H
99

1010
#include "Common/Cpp/Options/EditableTableOption.h"
1111
#include "Common/Cpp/Options/SimpleIntegerOption.h"
1212
#include "Common/Cpp/Options/BooleanCheckBoxOption.h"
1313
#include "Common/Cpp/Options/EnumDropdownOption.h"
1414

1515
namespace PokemonAutomation{
16-
namespace NintendoSwitch{
17-
namespace PokemonHome{
16+
namespace Pokemon{
1817

19-
enum class BoxSortingSortType
18+
enum class SortingRuleType
2019
{
2120
NationalDexNo,
2221
Shiny,
@@ -26,10 +25,10 @@ enum class BoxSortingSortType
2625
Gender,
2726
};
2827

29-
struct BoxSortingSelection
28+
struct SortingRule
3029
{
31-
BoxSortingSortType sort_type;
32-
bool reverse;
30+
SortingRuleType sort_type = SortingRuleType::NationalDexNo;
31+
bool reverse = false;
3332
};
3433

3534
class BoxSortingRow : public EditableTableRow{
@@ -38,7 +37,7 @@ class BoxSortingRow : public EditableTableRow{
3837
virtual std::unique_ptr<EditableTableRow> clone() const;
3938

4039
public:
41-
EnumDropdownCell<BoxSortingSortType> sort_type;
40+
EnumDropdownCell<SortingRuleType> sort_type;
4241
BooleanCheckBoxCell reverse;
4342
};
4443

@@ -48,7 +47,7 @@ class BoxSortingTable : public EditableTableOption_t<BoxSortingRow>{
4847
public:
4948
BoxSortingTable(std::string label);
5049

51-
std::vector<BoxSortingSelection> preferences() const;
50+
std::vector<SortingRule> preferences() const;
5251

5352
virtual std::vector<std::string> make_header() const;
5453

@@ -59,7 +58,6 @@ class BoxSortingTable : public EditableTableOption_t<BoxSortingRow>{
5958

6059

6160

62-
}
6361
}
6462
}
6563
#endif
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/* Collected Pokemon Info
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
#include "Common/Cpp/Exceptions.h"
8+
#include "Pokemon/Pokemon_Strings.h"
9+
#include "Pokemon/Resources/Pokemon_PokemonNames.h"
10+
#include "Pokemon/Resources/Pokemon_PokemonSlugs.h"
11+
#include "Pokemon_CollectedPokemonInfo.h"
12+
13+
namespace PokemonAutomation{
14+
namespace Pokemon{
15+
16+
17+
bool operator==(const CollectedPokemonInfo& lhs, const CollectedPokemonInfo& rhs){
18+
// NOTE edit when adding new struct members
19+
return lhs.national_dex_number == rhs.national_dex_number &&
20+
lhs.shiny == rhs.shiny &&
21+
lhs.gmax == rhs.gmax &&
22+
lhs.alpha == rhs.alpha &&
23+
lhs.ball_slug == rhs.ball_slug &&
24+
lhs.gender == rhs.gender &&
25+
lhs.ot_id == rhs.ot_id;
26+
}
27+
28+
// Sort two pokemon slot. "Smaller" pokemon is placed closer to front.
29+
// If a slot is empty, it is always larger than non-empty slot so all the empty slots are at end after sorting.
30+
// For two pokemon, check each preference rule. If we cannot determine the order based on the first rule, go
31+
// to the second rule, and so on.
32+
// Available rules:
33+
// - National dex number: smaller ID should be at front.
34+
// - Shiny: shiny pokemon should be at front.
35+
// - Gigantamax: Gigantamax pokemon should be at front.
36+
// - Alpha: Alpha pokemon should be at front.
37+
// - Ball slug: pokemon with a ball slug that's smaller in the alphabetical order should be at front.
38+
// - Gender: Male should be at front, then comes female, and genderless is last
39+
// Each rule type also has a "reverse" which if true, reverses above ordering for that rule type.
40+
// If user does not give a preference ruleset, sort by national dex number.
41+
bool operator<(const std::optional<CollectedPokemonInfo>& lhs, const std::optional<CollectedPokemonInfo>& rhs){
42+
if (!lhs.has_value()){ // lhs is empty
43+
return false;
44+
}
45+
if (!rhs.has_value()){ // lhs not empty but rhs is empty
46+
return true;
47+
}
48+
// both sides are not empty:
49+
for (const SortingRule& preference : *lhs->preferences){
50+
switch(preference.sort_type){
51+
// NOTE edit when adding new struct members
52+
case SortingRuleType::NationalDexNo:
53+
if (lhs->national_dex_number != rhs->national_dex_number){
54+
// we use (boolean != reverse) to apply the reverse effect
55+
return (lhs->national_dex_number < rhs->national_dex_number) != preference.reverse;
56+
}
57+
break;
58+
case SortingRuleType::Shiny:
59+
if (lhs->shiny != rhs->shiny){
60+
return lhs->shiny != preference.reverse;
61+
}
62+
break;
63+
case SortingRuleType::Gigantamax:
64+
if (lhs->gmax != rhs->gmax){
65+
return lhs->gmax != preference.reverse;
66+
}
67+
break;
68+
case SortingRuleType::Alpha:
69+
if (lhs->alpha != rhs->alpha){
70+
return lhs->gmax != preference.reverse;
71+
}
72+
break;
73+
case SortingRuleType::Ball_Slug:
74+
if (lhs->ball_slug != rhs->ball_slug){
75+
return (lhs->ball_slug < rhs->ball_slug) != preference.reverse;
76+
}
77+
break;
78+
case SortingRuleType::Gender:
79+
if (lhs->gender != rhs->gender){
80+
return (lhs->gender < rhs->gender) != preference.reverse;
81+
}
82+
break;
83+
default:
84+
throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "unknown SortingRuleType");
85+
} // end switch
86+
} // end for preference
87+
88+
// Default to sort by national dex number
89+
return lhs->national_dex_number < rhs->national_dex_number;
90+
}
91+
92+
std::ostream& operator<<(std::ostream& os, const std::optional<CollectedPokemonInfo>& pokemon)
93+
{
94+
if (pokemon.has_value()){
95+
// NOTE edit when adding new struct members
96+
os << "(";
97+
os << "national_dex_number:" << pokemon->national_dex_number << " ";
98+
os << "shiny:" << (pokemon->shiny ? "true" : "false") << " ";
99+
os << "gmax:" << (pokemon->gmax ? "true" : "false") << " ";
100+
os << "alpha:" << (pokemon->alpha ? "true" : "false") << " ";
101+
os << "ball_slug:" << pokemon->ball_slug << " ";
102+
os << "gender:" << gender_to_string(pokemon->gender) << " ";
103+
os << "ot_id:" << pokemon->ot_id << " ";
104+
os << ")";
105+
}else{
106+
os << "(empty)";
107+
}
108+
return os;
109+
}
110+
111+
std::string create_overlay_info(const CollectedPokemonInfo& pokemon){
112+
const std::string& species_slug = NATIONAL_DEX_SLUGS()[pokemon.national_dex_number-1];
113+
const std::string& display_name = get_pokemon_name(species_slug).display_name();
114+
std::string overlay_log = display_name;
115+
if(pokemon.gender == StatsHuntGenderFilter::Male){
116+
overlay_log += " " + UNICODE_MALE;
117+
} else if (pokemon.gender == StatsHuntGenderFilter::Female){
118+
overlay_log += " " + UNICODE_FEMALE;
119+
}
120+
if (pokemon.shiny){
121+
overlay_log += " *";
122+
}
123+
if (pokemon.gmax){
124+
overlay_log += " G";
125+
}
126+
if (pokemon.alpha){
127+
overlay_log += " " + UNICODE_ALPHA;
128+
}
129+
return overlay_log;
130+
}
131+
132+
133+
}
134+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/* Collected Pokemon Info
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
#ifndef PokemonAutomation_Pokemon_CollectedPokemonInfo_H
8+
#define PokemonAutomation_Pokemon_CollectedPokemonInfo_H
9+
10+
#include <cstdint>
11+
#include <string>
12+
#include <optional>
13+
#include <vector>
14+
#include <ostream>
15+
#include "Pokemon/Options/Pokemon_StatsHuntFilter.h"
16+
#include "Pokemon/Options/Pokemon_BoxSortingTable.h"
17+
18+
namespace PokemonAutomation{
19+
namespace Pokemon{
20+
21+
22+
struct CollectedPokemonInfo{
23+
const std::vector<SortingRule>* preferences;
24+
25+
// When adding any new member here, do not forget to modify the operators below (ctrl-f "new struct members")
26+
uint16_t national_dex_number = 0;
27+
bool shiny = false;
28+
bool gmax = false;
29+
bool alpha = false;
30+
std::string ball_slug = "";
31+
StatsHuntGenderFilter gender = StatsHuntGenderFilter::Genderless;
32+
uint32_t ot_id = 0; // original trainer ID
33+
};
34+
35+
bool operator==(const CollectedPokemonInfo& lhs, const CollectedPokemonInfo& rhs);
36+
37+
// Sort two pokemon slot. "Smaller" pokemon is placed closer to front.
38+
// If a slot is empty, it is always larger than non-empty slot so all the empty slots are at end after sorting.
39+
// For two pokemon, check each preference rule. If we cannot determine the order based on the first rule, go
40+
// to the second rule, and so on.
41+
// Available rules:
42+
// - National dex number: smaller ID should be at front.
43+
// - Shiny: shiny pokemon should be at front.
44+
// - Gigantamax: Gigantamax pokemon should be at front.
45+
// - Alpha: Alpha pokemon should be at front.
46+
// - Ball slug: pokemon with a ball slug that's smaller in the alphabetical order should be at front.
47+
// - Gender: Male should be at front, then comes female, and genderless is last
48+
// Each rule type also has a "reverse" which if true, reverses above ordering for that rule type.
49+
// If user does not give a preference ruleset, sort by national dex number.
50+
bool operator<(const std::optional<CollectedPokemonInfo>& lhs, const std::optional<CollectedPokemonInfo>& rhs);
51+
52+
// Print pokemon info into ostream
53+
std::ostream& operator<<(std::ostream& os, const std::optional<CollectedPokemonInfo>& pokemon);
54+
55+
// Create short info of a pokemon for overlay log display
56+
std::string create_overlay_info(const CollectedPokemonInfo& pokemon);
57+
58+
59+
}
60+
}
61+
#endif

0 commit comments

Comments
 (0)