2015-06-17 3 views
0

У меня есть набор # определить годов в сгенерированном заголовке, например, как это:Сжатый способ расчета #define

#define SFX_SOIL_DESTROY_1 2 
#define SFX_SOIL_DESTROY_2 14 
#define SFX_SOIL_PLACE_1 32 
#define SFX_SOIL_PLACE_2 33 
#define SFX_WOOD_DESTROY_1 5 

У меня есть метод, который должен возвращать правильный определить для типа материала и типа звучания. Вот длинный, inconcise решение:

int getSfx (MaterialType material, SoundType sound) 
{ 
    switch (material) 
    { 
     case SOIL: 
     { 
      switch (sound) 
      { 
       case DESTROY: 
        return rand()%2 ? SFX_SOIL_DESTROY_1 : SFX_SOIL_DESTROY_2; 
       case PLACE: 
       // And so on 

Есть ли какие-то макро-хака, который может конденсироваться это? Любая помощь приветствуется.

+4

Вы говорите, что заголовок создан. Вы считали, что генерируете «длинное, неудобное решение»? – zwol

+0

@zwol Определения создаются из внешнего инструмента, поэтому я не могу редактировать этот инструмент. С другой стороны, Im не возражал против написания препроцессорного взлома или что-то в этом роде для «генерации» метода длинных неудобств. –

+0

Я думал больше о линиях дополнительного инструмента, который бы сгенерировал нужный вам код. Одноразовые генераторы кода являются недооцененной техникой. – zwol

ответ

2

Хранение данных в режиме поиска данных происходит намного быстрее и требует обработки только один раз (при его настройке). Таким образом, предполагая, что материал и звук более или менее нуля последовательным (в противном случае сделать перевод подстановок):

int soundLut [MAX_MATERIAL][MAX_SOUND][2] = { 
    {  // SOIL 
     {SFX_SOIL_DESTROY_1, SFX_SOIL_DESTROY_2}, // destroy 
     {SFX_SOIL_PLACE_1, SFX_SOIL_PLACE_2},  // Place 
     // etc - if only one effect, put 2 values the same 
    }, 
    {  // WOOD 
     // and so on 
    }   
}; 

И потом:

int getSfx (MaterialType material, SoundType sound) 
{ 
    return soundLut [material][sound][rand()%2]; 
} 
1

Может быть, вы можете использовать карту для этой цели очень похожее решение, как @Mike (но, возможно, немного безопаснее).

void initialize() 
{ 
    // This is your class member. 
    // std::map< std::pair< MaterialType, SoundType >, std::pair< int, int > > sfxs; 

    sfxs[ std::make_pair(SOIL, DESTROY) ] = std::make_pair(SFX_SOIL_DESTROY_1, SFX_SOIL_DESTROY_2); 
    sfxs[ std::make_pair(SOIL, PLACE) ] = std::make_pair(SFX_SOIL_PLACE_1, SFX_SOIL_PLACE_2); 
    // ... 
} 

int getSfx(MaterialType aMaterial, SoundType aSound) 
{ 
    const auto key = std::make_pair(aMaterial, aSound); 
    if (sfxs.find(key) != sfxs.end()) 
    { 
     return (rand() % 2) ? (sfxs[ key ].first) : (sfxs[ key ].second); 
    } 
    return -1; 
} 
+0

Ваше решение также имеет то преимущество, что материалы не обязательно должны быть нуль-последовательными - это то, что я бы предложил включить в поиск. Кто-то, спрашивающий меня о наиболее сжатом способе делать что-то, как красный флаг для быка, тем не менее, поэтому я помещаю его в 1 таблицу (настроенную во время компиляции) и 1 строку кода. :-) – Mike

+1

@Mike Я думаю, что ваш код просто прекрасен и работает (поэтому я поддержал ваше решение), но я попытался сделать что-то более похожее на C++. –

Смежные вопросы