# Pokemon Table Implementation This document describes the high-performance Pokemon data table implementation for the Pokemon Battle Simulator. ## Overview The Pokemon Table is a high-performance data structure that provides O(1) lookup access to all Pokemon species data. It loads Pokemon data from JSON files and stores them in memory for fast runtime access. ## Features - **O(1) ID-based lookup**: Access any Pokemon by its ID in constant time - **O(1) Name-based lookup**: Access any Pokemon by its name using a hash map - **Automatic data loading**: Loads all Pokemon data from JSON files at startup - **Memory efficient**: Uses contiguous memory storage for optimal cache performance - **Type safety**: Strongly typed with comprehensive error handling - **Validation**: Built-in data validation to ensure integrity ## Architecture ### Core Classes #### `PokemonTable` The main class that manages the Pokemon data table. **Key Methods:** - `loadFromDataDirectory()`: Loads Pokemon data from the standard data directory - `loadFromFiles()`: Loads Pokemon data from specific JSON files - `getPokemon(uint16_t id)`: O(1) lookup by Pokemon ID - `getPokemonByName(std::string_view name)`: O(1) lookup by Pokemon name - `hasPokemon(uint16_t id)`: Check if a Pokemon ID exists - `size()`: Get the total number of loaded Pokemon - `validate()`: Validate the integrity of loaded data #### `PokemonSpecies` Struct containing all the data for a single Pokemon species. **Fields:** - `id`: Pokemon ID (1-based) - `name`: Pokemon name - `base_stats`: Base stats (HP, Attack, Defense, SpAttack, SpDefense, Speed) - `types`: Primary and secondary types ### Global Access The implementation provides a global Pokemon table instance for convenient access: ```cpp #include "core/pokemon_table.h" // Initialize the global table (call once at startup) bool success = PokEng::initializePokemonTable(); // Use the global table const auto* bulbasaur = PokEng::g_pokemonTable->getPokemon(1); const auto* charizard = PokEng::g_pokemonTable->getPokemonByName("charizard"); // Clean up (call at shutdown) PokEng::shutdownPokemonTable(); ``` ## Performance ### Benchmarks Based on the example program, the Pokemon table demonstrates excellent performance: - **Initialization**: ~89ms to load 1025 Pokemon species - **ID Lookups**: ~33,333 lookups per millisecond (100,000 lookups in 3ms) - **Memory Usage**: Minimal memory footprint with contiguous storage ### Storage Strategy The table uses a hybrid storage approach for optimal performance: 1. **Vector storage**: Pokemon species are stored in a `std::vector` indexed by ID 2. **Hash map**: Name-to-ID mapping using `std::unordered_map` for fast name lookups 3. **Index 0 unused**: Vector index 0 is unused, so Pokemon with ID 1 is at index 1 This approach provides: - O(1) ID lookups via direct vector indexing - O(1) average case name lookups via hash table - Excellent cache locality for ID-based access patterns ## Usage Examples ### Basic Usage ```cpp #include "core/pokemon_table.h" int main() { // Initialize the Pokemon table if (!PokEng::initializePokemonTable()) { std::cerr << "Failed to load Pokemon data!" << std::endl; return 1; } // Look up Pokemon by ID const auto* pikachu = PokEng::g_pokemonTable->getPokemon(25); if (pikachu) { std::cout << "Pikachu's speed: " << pikachu->base_stats.speed << std::endl; std::cout << "Pikachu's type: " << PokEng::TypeUtils::typeToString(pikachu->types.getPrimary()) << std::endl; } // Look up Pokemon by name const auto* charizard = PokEng::g_pokemonTable->getPokemonByName("charizard"); if (charizard) { std::cout << "Charizard ID: " << charizard->id << std::endl; } // Clean up PokEng::shutdownPokemonTable(); return 0; } ``` ### Advanced Usage ```cpp // Check if Pokemon exists if (PokEng::g_pokemonTable->hasPokemon(150)) { const auto* mewtwo = PokEng::g_pokemonTable->getPokemon(150); // Use mewtwo data... } // Iterate through all Pokemon for (uint16_t id = 1; id <= PokEng::g_pokemonTable->getMaxId(); ++id) { const auto* pokemon = PokEng::g_pokemonTable->getPokemon(id); if (pokemon) { // Process pokemon... } } // Get all Pokemon at once (for bulk operations) const auto& allPokemon = PokEng::g_pokemonTable->getAllPokemon(); for (const auto& pokemon : allPokemon) { if (pokemon.id != 0) { // Skip empty entries // Process pokemon... } } ``` ## Data Loading The Pokemon table automatically loads data from JSON files in the `data/pokemon/` directory: - `generation-i.json` through `generation-ix.json` - Each file contains Pokemon from a specific generation - Data is validated during loading ### JSON Format Each Pokemon entry in the JSON files has the following structure: ```json { "id": 1, "name": "bulbasaur", "height": 7, "weight": 69, "base_experience": 64, "types": ["grass", "poison"], "stats": { "hp": 45, "attack": 49, "defense": 49, "special-attack": 65, "special-defense": 65, "speed": 45 }, "abilities": [...], "species": {...} } ``` ## Error Handling The implementation includes comprehensive error handling: - **File loading errors**: Graceful handling of missing or corrupted JSON files - **JSON parsing errors**: Detailed error messages for malformed JSON - **Data validation**: Built-in validation to ensure data integrity - **Memory safety**: Proper resource management with RAII ## Testing The implementation includes comprehensive unit tests covering: - Data loading and initialization - ID-based and name-based lookups - Error handling for invalid inputs - Performance validation - Data integrity validation Run tests with: ```bash cd build make test ``` ## Integration The Pokemon table is designed to integrate seamlessly with other components: - **Pokemon creation**: Use table data to create Pokemon instances - **Battle calculations**: Fast access to base stats and types - **Type effectiveness**: Integration with type system for damage calculations - **Stat calculations**: Base stats for battle stat computations ## Future Enhancements Potential improvements for the Pokemon table: 1. **Lazy loading**: Load Pokemon data on-demand to reduce startup time 2. **Compressed storage**: Use compression to reduce memory footprint 3. **Multi-threading**: Parallel loading of Pokemon data 4. **Caching**: Implement LRU cache for frequently accessed Pokemon 5. **Serialization**: Save/load compiled Pokemon data for faster startup