Skip to content
Tags

,

Функциональные данные

by lakmus on January 22nd, 2011


Делаем компьютерную игру, игрок ходит по лесу. В лесу растут деревья и трава, всё как положено.
Допустим, у нас очень-очень много травы. Трава может быть разных типов: A, B, C … n. В зависимости от типа травы движок отрисовывает определённую картинку. Тип травы генерируется случайно, а не задаётся дизайнером уровня. Можно хранить объекты примерно так:

struct Grass
{
    int x, y, z;
    int type;

    Grass()
    {
        type = generator.GetRandomNumber(MAX_GRASS_TYPES);
    }

    void Draw()
    {
        Render('grass', type, x, y, z);
    }
};

Это хороший подход и он имеет право на жизнь. Но рассмотрим ситуацию, когда нужно хранить данные как можно компактнее, хоть и жертвуя скоростью рендера.
Мы можем избавиться от type, получая случайное значение на лету, выводя его из комбинированного хэша координат:

#include <boost/functional/hash.hpp>

struct Grass
{
    int x, y, z;

    void Draw()
    {
        std::size_t combined_seed = 0;

        boost::hash_combine(combined_seed, x);
        boost::hash_combine(combined_seed, y);
        boost::hash_combine(combined_seed, z);

        generator.SetSeed(combined_seed);

        const auto type = generator.GetRandomNumber(MAX_GRASS_TYPES);

        Render('grass', type, x, y, z);
    }
};

From → C++