纸牌游戏洗牌发牌排序算法设计

纸牌游戏洗牌发牌排序算法设计

本文提供纸牌游戏设计制作的基础部分,即洗牌,发牌,牌张排序排列显示的算法。
以及游戏开始时间使用时间的显示。我是用简单的C语言编译器MySpringC在安卓手机上编写的。此是游戏的框架,供游戏设计者参考。

下面是纸牌游戏设计的通用部分:
shuffle_cards ( ){    //  洗牌设计       }
transcards ( ){   //传入牌序号num转为牌点和牌花色,画出牌张     }
cardback ( ){    //发牌时隐藏牌面显示牌背图案    }
showtimes ( ){    //计算和显示使用时间                 }
print_t ( ){   //打印标题提示等文字 
                     //**  参数:位置 sx ,  sy,字串 t$,文字尺寸 tsize }

2aef26cde7634862bdd92bc9f6c3341e.png
 

//以下是样例的源码:
//************************************
//*    纸牌游戏《 □□□□ 》  Version   1.1.0    
//*    制作:张纯叔   ( micelu@126.com )        
//************************************
Canvas cs ;       //画布
string sBarDes[10];
int nBarId[10];
float src[4];  //ClearDraw (cls) clear screen
string s,ss,ss1,ss2,ss3 ;     //print ,  test
string s1,s2,s3,s4,s5,s6,s7,s8,s9 ;  //print text
int sx,sy,dx,dy,px,py;      //draw
int i,j,n,t,k;    //t = times
int num;      //select card number
int pn ;        //发牌序号数
int p1,p2,c1,c2,px1,py1,px2,py2 ;  //找配对
 int pnum[54];    //洗牌后的牌序列(2付牌)
int cardnum,cardstyle;   //牌点牌花色
string cas1,cas2,cas4;   //牌点牌花色图案$
string cas3,cas5 ;            //牌背花色, 下注图案
double Rn;    //random number
string t$;     //提示文字
int tsize;      //textsize
int isdo ;    //控制操作:  1 可操作 , 0 不可操作
int context;    //canvasProc
int obj;
int id;
int event;      //canvasProc
int tim[3];   //get Time & show finished time
 int thh,tmm,tss;
 int oldhh,oldmm,oldss;
 int newhh,newmm,newss;
 int mms;               //show using time
 string hhts,mmts,ssts;
 string ts,ts1,ts2;    
int round ;
int score0,score1,total0,total1 ;   //show score
int mode ;      //设置卡牌花色
int wnum ;      //切换玩家 2-4
int nn,wn,sn,en ;    //北西南东牌序号
int spn[13];     //user south 牌序列
int epn[13];     //user east   牌序列
int npn[13];     //user north 牌序列
int wpn[13];    //user west  牌序列
int temp ;       //排序

 

2e306dc8342b469f9a77af9781a9f900.png
 

main(){
setDisplay(1);
  cs.SetBackground(0,120,0);
  cs.Active();
  cs.SetProc (context, mycanvasProc);
   sBarDes[0]="重新开始";
   nBarId[0]=100;
   sBarDes[1]="开   局 ";
   nBarId[1]=101;
   sBarDes[2]="  ";
   nBarId[2]=102;
   sBarDes[3]="  ";
   nBarId[3]=103;
   sBarDes[4]="退出程序";
   nBarId[4]=104;
   sBarDes[5]="📱" ;
   nBarId[5]=105;
   setToolBarHeight(6);
   setButtonTextSize(13);
   setToolBarBackgroundColor(255,0,120,0);
   setButtonColor(255,0,0,240);
   setButtonTextColor(255,255,255,0);
   setToolBar(100,myToolBarProc,sBarDes,nBarId,6);
  setTitle("纸牌游戏-□□□□   ");
//**********
    cas3="🌺";       //预设牌背图案  
    cas4="🐒";       //预设牌面图案  
    cas5="🦁";       //预设图案   
      drawcover ();
      round=0 ;         //start round
      score0=0 ;  score1=0 ;
      total0=0 ;    total1=0 ;    
      //isdo=0 ;
 while (){}
  }//main () 

drawcover (){     // 画启动界面封面版本号
     cs.SetColor (255,0,130,0);  //back color
     cs.DrawRect (0,0,720,1030);
     cs.SetColor (255,0,250,0);
     cs.DrawRect (50,320,650,326);
     cs.SetColor (255,250,0,0);
     cs.DrawRect (52,322,648,324);
    px=390;    py=265;   
        num=11 ;     //11= Q♠ ,   27= 2♣ ,  13--25 ❤
        transcards ();
    px=300;    py=90;   
        num=13 ;   
        transcards ();
    px=390;    py=90;   //❤
        num=25 ;    
        transcards ();
    px=480;    py=120;   
        num=24 ;    
        transcards ();
     px=570;    py=120;  
        num=23 ;   
        transcards ();
     t$="❤" ;
     sx=140;   sy=220;    tsize=60;
     print_t ();
     t$=cas5 ;    //狮子图案
     sx=475;   sy=350;    tsize=120;
     print_t ();
     t$="纸牌游戏" ;
     sx=60;   sy=160;   tsize=60;
     print_t ();
     t$="####" ;
     sx=60;   sy=260;   tsize=80;
     print_t ();
     t$="欢迎加入纸牌游戏团" ;
     sx=135;   sy=440;   tsize=50;
     print_t1 ();
     cs.SetTextStyle (0);    //0正常,1粗体
     ss="Copyright  v.1.1.0   micelu@126.com ";
     cs.SetTextSize (22);
     cs.SetColor (255,250,20,250);
     cs.DrawText (ss,50,360);      
     cs.Update ();
     isdo=0 ;
}//drawcover ()

mycanvasProc (int context,int obj,int id,int event,float x,float y){
       if (isdo==0) return ;
//纸牌区域点击切换玩家
 
 if (x>150&&x<570&&y>810&&y<950&&wnum==1){
       sn=(int)((x-158)/80) ;     //纸牌排列坐标
       num=spn[sn] ;
       p1=num ;
       c1=(num-num/13*13) ;
       px1=sn*80+158 ;    //调整画牌left,top
       py1=815 ;
                  }    //南家

 }//mycanvasProc ()

score (){
 //显示局数,得分
    cs.SetColor(255,0,120,0); 
    cs.DrawRect (0,35,155,250);  // clear print
    cs.DrawRect (0,730,155,930);  // clear print
        t$=ts ;    //show start time
        sx=15;   sy=25;   tsize=24;
            print_t ();   
        t$="第 "+intToString (round)+" 局" ;    
        sx=15;   sy=70;   tsize=32;
            print_t1 ();   
        t$="总分:"+intToString (total0) ;    //北家
        sx=15;   sy=115;   tsize=26;
            print_t ();   
        t$="得分:"+intToString (score0) ;    
        sx=15;   sy=160;   tsize=26;
            print_t ();   
        t$="总分:"+intToString (total1) ;    //南家
        sx=15;   sy=845;   tsize=26;
            print_t ();   
        t$="得分:"+intToString (score1) ;    
        sx=15;   sy=890;   tsize=26;
            print_t ();   
        cs.Update () ;

    showtimes () ;   //finished & show times
         t$=ts1 ;
         sx=200;   sy=490;   tsize=40;
             print_t ();   
         t$=ts2 ;
         sx=200;   sy=530;   tsize=40;
             print_t ();   
        //print 最后得分
        t$="总分:"+intToString (total0) ;    
        sx=15;   sy=115;   tsize=26;
            print_t ();   
        t$="得分:"+intToString (score0) ;    
        sx=15;   sy=160;   tsize=26;
            print_t ();   
        t$="总分:"+intToString (total1) ;    
        sx=15;   sy=845;   tsize=26;
            print_t ();   
        t$="得分:"+intToString (score1) ;    
        sx=15;   sy=890;   tsize=26;
            print_t ();   
         isdo=0 ;    
                   
 }//score ()

 //纸牌序列:
//cardP num   0 to 12 黑桃 A234..JQK
//cardP num 13 to 25 红心 A234..JQK
//cardP num 26 to 38 梅花 A234..JQK
//cardP num 39 to 51 方块 A234..JQK
//52 大王  53 小王
// VB6,VS2007 编程:设picturebox: 
// cardP(54)图片数组
// 图片高宽为单张纸牌图大小
// 预制扑克牌序列图片底图,程序启动时按序将
// 每单张图片BitBlt..SRCCOPY到图片数组,
// cardP (i)就是整付牌的图片,洗牌发牌都要用到。
// 本程序简化用 num 序号表示54张牌
//********************

shuffle_cards (){    //洗牌设计
     cs.SetColor (255,0,120,0);   //backcolor
     cs.DrawRect (0,0,720,1030);
     cs.Update ();
      for (i=0;i<54;i++){ pnum[i]= -1  ;  }
      pn=0;  
         t$="纸牌游戏:  洗牌,验牌 " ;
         sx=20;   sy=60;   tsize=28;
             print_t ();   
//**** 洗牌 **********************
//**** 无大小王 52,有王54,二付牌108 

//如用2付牌可参考本站博文《小猫钓鱼》
  for (i=0;i<52;i++){    //洗牌, 54 ->108二付牌
      ResetPiece:        //已生成牌有相同则重新生成
      Rn=random()*52 ;  //随机洗牌
             num=(int )(Rn);
             pnum[i]=num ;
         for (k=0;k<i; k++){
         if (num==pnum[k]) goto ResetPiece ;        }
                    }
   for (k=0;k<52;k++){         //显示牌背面图案
        px=(k-k/13*13)*50+18;      //画牌定位
        py=k/13*150+100;
    //cardback ();  //洗牌后可显示牌背或不显示
   num=pnum[k] ;       //num 已洗牌序
// transcards ();  //用于洗牌查验测试,游戏时注释掉
                  }
 }//shuffle_cards ()

6474becbada74e04974d68e447959917.png

 

start (){    //开始游戏,每人发13张牌
      cs.SetColor (255,0,120,0);   //backcolor
      cs.DrawRect (0,0,720,1030);
         t$="纸牌游戏 >>     开局" ;
          sx=250;   sy=500;   tsize=30;
          print_t ();
          cs.Update () ;
    pn= -1 ;    //已洗牌,发牌SENW各发13张牌
    for (k=0;k<13;k++){  //牌序 pn= 0 to 51
        pn=pn+1 ;  sn=k ;      //南
        spn[sn]=pnum[pn];  
        pn=pn+1 ;  en=k ;      //东
        epn[en]=pnum[pn];   
        pn=pn+1 ;  nn=k ;      //北
        npn[nn]=pnum[pn];  
        pn=pn+1 ;  wn=k ;      //西
        wpn[wn]=pnum[pn];  
                 } //发牌定4家牌序号

 //**** SENW 四家已发牌排序显示 ****
      for (i=0;i<13;i++){      //SENW排序
      for (j=0;j<i;j++){          
          if (spn[j]>spn[i]) {   //south南
              temp=spn[i] ;
              spn[i]=spn[j];
              spn[j]=temp ;         }
          if (epn[j]>epn[i]) {    //east东
              temp=epn[i] ;
              epn[i]=epn[j];
              epn[j]=temp ;        }
          if (npn[j]>npn[i]) {    //north北
              temp=npn[i] ;
              npn[i]=npn[j];
              npn[j]=temp ;        }
          if (wpn[j]>wpn[i]) {    //west西
              temp=wpn[i] ;
              wpn[i]=wpn[j];
              wpn[j]=temp ;        }
                      }        }    //SENW排序

   for (k=0;k<13;k++){  //SENW排序后显示牌
            num=spn[k];  
        px=k*45+55 ;   //set position
        py=830;            //南家 
        transcards ();    
            num=epn[k];  
        px=640 ;            //set position
        py=k*40+200;   //东家  
        transcards ();     
            num=npn[k];  
        px=k*45+55 ;   //set position
        py=50;                //北家  
        transcards ();     
            num=wpn[k];  
        px=5 ;   //set position
        py=k*40+200;   //西家  
        transcards ();     
                 }

           round=round+1 ;
           score0=0 ;  score1=0 ;
           isdo=1 ;
  getTime (tim);      //取得系统时间
       oldhh=tim[0];
       oldmm=tim[1];
       oldss=tim[2];
   hhts=intToString (tim[0]);
   mmts=intToString (tim[1]);
   ssts=intToString (tim[2]);
   if (oldhh<10)hhts="0"+hhts;
   if (oldmm<10)mmts="0"+mmts;
   if (oldss<10)ssts="0"+ssts;
       ss2=hhts+" : "+mmts+" : "+ssts;
   ts="开始 >  "+ss2;   //show start time
      cs.SetColor (255,0,220,0);  //框线
      cs.SetTextSize(20);
      cs.DrawText (ts,10,25) ;  
      cs.Update ();
     //  change_id () ;      //玩家
 }//start ()

transcards (){  //num 转换 cardnum, cardstyle
//牌序号转为牌点和牌花色,传入px,py 画出牌张
//此为游戏通用设置,启动界面画牌
       if (num==-1) return ;
       if (num>53) num=num-54 ;    //二付牌
    //**** draw cards 圆角 ****
      cs.SetTextStyle (0);    //0正常,1粗体
     // cs.SetColor (255,250,160,0);  //框线
      cs.SetColor (255,0,80,0);  //框线
      cs.DrawRect (px+10,py-10,px+68,py+115);
      cs.DrawRect (px,py-1,px+79,py+104);
      cs.DrawCircle (px+10,py,9);
      cs.DrawCircle (px+10,py+105,9);
      cs.DrawCircle (px+69,py+105,9);
      cs.DrawCircle (px+69,py,9);
      cs.SetColor (255,250,250,250);  //牌面白色
      cs.DrawRect (px+13,py-8,px+65,py+113);
      cs.DrawRect (px+2,py,px+76,py+103);
      cs.DrawCircle (px+12,py+2,10);
      cs.DrawCircle (px+12,py+103,10);
      cs.DrawCircle (px+66,py+103,10);
      cs.DrawCircle (px+66,py+2,10);
     //******* 画出牌面
        cardnum=(num-num/13*13)+1;
        cardstyle=num/13;
        cas1=intToString(cardnum);
        if(cardnum==1) cas1="A";
        if(cardnum==11) cas1="J";
        if(cardnum==12) cas1="Q";
        if(cardnum==13) cas1="K";
        if (cardstyle==0) cas2="♠";
        if (cardstyle==1) cas2="❤";
        if (cardstyle==2) cas2="♣";
        if (cardstyle==3) cas2="🔶";
     if(cardstyle==0||cardstyle==2) {
            cs.SetColor (255,0,0,0);     }
     if(cardstyle==1||cardstyle==3) {
            cs.SetColor (255,250,0,0);      }
     cs.SetTextSize (30);
     n=0;
     if (cardnum==10) n=8;           
     cs.DrawText (cas1,px+14-n,py+20);
     cs.DrawText (cas2,px+5,py+50);        
          cs.SetTextSize (26);  
     cs.SetTextSize (42);      //牌面图
     cs.DrawText (cas4,px+14,py+95);
     cs.Update ();
}//transcards ()

cardback (){   //draw cards back picture
//发牌时隐藏牌面显示牌背图案
    if (num==-1) return ;
    //**** draw cards 圆角 ****
      cs.SetColor (255,250,160,0);  //框线
      cs.DrawRect (px+10,py-10,px+68,py+115);
      cs.DrawRect (px,py-1,px+79,py+104);
      cs.DrawCircle (px+10,py,9);
      cs.DrawCircle (px+10,py+105,9);
      cs.DrawCircle (px+69,py+105,9);
      cs.DrawCircle (px+69,py,9);
      cs.SetColor (255,0,180,200);  //牌背色
      cs.DrawRect (px+13,py-8,px+65,py+113);
      cs.DrawRect (px+2,py,px+76,py+103);
      cs.DrawCircle (px+12,py+2,10);
      cs.DrawCircle (px+12,py+103,10);
      cs.DrawCircle (px+66,py+103,10);
      cs.DrawCircle (px+66,py+2,10);
      cs.SetTextSize(50);
      cs.DrawText (cas3,px+8,py+70);  //show 背花
      cs.Update ();
}//cardback ()

showtimes (){    //计算使用时间
      getTime (tim);
      newhh=tim[0];
      newmm=tim[1];
      newss=tim[2];
      hhts=intToString (tim[0]);
      mmts=intToString (tim[1]);
      ssts=intToString (tim[2]);
      if (newhh<10)hhts="0"+hhts;    //格式00:00:00
      if (newmm<10)mmts="0"+mmts;
      if (newss<10)ssts="0"+ssts;
 mms=((newhh-oldhh)*3600)+
        ((newmm-oldmm)*60)+((newss-oldss));    
    if (mms<0) mms=mms+864000;
        thh=mms/3600;
        tmm=(mms-thh*2600)/60;
        tss=mms-thh*3600-tmm*60;
 ss1=intToString (tmm)+" 分  "+intToString (tss)+" 秒";
 ss2=hhts+" : "+mmts+" : "+ssts;
      ts1= "完成 >  "+ss2;      //输出
      ts2= "用时 >   "+ss1;     //输出
 }//showtimes ()

print_t (){   //打印标题提示等文字
//**  参数 sx,sy, ss0=$, tsize=text size   
 cs.SetFillMode (1);//0不填色,1填色
    cs.SetTextStyle (0);    //0正常,1粗体
 cs.SetTextSize (tsize);
    cs.SetColor (255,0,200,60);
 cs.DrawText (t$,sx+2,sy+3);
    cs.SetColor (255,250,120,0);
 cs.DrawText (t$,sx,sy);
 cs.SetFillMode (0);//0不填色,1填色
    cs.SetColor (255,250,250,0);
 cs.DrawText (t$,sx,sy);
 cs.SetFillMode (1);//0不填色,1填色
      cs.Update ();
}//print _t ()

print_t1 (){   //打印标题提示等文字
//**  参数 sx,sy, ss0=$, tsize=text size   
  cs.SetFillMode (1);//0不填色,1填色
    cs.SetTextStyle (1);    //0正常,1粗体
  cs.SetTextSize (tsize);
    cs.SetColor (255,0,20,100);
 cs.DrawText (t$,sx+3,sy+4);
    cs.SetColor (255,0,250,0);
 cs.DrawText (t$,sx,sy);
 cs.SetFillMode (0);//0不填色,1填色
    cs.SetColor (255,250,0,0);
 cs.DrawText (t$,sx,sy);
 cs.SetFillMode (1);//0不填色,1填色
      cs.Update ();
}//print _t1 ()

myToolBarProc(int nBtn,int nContext){
      if(nBtn==100){  // 卡牌花色
           setDisplay (1);
           shuffle_cards () ;    //洗牌
               }  
      if(nBtn==101){  // 开始摸鱼
           setDisplay (1);
           shuffle_cards () ;    //洗牌
           start () ;                    //开始
               }
      if(nBtn==102){  //换牌
            setDisplay (1);
          //  deal () ;
                }
      if(nBtn==103){//
           setDisplay (1);
                  }
      if(nBtn==104){//退出程序
           clearOutput();
           cs.ClearDraw (0,src);
           setDisplay (0);
           exit (0);
               }
     if(nBtn==105){//@About
           setDisplay (1);
           drawcover ();
                   }
}//myToolBar ()


//**** End ****

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值