有关于21点游戏的洗牌与发牌

作者在 2013-04-08 23:43:01 发布以下内容

        前两天帮同学做一个C++的作业 大致是这样的

        设计一个21点的纸牌游戏 21点的游戏规则我就不做介绍了 先给人发牌 每发一次问一声还要不要 要是不要了给电脑发 电脑每次都跟人的点数比较 直到比人的点大或者撑死游戏结束 基本流程就是这样

        我当时想了很久要怎么设计洗牌和发牌程序 嗯 对 是想了很久 我很弱的 

        当时我想的是先将52张牌定义成一个数组 至于牌本身定义个结构里面一个char个花色 一个int个牌数

        但是纠结的是怎么发牌 他题目上说的是编一个洗牌程序一个随机发牌函数 但我想他喵的要是随机发牌随机两次一样的牌怎么办 于是纠结在这里不可自拔 最后想的法子是先洗牌 然后按顺序发

        然后有了最初版的傻逼洗牌程序

        

void wash ( card sum[] ){                                                       
     int i , j , color ;                                                        
     card temp ;                                                                
     srand(time(NULL));
     for( i=0 ; i<52 ; i++ ){
          color = int ( rand()%4+1 ) ;                                        
          sum[i].color = new char[10] ;                                         
          re : if( color == 1 ) sum[i].color = "红桃" ;
               else if( color == 2 ) sum[i].color = "方片" ;
               else if( color == 3 ) sum[i].color = "黑桃" ;
               else sum[i].color = "梅花" ; 
          sum[i].num = int( rand()%13+1 ) ;                                      
          temp = sum[i] ;
          for( j=0 ; j<i-1 ; j++ ){
               if( temp.color == sum[j].color ) 
                  if( temp.num == sum[j].num ) goto re ;                        
          } 
     }
}
         不要吐槽我这个傻逼的goto语句是多么的麻烦QAQ


        人家已经婶婶的知道错了

        然后就是按顺序发牌了 基本满足的这个游戏的要求

        然后 那个同学还有一个同学 写了一个很有趣的随机洗牌算法 我觉得很好


void shufflel()
{
     for(int i=0;i<52;++i)
             deck[i]=i+1;
     for(int i=0;i<52;++i)
     {
             int j=0;
             j=rand()%52;
             int temp=0;
             temp=deck[i];
             deck[i]=deck[j];
             deck[j]=temp;
     }
     return;
}
         这个比我的高效多了 先按顺序来给牌定个序 然后将第 i 项和第 j 项交换 因为 j 是随机rand出来的 就满足了洗牌的条件


        但是这个程序有一点问题 就是 i 与 j 没有相关性 


j=rand()%52
         这有一个问题 就是如果我们的RP太差 每个 j 随机出来的数都跟 i 一样就跪了


        所以我把这句改成了这样


j=rang()%i
         这样每个 j 必然跟 i 不一样 而且也满足随机的条件


        最后我们都以为这个问题就这么圆满顺利的解决了

        结果 事实证明 太年轻了= =

        最后的答案给的是这样的

        洗牌程序就是给52张牌定序 没随机

        但他有个发牌程序


void provide_cards(float cards[4][13]){
	                                                                    
	srand(time(NULL));

	type[0] = rand()%4;
	type[1] = rand()%13;
        while (cards[type[0]][type[1]] == 0) {
            type[0]= rand()%4;
            type[1] = rand()%13;}
	}
         注意到这个while


        他在玩家阶段和电脑阶段加了一句


		provide_cards(cards);
		color = type[0];                                           
	        number = type[1];
		str_output += show_cards(color,number);
		total[0] += cards[color][number];
		cards[color][number] = 0;
         最后一句= =


        每次发完牌后直接将发出去的牌定义成0 下次发牌的时候只要card[type[0]][type[1]]==0 就跳 不发

        怎么说呢 在看到这个的时候 我只想说我擦

        感觉婶婶的被鄙视了= =

        其实一开始就想的有问题 一开始不知道怎么销掉已发出去的牌 就把注意力转移到了随机牌上 利用顺序发随机牌组来绕过发重复牌这个问题 殊不知可以用个很小的办法就可以解决

        好了 今天就写这么多 

C++学习过程 | 阅读 2562 次
文章评论,共1条
qunxingw
2013-04-09 11:30
1
别人洗牌是经典的,已早有先例,你也应为自己感到骄傲!
游客请输入验证码