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

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

我是编程爱好者。早期使用windows时就被扫雷游戏,钻石棋游戏,红心大战游戏迷住。相信大家也都玩过吧。在学习VB6编程时就编制过钻石棋和红心大战那样的纸牌游戏。都是标准Windows图形界面的。感兴趣的同好可参考我在同站上传的资源《纸牌游戏设计(VB6源码)》,其中有纸牌卡座制作和博眼子游戏。

今天再与大家共享C语言的纸牌游戏《21点》。此纸牌游戏起源于法国后流行世界各国,上世纪传入中国。它与《争上游》(俗称大怪路子或八十分)、《红心大战》(俗称拱猪)等都曾风靡上海滩。今试编此游戏程序介绍一些界面设计方法和游戏设计各个功能的算法。代码中加了注释,也展示了算法的设计要点和算法检验以及程序调试方法与过程。

算法设计:52张牌面制作显示。洗牌,随机显示52张牌。牌序0到51换算为A234...到JQK。界面显示圆角牌背牌面。界面提示文字显示。程序主要介绍了一些测试调试方法。代码中有详细注释。

drawcards ( ){。    //  设计制作显示52张牌,    验牌测试     }

showcard ( ){  //  验牌测试,洗牌显示     //设计过程:画牌验牌洗牌测试用  }

shuffle_cards ( ){    //  洗牌设计       }

transcards ( ){   //牌序号转为牌点和牌花色,           画出牌张     }

print_t ( ){   //打印标题提示等文字  //**  参数 sx,sy, ss3=$, tsize=text size   }

MySpringC是一个简化的C语言编译器。当前运行在Android平台上,是Android平台的一款应用。
使用MySpringC可以书写简单的C语言程序,编写完成后可以编译、运行并获得 结果。还可以做出安卓手机桌面app应用。SpringC支持的C与普通的C非常类似。MySpringC它没有复杂、庞大的编程环境,只要你了解一点C或java,只需要一部手机,在家里、在地铁上任何方便的时候,就可以编写满足自己特定需求的小程序。v.2.7是目前的完善版本。下面的游戏代码就是用它在安卓手机上编写的,可制作成安卓手机桌面app应用程序。
程序提供了一个框架,VB , VC,  VS 或 JAVA  改写可作为参考。
此样例可复制粘贴到编译器直接使用,亦可用 VB6 ,C++ ,  java  改写。

3929a992a4a3441ebd5edd737bc2cef1.png

//以下是源码:
//**************************************************
//*        纸牌游戏《 21 点》  Version   1.1.0                *
//**********         Black  Jack         ******************
//*        制作:张纯叔  ( micelu@126.com )               *
//**************************************************

Canvas cs ;       //画布
string sBarDes[10];
int nBarId[10];
string sMenu[50];
int nMenu[50];
float src[4];  //ClearDraw (cls) clear screen
string s,ss,ss1,ss2,ss3;      //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 pnum[54];    //洗牌后的牌序列
int cardnum,cardstyle;  //牌点牌花色
string cas1,cas2,cas4;           //牌点牌花色图案$
string cas3,cas5 ;         //牌背花色, 下注图案
double Rn;    //random number
string t$;     //提示文字
int tsize;      //textsize
int users1,users2,users3;  //东北西玩家分数
int bankers ;      //庄家分数 score
int bs,us1,us2,us3 ;   //计算分数 banker & users
int c1,c2,c1s,c2s ;      //calculate score
int bn, bpn[5];    //banker 牌序列
int un, upn[5];    //user 牌序列
int userdo;        //补牌
int gscore ;    //输入c1c2计算各家分数
int bet ;        //赌注,计算胜负 bet*2
int isdo;       //1 翻牌可计算分,0 不计
int context;    //canvasProc
int obj;
int id;
int event;      //canvasProc
int getA ;       //A 可算作 1 点 或  11 点

2308675429b949c09c1a013d900ac107.png
main(){
setDisplay(1);
  cs.SetBackground(205,205,205);
  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]="V.";
   nBarId[5]=105;
   setToolBarHeight(6);
   setButtonTextSize(13);
   setToolBarBackgroundColor(255,192,192,192);
   setButtonColor(255,0,0,240);
   setButtonTextColor(255,255,255,0);
   setToolBar(100,myToolBarProc,sBarDes,nBarId,6);

   sMenu[0]="重新开始";
   nMenu[0]=200;
   sMenu[1]="发牌" ;
   nMenu[1]=201;
   sMenu[2]="补牌";
   nMenu[2]=202;
   sMenu[3]="  ";
   nMenu[3]=203;
   sMenu[4]="测试 => 洗牌验牌";
   nMenu[4]=204;
   sMenu[5]="测试 => 查看计分";
   nMenu[5]=205;
   sMenu[6]="显示游戏主屏幕";
   nMenu[6]=206;
   sMenu[7]="退出";
   nMenu[7]=207;
   setMenu(200,myMenuProc,sMenu,nMenu,8);
  setTitle("纸牌游戏 21 点   ");
//**********
      cas3="🐵";         //预设牌背图案
      cas4="🐒";         //预设牌面图案
      cas5="💸";         //预设下注图案
    bankers=1000;    //预定分数
      //users1=500;
      users2=1000;
      //users3=500;
      bet=25 ;
      drawcover ();
 while (){}
  }//main ()

drawcover (){     // 画启动界面封面版本号
     cs.SetColor (255,0,120,0);  //back color
     cs.DrawRect (2,2,718,900);
     cs.SetColor (255,0,180,0);
     cs.DrawRect (50,320,650,326);
     cs.SetColor (255,250,0,0);
     cs.DrawRect (52,322,648,324);
   px=400;    py=90;   //A
        num=25 ;     c1=num ;
        transcards ();
    px=500;    py=70;   //K
        num=0;    c2=num ;
        transcards ();
    t$=cas4 ;
     sx=450;   sy=350;    tsize=120;
     print_t ();
     t$="纸牌游戏" ;
     sx=130;   sy=160;   tsize=60;
     print_t ();
     t$="21 点" ;
     sx=155;   sy=260;   tsize=80;
     print_t ();
     t$="欢迎加入纸牌游戏团" ;
     sx=135;   sy=440;   tsize=50;
     print_t1 ();
     ss="Copyright  v.1.1.0   micelu@126.com ";
     cs.SetTextSize (22);
     cs.SetColor (255,250,250,250);
     cs.DrawText (ss,50,360);      
     cs.Update ();
    // drawcards ();   //测试: 画牌
}//drawcover ()

mycanvasProc (int context,int obj,int id,int event,float x,float y){
    //**** button 1 - 6 **** 
    if (x>450&&x<680&&y>280&&y<400){  
               result () ;     }        //翻牌
         // if (x>450&&x<680&&y>450&&y<550){ 备用    }
    if (x>450&&x<680&&y>530&&y<650){
             stand () ;      }           //停牌
     //****  下注预定 10,25,50 三种分值
    if (x>40&&x<170&&y>870&&y<990) {
             bet=10 ;   redeal () ;    putbet () ;         }
    if (x>190&&x<320&&y>870&&y<990) {
             bet=25 ;   redeal () ;    putbet () ;         }
    if (x>340&&x<470&&y>870&&y<990) {
             bet=50 ;   redeal () ;    putbet () ;         }
}//mycanvasProc ()

putbet (){    //下注   
    // 屏幕点击筹码显示下注数
     cs.SetColor (255,0,120,0);  //clear text
     cs.DrawRect (2,370,350,435);
     ss=intToString(bet) ;
     t$="下注  "+cas5+"   "+ss ;
     sx=70;   sy=420;   tsize=50;
     print_t ();
     cs.Update ();
}//putbet ()

renewscreen (){    
  //** draw interface 画界面按钮
   cs.SetStrokeWidth(1);//画笔线宽
   cs.SetFillMode (1);//0不填色,1填色
   px=500 ;   py=340 ;
   for (i=0;i<2;i++){     //cmd3p
   for (j=0;j<40;j++){
          cs.SetColor (255,255-j*5,255-j*3,255-j*5);   
    cs.DrawCircle (j*3+502,i*250+py+2,52);
         cs.SetColor (35,j*3+50,j*2+60,j*2+80);   
     cs.DrawCircle (j*3+500,i*250+py,49);
            }   }
     cs.SetFillMode (0);//0不填色,1填色
  for (i=0;i<48;i++){    //彩球○
        cs.SetColor (255,255-i*2,255-i,255-i*2);
        cs.DrawCircle (px+120,py+1,i);  
        cs.DrawCircle (px+120,py+251,i);  
                  }
 
  cs.SetFillMode (1);//0不填色,1填色^
      t$="翻  牌" ;
     sx=480;   sy=py+15;    tsize=50;
     print_t1 ();
      t$="停  牌" ;
     sx=480;   sy=py+265;    tsize=50;
     print_t1 ();

   for (i=0;i<=2;i++){
         cs.SetColor (255,0,60,0);   
    cs.DrawCircle (i*150+102,932,62);
          cs.SetColor (255,250,180,30);   
    cs.DrawCircle (i*150+100,930,61);

        cs.SetColor (255,120,50,180);   
    cs.DrawCircle (i*150+100,930,60);
         cs.SetColor (255,250,220,30);   
    cs.DrawCircle (i*150+100,930,45);
         cs.SetColor (255,250,150,30);   
    cs.DrawCircle (i*150+101,931,45);
            }       
    cs.SetFillMode (0);//0不填色,1填色
        px=100 ;   py=930 ;
    for (i=0;i<44;i++){     //彩球○
      cs.SetColor (255,255-i*2,255-i*4,i*6);
      cs.DrawCircle (px,py,i);  
      cs.DrawCircle (px+150,py,i);  
      cs.DrawCircle (px+300,py,i);  
               }
 
  cs.SetFillMode (1);//0不填色,1填色
      t$="10" ;
     sx=65;   sy=950;    tsize=60;
     print_t ();
      t$="25" ;
     sx=215;   sy=950;    tsize=60;
     print_t ();
      t$="50" ;
     sx=365;   sy=950;    tsize=60;
     print_t ();
        cs.Update () ;
}//renewscreen ()

drawcards (){  //预制54张牌,验牌测试
//****  设计制作显示52张牌,调试
    cs.SetColor (255,0,120,0);  //back color
    cs.DrawRect (2,2,718,900);
      cs.SetTextStyle (1);
      t$="纸牌制作测试:画牌" ;
      sx=20;   sy=50;   tsize=30;
      print_t ();
   //**** 画牌 ********
   for (i=0;i<=51;i++){
        px=(i-i/13*13)*48+15;
        py=i/13*170+100;
    //**** draw cards 圆角 ****
      cs.SetColor (255,0,0,70);  //黑色框线
      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);
    //牌号 0 => 51 转为4花色 A 1234...JQK ****
        cardnum=(i-i/13*13)+1;
        cardstyle=i/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="🔶";
       // print i," , ",cardnum," , ",cardstyle;   
       // print cas1+" "+ cas2;    //*** test ***
     if(cardstyle==0||cardstyle==2) {
            cs.SetColor (255,0,0,0);     }
     if(cardstyle==1||cardstyle==3) {
            cs.SetColor (255,250,0,0);      }
     n=0;
     if (cardnum==10) n=8;           
      cs.SetTextSize (30);
      cs.DrawText (cas1,px+15-n,py+1);
      cs.DrawText (cas2,px+8,py+35);      
      cs.SetTextSize (60);
      cs.DrawText (cas4,px+37,py+93);      
               }
      cs.Update ();
      setDisplay(1);
}//drawcards ()

showcard (){  //验牌测试,洗牌显示
//设计过程:画牌验牌洗牌测试用
    cs.SetColor (255,0,120,0);  //backcolor
    cs.DrawRect (2,2,718,900);
     cs.Update ();
   cs.SetFillMode (1);//0不填色,1填色
      cs.SetTextStyle (1);
      t$="纸牌制作测试:洗牌" ;
      sx=20;   sy=50;   tsize=30;
      print_t1 ();
     for (k=0;k<=51;k++){
        i=pnum[k];
        px=(k-k/13*13)*48+15;
        py=k/13*170+100;
    //**** 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);
    //牌号 0 => 51 转为4花色 A 1234...JQK ****
        cardnum=(i-i/13*13)+1;
        cardstyle=i/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="🔶";
       // print i," , ",cardnum," , ",cardstyle;   
       // print cas1+" "+ cas2;    //*** test ***
     if(cardstyle==0||cardstyle==2) {
            cs.SetColor (255,0,0,0);     }
     if(cardstyle==1||cardstyle==3) {
            cs.SetColor (255,250,0,0);      }
     n=0;
     if (cardnum==10) n=8;           
      cs.SetTextSize (30);
      cs.DrawText (cas1,px+15-n,py+1);
      cs.DrawText (cas2,px+8,py+35);      
      cs.SetTextSize (60);
      cs.DrawText (cas4,px+37,py+93);      
              }
      cs.Update ();
 }//showcard ()

//纸牌序列:
//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张牌
//********************

4cd1a9b856c846bd86d3c74a50ffeb56.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
//** 洗牌 **********************
     t$="游戏开始 >>>       请下注" ;
     sx=50;   sy=50;    tsize=30;
     print_t ();
  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 ();     //draw cards back picture
                }
      cs.Update ();
   // showcard();  //用于洗牌查验测试,游戏时注释掉
 }//shuffle_cards ()

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 ()

redeal (){    //游戏开始,发牌,重新发牌
 // 预设玩家4人,本游戏为双人对博
     bankers=1000;
    //  users1=500;
      users2=1000;
   //   users3=500;
   pn=0 ;    //重新开始,发牌序数清 0 
   bn=0 ;    un=0 ;
   for (i=0;i<=5;i++){     //init
          bpn[i]=-1 ;     upn[i]=-1 ;    }
     cs.SetColor (255,0,120,0);  //back color
     cs.DrawRect (2,2,718,900);
     cs.Update ();
     t$="游戏开始 >>>       请下注" ;
     sx=50;   sy=50;    tsize=30;
     print_t ();
     renewscreen ();
     cs.Update ();
}//redeal ()

bf533cfdacf544c5920709749d7f3ca1.png

56ed8a4eee9e402ba0e8fc37e8d3ed4c.png 

 

transcards (){  //num 转换 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 ()

addcard (){   //补牌 Hit
     //clearOutput();    //查看测试
            if (pn>10||userdo>1) return ;
  // 发牌时已计算庄家点数
  // 若庄家点数小于17点或小于玩家点数则补牌,
  // 若庄家点数大于玩家点数则翻牌结算
     if (userdo==0) {  //庄家补牌
          bs=0 ;    //init   
          bn=bn+1 ;   pn=pn+1 ;
        if (bn>4) return ;
           px=bn*120+60;    py=140;    //庄家
           num=pnum[pn];    c1=num ;
           bpn[bn]=num ;   
  print "num = ",num,"   Usernum = ", bn ;
           transcards ();
         getA=0 ;    bs=0 ;
    for (i=0;i<=bn;i++){     //计算分数
            c1=bpn[i] ;   
            cal_score ();
            bs=bs+gscore ;   
   c1s=(c1-c1/13*13)+1;  //1-52 转 1-13
           if (c1s==1) getA=getA+1 ;    //有牌A
                  }
        if (getA>0&&bs>21) bs=bs-10 ;
        if (getA>0&&bs<=11) bs=bs+10 ;
            print "          庄家点数 = ", bs ;   
        if (bs>21) {  //???
                  bs=0 ;  result () ;    } //爆牌 bust
        if (bs>=us2&&bs<=21) { 
             result () ;     }  //庄家点数大于玩家则胜
              }

//===============
// 玩家补牌后计算 upn (5) 合计分数,若大于21分
// 则直接判玩家输,结束此局牌。
          //   clearOutput();
   if (userdo==1) {  //玩家补牌
          us2=0 ;    //init   
          un=un+1 ;   pn=pn+1 ;
        if (un>4) { stand () ;     return ;  }
           px=un*120+60;    py=700;    //南家
           num=pnum[pn];    c1=num ;
           upn[un]=num ;   
  print "num = ",num,"   Usernum = ", un ;
           transcards ();
          getA=0 ;  us2=0 ;
    for (i=0;i<=un;i++){     //计算分数
            c1=upn[i] ;   
            cal_score ();
            us2=us2+gscore ;   
   c1s=(c1-c1/13*13)+1;  //1-52 转 1-13
           if (c1s==1) getA=getA+1 ;    //有牌A
                  }
         if (getA>0&&us2>21) us2=us2-10 ;
         if (getA>0&&us2<=11) us2=us2+10 ;
      print "      玩家点数 = ", us2 ;   
            if (us2>21) {  //????
                    us2=0 ;    result () ;    }    //爆牌 bust
           }
//================
}//addcard ()

5997bbf67a334f7a85d5d8a0f6b256fa.png

 

game2 (){   //游戏 ”二十一点”  >>> 发牌
     cs.SetColor (255,0,120,0);   //backcolor
     cs.DrawRect (2,2,718,900);
         clearOutput();
         renewscreen ();    //画界面
         cs.Update ();
   bn=0 ;    un=0 ;    pn=0 ;  
   for (i=0;i<=5;i++){     //init
          bpn[i]=-1 ;     upn[i]=-1 ;    }

  //*******显示"庄家"...文字及分数
     ss=intToString (bankers);
     t$="庄家 "+"  "+ss ;
     sx=80;   sy=80;   tsize=40;
     print_t ();
     ss=intToString (users2);
     t$="玩家 "+"  "+ss ;
     sx=80;   sy=630;    tsize=40;
     print_t ();
  
//**** 发牌 >>>
    px=60;    py=700;   //南家 玩家
         num=pnum[0];     //发牌顺序南北
          transcards ();    //  cardback ();
         upn[0]=num ;
    px=180;    py=700;    //南家
         num=pnum[2];
         transcards ();    //  cardback ();
         upn[1]=num ;
           un=1 ;

     px=60;    py=140;   //北家  庄家
        num=pnum[1];
        cardback ();    //显示牌背,庄家一张暗牌
        //transcards ();    //显示牌面
        bpn[0]=num ;
    px=180;    py=140;   //北家
         num=pnum[3];  
         transcards ();    
          bpn[1]=num ;
         bn=1 ;
         pn=3 ;    //发牌序
     putbet () ;      // 下注,预设 25
     t$="补牌" ;
     sx=360;   sy=75;    tsize=25;
         print_t1 ();
     sx=360;   sy=625 ;    tsize=25;
         print_t1 ();     
     cs.SetColor (255,120,0,0);  //补牌提示标记红
     cs.DrawCircle (330,68,15);
     cs.SetColor (255,250,0,0);  
     cs.DrawCircle (330,68,11);
     cs.SetColor (255,0,160,0);  //补牌提示标记绿
     cs.DrawCircle (330,618,15);
     cs.SetColor (255,0,250,0);  
     cs.DrawCircle (330,618,11);

  cs.Update ();
//*********
        getA=0 ;  us2=0 ;
    for (i=0;i<=un;i++){     //计算分数
            c1=upn[i] ;   
            cal_score ();
            us2=us2+gscore ;   
    c1s=(c1-c1/13*13)+1;  //1-52 转 1-13
            if (c1s==1) getA=getA+1 ;    //有牌A
                  }
         if (getA>0&&us2>21) us2=us2-10 ;
         if (getA>0&&us2<=11) us2=us2+10 ;
         print "   玩家点数 =  ",us2 ;        

   //发牌后若庄家牌为A + KQJ或 10  是通吃牌
  //若玩家是五龙则胜
         getA=0 ;  bs=0 ;
    for (i=0;i<=bn;i++){     //计算分数
            c1=bpn[i] ;   
            cal_score ();
            bs=bs+gscore ;   
    c1s=(c1-c1/13*13)+1;  //1-52 转 1-13
            if (c1s==1) getA=getA+1 ;    //有牌A
                      }
         if (getA>0&&bs>21) bs=bs-10 ;
         if (getA>0&&bs<=11) bs=bs+10 ;
         print "   庄家点数 =  ",bs ;        
    isdo=1;    //重新发牌可计分
    userdo=1 ;  //玩家补牌
  }//game2 ()

stand (){     //停牌 user stand
// 停牌:玩家stand停牌,改userdo=0,
// userdo=0 庄家Dealer可补牌Hit  addcard ( ) 。
// 玩家计算牌张 upn(5) 合计分数 us2 
    cs.SetColor (255,0,160,0);  //补牌提示标记绿
     cs.DrawCircle (330,68,15);
     cs.SetColor (255,0,250,0);  
     cs.DrawCircle (330,68,11);
     cs.SetColor (255,120,0,0);  //补牌提示标记红
     cs.DrawCircle (330,618,15);
     cs.SetColor (255,250,0,0);  
     cs.DrawCircle (330,618,11);
//******
     userdo=0;      //玩家停牌,庄家可补牌
//**** 翻牌结算庄家显示暗牌 *******
        px=60;    py=140;   //庄家显示暗牌
        num=pnum[1];    c1=num ;
        transcards ();
    if (bs>=us2) result () ;  //玩家停牌已负翻牌结算   
 }//stand ()

result (){   //翻牌比大小
     if (isdo==0) return ;   //发牌后计分,不重复计分
     if (userdo==2) return ;
//****************
//比大小计算各家得分
    if (bs>21) bs=0 ;       // 爆牌 bust
    if (us2>21) us2=0 ;   // 爆牌 bust
// 若牌张为5,点数小于等于21则是乌龙( 五龙)
// 若五龙则加权,五龙大于 AK 等 21 点
     if (un==4&&us2<=21) { 
              bs=0 ;   us2=21+1 ;       }
      if (bn==4&&bs<=21) { 
              bs=22 ;   us2=0 ;        }
     print " Banker  score bs   = ",bs ;
     print "     User  score us2 = ",us2 ;
 //**** 计算点数 ******
     if (bs<us2){
           bankers=bankers-bet*2 ;
           users2=users2+bet*2 ;  
           t$="玩家 胜 !" ;  }
     if (bs>=us2){
          bankers=bankers+bet*2 ;
          users2=users2-bet*2 ;  
          t$="玩家 负 !" ;  }
     sx=120;   sy=550;    tsize=50;
     print_t1 ();
     t$="🐒" ;
     sx=510;   sy=510;    tsize=120;
     print_t ();

//更新显示分数
 showscore :
     cs.SetColor (255,0,120,0);  //clear text
     cs.DrawRect (2,40,300,100);
     cs.DrawRect (2,590,300,650);
     ss=intToString (bankers);
     t$="庄家 "+"  "+ss ;
     sx=80;   sy=80;   tsize=40;
     print_t ();
     ss=intToString (users2);
     t$="玩家 "+"  "+ss ;
     sx=80;   sy=630;    tsize=40;
     print_t ();
     cs.Update ();
        isdo=0;   //翻牌计分后不重复计分
        userdo=2 ;  //玩家庄家停止补牌
}//result ()

//**** 计分规则:
// 21点计分相对其他游戏较为简单
// A 可计1分或10分,人头牌加A , 就是21点,
// KQJ人头牌计10分,牌数10,计10分
// 其他牌按牌面数计分 9计9分,8计8分,以此类推

cal_score (){
 // 计算分数,输入为c1,c2,输出 gscore
 // 为计分:c1 换算为 1 ->> 13 (A ->> K )序
    c1s=(c1-c1/13*13)+1;  
//---------------
        if (c1s==13)  gscore=10 ;       //计算得分
        if (c1s==12)  gscore=10 ;       
        if (c1s==11)  gscore=10 ;       
        if (c1s==10)  gscore=10 ;       
        if (c1s==9)  gscore=9 ;       
        if (c1s==8)  gscore=8 ;       
        if (c1s==7)  gscore=7 ;       
        if (c1s==6)  gscore=6 ;       
        if (c1s==5)  gscore=5 ;       
        if (c1s==4)  gscore=4 ;       
        if (c1s==3)  gscore=3 ;       
        if (c1s==2)  gscore=2 ;       
        if (c1s==1)  gscore=1 ;       //计算得分
    if (c1s==1&&us2<10) gscore=11 ;  //A
     if (c1s==1&&bs<10) gscore=11 ;  //A
// 测试显示 AKQJ  
        ss=intToString (c1s);
       if (c1s==1)  ss="A" ;       
       if (c1s==13)  ss="K" ;       
        if (c1s==12)  ss="Q" ;       
        if (c1s==11)  ss="J" ;       
//**** 测试 print test ****
//  putout:   
//calculate & putout gscore,  return gscore
     //   print "取得牌面 = ",ss ,"     牌序 ", c1s ;
     //print "gscore = ",gscore ;
     // print "  " ;     //print 算法测试检验,可注释掉
}//cal_score ()

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

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

myToolBarProc(int nBtn,int nContext){8
      if(nBtn==100){//redeal 重新开始
           setDisplay (1);
           redeal ();
              }  
      if(nBtn==101){//发牌
            setDisplay (1);
            shuffle_cards ();
            renewscreen ();
            game2 () ;
             }
      if(nBtn==102){//补牌
            setDisplay (1);
            addcard () ;
             }
      if(nBtn==103){//停牌  XX空
           setDisplay (1);
         //  stand () ;
              }
      if(nBtn==104){//退出程序
          clearOutput();
          cs.ClearDraw (0,src);
          setDisplay (0);
          exit (0);
               }
     if(nBtn==105){//@About
            setDisplay (1);
            drawcover ();
                 }
}//myToolBar ()

myMenuProc(int nMen,int nContext){
     if(nMen==200){  //重新开始
          setDisplay (1);
          redeal ();
                 }   
     if(nMen==201){   // 发牌
          setDisplay (1);
          shuffle_cards ();
           game2 () ;
                  }   
     if(nMen==202){    //补牌
           setDisplay (1);
           addcard ();
                     }
      if (nMen==203){  //停牌 空
             //stand ();
                    }
    if (nMen==204){//选项:洗牌验牌
            shuffle_cards ();
               sleep (1000);
            //drawcards ();    //原顺序显示牌面
            showcard ();       //洗牌后显示牌面
              }
  if(nMen==205){//close canvas 测试查看
        setDisplay (0);  
             }  
    if(nMen==206){//show canvas
          setDisplay (1);    
             }
    if (nMen==207){//Exit 
        clearOutput();
        cs.ClearDraw (0,src);
        exit (0);
          }
  }//myMenu()

 

//**** End ****

  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的10纸牌游戏代码,使用C语言编写: ```c #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { int cards[52] = {1,2,3,4,5,6,7,8,9,10,10,10,10, 1,2,3,4,5,6,7,8,9,10,10,10,10, 1,2,3,4,5,6,7,8,9,10,10,10,10, 1,2,3,4,5,6,7,8,9,10,10,10,10}; //初始化一副扑克牌 int player_cards[10] = {0}; //玩家手牌 int dealer_cards[10] = {0}; //庄家手牌 int player_sum = 0; //玩家手牌数 int dealer_sum = 0; //庄家手牌数 int player_count = 0; //玩家手牌数量 int dealer_count = 0; //庄家手牌数量 int i, j; //循环计数器 char hit; //是否继续要牌 srand(time(NULL)); //设置随机数种子 //洗牌 for (i = 0; i < 52; i++) { int r = rand() % 52; int temp = cards[i]; cards[i] = cards[r]; cards[r] = temp; } //发牌 player_cards[0] = cards[0]; dealer_cards[0] = cards[1]; player_cards[1] = cards[2]; dealer_cards[1] = cards[3]; player_count = 2; dealer_count = 2; //计算玩家手牌数 for (i = 0; i < player_count; i++) { if (player_cards[i] == 1 && player_sum + 11 <= 10) { player_sum += 11; } else { player_sum += player_cards[i]; } } //计算庄家手牌数 for (i = 0; i < dealer_count; i++) { if (dealer_cards[i] == 1 && dealer_sum + 11 <= 10) { dealer_sum += 11; } else { dealer_sum += dealer_cards[i]; } } //玩家要牌 while (player_sum < 10.5) { printf("Your cards: "); for (i = 0; i < player_count; i++) { printf("%d ", player_cards[i]); } printf("\n"); printf("Do you want to hit? (y/n)\n"); scanf(" %c", &hit); if (hit == 'y') { player_cards[player_count] = cards[4 + player_count]; player_count++; if (player_cards[player_count - 1] == 1 && player_sum + 11 <= 10) { player_sum += 11; } else { player_sum += player_cards[player_count - 1]; } } else { break; } } //庄家要牌 while (dealer_sum < 10.5) { dealer_cards[dealer_count] = cards[4 + dealer_count + player_count]; dealer_count++; if (dealer_cards[dealer_count - 1] == 1 && dealer_sum + 11 <= 10) { dealer_sum += 11; } else { dealer_sum += dealer_cards[dealer_count - 1]; } } //输出玩家和庄家的手牌和数 printf("Your cards: "); for (i = 0; i < player_count; i++) { printf("%d ", player_cards[i]); } printf("\n"); printf("Your sum: %.1f\n", player_sum); printf("Dealer's cards: "); for (i = 0; i < dealer_count; i++) { printf("%d ", dealer_cards[i]); } printf("\n"); printf("Dealer's sum: %.1f\n", dealer_sum); //判断胜负 if (player_sum > 10.5) { printf("You bust!\n"); } else if (dealer_sum > 10.5) { printf("Dealer bust!\n"); } else if (player_sum > dealer_sum) { printf("You win!\n"); } else if (player_sum < dealer_sum) { printf("Dealer win!\n"); } else { printf("Push!\n"); } return 0; } ``` 注意:这只是一个简单的实现,可能还有很多需要完善的地方。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值