回 帖 发 新 帖 刷新版面

主题:求随机发牌的算法,多谢

老师布置的作业,求两副牌发给四个人的算法。自己写了一个,但运行效果很不理想。请问有什么比较好的算法吗?多谢!!!

回复列表 (共4个回复)

沙发

做一个108大小的数组,然后用rand()函数随即108,给每个人发,同时有一个判断条件
if(a != b || a! c........),等于了在rand()一次下一次发的时候先判断是否有和上次rand()出来的一样,一样了在rand(),放心 108张牌效率绝对高

板凳

觉得发牌跟洗牌一回事,先定义一个108的数组放牌。然后每次先洗一下,再把4个27张分给4个人。具体洗牌方法很经典。可以参考这帖的2楼程序:
http://www.programfan.com/club/showbbs.asp?id=137039

3 楼

#include <time.h>
#include <stdlib.h>
#include <iostream.h>
#define CARD_NUMBERS 52 //一副牌的个数
#define MAX_CARD_INDEX 13//牌的最大数字
#define CARD_TYPE 4//牌的种类
#define DULP_NUM 2//几副牌
#define BIG_KING 15//大王
#define SMALL_KING 14//小王
enum cardType
{
       readPeach,//红桃
        blackPeach,//黑桃
        square,//方块
        clubs,//梅花
        king//王
};
typedef int cardNum;
//一张牌的定义(除去大小king)
struct card
{
    cardType Type;//牌的种类
    cardNum Number;//牌的大小
}; 
card * getCards();//获得一副牌,它是整齐摆放的
void shuffle(card * , card *);//将两副牌打乱
void deal_out(card * A, card* B);//顺序将两副牌发给四个参与者
void main()
{
    srand((unsigned)time(NULL));
    //不妨称之为买牌
    card * A = getCards();
    card * B = getCards();
    //洗牌
    shuffle(A, B);
    //不放心,再洗一次 ^_^
    shuffle(A, B);
    //发牌
    deal_out(A, B);
    delete A;
    delete B;
}
struct card * getCards()
{
    struct card * A_CARDS = new card[CARD_NUMBERS + 2];
    
    for(int i = 0; i < MAX_CARD_INDEX; i++)
    {
    /*
    给每一张牌设一个花色
        */
        A_CARDS[CARD_TYPE * i + 0].Type = readPeach;
        A_CARDS[CARD_TYPE * i + 1].Type = blackPeach;
        A_CARDS[CARD_TYPE * i + 2].Type = square;
        A_CARDS[CARD_TYPE * i + 3].Type = clubs;
        /*
        设置牌的数字
        */
        for(int j = 0; j < CARD_TYPE; j++)
        {
            A_CARDS[4 * i + j].Number = i + 1;
            
        }
    }   
    /*
    完成大小king的设置
    */
    do 
    {
        A_CARDS[CARD_NUMBERS].Type = king;
        A_CARDS[CARD_NUMBERS].Number = SMALL_KING;
        A_CARDS[CARD_NUMBERS + 1].Type = king;
        A_CARDS[CARD_NUMBERS + 1].Number = BIG_KING;
        
    }while(false);
    //返回牌
    return A_CARDS;
}
void deal_out(card * A, card * B)
{
    cout<<"\t\tPerson1\t\tPerson2\t\tPerson3\t\tPerson4\n"<<endl;
    static num = 0;
    for(int i = 0; i < 2 * (CARD_NUMBERS + 2); i++)
    {
        struct card * C = (i < CARD_NUMBERS + 2) ? &(A[i]) : &(B[ i - CARD_NUMBERS  - 2]);   
        static counter = 0;
        /*
        轮番顺序发牌
        */
        switch(i % 4)
        {
        /*
        应该给第一个人发牌
            */
        case 0: cout<<"\t\t"<<C->Type<<","<<C->Number; counter++; break;
        /*
        ......
            */
        case 1: cout<<"\t\t"<<C->Type<<","<<C->Number;counter++;break;
        case 2: cout<<"\t\t"<<C->Type<<","<<C->Number;counter++; break;
        /*
        肯定剩下第四个人
            */
        default:cout<<"\t\t"<<C->Type<<","<<C->Number; counter++; break;
        }
        /*
        为了打印平齐的效果
        */
        if(counter == 4)
        {
            cout<<endl;
            counter =0;
            /*
            每个人拿到的牌数
            */
            num++;
        }
    }
    cout<<"Everyone get "<<num<<" cards"<<endl;
}
/*
掺和牌A和牌B
*/
void shuffle(card * A, card * B)
{
    for(int i = 0 ; i < CARD_NUMBERS + 2; i++)
    {
    /*
    从B牌中随即抽出一张插入A牌中,这样洗牌应该很科学吧,
    也可以试试把牌多洗几次的效果,那就多调用几次这个函数
        */
        int index = rand()%(CARD_NUMBERS + 2);
        if(index == 0) index = i;
        do 
        {
            cardType t1 = A[i].Type;
            int t2 = A[i].Number;
            A[i].Type = B[index].Type;
            A[i].Number = B[index].Number; 
            B[index].Type = t1;
            B[index].Number = t2;
        } while(false);
    }
    
}
自己写了一个,看看,还可以吧

4 楼

               Person1         Person2         Person3         Person4

                2,6             2,5             3,11            0,2
                3,1             3,12            1,5             0,1
                4,14            3,10            3,11            1,7
                3,7             1,12            4,15            2,12
                3,13            1,4             1,10            1,11
                0,8             1,6             0,11            2,8
                3,2             0,13            3,8             3,9
                0,12            2,4             2,11            0,8
                2,12            1,1             3,12            0,4
                0,9             3,6             1,7             3,6
                2,7             2,1             1,13            4,14
                0,3             2,3             2,13            1,12
                0,3             3,1             3,8             3,3
                1,8             0,11            0,1             3,10
                4,15            0,7             2,9             1,2
                3,9             1,13            1,10            0,9
                0,6             3,13            2,2             1,4
                2,9             3,4             2,5             2,6
                2,13            3,5             2,3             0,2
                3,3             1,3             1,9             0,12
                2,7             3,7             1,11            2,10
                1,6             2,11            1,1             1,9
                0,5             2,4             1,8             2,2
                2,10            0,7             2,1             0,4
                1,5             3,5             3,4             0,5
                0,6             2,8             0,13            0,10
                1,2             0,10            3,2             1,3
Everyone gets 27 cards
Press any key to continue

我来回复

您尚未登录,请登录后再回复。点此登录或注册