typedef enum {Clubs = 1, Diamonds, Hearts, Spades} suit_t;
typedef enum {Ace = 1, Two = 2, Three = 3, Four = 4, Five = 5,
Six = 6, Seven = 7, Eight = 8, Nine = 9, Ten = 10,
Jack = 11, Queen = 12, King = 13} face_t;
typedef struct card_t
{
suit_t suit;
face_t face;
} card;
typedef struct stack_t
{
struct card_t deck[53];
int size;
} stack_h;
void shuffle_deck(stack_h *stack)
{
stack_h temp, *cardptr;
int i,num;
for(i = 0; i < stack->size; i++)
{
i = rand() %stack->size;
*cardptr = *stack;
temp = *cardptr;
*cardptr = *stack;
*stack = temp;
}
}
所以我尝试了许多不同的方法让我的牌组洗牌,但不幸的是我没有运气,我想要做的就是把它编制的牌组洗得很好但是当它改组牌时它会分段错误。关于如何修复它的任何想法?一切都有效,但改组功能。
答案 0 :(得分:1)
这一行:
*cardptr = *stack;
在变量cardptr
指向任何内容之前发生,因此它指向您覆盖的随机内存。
改组是一个众所周知的解决问题。 Google&#34; Fisher-Yates&#34;。
答案 1 :(得分:0)
您的交换代码充其量是可疑的。使用它可能更接近正确:
for (i = 0; i < stack->size; i++)
{
int j = rand() % stack->size;
card_t temp = stack->deck[i];
stack->deck[i] = stack->deck[j];
stack->deck[j] = temp;
}
这可能不是一个无偏见的随机播放。请参阅维基百科上的Fisher-Yates以及编码恐怖中的The Danger of Naïveté。
答案 2 :(得分:0)
首先考虑算法。有多种方法可以执行随机播放,但常见的技术(Fisher-Yates)是:
C中的实现可能如下所示:
void shuffle_deck(stack_h *stack)
{
int last;
for (last = stack->size - 1; last > 0; last -= 1)
{
int i = rand() % (last + 1);
if (i < last) {
card_t temp = stack->deck[i];
stack->deck[i] = stack->deck[last];
stack->deck[last] = temp;
} // else the chosen element is already in the target position
}
}