codebase refactor
This commit is contained in:
26
include/core/battle.h
Normal file
26
include/core/battle.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef BATTLE_H
|
||||
#define BATTLE_H
|
||||
|
||||
#include "pokemon.h"
|
||||
|
||||
namespace PokEng {
|
||||
|
||||
// High-level type system functions for easy use
|
||||
template <Generation Gen = Generation::I>
|
||||
inline uint32_t calculateTypeDamage(uint32_t baseDamage, Type attackType, const PokemonTypes& defenderTypes) {
|
||||
return calculateDamage<Gen>(baseDamage, attackType, defenderTypes);
|
||||
}
|
||||
|
||||
template <Generation Gen = Generation::I>
|
||||
inline uint32_t calculateTypeDamage(uint32_t baseDamage, Type attackType, Type defenderType) {
|
||||
return calculateDamage<Gen>(baseDamage, attackType, PokemonTypes(defenderType));
|
||||
}
|
||||
|
||||
template <Generation Gen = Generation::I>
|
||||
inline uint32_t calculateTypeDamage(uint32_t baseDamage, Type attackType, Type defenderType1, Type defenderType2) {
|
||||
return calculateDamage<Gen>(baseDamage, attackType, PokemonTypes(defenderType1, defenderType2));
|
||||
}
|
||||
|
||||
} // namespace PokEng
|
||||
|
||||
#endif
|
||||
24
include/core/config.h
Normal file
24
include/core/config.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace PokEng {
|
||||
|
||||
// Generation support
|
||||
enum class Generation : uint8_t {
|
||||
I = 1,
|
||||
II = 2,
|
||||
III = 3,
|
||||
IV = 4,
|
||||
V = 5,
|
||||
VI = 6,
|
||||
VII = 7,
|
||||
VIII = 8,
|
||||
IX = 9
|
||||
};
|
||||
|
||||
} // namespace PokEng
|
||||
|
||||
|
||||
#endif
|
||||
50
include/core/pokemon.h
Normal file
50
include/core/pokemon.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef POKEMON_H
|
||||
#define POKEMON_H
|
||||
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
#include <string>
|
||||
|
||||
namespace PokEng {
|
||||
|
||||
|
||||
class Pokemon {
|
||||
public:
|
||||
Pokemon() = default;
|
||||
~Pokemon() = default;
|
||||
|
||||
Pokemon(uint16_t id) : m_id(id) {}
|
||||
Pokemon(uint16_t id, uint16_t health) : m_id(id), m_health(health) {}
|
||||
Pokemon(uint16_t id, uint16_t health, Type primaryType) : m_id(id), m_health(health), m_types(primaryType) {}
|
||||
Pokemon(uint16_t id, uint16_t health, Type primaryType, Type secondaryType) : m_id(id), m_health(health), m_types(primaryType, secondaryType) {}
|
||||
|
||||
public:
|
||||
// Getters
|
||||
uint16_t getId() const { return m_id; }
|
||||
uint16_t getHealth() const { return m_health; }
|
||||
PokemonTypes getTypes() const { return m_types; }
|
||||
Type getPrimaryType() const { return m_types.getPrimary(); }
|
||||
Type getSecondaryType() const { return m_types.getSecondary(); }
|
||||
|
||||
// Setters
|
||||
void setHealth(uint16_t health) { m_health = health; }
|
||||
void setTypes(Type primary) { m_types.setPrimary(primary); m_types.setSecondary(Type::NONE); }
|
||||
void setTypes(Type primary, Type secondary) { m_types.setPrimary(primary); m_types.setSecondary(secondary); }
|
||||
void SetPokemonTypes(PokemonTypes types) { m_types = types; }
|
||||
|
||||
public:
|
||||
// Type-based operations
|
||||
template <Generation Gen = Generation::I>
|
||||
uint32_t calculateDamageTaken(uint32_t baseDamage, Type attackType) const {
|
||||
return calculateDamage<Gen>(baseDamage, attackType, m_types);
|
||||
}
|
||||
|
||||
private:
|
||||
uint16_t m_id;
|
||||
uint16_t m_health;
|
||||
PokemonTypes m_types;
|
||||
};
|
||||
|
||||
} // namespace PokEng
|
||||
|
||||
#endif
|
||||
183
include/core/types.h
Normal file
183
include/core/types.h
Normal file
@@ -0,0 +1,183 @@
|
||||
#ifndef POKEMON_m_typesH
|
||||
#define POKEMON_m_typesH
|
||||
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
#include <string_view>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
namespace PokEng {
|
||||
|
||||
// Forward declarations
|
||||
enum class Type : uint8_t;
|
||||
struct TypeChartEntry;
|
||||
|
||||
// Type enumeration - ordered for optimal cache performance
|
||||
enum class Type : uint8_t {
|
||||
NONE = 0,
|
||||
NORMAL,
|
||||
FIRE,
|
||||
WATER,
|
||||
ELECTRIC,
|
||||
GRASS,
|
||||
ICE,
|
||||
FIGHTING,
|
||||
POISON,
|
||||
GROUND,
|
||||
FLYING,
|
||||
PSYCHIC,
|
||||
BUG,
|
||||
ROCK,
|
||||
GHOST,
|
||||
DRAGON,
|
||||
DARK, // Generation 2+
|
||||
STEEL, // Generation 2+
|
||||
FAIRY, // Generation 6+
|
||||
TYPE_COUNT // Keep this last for array sizing
|
||||
};
|
||||
|
||||
// Type multipliers as integers (multiply by 2 for 0.5x, 4 for 0.25x, etc.)
|
||||
enum class TypeMultiplier : uint8_t {
|
||||
ZERO = 0, // 0x damage (immune)
|
||||
QUARTER = 1, // 0.25x damage
|
||||
HALF = 2, // 0.5x damage
|
||||
NEUTRAL = 4, // 1x damage (neutral)
|
||||
DOUBLE = 8, // 2x damage
|
||||
QUADRUPLE = 16 // 4x damage
|
||||
};
|
||||
|
||||
// Compile-time type chart traits
|
||||
template <Generation Gen>
|
||||
struct TypeChartTraits {
|
||||
static constexpr size_t TYPE_COUNT = static_cast<size_t>(Type::TYPE_COUNT);
|
||||
static constexpr size_t CHART_SIZE = TYPE_COUNT * TYPE_COUNT;
|
||||
|
||||
// Each generation has its own type chart
|
||||
static const std::array<TypeMultiplier, CHART_SIZE>& getTypeChart();
|
||||
};
|
||||
|
||||
// Pokemon type representation
|
||||
class PokemonTypes {
|
||||
public:
|
||||
PokemonTypes() = default;
|
||||
PokemonTypes(Type primary) : primary_(primary), secondary_(Type::NONE) {}
|
||||
PokemonTypes(Type primary, Type secondary) : primary_(primary), secondary_(secondary) {}
|
||||
|
||||
Type getPrimary() const { return primary_; }
|
||||
Type getSecondary() const { return secondary_; }
|
||||
bool hasSecondary() const { return secondary_ != Type::NONE; }
|
||||
|
||||
void setPrimary(Type type) { primary_ = type; }
|
||||
void setSecondary(Type type) { secondary_ = type; }
|
||||
|
||||
private:
|
||||
Type primary_{Type::NONE};
|
||||
Type secondary_{Type::NONE};
|
||||
};
|
||||
|
||||
// Type utility functions
|
||||
class TypeUtils {
|
||||
public:
|
||||
// Convert string to Type enum
|
||||
static std::optional<Type> stringToType(std::string_view typeStr);
|
||||
|
||||
// Convert Type enum to string
|
||||
static std::string_view typeToString(Type type);
|
||||
|
||||
// Get type effectiveness multiplier
|
||||
template <Generation Gen>
|
||||
static TypeMultiplier getTypeEffectiveness(Type attackType, Type defendType);
|
||||
|
||||
// Calculate damage multiplier for dual-type Pokemon
|
||||
template <Generation Gen>
|
||||
static uint32_t calculateDamageMultiplier(Type attackType, const PokemonTypes& defenderTypes);
|
||||
|
||||
// Load type chart from JSON file
|
||||
template <Generation Gen>
|
||||
static bool loadTypeChartFromFile(const std::string& filename);
|
||||
|
||||
public:
|
||||
// Type chart storage for each generation (public for template access)
|
||||
static std::array<TypeMultiplier, TypeChartTraits<Generation::I>::CHART_SIZE> s_gen1Chart;
|
||||
static std::array<TypeMultiplier, TypeChartTraits<Generation::II>::CHART_SIZE> s_gen2Chart;
|
||||
static std::array<TypeMultiplier, TypeChartTraits<Generation::III>::CHART_SIZE> s_gen3Chart;
|
||||
static std::array<TypeMultiplier, TypeChartTraits<Generation::IV>::CHART_SIZE> s_gen4Chart;
|
||||
static std::array<TypeMultiplier, TypeChartTraits<Generation::V>::CHART_SIZE> s_gen5Chart;
|
||||
static std::array<TypeMultiplier, TypeChartTraits<Generation::VI>::CHART_SIZE> s_gen6Chart;
|
||||
static std::array<TypeMultiplier, TypeChartTraits<Generation::VII>::CHART_SIZE> s_gen7Chart;
|
||||
static std::array<TypeMultiplier, TypeChartTraits<Generation::VIII>::CHART_SIZE> s_gen8Chart;
|
||||
static std::array<TypeMultiplier, TypeChartTraits<Generation::IX>::CHART_SIZE> s_gen9Chart;
|
||||
};
|
||||
|
||||
// High-performance damage calculation
|
||||
template <Generation Gen>
|
||||
inline uint32_t calculateDamage(uint32_t baseDamage, Type attackType, const PokemonTypes& defenderTypes) {
|
||||
uint32_t rawMultiplier = TypeUtils::calculateDamageMultiplier<Gen>(attackType, defenderTypes);
|
||||
|
||||
// Apply the multiplier: damage = (baseDamage * rawMultiplier) / 4
|
||||
// Since our multipliers are: 0, 1, 2, 4, 8, 16 representing 0x, 0.25x, 0.5x, 1x, 2x, 4x
|
||||
// We divide by 4 (NEUTRAL) to normalize back to actual damage multiplier
|
||||
return (baseDamage * rawMultiplier) / static_cast<uint32_t>(TypeMultiplier::NEUTRAL);
|
||||
}
|
||||
|
||||
// Template specializations for type chart access
|
||||
template <>
|
||||
inline const std::array<TypeMultiplier, TypeChartTraits<Generation::I>::CHART_SIZE>&
|
||||
TypeChartTraits<Generation::I>::getTypeChart() {
|
||||
return TypeUtils::s_gen1Chart;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const std::array<TypeMultiplier, TypeChartTraits<Generation::II>::CHART_SIZE>&
|
||||
TypeChartTraits<Generation::II>::getTypeChart() {
|
||||
return TypeUtils::s_gen2Chart;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const std::array<TypeMultiplier, TypeChartTraits<Generation::III>::CHART_SIZE>&
|
||||
TypeChartTraits<Generation::III>::getTypeChart() {
|
||||
return TypeUtils::s_gen3Chart;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const std::array<TypeMultiplier, TypeChartTraits<Generation::IV>::CHART_SIZE>&
|
||||
TypeChartTraits<Generation::IV>::getTypeChart() {
|
||||
return TypeUtils::s_gen4Chart;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const std::array<TypeMultiplier, TypeChartTraits<Generation::V>::CHART_SIZE>&
|
||||
TypeChartTraits<Generation::V>::getTypeChart() {
|
||||
return TypeUtils::s_gen5Chart;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const std::array<TypeMultiplier, TypeChartTraits<Generation::VI>::CHART_SIZE>&
|
||||
TypeChartTraits<Generation::VI>::getTypeChart() {
|
||||
return TypeUtils::s_gen6Chart;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const std::array<TypeMultiplier, TypeChartTraits<Generation::VII>::CHART_SIZE>&
|
||||
TypeChartTraits<Generation::VII>::getTypeChart() {
|
||||
return TypeUtils::s_gen7Chart;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const std::array<TypeMultiplier, TypeChartTraits<Generation::VIII>::CHART_SIZE>&
|
||||
TypeChartTraits<Generation::VIII>::getTypeChart() {
|
||||
return TypeUtils::s_gen8Chart;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const std::array<TypeMultiplier, TypeChartTraits<Generation::IX>::CHART_SIZE>&
|
||||
TypeChartTraits<Generation::IX>::getTypeChart() {
|
||||
return TypeUtils::s_gen9Chart;
|
||||
}
|
||||
|
||||
} // namespace PokEng
|
||||
|
||||
#endif // POKEMON_m_typesH
|
||||
Reference in New Issue
Block a user