2013-04-29 140 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

哪种语言? – 2013-04-29 14:26:53

+0

这是什么语言? C也许?请添加一个合适的语言标签(在您的问题下面有一个编辑链接) – 2013-04-29 14:27:03

+0

'1,5,9,10,14,15,19,20'是一个字符串还是一个多值数组? – 2013-04-29 14:27:31

回答

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”的原因。 – 2013-04-29 14:31:43

+0

@Damien_The_Unbeliever对,谢谢。澄清我的答案是多一点语言中立。 – 2013-04-29 14:33:45

+0

如果代码是C或C++,那么* last *表达式的结果是重要的。尝试'int i = 1; if(i == 1,0){cout <<“1,0!” << endl; } if(i == 2,99){cout <<“2,99!” << endl; }' – 2013-04-29 14:35:23

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) 

这是因为==是一个二元运算符这需要兼容类型的两个值。

在这种情况下,@Ondrej解释过,switch ... case语句是首选。

我能想到的至少两种替代方式来模拟一个骰子(它似乎你正在尝试做的:

  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 2013-04-30 08:03:23

+0

@真诚的好点。我没有看到“prand”的初始化,因为这不是OP问题的核心部分。当然这很容易解决:'int prand =(rand()%20)+1;' – 2013-05-01 02:15:49

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 Nice替代解决方案! – 2013-05-01 02:20:39

0

您应该使用或公司或switch语句。例如,如果

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

您的编译器应该已经向您发出警告。有些东西给 一个无用表达式的影响。