纸牌游戏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 改写。
//以下是源码:
//**************************************************
//* 纸牌游戏《 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 点
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张牌
//********************
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 ()
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 ()
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 ****