Ethan Hunt


Jump to: navigation, search



In the Pokémon games, each Pokémon is given either one or two types out of the 18 available types. Each type has its own weaknesses and strengths in battle, and trying to memorize the type chart can be difficult for beginning players to get a grasp of.


This is the best image available displaying the type chart that Pokémon uses in its game.

I have created a code that allows the user to select a type or types and it will tell the user what the weaknesses and strengths are for that type, basically an easy to use type chart so that the user can start to learn the matchups easier. I have given the user three options to choose from; Single Type, Dual Type, and Select Pokémon.

The single type allows the user to click a button out of the 18 different types and it will display the type matchups in the results slot at the bottom.

The dual typing allows the user to select from two types, the code keeping track of the types you have selected, and displays the type matchup for a Pokémon with the dual typing of the last two types the user chose.

The select Pokémon page allows the user to select a Pokémon from the 8 regions in the Pokémon universe, displaying the typing of the Pokémon and its type matchups when one is selected.


The code for this project was very long and difficult to make, having to make several adjustments along the way to make sure it was compact and able to work the intended way.

   //An array of all 18 types
   ArrayList<String> Types = new ArrayList<>(Arrays.asList("Normal", "Fire", "Water", "Electric", "Grass", "Ice", "Fighting", "Poison", "Ground", "Flying", "Psychic", "Bug", "Rock", "Ghost", "Dragon", "Dark", "Steel", "Fairy"));

The first thing that I needed to worry about was creating an array that stored all of the types that are in the games.

   //Buttons and Weaknesses/Strengths for Normal
   Button btNormalSingle = new Button("Normal"); Button btNormalDual = new Button("Normal");
   ArrayList<String> WeaknessesNormal = new ArrayList<>(Arrays.asList("Fighting"));
   ArrayList<String> StrengthsNormal = new ArrayList<>(Arrays.asList("Nothing"));
   ArrayList<String> NoEffectNormal = new ArrayList<>(Arrays.asList("Ghost"));

My second task was to create the different buttons that the user would be able to use on the single and dual type pages, along with the necessary weaknesses, strengths, and types that have no effect for all 18 types.

   //Labels and Buttons for the different pages
   Label lbSingle = new Label("Select a type: "); Label lbDual = new Label("Select two types: "); Label lbSelect = new Label("Select a Pokemon: ");
   Button btSingleDual = new Button("Single Type"); Button btSingleSelect = new Button("Single Type");
   Button btDualSingle = new Button("Dual Typing"); Button btDualSelect = new Button("Dual Typing"); Button btResult = new Button("Results");
   Button btSelectSingle = new Button("Select Pokemon"); Button btSelectDual = new Button("Select Pokemon");
   //Labels for the Pokemon Select page Combo Boxes
   Label lbKanto = new Label("Kanto (1 - 151): "); Label lbJohto = new Label("Johto (152 - 251): "); Label lbHoenn = new Label("Hoenn (252 - 386): "); Label lbSinnoh = new Label("Sinnoh (387 - 493): ");
   Label lbUnova = new Label("Unova (494 - 649): "); Label lbKalos = new Label("Kalos (650 - 721): "); Label lbAlola = new Label("Alola (722 - 809): "); Label lbGalar = new Label("Galar (810 - 898): ");
   //Labels displaying the results
   Label lbSingleResults = new Label(); Label lbDualResults = new Label(); Label lbSelectResults = new Label();
   //Labels displaying types chosen for the Dual Type page
   Label Type1 = new Label(""); Label Type2 = new Label("");

After that, I needed to make sure that I had all of the correct buttons to swap between pages and the text that was used to indicate what the user was supposed to do.

   ArrayList<String> KantoPokemon = new ArrayList<>(Arrays.asList("Kanto Pokemon", "001: Bulbasaur", "002: Ivysaur", "003: Venusaur", "003: Mega Venusaur", "003: G-Max Venusaur", "004: Charmander", "005: Charmeleon",
           "006: Charizard", "006: Mega Charizard X", "006: Mega Charizard Y", "006: G-Max Charizard", "007: Squirtle", "008: Wartortle", "009: Blastoise", "009: Mega Blastoise", "009: G-Max Blastoise", "010: Caterpie",
           "011: Metapod", "012: Butterfree", "012: G-Max Butterfree", "013: Weedle", "014: Kakuna", "015: Beedrill", "015: Mega Beedrill", "016: Pidgey", "017: Pidgeotto", "018: Pidgeot", "018: Mega Pidgeot",
           "019: Rattata", "019: Alolan Rattata", "020: Raticate", "020: Alolan Raticate", "021: Spearow", "022: Fearow", "023: Ekans", "024: Arbok", "025: Pikachu", "025: G-Max Pikachu", "026: Raichu", "026: Alolan Raichu",
           "027: Sandshrew", "027: Alolan Sandshrew", "028: Sandslash", "028: Alolan Sandslash", "029: Nidoran-F", "030: Nidorina", "031: Nidoqueen", "032: Nidoran-M", "033: Nidorino", "034: Nidoking", "035: Clefairy",
           "036: Clefable", "037: Vulpix", "037: Alolan Vulpix", "038: Ninetails", "038: Alolan Ninetails", "039: Jigglypuff", "040: Wigglytuff", "041: Zubat", "042: Golbat", "043: Oddish", "044: Gloom", "045: Vileplume",
           "046: Paras", "047: Parasect", "048: Venonat", "049: Venomoth", "050: Diglett", "050: Alolan Diglett", "051: Dugtrio", "051: Alolan Dugtrio", "052: Meowth", "052: Alolan Meowth", "052: Galarian Meowth",
           "052: G-Max Meowth", "053: Persian", "053: Alolan Persian", "054: Psyduck", "055: Golduck", "056: Mankey", "057: Primeape", "058: Growlithe", "059: Arcanine", "060: Poliwag", "061: Poliwhirl", "062: Poliwrath",
           "063: Abra", "064: Kadabra", "065: Alakazam", "065: Mega Alakazam", "066: Machop", "067: Machoke", "068: Machamp", "068: G-Max Machamp", "069: Bellsprout", "070: Weepinbell", "071: Victreebel", "072: Tentacool",
           "073: Tentacruel", "074: Geodude", "074: Alolan Geodude", "075: Graveler", "075: Alolan Graveler", "076: Golem", "076: Alolan Golem", "077: Ponyta", "077: Galarian Ponyta", "078: Rapidash", "078: Galarian Rapidash",
           "079: Slowpoke", "079: Galarian Slowpoke", "080: Slowbro", "080: Galarian Slowbro", "080: Mega Slowbro", "081: Magnemite", "082: Magneton", "083: Farfetch'd", "083: Galarian Farfetch'd", "084: Doduo", "085: Dodrio",
           "086: Seel", "087: Dewgong", "088: Grimer", "088: Alolan Grimer", "089: Muk", "089: Alolan Muk", "090: Shellder", "091: Cloyster", "092: Gastly", "093: Haunter", "094: Genger", "094: Mega Gengar", "094: G-Max Gengar",
           "095: Onix", "096: Drowzee", "097: Hypno", "098: Krabby", "099: Kingler", "099: G-Max Kingler", "100: Voltorb", "101: Electrode", "102: Exeggcute", "103: Exeggutor", "103: Alolan Exeggutor", "104: Cubone",
           "105: Marowak", "105: Alolan Marowak", "106: Hitmonlee", "107: Hitmonchan", "108: Lickitung", "109: Koffing", "110: Weezing", "110: Galarian Weezing", "111: Rhyhorn", "112: Rhydon", "113: Chansey", "114: Tangela",
           "115: Kangaskhan", "115: Mega Kangaskhan", "116: Horsea", "117: Seadra", "118: Goldeen", "119: Seaking", "120: Staryu", "121: Starmie", "122: Mr. Mime", "122: Galarian Mr. Mime", "123: Scyther", "124: Jynx",
           "125: Electabuzz", "126: Magmar", "127: Pinsir", "127: Mega Pinsir", "128: Tauros", "129: Magikarp", "130: Gyarados", "130: Mega Gyarados", "131: Lapras", "131: G-Max Lapras", "132: Ditto", "133: Eevee",
           "133: G-Max Eevee", "134: Vaporeon", "135: Jolteon", "136: Flareon", "137: Porygon", "138: Omanyte", "139: Omastar", "140: Kabuto", "141: Kabutops", "142: Aerodactyl", "142: Mega Aerodactyl", "143: Snorlax",
           "143: G-Max Snorlax", "144: Articuno", "144: Galarian Articuno", "145: Zapdos", "145: Galarian Zapdos", "146: Moltres", "146: Galarian Moltres", "147: Dratini", "148: Dragonair", "149: Dragonite", "150: Mewtwo",
           "150: Mega Mewtwo X", "150: Mega Mewtwo Y", "151: Mew"));
   ArrayList<String> KantoPokemonType1 = new ArrayList<>(Arrays.asList("Grass", "Grass", "Grass", "Grass", "Grass", "Fire", "Fire", "Fire", "Fire", "Fire", "Fire", "Water", "Water", "Water", "Water", "Water", "Bug",
           "Bug", "Bug", "Bug", "Bug", "Bug", "Bug", "Bug", "Normal", "Normal", "Normal", "Normal", "Normal", "Dark", "Normal", "Dark", "Normal", "Normal", "Poison", "Poison", "Electric", "Electric", "Electric", "Electric",
           "Ground", "Ice", "Ground", "Ice", "Poison", "Poison", "Poison", "Poison", "Poison", "Poison", "Fairy", "Fairy", "Fire", "Ice", "Fire", "Ice", "Normal", "Normal", "Poison", "Poison", "Grass", "Grass", "Grass", "Bug",
           "Bug", "Bug", "Bug", "Ground", "Ground", "Ground", "Ground", "Normal", "Dark", "Steel", "Normal", "Normal", "Dark", "Water", "Water", "Fighting", "Fighting", "Fire", "Fire", "Water", "Water", "Water", "Psychic",
           "Psychic", "Psychic", "Psychic", "Fighting", "Fighting", "Fighting", "Fighting", "Grass", "Grass", "Grass", "Water", "Water", "Rock", "Rock", "Rock", "Rock", "Rock", "Rock", "Fire", "Psychic", "Fire", "Psychic",
           "Water", "Psychic", "Water", "Psychic", "Water", "Electric", "Electric", "Normal", "Fighting", "Normal", "Normal", "Water", "Water", "Poison", "Poison", "Poison", "Poison", "Water", "Water", "Ghost", "Ghost",
           "Ghost", "Ghost", "Ghost", "Rock", "Psychic", "Psychic", "Water", "Water", "Water", "Electric", "Electric", "Grass", "Grass", "Grass", "Ground", "Ground", "Ghost", "Fighting", "Fighting", "Normal", "Poison", "Poison",
           "Poison", "Ground", "Ground", "Normal", "Grass", "Normal", "Normal", "Water", "Water", "Water", "Water", "Water", "Water", "Psychic", "Ice", "Bug", "Ice", "Electric", "Fire", "Bug", "Bug", "Normal", "Water", "Water",
           "Water", "Water", "Water", "Normal", "Normal", "Normal", "Water", "Electric", "Fire", "Normal", "Rock", "Rock", "Rock", "Rock", "Rock", "Rock", "Normal", "Normal", "Ice", "Psychic", "Electric", "Fighting", "Fire",
           "Dark", "Dragon", "Dragon", "Dragon", "Psychic", "Psychic", "Psychic", "Psychic"));
   ArrayList<String> KantoPokemonType2 = new ArrayList<>(Arrays.asList("Poison", "Poison", "Poison", "Poison", "Poison", "None", "None", "Flying", "Dragon", "Flying", "Flying", "None", "None", "None", "None", "None",
           "None", "None", "Flying", "Flying", "Poison", "Poison", "Poison", "Poison", "Flying", "Flying", "Flying", "Flying", "None", "Normal", "None", "Normal", "Flying", "Flying", "None", "None", "None", "None", "None",
           "Psychic", "None", "Steel", "None", "Steel", "None", "None", "Ground", "None", "None", "Ground", "None", "None", "None", "None", "None", "Fairy", "Fairy", "Fairy", "Flying", "Flying", "Poison", "Poison", "Poison",
           "Grass", "Grass", "Poison", "Poison", "None", "Steel", "None", "Steel", "None", "None", "None", "None", "None", "None", "None", "None", "None", "None", "None", "None", "None", "None", "Fighting", "None", "None", "None",
           "None", "None", "None", "None", "None", "Poison", "Poison", "Poison", "Poison", "Poison", "Ground", "Electric", "Ground", "Electric", "Ground", "Electric", "None", "None", "None", "Fairy", "Psychic", "None", "Psychic",
           "Poison", "Psychic", "Steel", "Steel", "Flying", "None", "Flying", "Flying", "None", "Ice", "None", "Dark", "None", "Dark", "None", "Ice", "Poison", "Poison", "Poison", "Poison", "Poison", "Ground", "None", "None",
           "None", "None", "None", "None", "None", "Psychic", "Psychic", "Dragon", "None", "None", "Fire", "None", "None", "None", "None", "None", "Fairy", "Rock", "Rock", "None", "None", "None", "None", "None", "None", "None",
           "None", "None", "Psychic", "Fairy", "Psychic", "Flying", "Psychic", "None", "None", "None", "Flying", "None", "None", "Flying", "Dark", "Ice", "Ice", "None", "None", "None", "None", "None", "None", "None", "Water",
           "Water", "Water", "Water", "Flying", "Flying", "None", "None", "Flying", "Flying", "Flying", "Flying", "Flying", "Flying", "None", "None", "Flying", "None", "Fighting", "None", "None"));

Once I had all of the button and labels created, I needed to import all of the Pokémon, their first type, and their second type for all 8 regions. This process took a while to completely fill out, and then I decided to go back and add the extra/alternate forms that some Pokémon have. The reason that I have the typings seperated out into two arrays is because it is easier to manage later in the code, as I will need to take from both types in order to print out the correct result. For Pokémon that only had one type, I had to put in the Type2 arrays a "None" so that the code wouldn't print out the results for a dual type Pokémon if they were a pure, single type.

   //Combo Boxes for Select Pokemon page
   ComboBox kanto = new ComboBox(); ComboBox johto = new ComboBox(); ComboBox hoenn = new ComboBox(); ComboBox sinnoh = new ComboBox();
   ComboBox unova = new ComboBox(); ComboBox kalos = new ComboBox(); ComboBox alola = new ComboBox(); ComboBox galar = new ComboBox();
   //Blank arrays for the Single Type page to properly display Weaknesses/Strengths
   ArrayList<String> TypeWeaknesses = new ArrayList<>(); ArrayList<String> TypeNeutrals = new ArrayList<>();
   ArrayList<String> TypeStrengths = new ArrayList<>(); ArrayList<String> TypeNoEffect = new ArrayList<>();
   //Blank arrays for the Dual Type page to properly display Weaknesses/Strengths
   ArrayList<String> Type1WeakDual = new ArrayList<>(); ArrayList<String> Type1StrongDual = new ArrayList<>();
   ArrayList<String> Type1NoEffectDual = new ArrayList<>(); ArrayList<String> Type2WeakDual = new ArrayList<>();
   ArrayList<String> Type2StrongDual = new ArrayList<>(); ArrayList<String> Type2NoEffectDual = new ArrayList<>();
   ArrayList<String> VeryWeakDual = new ArrayList<>(); ArrayList<String> WeakDual = new ArrayList<>();
   ArrayList<String> NeutralDual = new ArrayList<>(); ArrayList<String> StrongDual = new ArrayList<>();
   ArrayList<String> VeryStrongDual = new ArrayList<>(); ArrayList<String> NoEffectDual = new ArrayList<>();
   //Blank Arrays for Select Pokemon page to properly display Weaknesses/Strengths
   ArrayList<String> Type1WeakSelect = new ArrayList<>(); ArrayList<String> Type1StrongSelect = new ArrayList<>();
   ArrayList<String> Type1NoEffectSelect = new ArrayList<>(); ArrayList<String> Type2WeakSelect = new ArrayList<>();
   ArrayList<String> Type2StrongSelect = new ArrayList<>(); ArrayList<String> Type2NoEffectSelect = new ArrayList<>();
   ArrayList<String> VeryWeakSelect = new ArrayList<>(); ArrayList<String> WeakSelect = new ArrayList<>();
   ArrayList<String> NeutralSelect = new ArrayList<>(); ArrayList<String> StrongSelect = new ArrayList<>();
   ArrayList<String> VeryStrongSelect = new ArrayList<>(); ArrayList<String> NoEffectSelect = new ArrayList<>();

Once I had everything in the code that I needed to use in calculations, I needed to have arrays and drop down lists to store those calculations. These are those arrays and drop down lists that I use later in the code in order to print the correct results.

After creating all of the necessary arrays, buttons, label, and drop down lists, I can finally start creating the pages. I added all of the elements to the pages that I needed to and then started coding the buttons to do things when they are pressed.

//Single Type page button on Dual Type page (Swapping from Dual Type to Single Type)

       btSingleDual.setOnAction(e -> {
           stage.setTitle("Pokemon Type Chart: Single Type Menu");
           lbDualResults.setText(""); Type1.setText(""); Type2.setText("");
           Type1NoEffectDual.clear(); Type1WeakDual.clear(); Type1StrongDual.clear();
           Type2NoEffectDual.clear(); Type2WeakDual.clear(); Type2StrongDual.clear();
       //Single Type page button on Select Pokemon page
       btSingleSelect.setOnAction(e -> {
           stage.setTitle("Pokemon Type Chart: Single Type Menu");
       //Dual Type page button on Single Type page (Swapping from Single Type to Dual Type)
       btDualSingle.setOnAction(e -> {
           stage.setTitle("Pokemon Type Chart: Dual Type Menu");
           TypeWeaknesses.clear(); TypeNeutrals.clear();
           TypeStrengths.clear(); TypeNoEffect.clear();
       //Dual Type page button on Select Pokemon page
       btDualSelect.setOnAction(e -> {
           stage.setTitle("Pokemon Type Chart: Dual Type Menu");
       //Select Pokemon page button on Single Type page
       btSelectSingle.setOnAction(e -> {
           stage.setTitle("Pokemon Type Chart: Select Pokemon Menu");
           TypeWeaknesses.clear(); TypeNeutrals.clear();
           TypeStrengths.clear(); TypeNoEffect.clear();
       //Select Pokemon page button on Dual Type page
       btSelectDual.setOnAction(e -> {
           stage.setTitle("Pokemon Type Chart: Select Pokemon Menu");
           lbDualResults.setText(""); Type1.setText(""); Type2.setText("");
           Type1NoEffectDual.clear(); Type1WeakDual.clear(); Type1StrongDual.clear();
           Type2NoEffectDual.clear(); Type2WeakDual.clear(); Type2StrongDual.clear();

This code makes it to where, when the user switches pages, it clears the page that they were just on and switches the scene to the page selected. I clear the scene so that the user won't go back and still have the inputs that they had entered before piled up on the screen when they switch back.

   public void printResultsSingle(String type, ArrayList<String> weaknesses, ArrayList<String> strengths, ArrayList<String> noEffect) {
       //Cloning the already made arrays so that they can be changed but keep the original ones
       TypeWeaknesses = (ArrayList<String>) weaknesses.clone();
       TypeStrengths = (ArrayList<String>) strengths.clone();
       TypeNoEffect = (ArrayList<String>) noEffect.clone();
       //Creating the Neutral Damage array so that it doesn't take up as much space for each type
       TypeNeutrals.removeAll(TypeWeaknesses); TypeNeutrals.removeAll(TypeStrengths); TypeNeutrals.removeAll(TypeNoEffect);
       //Printing the statement
       lbSingleResults.setText(type + " Types Take 2x Damage From: \n" + TypeWeaknesses + "\n\n" + type
               + " Types Take 1x Damage From: \n" + TypeNeutrals + "\n\n" + type + " Types Take 0.5x Damage From: \n"
               + TypeStrengths + "\n\n" + type + " Types Take 0 Damage From: \n" + TypeNoEffect);
       //Clearing the arrays so that they have no chance of retaining information from a previous type
       TypeWeaknesses.clear(); TypeNeutrals.clear(); TypeStrengths.clear(); TypeNoEffect.clear();

Next, I coded each button on the Single Type page. Because the results are for a singular type, I don't have to worry about the results of two types and trying to balance it to create the correct type matchup. This code takes the type (Gotten from specific button pressed), the weaknesses, strengths, and no effect arrays in order to print the correct statement. It also takes those arrays and creates the Neutral array, which means that the Pokémon isn't weak or strong against it, so it just does normal damage. After printing the statement, it clears the created arrays so that they will not be an issue when pressing a different button with lingering types in each array.

   public void setFinalArray(String type, ArrayList<String> weaknesses, ArrayList<String> strengths, ArrayList<String> noEffect) {
       //Setting the first type selected to the first type array if there is nothing selected
       if (Type1WeakDual.size() == 0 || Type1.getText() == ""){
           Type1WeakDual = (ArrayList<String>) (weaknesses.clone());
           Type1StrongDual = (ArrayList<String>) (strengths.clone());
           Type1NoEffectDual = (ArrayList<String>) (noEffect.clone());
       //Setting the second type selected to the second type array if there is a type in the first array but not in the second
       else if ((Type1WeakDual.size() > 0 && Type2WeakDual.size() == 0 && Type1.getText() != type) || (Type1.getText() != "" && Type2.getText() == "" && Type1.getText() != type)) {
           Type2WeakDual = (ArrayList<String>) (weaknesses.clone());
           Type2StrongDual = (ArrayList<String>) (strengths.clone());
           Type2NoEffectDual = (ArrayList<String>) (noEffect.clone());
       //If there are two types selected, delete the first type, set the second type to the first type, and set the second type as the one selected
       else if (Type1.getText() != "" && Type2.getText() != "" && Type1.getText() != type && Type2.getText() != type) {
           Type1.setText(Type2.getText()); Type2.setText(type);
           Type1WeakDual = (ArrayList<String>) Type2WeakDual.clone();
           Type1StrongDual = (ArrayList<String>) Type2StrongDual.clone();
           Type1NoEffectDual = (ArrayList<String>) Type2NoEffectDual.clone();
           Type2WeakDual = (ArrayList<String>) (weaknesses.clone());
           Type2StrongDual = (ArrayList<String>) (strengths.clone());
           Type2NoEffectDual = (ArrayList<String>) (noEffect.clone());

With each dual type page button, they call upon this method that sets the arrays needed to print the type chart for the two types selected. It no button has been pressed, it adds it to the Type1 array. If a button has been pressed, it makes sure that it isn't the same as the first one and adds it to the Type2 array. If two buttons have been pressed, it makes sure that the third one selected isn't the same as the first two. After checking that they aren't the same, it switches the second selected to the Type1 array and puts the third selected type into the Type2 array, eliminating the first type all together from being selected.

    public void printResultsDual() {
       //Creating the No Effect Array for printing
       NoEffectDual.addAll(Type1NoEffectDual); NoEffectDual.addAll(Type2NoEffectDual);
       if (NoEffectDual.size() == 0) {NoEffectDual.add("Nothing");}
       else if (NoEffectDual.contains("Nothing")) {NoEffectDual.remove("Nothing");}
       //Creating the Very Weak Array for printing
       VeryWeakDual.retainAll(Type2WeakDual); VeryWeakDual.removeAll(NoEffectDual);
       if (VeryWeakDual.size() == 0) {VeryWeakDual.add("Nothing");}
       else if (VeryWeakDual.contains("Nothing")) {VeryWeakDual.remove("Nothing");}
       //Creating the Weak Array for printing
       for (int i = 0; i < Type2WeakDual.size(); i++) {
           if (WeakDual.contains(Type2WeakDual.get(i))) {continue;}
           else {WeakDual.add(Type2WeakDual.get(i));}
       WeakDual.removeAll(Type1StrongDual); WeakDual.removeAll(Type2StrongDual);
       WeakDual.removeAll(NoEffectDual); WeakDual.removeAll(VeryWeakDual);
       if (WeakDual.size() == 0) {WeakDual.add("Nothing");}
       else if (WeakDual.contains("Nothing")) {WeakDual.remove("Nothing");}
       //Creating the Very Strong Array for printing
       if (VeryStrongDual.size() == 0) {VeryStrongDual.add("Nothing");}
       else if (VeryStrongDual.contains("Nothing")) {VeryStrongDual.remove("Nothing");}
       //Creating the Strong Array for printing
       for (int i = 0; i < Type2StrongDual.size(); i++) {
           if (StrongDual.contains(Type2StrongDual.get(i))) {continue;}
           else {StrongDual.add(Type2StrongDual.get(i));}
       StrongDual.removeAll(Type1WeakDual); StrongDual.removeAll(Type2WeakDual);
       StrongDual.removeAll(NoEffectDual); StrongDual.removeAll(VeryStrongDual);
       if (StrongDual.size() == 0) {StrongDual.add("Nothing");}
       else if (StrongDual.contains("Nothing")) {StrongDual.remove("Nothing");}
       //Creating the Neutral Array for printing
       NeutralDual.removeAll(NoEffectDual); NeutralDual.removeAll(VeryWeakDual); NeutralDual.removeAll(VeryStrongDual);
       NeutralDual.removeAll(WeakDual); NeutralDual.removeAll(StrongDual);
       if (NeutralDual.size() == 0) {NeutralDual.add("Nothing");}
       else if (NeutralDual.contains("Nothing")) {NeutralDual.remove("Nothing");}
       //Printing the Dual Type Results
       lbDualResults.setText("A " + Type1.getText() + " and " + Type2.getText() + " Type Takes 4x Damage From: \n" + VeryWeakDual + "\n\nA " + Type1.getText() + " and " + Type2.getText() + " Type Takes " +
               "2x Damage From: \n" + WeakDual + "\n\nA " + Type1.getText() + " and " + Type2.getText() + " Type Take 1x Damage From: \n" + NeutralDual + "\n\nA " + Type1.getText() + " and " + Type2.getText()
               + " Type Takes 0.5x Damage From: \n" + StrongDual + "\n\nA " + Type1.getText() + " and " + Type2.getText() + " Type Takes 0.25x Damage From: \n" + VeryStrongDual + "\n\nA " + Type1.getText()
               + " and " + Type2.getText() + " Type Takes 0 Damage From: \n" + NoEffectDual);
       //Clearing the Arrays so that there is nothing left to mess up future selections
       VeryWeakDual.clear(); WeakDual.clear(); NeutralDual.clear(); StrongDual.clear();
       VeryStrongDual.clear(); NoEffectDual.clear(); Type1.setText(""); Type2.setText("");

After clicking the results button, the code balances both selected types to produce the correct type chart. It first makes sure to add both types that have no effect, such as Electric having no effect on Ground. Then, it checks if both selected types are weak to the same type and if they are strong against the same type. Once these are selected, then it moves on to one type being weak or strong against another. It makes sure to take out any weaknesses or strengths that have no effect as well as any ones that both types are strong or weak against. If a Pokémon has one type that is weak against the type used and the other is strong against it, then the damage becomes neutral. After getting these arrays, the result is printed for the user to see.

   //Setting the Combo Boxes to find the types and print the result
       kanto.setOnAction(e -> {
           int selectedIndex = kanto.getSelectionModel().getSelectedIndex();
           if (selectedIndex > 0) {
               String selectedPokemon = KantoPokemon.get(selectedIndex);
               String type1 = KantoPokemonType1.get(selectedIndex - 1);
               String type2 = KantoPokemonType2.get(selectedIndex - 1);
               if (type2 == "None") {
                   findPokemonSingleType(selectedPokemon, type1);
               else {
                   findPokemonDualType(selectedPokemon, type1, type2);

For the select Pokémon menu, it was the same thing as before with the printed result. However, drop down boxes work differently and so I needed to make a setOnAction one for each box. This code sets the previous result to nothing and gets the specific place that the user selected. The box is then set back to displaying ":Specific Region: Pokémon" and then the code gets to work displaying the correct results. It gets the specific Pokémon selected and its first and second types. If it is a pure, single type Pokémon, then it prints the results for a single type. If the Pokémon is dual type, then it prints the results for a dual type Pokémon. These print methods are the same as before, so the code isn't different for them.



This is the Single Type page, allowing the user to select from 1 of 18 types to see the results of a pure, single type Pokémon or to switch to a different page.T


This is the results on the Single Type page when a type is selected, the arrays changing when a different type is selected as well as the name of the type selected at the beginning.


This is the Dual Type page, allowing the user to select 2 out of 18 types and either see the results or switch to a different page. Also, if more than 2 types are selected, then the program will take from the last two types that the user had selected.


This is the results from the Dual Type page, displaying the correct arrays for the weaknesses, strengths, neutrals, and no effect combinations for the 2 types selected. The types selected are shown above the Results button, however they are cleared when it is click, so I selected them again to show how the program shows the user the last two types the selected. It also won't allow the user to select the same type as the one or two types already selected, meaning that is "Flying" is selected, you can't select it again until it is not displayed above the Results button.


This is the Select Pokémon page, allowing the user to use the drop down menu and select a Pokémon out of the 898 Pokémon created. Once the user selects a Pokémon, the program gets the name and types from the arrays that I created and displays the results to the user.


After the user selects a Pokémon, then the program displays the results of the Pokémon selected its type/types. The user can also go back and select a new Pokémon at any time, the program going to display the correct results even if a new one is selected and the results label is not cleared.


My original idea was to have the page allow the user to select an attacking type and a defending type/types. After starting to code the program, I realized that it would be a complicated to display that instead of just having the user select a type and the program display everything about it. I also had originally planed to try and code in C++, but since I knew nothing about C++, I decided to go with Javafx because I am learning that language in my programming class.

Difficulties with the project came with adding all of the Pokémon to the Select Pokémon page. In my first draft of trying to implement the page, I was going to have the program pull from text files and get the information that way so that I didn't have to add every Pokémon into an array in the code itself. When I tried coding it however, the program decided that it didn't want to read the imported strings as string, resulting in my code not wanting to run at all and display the same wrong results no matter how many different things I tried.

Other than that, the difficulty was trying to make the code shorter. In my first ever draft after getting the Single Type and Dual Type pages to work, my code was 1000+ lines of code. I knew that was way too much for this project, so I set to work toning the lines down a bit. My second draft came out to a little under 500 lines of code, which was a big improvement. Then came adding in all the Pokémon, which I thought was going to take up way more code than it did. After polishing and making sure everything still worked as it should, my final code came out to 990 lines with the full code finished.

How This Project Relates to Prolog 1.5

In Prolog 1.5, the main premise of the section is about being able to understand different queries within a code. How I understood this section is: with a database of information, the user wants to know what animal eats what according to the animals in the database. The user can then enter that query into the system and the program will output the answer. The user can also ask what animal eats what and is also specifically this animal, to which the program displays the results.

This was the basic idea that I had for this program but on a more broad spectrum. If the user had a question about Rock type Pokémon, like what they are weak to, then they can select from the Single Type page the rock type and the program will display the results that the user was looking for along with more. This can also be done with dual types, such as the user having a question such as: if a Pokémon is Type 1 and Type 2, are they weak ro strong against Type3. The program would then take those inputs and give the user the answer that they were looking for along with any other information or questions they may have had about that specific type combo.


Pokémon DB. (n.d.). Pokémon types & type chart [Photo].

Check Out The Code

The entire Pokémon Type Chart code: Media:PokemonTypeChart.pdf (This pdf copied the code OK, but much of the formatting looks wrong because it doesn't transfer to a Word document well)

Personal tools