C语言卡牌洗牌函数运行异常,多数卡牌位置未变化问题排查
卡牌洗牌函数错误原因分析
以下是导致洗牌异常的核心错误:
随机数种子初始化位置错误
swap函数内每次执行都会调用srand((unsigned) time(&t))重置随机数种子,而time()函数返回值的精度为秒,遍历52张牌的全程远小于1秒,所有swap调用使用的种子完全相同,rand()生成的随机数序列完全一致,仅前少数几次交换有效,绝大多数卡牌的交换目标位置重复,最终只有少量卡牌位置变化。
正确的处理方式是将srand调用移到程序初始化阶段,全局仅执行一次即可。随机数范围校验逻辑错误
while循环的校验条件存在运算符优先级问题:&&优先级高于||,原条件等价于rowToSwap < 0 || (rowToSwap > 3 && colToSwap < 0) || colToSwap > 12,和你预期的「行或列超出合法范围就重新生成随机数」的逻辑完全不符。
实际上rand() % 4天然生成0~3的合法行号,rand() % 13天然生成0~12的合法列号,该while校验逻辑完全多余,可以直接删除。洗牌算法概率不均匀(可选优化)
当前实现的遍历每个元素与全局任意位置交换的逻辑,不属于标准Fisher-Yates洗牌算法,会导致牌组排列概率不均匀。如果需要公平洗牌,可以修改为:遍历到第n个元素时,仅与第n个及之后的未排序元素交换,避免已经确定位置的卡牌被再次交换打乱。
内容的提问来源于stack exchange,提问作者chessfordays
相关产品推荐
相关产品推荐

