【问题标题】:rand() returns the same value after the first timerand() 在第一次之后返回相同的值
【发布时间】:2014-12-10 21:49:47
【问题描述】:

首先,这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>

#define NUM_SUITS 4
#define NUM_RANKS 13

bool in_hand[NUM_SUITS][NUM_RANKS] = {false};
bool newcard = {false};
int num_cards, rank, suit, totrank;
const char rank_code[] = {'A','2','3','4','5','6','7','8','9','T','J','Q','K',};
const char suit_code[] = {'C','D','H','S'};

int main_hand ()
{
    suit = rand() % NUM_SUITS;
    rank = rand() % NUM_RANKS;
    if (!in_hand[suit][rank]) {
        in_hand[suit][rank] = true;
        num_cards--;
        if (suit == 0){
            printf("%c of Clubs \n", rank_code[rank]);
        }
        else if (suit == 1){
            printf("%c of Diamonds \n", rank_code[rank]);
        }
        else if (suit == 2){
            printf("%c of Hearts \n", rank_code[rank]);
        }
        else if (suit == 3){
            printf("%c of Spades \n", rank_code[rank]);
       }
    }
}

int print_hand (suit)
{

}

int totrank_check (totrank)
{
    if (totrank > 21) {
        printf ("You lose!");
    }
    else if (totrank == 21) {
        printf ("You win!");
    }
}

int main()
{
     bool stay = {false};
     srand((unsigned) time(NULL));

     totrank = 0;
     num_cards = 2;
     printf("Your hand: ");
     while (num_cards > 0) {
         main_hand();
         totrank = totrank + (rank + 1);
     }
     printf("Total rank: %d\n", totrank);
     totrank_check(totrank);
     printf("\n");
     while (totrank < 24 && stay == false) {
        printf("Another card? 1. Yes 0. No\n");
        scanf("%d", &newcard);
        if(!newcard) {
            main_hand();
        }
        totrank = totrank + (rank + 1);
        totrank_check(totrank);
        printf("Total rank: %d\n", totrank);
        printf("Stay? 1. Yes 0. No\n");
        scanf("%d", &stay);
     }
    return 0;
}

基本上这是一个“模拟”二十一点的代码。 它开始,rand() 选择两个数字,即牌的等级和花色,它们在矩阵中设置为真,这样它们就不能在相同的组合中再次被选择然后打印。 检查卡的总排名(如果超过 21,您将自动输掉),然后系统会询问您是要另一张卡还是要留下。

错误如下:如果您选择想要其他卡片,则这张新卡片将与上一张卡片相同。 基本上,你得到一张黑桃 A、方块 2,然后你想要另一张牌,你又得到另一张方块 2。还有一个,另一个。如果您在第二个中删除排名检查,您可以看到排名根据最后一张卡的排名增长。

之前,printfs 在 print_hand() 函数中,你可以看到你总是得到同一张卡,现在我将它们移动到 main_hand() 函数中,因为我认为这可能是问题所在(它不是t) 并且因为具有单独的打印功能是多余的。但是您可以看到,从技术上讲,if(!in_hand[suit][rank]) 有效,因为由于卡片是相同的,它不会进入 if 并且不会被打印。

我不知道是什么导致了这个问题。有什么想法吗?

请注意,我已经在使用 srand((unsigned) time(NULL)); 播种 rand()

【问题讨论】:

  • 您的main_hand 例程只会随机选择一次卡片,即使它已经被占用。您需要重试,直到找到未使用的卡片(粗略但可以完成工作)或维护一系列“免费”卡片供您选择。
  • 我不这样做吗?一旦 rand() 选择了卡片,就会有一个 if 检查花色和等级是否存在于数组中。如果它们不存在,则添加它们,要提供的牌的计数器减少,并打印选择的牌。如果卡片已经存在,则 if 不会启动,计数器不会减少,卡片不会打印并且 while 循环继续进行,直到选择新卡片。
  • 无论结果如何,您都会不断增加totrank。 (我想知道totrank 应该代表什么。)
  • totrank 应该是各种排名的总和,因为这应该是一手二十一点,如果您的总排名超过 21,您就输了。但你是对的,如果我第二次调用 main_hand(),我将第二次增加移动到相同的位置,这样只有在绘制不同的卡片时才会增加。
  • 我去埋葬自己。

标签: c


【解决方案1】:

scanf("%d", &amp;newcard);scanf("%d", &amp;stay); 是个问题,因为变量是bool,但格式说明符是int。在 2 个地方,更改如下:

// scanf("%d", &newcard);
int t;
scanf("%d", &t);
newcard = !!t;

3 个函数返回 int 但不返回任何内容。更改为 void 函数。

// int main_hand() {
void main_hand() {    

似乎还有其他逻辑问题。
1) 代码有时存在而不知道是否赢/输
2)@Jongware 上面的评论正确:

最后:如果仍然出现相同的随机序列,请将代码剥离到裸露的 main srand time printf rand 并查看是否有效。 time(),如果不工作总是返回-1。
或者简单地添加以下内容并验证使用不同值调用的srand()

 int main(void) {
   unsigned now = (unsigned) time(NULL);
   printf("now = %u\n", now);
   srand(now);

【讨论】:

  • 我将 bool 变量更改为 int(顺便说一下,bool 的正确说明符是什么?我用谷歌搜索并找到了 %d,这就是我使用它的原因)。我还将函数从 int 更改为 void。现在,我将该部分添加到我的代码中,但问题仍然存在。我注意到现在总是等于 4201408,即使我多次启动该程序。这可能是问题吗?对于那个逻辑错误,我知道,我想修复它,但我想了解为什么我不能先获得超过 2 个随机数。
  • 我也回复了@jongware,我想我已经按照他的建议去做了(除非我做错了一切)。
  • @Paul,至少我们知道问题不在于卡,而是time()。试试printf("%lld\n", (long long) time());,这样我们就能得到全部的时间。
  • @Paul,确信scanf() 没有bool 的格式说明符。见stackoverflow.com/questions/12920694/…
  • 我在 time() 中添加了 NULL (因为我得到了一个“参数太少”的错误),我得到的是 1418941711 (并且它在程序的重新运行之间略有增加)而现在和以前一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-03
  • 1970-01-01
  • 2014-07-23
  • 1970-01-01
  • 2021-12-20
  • 2023-01-22
相关资源
最近更新 更多