2013-04-29 2 views
1

Независимо от того, какое число сгенерировано здесь, я всегда получаю первый вариант (пингвины). Кажется, я не вижу никаких проблем с моим кодом, кто-нибудь еще видит, что не так?Множество условий в if-заявлении

{ 
    srand(time(0)); 
    prand = (rand() % 20); 
    if (prand == 1,5,9,10,14,15,19,20){ 
     entity = "penguins"; 
     srand(time(0)); 
     pquantity = (rand() % 8) + 2; 
    } 
    else if (prand == 2,6,11,16,18){ 
     entity = "troll"; 
     pquantity = 1; 
    } 
    else if (prand == 3,7,12,17){ 
     entity = "goblin"; 
     pquantity = 1; 
    } 
    else if (prand == 4,8,13){ 
     entity = "wizard"; 
     pquantity = 1; 
    } 
} 
+2

На каком языке? –

+0

На каком языке это? Может,? Добавьте подходящий языковой тег (есть ссылка для редактирования под вашим вопросом) –

+0

Является ли '1,5,9,10,14,15,19,20' строка или массив из нескольких значений? –

ответ

10

фрагмент кода prand == 1,5,9,10,14,15,19,20 является последовательности выражений, обычно знают как запятой оператор), где результат из первого (или последний - в зависимости от языка) выражение только используется как условие для заявления if. Остальные выражения оцениваются и их значение забывается (обратите внимание, что это может привести к серьезным побочным эффектам в более сложных ситуациях.)

Не совсем понятно, на каком языке вы используете, но, скажем, на C#, вы можете использовать switch statement добиться того, что вы хотите:

switch (prand) 
{ 
    // first set of options 
    case 1: 
    case 5: 
    … 
    case 20: 
     // your code here 
     break; 

    // second set of options 
    case 2: 
    case 6: 
    … 
    case 18: 
     // your code here 
     break; 

    default: 
     // all other options not listed above 
     break; 
} 

Большинство языков такого заявления. См. Это wikipedia article для общего описания.

+4

Если это C или C++, тогда используется результат выражения * last *, поэтому всегда вводится 'if'. –

+0

@Damien_The_Unbeliever Правильно, спасибо. Уточненный мой ответ был немного более нейтральным для языка. –

+0

Если код находится в C или C++, то результат выражения * last * - это то, что считается. Попробуйте 'int i = 1; if (i == 1,0) {cout << "1,0!" << endl; } if (i == 2,99) {cout << "2,99!" << endl; } ' –

1
if (prand == 1,5,9,10,14,15,19,20) 

Хотя это действительно C++ и скомпилируется, оно не делает то, что вы ожидаете. Вам нужно сравнить переменную с каждым значением в свою очередь:

if (prand == 1 || prand == 5 || prand == 9 || prand == 10 || prand == 14 || prand == 15 || prand == 19 || prand == 20) 

Это потому, что == является бинарным оператором, который принимает два значения совместимых типов.

В этой ситуации оператор switch ... case предпочтителен, как пояснил @Ondrej.

я могу думать, по крайней мере, два альтернативных способов имитации кости рулона (который появляется вы пытаетесь сделать:

  1. Используйте последовательные значения для каждого параметра:

    if (prand >= 1 && prand <= 8) { 
        // ... 
    } else if (prand >= 9 && prand <= 13) { 
        // ... 
    } else if (prand >= 14 && prand <= 17) { 
        // ... 
    } else if (prand >= 18 && prand <= 20) { 
        // ... 
    } else { 
        // Print an error message 
    } 
    
  2. Сохраняйте различные возможности в std::list<std::set<int>>. Затем вы можете выполнять итерацию по наборам в списке и использовать метод std::set.contains(), чтобы проверить, содержит ли текущий набор значение. Это имеет преимущество масштабируемости. Например, это упрощает кодируйте варианты для 1d100 или других рулонов кости с большим количеством возможных значений.

+0

Хорошее решение. Но 'prand' никогда не будет равняться 20, но может быть 0. Таким образом, у вас будет сообщение об ошибке. Рано или поздно ... – TrueY

+0

@TrueY Хорошая точка. Я не смотрел на интилизацию «prand», поскольку это не было центральной частью вопроса OP. Конечно, достаточно легко исправить: 'int prand = (rand()% 20) + 1;' –

1

Если это «C», то вы тестируете результат оператора запятой. Таким образом, результат prand == 1,5,9,10,14,15,19,20, является последним элементом (BTW первым элементом является prand == 1). Это 20, что всегда верно.

Я хотел бы предложить, чтобы построить массив и проверить его элементы ...

enum Being_t {BEING_PENGUIN, BEING_TROLL, BEING_GOBLIN, BEING_WIZARD}; 
enum Being_t arr[20] = {BEING_PENGUIN, BEING_TROLL, BEING_GOBLIN, BEING_WIZARD, 
    BEING_PENGUIN, BEING_TROLL, BEING_GOBLIN, BEING_WIZARD, ...}; 

Затем Вы можете использовать переключатель

srand(time(0)); 
prand = (rand() % 20); 
switch (arr[prand]) { 
case BEING_PENGUIN: 
    ... 
    break; 
... 
} 
+0

+1 Хорошее альтернативное решение! –

0

Вы должны использовать или'S или переключить заявления.Например, если

if (prand == 1 || prand == 5 || prand == 9 || prand == 10 || prand == 14|| prand == 15|| prand == 19|| prand == 20) 
{ 
     // your code here 
} 

и с переключателем

switch (prand) 
{ 
    case 1: 
    { 

     // your code here 

     break; 
    } 
    case 5: 
    { 

     // your code here 

     break; 
    } 
    case 9: 
    { 

     // your code here 

     break; 
    } 
    case 10: 
    { 

     // your code here 

     break; 
    } 
    case 14: 
    { 

     // your code here 

     break; 
    } 
    case 15: 
    { 

     // your code here 

     break; 
    } 
    case 19: 
    { 

     // your code here 

     break; 
    } 
    case 20: 
    { 

     // your code here 

     break; 
    } 
} 
3

Вы злоупотребляя оператор запятой. Выражение в первом , если это:

if ((prand == 1), (5), (9), (10), (14), (15), (19), (20)) 

с каждым из запятой оператор запятой. Определение - оператор запятой - оценить первое выражение (для возможных побочных эффектов), затем оценить второе; значение выражение представляет собой значение второго выражения. Так что ваши если становится точный эквивалент:

if (20) 

И 20 неявно преобразуется в bool, в результате чего true.

Ваш компилятор должен был предупредить вас об этом. Что-то до эффект бесполезного выражения.

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