Quantcast
Channel: Pokemon stats calculator - Code Review Stack Exchange
Viewing all articles
Browse latest Browse all 4

Pokemon stats calculator

$
0
0

I have a simple working (so it's not a hypothetical stub) framework for calculating Pokemon stats that will later be incorporated in a game. It uses the LCRNG from the first game in order to be as compatible as possible. I use formulas from the Bulbapedia Wiki. The example output matches the example given here.

Things I want to focus on:

  • Does the random engine satisfy the UniformRandomNumberGenerator concept correctly? Can its usability be improved? I don't want to go crazy and over-engineer it.

  • I'm not working on embedded system but I use uint8_t to make it explicit that the values have range [0, 255]. And there is some (tiny) bit manipulation as well. Or is it just better to use an int?

  • Better way to organize my data structures. Right now I made the class an aggregate for easy initialization but that limits the usefulness of the class. I'm worried about maintainability and don't want to give the Pokemon class too much responsibility.

  • The "extern" thing is terrible, but it's better than duplication with a "base_stats_class". Better way of handling it?

Of course, readability and other stuff are welcome criticism too.

#include <array>#include <algorithm>#include <iostream>#include <cmath>#include <cstdint>#include <random>#include <limits>/* Satisfies UniformRandomNumberGenerator concept */struct PokemonRandEngine{    using result_type = uint32_t;    result_type min() { return std::numeric_limits<result_type>::min(); }    result_type max() { return std::numeric_limits<result_type>::max(); }    result_type g() { return prand(); }    result_type operator()()    {        return g();    }    PokemonRandEngine()    {        static std::random_device rd;        seed(rd());    }private:    uint32_t next = 1;    /* Pokemon's LCRNG */    uint32_t prand()    {        next = (next * 0x41C64E6D) + 0x6073;        return next;    }    /* Seed prand */    void seed(uint32_t seed)    {        next = seed;    }};struct stats_t{    uint8_t hp;    uint8_t atk;    uint8_t def;    uint8_t spd;    uint8_t spc; /* special */};struct pokemon{    std::string name;    stats_t stats;    stats_t ivs;    int level;    void populate_ivs()    {        static std::uniform_int_distribution<int8_t> uid(0, 15);        static PokemonRandEngine cre;        ivs.atk = uid(cre);        ivs.def = uid(cre);        ivs.spd = uid(cre);        ivs.spc = uid(cre);        /* The HP IV is calculated by taking the least significant bit         * of each IV and then constructing a binary string         */        ivs.hp = (ivs.atk & 1) | (ivs.def & 1) | (ivs.spd & 1) | (ivs.spc & 1);    }    uint8_t calculate_hp(uint8_t base, uint8_t iv)    {        return floor(                (                    ((base + iv) * 2+ floor(ceil(sqrt(0))/4)) /* Assume 0 for Effort Values for now */                    * level                ) / 100            )+ level+ 10;    }    uint8_t calculate_otherstat(uint8_t base, uint8_t iv)    {        return floor(                (                    ((base + iv) * 2+ floor(ceil(sqrt(0))/4)) /* Assume 0 for Effort Values for now */                    * level                ) / 100            )+ 5;    }        void calculate_stats()    {        extern std::array<pokemon, 1> base_stats_array;        stats_t base_stats =             std::find_if(base_stats_array.begin(), base_stats_array.end(),            [this] (pokemon p) { return p.name == name; })->stats;        stats.hp = calculate_hp(base_stats.hp, ivs.hp);        stats.atk = calculate_otherstat(base_stats.atk, ivs.atk);        stats.def = calculate_otherstat(base_stats.def, ivs.def);        stats.spd = calculate_otherstat(base_stats.spd, ivs.spd);        stats.spc = calculate_otherstat(base_stats.spc, ivs.spc);    }};std::array<pokemon, 1> base_stats_array = {    { { "mewtwo", { 106, 110, 90, 130, 154 } } }};int main(){    pokemon wild;    wild.name = "mewtwo";    wild.level = 70;    wild.ivs = { 4, 14, 5, 8, 6 };    wild.calculate_stats();    std::cout << (int)wild.stats.hp << ""<< (int)wild.stats.atk << ""<< (int)wild.stats.def << ""<< (int)wild.stats.spd << ""<<  (int)wild.stats.spc;    std::cout << std::endl;    wild.ivs = { 0, 2, 6, 10, 12 };    wild.calculate_stats();    std::cout << (int)wild.stats.hp << ""<< (int)wild.stats.atk << ""<< (int)wild.stats.def << ""<< (int)wild.stats.spd << ""<<  (int)wild.stats.spc;}

Output:

234 178 138 198 229228 161 139 201 237

Viewing all articles
Browse latest Browse all 4

Latest Images

Trending Articles





Latest Images