纸牌游戏程序设计要点(C语言)

纸牌游戏设计制作要点(C语言)

在本站看了一些C语言纸牌游戏设计的一些算法,此不置评。
下面列举设计要点和简洁算法供大家参考。
程序设计解决问题的方法就是算法,也就是功能函数 function ( )。
完整源码可参阅本人在本站的博文《纸牌游戏炸金花设计制作》以及其他纸牌游戏设计制作。
 
纸牌游戏设计的几个要点:
设计纸牌、画出纸牌、洗牌算法、界面设计文字打印,按游戏规则计算分数比大小定输赢。

transcards ( ){      //传入 num 0-51转换为 cardnum, cardstyle
              //牌序号转为牌点和牌花色,画出牌张     }
cardback ( ){     //发牌时隐藏牌面显示牌背图案    }
shuffle_cards ( ){    //洗牌设计           }
print_t ( ){   //打印标题提示等美术文字
                    //传入参数 sx,sy, t$, tsize=text size      }
cal_score ( ){       //计算分数,传入为c1,c2,c3,c4,c5 输出 gscore       }

714e5b5290fd48f7b89cb064f69f0605.png

 

下面是要点的源码:

全局变量声明
canvas cs ;          //画布,picturebox  用于画程序界面和显示纸牌
string s,ss ;          //print text
string ss0,ss1,ss2,ss3,ss4,ss5;      //print text
int sx,sy,dx,dy,px,py;      //draw 绘画定位x,y 
int i,j,n,t,k;    //t = times
int num,num1 ;      //select card number
int pn ;        //发牌计数
int pnum[54];    //洗牌后的牌序列
int cardnum,cardstyle;   //牌点牌花色
string cas1,cas2,cas4;   //牌点牌花色图案$
string cas3,cas5 ;            //牌背花色, 下注图案
double Rn;    //random 洗牌
string t$;     //提示文字
int tsize;      //textsize
int users1,users2,users3;  //东北西玩家分数
int bankers ;      //庄家分数 score
 int bs,us1,us2,us3 ;   //计算分数 banker & users
 int c1,c2,c3,c4,c5 ;      //calculate score
 int c1s,c2s,c3s,c4s,c5s ;      //calculate score
 int b1,b2,b3,b4,b5 ;    //庄家和玩家都杂牌时比大小
 int b1s,b2s,b3s,b4s,b5s ; //玩家都杂牌时比大小
int csh1,csh2,csh3,csh4,csh5 ;   //玩家5张牌花色
int bf1,bf2 ;   //计算分数比大小
int cc[5] ;       //计算比分排序
int temp ;     //排序
int spn[5];     //user south 牌序列
int epn[5];     //user east   牌序列
int npn[5];     //user north 牌序列
int wpn[5];    //user west  牌序列
int nn,wn,sn,en ;    //北西南东牌序号
int gscore ;    //输入c1c2c3计算return各家分数
int bet ;          //赌注,预设10,20,30
int zu1,zu2,zu3,zu4 ;    //北西南东下注数
int wnum ;  //庄家和3玩家id切换,1,   2,3 4
int isdo;       //1 可发牌翻牌可计算分,0 不可

//纸牌序列:
//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
// VB6,VS2007 编程:设picturebox: 
// cardP(54)图片数组
// 图片高宽为单张纸牌图大小
// 预制扑克牌序列图片底图,程序启动时按序将
// 每单张图片BitBlt..SRCCOPY到图片数组,
// cardP (i)就是整付牌的图片,洗牌发牌都要用到。
// 本程序简化用 num 序号表示54张牌


transcards (){ 
 //传入 num 0-51转换为 cardnum, cardstyle
//牌序号转为牌点和牌花色,画出牌面
    //**** draw cards 圆角 ****
      cs.SetColor (255,0,0,60);  //黑色框线
      cs.DrawRect (px+10,py-30,px+109,py+122);
      cs.DrawRect (px,py-20,px+117,py+112);
      cs.DrawCircle (px+10,py-20,9);
      cs.DrawCircle (px+10,py+112,9);
      cs.DrawCircle (px+108,py+113,9);
      cs.DrawCircle (px+108,py-20,9);
      cs.SetColor (255,250,250,250);  //牌面白色
      cs.DrawRect (px+12,py-28,px+107,py+120);
      cs.DrawRect (px+2,py-18,px+115,py+111);
      cs.DrawCircle (px+12,py-19,9);
      cs.DrawCircle (px+12,py+111,9);
      cs.DrawCircle (px+106,py+111,9);
      cs.DrawCircle (px+106,py-19,9);
     //******* 画出牌面
        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+15-n,py+2);
     cs.DrawText (cas2,px+8,py+35);                
      cs.SetTextSize (60);
     cs.DrawText (cas4,px+37,py+93);      
     cs.Update ();
}//transcards ()

15db955956074e25911041904906c736.png

72ecd6923ace4805a9fa1cf494c08bdf.png

 cardback (){   //draw cards back picture
//发牌时隐藏牌面显示牌背图案
     //**** draw cards 圆角 ****
      cs.SetColor (255,0,0,60);  //黑色框线
      cs.DrawRect (px+10,py-30,px+109,py+122);
      cs.DrawRect (px,py-20,px+117,py+112);
      cs.DrawCircle (px+10,py-20,9);
      cs.DrawCircle (px+10,py+112,9);
      cs.DrawCircle (px+108,py+113,9);
      cs.DrawCircle (px+108,py-20,9);
      cs.SetColor (255,0,150,150);  //牌背蓝色
      cs.DrawRect (px+12,py-28,px+107,py+120);
      cs.DrawRect (px+2,py-18,px+115,py+111);
      cs.DrawCircle (px+12,py-19,9);
      cs.DrawCircle (px+12,py+111,9);
      cs.DrawCircle (px+106,py+111,9);
      cs.DrawCircle (px+106,py-19,9);
     cs.SetTextSize(70);
      cs.DrawText (cas3,px+18,py+70);  //show 背花
      cs.Update ();
}//cardback ()

 7dc34c199673477faf4bff488d21c0df.png 

shuffle_cards (){    //洗牌设计
     cs.SetColor (255,0,120,0);   //backcolor
     cs.DrawRect (2,2,718,900);
     cs.Update ();
      for (i=0;i<=51;i++){ pnum[i]=-1 ;   }
      pn=0;    //发牌计数清0
//** 洗牌 **********************
   for (i=0;i<=51;i++){    //洗牌
      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<=51;k++){  //显示牌背面图案
        px=(k-k/13*13)*48+15;
        py=k/13*170+100;
     //cardback ();  //洗牌后可显示牌背或不显示
                }
      cs.Update ();
   // showcard();  //用于洗牌查验测试,游戏时注释掉
}//shuffle_cards ()


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

gamestart (){   //游戏 ”梭哈”  >>> 开局发牌
         shuffle_cards () ;    //洗牌
         clearOutput();         //清除测试输出
          renewscreen ();    //画界面
          putbet () ;               //设置筹码
 //游戏开局时先发2张牌,一暗一明,然后轮流下注
  for (i=0;i<3;i++){     //init 北西南东
        npn[i]=-1 ;  wpn[i]=-1 ;  spn[i]=-1 ; epn[i]=-1 ; }
   // 发牌时各家底注为 10
        zu1=10 ; zu2=10 ; zu3=10 ; zu4=10 ;
        wnum=1 ;    //开局预设东家
         change_id () ;       //切换玩家
  //*******显示"庄家"...文字及分数和下注数
         ss=intToString (bankers);
         s=intToString (zu1);
     t$="庄家 "+"  "+ss +"  "+s;
     sx=235;   sy=60;   tsize=40;
     print_t ();

         ss=intToString (users3);
          s=intToString (zu4);
      t$="西家 "+"  "+ss+"  "+s  ;
      sx=20;   sy=520;    tsize=40;
      print_t ();

         ss=intToString (users2);
         s=intToString (zu3);
      t$="南家 "+"  "+ss+"  "+s ;
      sx=235;   sy=850;    tsize=40;
      print_t ();

       t$="东家 " ;
     sx=620;   sy=520;    tsize=40;
     print_t ();
         ss=intToString (users1);
         s=intToString (zu2);
      t$=ss+"  "+s ;
      sx=440;   sy=520;    tsize=40;
      print_t ();

//**** 发牌 >>  ** 发牌顺序 北西南东
//transcards (int num) 传入num=0--51显示牌面
        px=180;    py=120;   //北家  
        npn[0]=pnum[0];  
         num=npn[0];    nn=0 ;
        px=nn*60+180 ;
        cardback ();   
   sleep (500) ;
       px=5;    py=340;   //西家  
       wpn[0]=pnum[1];  
        num=wpn[0];    wn=0 ;
        px=wn*40+5 ;
        cardback ();    
   sleep (500) ;
        px=180;    py=670;   //南家 
        spn[0]=pnum[2];  
        num=spn[0];    sn=0 ;
        px=sn*60+180 ;
        cardback ();    
   sleep (500) ;
       px=435;    py=340;   //东家  
       epn[0]=pnum[3];  
       num=epn[0];    en=0 ;
        px=en*40+435 ;
        cardback ();    
   sleep (500) ;
        px=180;    py=120;   //北家  
        npn[1]=pnum[4];  
        num=npn[1];    nn=1 ;
        px=nn*60+180 ;
        transcards ();     
    sleep (500) ;
       px=5;    py=340;   //西家  
        wpn[1]=pnum[5];  
        num=wpn[1];    wn=1 ;
        px=wn*40+5 ;
        transcards ();      
   sleep (500) ;
        px=180;    py=670;   //南家 
        spn[1]=pnum[6];  
        num=spn[1];    sn=1 ;
        px=sn*60+180 ;
        transcards ();      
      sleep (500) ;
        px=435;    py=340;   //东家  
        epn[1]=pnum[7];  
        num=epn[1];    en=1 ;
        px=en*40+435 ;
        transcards ();      
        pn=7 ;    //已发8张牌
    isdo=1 ;      //开局后方可发牌 deal ()
}//gamestart ()

//游戏是安卓单机版设计,故
//游戏规则稍加改动,以北家为庄家,
//比分大小关键:相同对子时要比散牌点大小
//都是散牌时要逐张牌比大小,比较复杂
//如都是金花也要逐张牌比大小
//相同分数时逐张比大小,比花色大小,
//本游戏暂不设比花色大小,只要对四花色加权就可比出大小
//(bs&&user  n<100)为散牌, 500+ 为同花 
//**** 计算赢家分数 ** 首三张加权 ****
//**  bs 北家,us1 西家 , us2 南家 , us3 东家   
//最大分值为赢家,输家赔分,赢家独得 
//此安卓版手机游戏改为坐庄制,玩家与庄家比分

//**** 梭哈游戏计分规则:
// 皇家同花顺 AKQJT    500+400+  =900+
// 炸弹 AAAA ......>  2222      700+
// 葫芦 AAAKK  33222            600+
// 同花 A♡Q♡J♡8♡5♡      500+
// 顺子 AKQJT ==>  A5432    400+
// 三条 AAA23   222K8           300+
// 双对子 AAKK◇ ==>  3322♤    200+
// 对子 AA○◇♧ ==> 22♧◇○   100+
// 散牌 按牌面计分 A +计 14分 =>> 2 +计 2分
//梭哈5 张牌比分计算稍微复杂些

cal_score (){      //梭哈游戏比分计算
//计算分数,输入为c1,c2,c3,c4,c5 输出 gscore
//为计分:c1->c5 换算为 1 ->> 13 (A ->> K )序  
    c1s=(c1-c1/13*13)+1;     //牌点
    c2s=(c2-c2/13*13)+1;  
    c3s=(c3-c3/13*13)+1;  
    c4s=(c4-c4/13*13)+1;  
    c5s=(c5-c5/13*13)+1;  
    csh1=c1/13 ;  csh2=c2/13 ;  csh3=c3/13 ; 
    csh4=c4/13 ;  csh5=c5/13 ;        //花色
       if (c1s==1) c1s=14 ;            //A 计点分为 14
       if (c2s==1) c2s=14 ;
       if (c3s==1) c3s=14 ;
       if (c4s==1) c4s=14 ;
       // if (c5s==1) c5s=14 ;
// 计算各家总分,
// 同花顺>四条>葫芦>同花>顺子>三条>对子加权
// 5张散牌或同花计分较复杂,要逐张牌比大小,
// 设置在翻牌result () 对比计算
        gscore=c1s+c2s+c3s+c4s+c5s  ;     
            //gscore = 5张牌合计分
 //皇家同花顺:AKQJT 加权,最大
 //若是同花加顺子:同花500+顺子400+ => 900+

    //四条,99992 ,4连张炸弹  
     if (c1s==c2s&&c1s==c3s&&c1s==c4s){
             gscore=c1s*4+700 ;        
                     goto  putout ;        }
    if (c2s==c3s&&c2s==c4s&&c2s==c5s){
             gscore=c1s*4+700 ;         
                     goto  putout ;        }

      //葫芦AAAKK , 33222
     if (c1s==c2s&&c1s==c3s&&c4s==c5s){
             gscore=c1s*3+600 ;        
                     goto  putout ;        }
    if (c1s==c2s&&c3s==c4s&&c3s==c5s){
             gscore=c3s*3+600 ;         
                     goto  putout ;        }
    if(csh1==csh2&&csh1==csh3&&csh1==csh4&&csh1==csh5){  //同花♡♡♡♡♡
             gscore=gscore+500 ;        }         


 if(c5s==(c4s-1)&&c4s==(c3s-1)&&c3s==(c2s-1)&&c2s==(c1s-1)){  
             //AKQJT 460分 ==>>  65432 顺子
             gscore=gscore+400 ;        }     


 if(c1s==14&&c2s==5&&c3s==4&&c4s==3&&c5s==2) {    //A5432 =A 顺子  最小
              gscore=gscore-13+400 ;      }

  //三条  AAA23  22234  比三条大小即可,不加权
    if (c1s==c2s&&c1s==c3s){
             gscore=c1s*3+300 ;    
             goto putout ;      }
    if (c2s==c3s&&c2s==c4s){
             gscore=c2s*3+300 ;    
             goto putout ;      }
    if (c3s==c4s&&c3s==c5s){
             gscore=c3s*3+300 ;    
             goto putout ;      }
    
  //双对子   AAKK6  33225
     if (c1s==c2s&&c3s==c4s){
             gscore=c1s*3+c3s*2+200 ;    
             goto putout ;      }
    if (c2s==c3s&&c4s==c5s){
             gscore=c2s*3+c4s*2+200 ;   
            goto putout ;      }
    if (c1s==c2s&&c4s==c5s){
             gscore=c1s*3+c4s*2+200 ;   
            goto putout ;      }

        //对子: 相同对子情况较少故散牌不加权
    if (c1s==c2s) gscore=c1s*4+100 ;       
    if (c2s==c3s) gscore=c2s*4+100 ;       
    if (c3s==c4s) gscore=c3s*4+100 ;       
    if (c4s==c5s) gscore=c4s*4+100 ;       
        
 // **** 算法测试:print "..."  显示牌面 *******
putout :
        //显示大牌点 AKQJ 
           ss1=intToString (c1s) ;
        if (c1s==1||c1s==14)  ss1="A" ;       
        if (c1s==13)  ss1="K" ;       
        if (c1s==12)  ss1="Q" ;       
        if (c1s==11)  ss1="J" ;       
            ss2=intToString (c2s) ;
        if (c2s==1||c2s==14)  ss2="A" ;       
        if (c2s==13)  ss2="K" ;       
        if (c2s==12)  ss2="Q" ;       
        if (c2s==11)  ss2="J" ;       
            ss3=intToString (c3s) ;
        if (c3s==1||c3s==14)  ss3="A" ;       
        if (c3s==13)  ss3="K" ;       
        if (c3s==12)  ss3="Q" ;       
        if (c3s==11)  ss3="J" ;       
            ss4=intToString (c4s) ;
        if (c4s==1||c4s==14)  ss4="A" ;       
        if (c4s==13)  ss4="K" ;       
        if (c4s==12)  ss4="Q" ;       
        if (c4s==11)  ss4="J" ;       
            ss5=intToString (c5s) ;
        if (c5s==1||c5s==14)  ss5="A" ;       
        if (c5s==13)  ss5="K" ;       
        if (c5s==12)  ss5="Q" ;       
        if (c5s==11)  ss5="J" ;       

//**** 测试 print test ** return gscore ****
//calculate & putout gscore,  return gscore
    print "  " ;     // 算法测试检验,可注释掉
        print "取得牌面 = ",ss1 ,"     牌序 ", c1s ;
        print "取得牌面 = ",ss2 ,"     牌序 ", c2s ;
        print "取得牌面 = ",ss3 ,"     牌序 ", c3s ;
        print "取得牌面 = ",ss4 ,"     牌序 ", c4s ;
        print "取得牌面 = ",ss5 ,"     牌序 ", c5s ;
      // print "return  gscore = ",gscore ;
 }//cal_score ()


cal_score (){    //三张牌的炸金花比分计算较为简单
//计算分数,输入为c1,c2,c3, 输出 gscore
 //为计分:c1,c2,c3 换算为 1 ->> 13 (A ->> K )

    c1s=(c1-c1/13*13)+1;     //牌点

    c2s=(c2-c2/13*13)+1;  
    c3s=(c3-c3/13*13)+1;  
    csh1=c1/13 ;  csh2=c2/13 ;  csh3=c3/13 ;  //花色
       if (c1s==1) c1s=14 ;
       if (c2s==1) c2s=14 ;
       if (c3s==1) c3s=14 ;
// 计算各家总分,豹子金花顺子对子加权
// 3张杂牌或同花计分较复杂,要逐张牌比大小,
// 翻牌result () 对比计算
        gscore=c1s+c2s+c3s ;      //3张牌合计分
     if (c1s==c2s&&c1s==c3s){  //豹子
             gscore=c1s*3+600 ;           
             goto putout ;    }
    //金花顺 = 300+ 200+
      if (csh1==csh2&&csh1==csh3){    //金花
             gscore=gscore+300 ;        }         
     if (c3s==(c2s-1)&&c2s==(c1s-1)){  //顺子
             gscore=gscore+200 ;        }          

 

     if (c1s==14&&c2s==3&&c3s==2) { 
        //A32   = A23 顺子   算A顺子加30 大于K顺子
             gscore=gscore+30+200 ;        }   

         //对子 加权
     if (c1s==c2s) gscore=c1s*4+100 ;       
     if (c2s==c3s) gscore=c2s*4+100 ;           

// 若有豹子则 杂花 235 吃豹子
       if (bs>600){    // 庄家有豹子
       if (csh1>csh2||csh1<csh3){    //杂花
       if (gscore==10) gscore=gscore+700 ;   }   }
           
 // **** 测试:显示牌面 *******
putout :
           ss1=intToString (c1s) ;
        if (c1s==1||c1s==14)  ss1="A" ;       
        if (c1s==13)  ss1="K" ;       
        if (c1s==12)  ss1="Q" ;       
        if (c1s==11)  ss1="J" ;       
            ss2=intToString (c2s) ;
        if (c2s==1||c2s==14)  ss2="A" ;       
        if (c2s==13)  ss2="K" ;       
        if (c2s==12)  ss2="Q" ;       
        if (c2s==11)  ss2="J" ;       
            ss3=intToString (c3s) ;
        if (c3s==1||c3s==14)  ss3="A" ;       
        if (c3s==13)  ss3="K" ;       
        if (c3s==12)  ss3="Q" ;       
        if (c3s==11)  ss3="J" ;       

//**** 测试 print test ** return gscore ****
//  putout:   
//calculate & putout gscore,  return gscore
    print "  " ;     // 算法测试检验,可注释掉
        print "取得牌面 = ",ss1 ,"     牌序 ", c1s ;
        print "取得牌面 = ",ss2 ,"     牌序 ", c2s ;
        print "取得牌面 = ",ss3 ,"     牌序 ", c3s ;
       // print "return  gscore = ",gscore ;
 }//cal_score ()


//****  End   ****

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值