As a base approach, I would probably use:
enum races = { HUMAN, ELF, DWARF, RACES };enum classes = { WARRIOR, WIZARD, THIEF, CLASSES };struct modifier { int str, dex, int, health, mana; };modifier race_traits[RACES] = { { 0, 0, 0, 0, 0 }, // HUMAN { -1, +1, +1, -2, +1 }, // ELF { +2, +1, -3, +2, -2 } // DWARF };modifier class_traits[CLASSES] = { { +1, +1, -2, +1, -1 }, // WARRIOR { -1, -1, +2, -2, +2 }, // WIZARD { -1, +1, +1, -1, 0 } // THIEF};
The point is that you can keep this data and use it
regardless of whether you implement race/class configuration as a class hierarchy or as a single class. And code which you can keep using even when the rest of the code changes is good.