游戏开发论坛

 找回密码
 立即注册
搜索
查看: 7620|回复: 18

求教一个扑克牌洗牌的算法

[复制链接]

4

主题

21

帖子

21

积分

注册会员

Rank: 2

积分
21
发表于 2006-5-10 17:59:00 | 显示全部楼层 |阅读模式
54张扑克牌,除开大小鬼,还有52张牌,只需要洗牌就行,要求够随机分布的,请问谁能帮我写个好点的算法?

11

主题

162

帖子

189

积分

注册会员

Rank: 2

积分
189
QQ
发表于 2006-5-10 18:10:00 | 显示全部楼层

Re: 求教一个扑克牌洗牌的算法

int i, a;
card_t tmp; // card_t 为扑克牌类型

for (i = 0; i < 52; i++)
  {
    a = rand() % 52;
    tmp = cards; // cards 数组存放扑克牌
    cards = cards[a];
    cards[a] = tmp;
  }

60

主题

1319

帖子

1319

积分

金牌会员

Rank: 6Rank: 6

积分
1319
发表于 2006-5-10 18:25:00 | 显示全部楼层

Re:求教一个扑克牌洗牌的算法


  1. #include <algorithm>
  2. #include <vector>
  3. using namespace std;

  4. void foo(void)
  5. {
  6.   vector<int> v1;
  7.   for(int i=0;i<52;i++)
  8.   {
  9.     v1.push_back(i);
  10.     random_shuffle( v1.begin( ), v1.end( ) );
  11.   }
  12. }

复制代码

11

主题

162

帖子

189

积分

注册会员

Rank: 2

积分
189
QQ
发表于 2006-5-10 18:54:00 | 显示全部楼层

Re:求教一个扑克牌洗牌的算法

为什么 random_shuffle 不能放在 for 外面? 要快很多的

60

主题

1319

帖子

1319

积分

金牌会员

Rank: 6Rank: 6

积分
1319
发表于 2006-5-10 19:21:00 | 显示全部楼层

Re:求教一个扑克牌洗牌的算法

打错了,不好意思,是应该放外面的

4

主题

21

帖子

21

积分

注册会员

Rank: 2

积分
21
 楼主| 发表于 2006-5-10 22:28:00 | 显示全部楼层

Re:求教一个扑克牌洗牌的算法

谢谢楼上的几位,我想在问下如果用linux下的/dev/random这个随机数产生设备产生的随机数来作洗牌的话,该怎么用呢? 因为不是自己写着好玩,是在给公司做这个游戏写的洗牌算法,所以必须得保证随机性的效果好

103

主题

1432

帖子

1458

积分

金牌会员

Rank: 6Rank: 6

积分
1458
QQ
发表于 2006-5-11 00:31:00 | 显示全部楼层

Re:求教一个扑克牌洗牌的算法


我有个很好的算法。
根据上一轮的出牌顺序,将牌排列好。然后去偶数的牌出来。接着偶数的队列和奇数的队列前后排列好。重复几轮后,就能保证是乱序的~

这种算法的优秀之处,在于模拟了人工的洗牌操作~~



11

主题

162

帖子

189

积分

注册会员

Rank: 2

积分
189
QQ
发表于 2006-5-11 10:38:00 | 显示全部楼层

/dev/random

Isn't the /dev/random device in GNU/Linux accessable with normal stdio
functions (fopen()/fread())?

However I don't think that's actually necessary as srand()/rand() is
already random enough for any games, we aren't doing something like SSH,
eh?

11

主题

162

帖子

189

积分

注册会员

Rank: 2

积分
189
QQ
发表于 2006-5-11 10:41:00 | 显示全部楼层

Re: Re:求教一个扑克牌洗牌的算法

航天奇侠: Re:求教一个扑克牌洗牌的算法


我有个很好的算法。
根据上一轮的出牌顺序,将牌排列好。然后去偶数的牌出来。接着偶数的队列和奇数的队...


I don't think this is a good algorithm as this won't result in enough
randomness, and it doesn't actually simulate the way humans shuffle
the cards (humans are not that "accurate" to always get one card).

4

主题

21

帖子

21

积分

注册会员

Rank: 2

积分
21
 楼主| 发表于 2006-5-11 16:56:00 | 显示全部楼层

Re:求教一个扑克牌洗牌的算法

谢谢楼上的朋友,以下是根据楼上的朋友的方法我自己综合了一下写的
void poker::random_init(void)
{
        int rfd = open("/dev/random",O_RDONLY);
        if (rfd = 0) {
                rfd = open("/dev/ramdon",O_RDONLY);
        }

        m_iCount = read(rfd,m_rseed,1*1024);
        close(rfd);
}

int poker::get_random()
{
        if (m_iCount < 2) random_init();
        srand(m_rseed[m_iCount]+m_rseed[m_iCount-1] << 8);
        m_iCount -= 2;
        return (random()%52);
}

void poker::shuffle()
{
        int i,j,tmp;
        random_shuffle(m_Card,m_Card+52);
        for (i=1;i<=52;i++)
        {
                j = poker::get_random();
                tmp = m_Card;
                m_Card = m_Card[j];
                m_Card[j] = tmp;
        }
        random_shuffle(m_Card, m_Card+52);
        m_iCursor = 0;
}

shuffle是洗牌函数,我用一52个整数的数组表示牌号,但是我在linux下编译的时候报random_shuffle函数未定义,不知道这个函数是否能在linux下使用还是我包含头文件错了

请指教一下
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-24 12:54

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表