纸牌游戏炸金花设计制作 (C语言)
我是编程爱好者。早期使用windows时就被扫雷游戏,钻石棋游戏,红心大战游戏迷住。相信大家也都玩过吧。在学习VB6编程时就编制过钻石棋和红心大战那样的游戏。都是标准Windows图形界面的。感兴趣的同好可参考我在同站上传的资源《纸牌游戏设计(VB6源码)》,其中有纸牌卡座制作和博眼子游戏。
前些日我在本站发了2个我原创的纸牌游戏设计制作的博文,一是《博眼子》,另一是《21点》。今天我凭借对纸牌游戏程序的热情再接再厉又设计制作了这个C语言的纸牌游戏《炸金花》。此游戏流行于上个世纪,至今流行民间,经久不衰。今试编此游戏程序介绍一些界面设计方法和游戏设计各个功能的算法。代码中加了注释,也展示了算法的设计要点和算法检验以及程序调试方法与过程。
算法设计:52张牌面制作显示。洗牌,随机显示52张牌。牌序0到51换算为A234...到JQK。界面设计:界面显示圆角牌背牌面,界面提示文字显示。程序主要介绍了一些测试调试方法。代码中有详细注释。
此游戏规则看似简单,就三张牌比大小,其实不简单。有三连张对的豹子,三连金花顺子,杂花色顺子,三连张花色的金花,二连的对子。最难比对是三张杂花色牌逐张牌比大小。本程序设计都给出了简单明了的算法。
drawcards ( ){ // 设计制作显示52张牌,验牌测试 }
showcard ( ){ // 验牌测试,洗牌显示 //设计过程:画牌验牌洗牌测试用 }
shuffle_cards ( ){ // 洗牌设计 }
transcards ( ){ //牌序号转为牌点和牌花色,画出牌张 }
cal_score ( ){ //计算分数,输入为c1,c2,c3, 输出 gscore }
result ( ){ //翻牌比大小,计算各家得分,界面显示。 }
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 改写。
//**************************************************
//* 纸牌游戏《炸金花》 Version 1.1.0 *
//* 制作:张纯叔 ( 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,ss0,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,c3,c1s,c2s,c3s ; //calculate score
int b1,b2,b3 ; //庄家和玩家都杂牌时比大小
int b1s,b2s,b3s ; //庄家和玩家都杂牌时比大小
int c1sf,c2sf,c3sf ; //玩家牌点分值
int csh1,csh2,csh3 ; //玩家3张牌花色
int bf1,bf2 ; //计算分数比大小
int bpn[3]; //banker 牌序列
int epn[3]; //user esat 牌序列
int npn[3]; //user north 牌序列
int wpn[3]; //user west 牌序列
int gscore ; //输入c1c2c3计算rerurn各家分数
int bet ; //赌注,计算胜负 bet
int zu1,zu2,zu3,zu4 ; //下注
int wnum ; //庄家和3玩家id切换,1, 2,3 4
int isdo; //1 翻牌可计算分,0 不计
int context; //canvasProc
int obj;
int id;
int event; //canvasProc
int temp ; //排序
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("纸牌游戏-炸金花 ");
//**********
cas3="🐵"; //预设牌背图案
cas4="🐒"; //预设牌面图案
cas5="💸"; //预设下注图案
bankers=2000; //预定分数
users1=2000;
users2=2000;
users3=2000;
bet=10 ; wnum=0 ;
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=300; py=90; //A
num=13 ; c1=num ;
transcards ();
px=400; py=80; //K
num=25; c2=num ;
transcards ();
px=500; py=70; //Q
num=24; c2=num ;
transcards ();
t$=cas4 ;
sx=450; sy=350; tsize=120;
print_t ();
t$="纸牌游戏" ;
sx=100; sy=160; tsize=60;
print_t ();
t$="炸金花" ;
sx=100; 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){
// cs.SetFillMode(0);//0不填色,1填色,调试
// cs.SetColor (255,250,50,0);
// cs.DrawRect (180,640,550,850); //南
// cs.DrawRect (180,30,550,240); //北
// cs.DrawRect (430,310,710,520); //东
// cs.DrawRect (20,310,290,520); //西
// cs.DrawRect (560,720,710,800);
// cs.DrawRect (560,820,710,900);
// cs.DrawRect (560,920,710,1000);
// cs.DrawRect (30,890,150,1010);
//cs.DrawRect (180,890,300,1010);
// cs.DrawRect (330,890,450,1010);
// cs.Update ();
//纸牌区域点击切换玩家
if (x>180&&x<550&&y>640&&y<850){
wnum=0 ; change_id () ; } //南
if (x>430&&x<710&&y>310&&y<520){
wnum=1 ; change_id () ; } //东
if (x>180&&x<550&&y>30&&y<240){
wnum=2 ; change_id () ; } //北
if (x>20&&x<290&&y>310&&y<520){
wnum=3 ; change_id () ; } //西
//**** button 1 - 6 **** test 用于调试
if (x>560&&x<710&&y>720&&y<800){
watch () ; } //看牌
if (x>560&&x<710&&y>820&&y<900){
isdo=1 ; } // 比牌暂未设置
if (x>560&&x<710&&y>920&&y<1000){
result () ; } //比牌
//**** 下注预定 10,20,30 三种分值
if (x>30&&x<150&&y>890&&y<1010) {
bet=10 ; putbet () ; }
if (x>180&&x<300&&y>890&&y<1010) {
bet=20 ; putbet () ; }
if (x>330&&x<450&&y>890&&y<1010) {
bet=30 ; putbet () ; }
}//mycanvasProc ()
watch (){ //看牌 显示牌面
if (wnum==1) {
px=180; py=670; //南家 庄家
num=bpn[0];
transcards ();
px=305; py=670; //南家
num=bpn[1];
transcards ();
px=430; py=670;
num=bpn[2];
transcards (); }
if (wnum==2) {
px=440; py=340; //东家
num=epn[0];
transcards ();
px=510; py=340; //东家
num=epn[1];
transcards ();
px=580; py=340;
num=epn[2];
transcards (); }
if (wnum==3) {
px=180; py=120; //北家
num=npn[0];
transcards ();
px=305; py=120; //北家
num=npn[1];
transcards ();
px=430; py=120;
num=npn[2];
transcards (); }
if (wnum==4) {
px=30; py=340; //西家
num=wpn[0];
transcards ();
px=100; py=340; //西家
num=wpn[1];
transcards ();
px=170; py=340;
num=wpn[2];
transcards (); }
}//watch ()
putbet (){ //下注
// 屏幕点击筹码显示下注数
cs.SetColor (255,0,150,0); //clear text
cs.DrawRect (2,805,140,870);
cs.DrawCircle (140,838,32);
ss=intToString(bet) ;
t$= cas5+" "+ss ;
sx=20; sy=850; tsize=40;
print_t ();
cs.Update ();
}//putbet ()
add_bet (){ //玩家加注
if (wnum==1){
zu1=zu1+bet ; }
if (wnum==2){
zu2=zu2+bet ; }
if (wnum==3){
zu3=zu3+bet ; }
if (wnum==4){
zu4=zu4+bet ; }
cs.SetColor (255,0,120,0); //clear text
cs.DrawRect (250,20,550,70);
cs.DrawRect (20,480,700,530);
cs.DrawRect (250,810,550,860);
//*******显示"庄家"...文字及分数和下注数
ss=intToString (bankers);
s=intToString (zu1);
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=450; sy=520; tsize=40;
print_t ();
ss=intToString (users2);
s=intToString (zu3);
t$="北家 "+" "+ss+" "+s ;
sx=235; sy=60; tsize=40;
print_t ();
ss=intToString (users3);
s=intToString (zu4);
t$="西家 "+" "+ss+" "+s ;
sx=30; sy=520; tsize=40;
print_t ();
}//add_bet ()
renewscreen (){
//** draw interface 画界面按钮
cs.SetStrokeWidth(1);//画笔线宽
cs.SetFillMode (1);//0不填色,1填色
px=700 ; py=760 ;
for (i=0;i<3;i++){ //cmd3p
for (j=0;j<24;j++){
cs.SetColor (255,255-j*8,255-j*5,255-j*7);
cs.DrawCircle (j*3+602,i*100+py+2,40);
} }
cs.SetFillMode (0);//0不填色,1填色
for (i=0;i<39;i++){ //彩球○
cs.SetColor (255,255-i*2,255-i,255-i*2);
cs.DrawCircle (px-30,py+2,i);
cs.DrawCircle (px-30,py+102,i);
cs.DrawCircle (px-30,py+202,i);
}
cs.SetFillMode (1);//0不填色,1填色
t$="看牌" ;
sx=590; sy=py+15; tsize=42;
print_t1 ();
t$="比牌" ;
sx=590; sy=py+115; tsize=42;
print_t1 ();
t$="翻牌" ;
sx=590; sy=py+215; tsize=42;
print_t1 ();
// **** draw bet picecs ****
for (i=0;i<=2;i++){
cs.SetColor (255,0,60,0);
cs.DrawCircle (i*150+92,952,62);
cs.SetColor (255,250,180,30);
cs.DrawCircle (i*150+90,950,61);
cs.SetColor (255,120,50,180);
cs.DrawCircle (i*150+90,950,60);
cs.SetColor (255,250,220,30);
cs.DrawCircle (i*150+90,950,45);
cs.SetColor (255,250,150,30);
cs.DrawCircle (i*150+91,951,45);
}
cs.SetFillMode (0);//0不填色,1填色
px=90 ; py=950 ;
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=56; sy=970; tsize=60;
print_t ();
t$="20" ;
sx=206; sy=970; tsize=60;
print_t ();
t$="30" ;
sx=356; sy=970; 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 (); //洗牌后可显示牌背或不显示
}
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人,本游戏为4人博奕
bankers=2000;
users1=2000;
users2=2000;
users3=2000;
bet=10 ; putbet () ; //显示底注和加注额
//pn=0 ; //重新开始,发牌序数清 0 用于其他游戏
for (i=0;i<3;i++){ //init
bpn[i]=-1 ; epn[i]=-1 ; npn[i]=-1 ; wpn[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 ();
game3 () ;
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 ()
change_id (){ //切换庄家和3玩家 id
cs.SetColor (255,0,250,0);
cs.DrawCircle (363,580,15);
cs.DrawCircle (363,290,15);
cs.DrawCircle (320,380,15);
cs.DrawCircle (405,380,15);
wnum=wnum+1 ;
if (wnum>4) wnum=1 ;
if (wnum==1){
cs.SetColor (255,250,0,0);
cs.DrawCircle (363,580,13); }
if (wnum==2){
cs.SetColor (255,250,0,0);
cs.DrawCircle (405,380,13); }
if (wnum==3){
cs.SetColor (255,250,0,0);
cs.DrawCircle (363,290,13); }
if (wnum==4){
cs.SetColor (255,250,0,0);
cs.DrawCircle (320,380,13); }
cs.Update ();
}//change_id ()
game3 (){ //游戏 ”炸金花” >>> 发牌
cs.SetColor (255,0,120,0); //backcolor
cs.DrawRect (2,2,718,900);
clearOutput();
renewscreen (); //画界面
cs.Update ();
for (i=0;i<3;i++){ //init
bpn[i]=-1 ; epn[i]=-1 ; npn[i]=-1 ; wpn[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=850; tsize=40;
print_t ();
t$="东家 " ;
sx=620; sy=520; tsize=40;
print_t ();
ss=intToString (users1);
s=intToString (zu2);
t$=ss+" "+s ;
sx=450; sy=520; tsize=40;
print_t ();
ss=intToString (users2);
s=intToString (zu3);
t$="北家 "+" "+ss+" "+s ;
sx=235; sy=60; tsize=40;
print_t ();
ss=intToString (users3);
s=intToString (zu4);
t$="西家 "+" "+ss+" "+s ;
sx=30; sy=520; tsize=40;
print_t ();
//**** 发牌 >> 排序 ** 发牌顺序 东北西南
bpn[0]=pnum[3];
bpn[1]=pnum[7];
bpn[2]=pnum[11];
for (i=0;i<3;i++){ //排序
for (j=0;j<i;j++){
bf1=bpn[j] ; bf2=bpn[i] ;
bf1=(bf1-bf1/13*13)+1;
bf2=(bf2-bf2/13*13)+1;
if (bf1==1) bf1=14 ; //A
if (bf2==1) bf2=14 ; //A
if (bf1<bf2) {
temp=bpn[i] ;
bpn[i]=bpn[j];
bpn[j]=temp ; }
} } //排序
px=180; py=670; //南家 庄家
num=bpn[0];
cardback ();
px=305; py=670; //南家
num=bpn[1];
cardback ();
px=430; py=670; //南家
num=bpn[2];
cardback ();
//北家发牌 ******
npn[0]=pnum[1];
npn[1]=pnum[5];
npn[2]=pnum[9];
for (i=0;i<3;i++){ //排序
for (j=0;j<i;j++){
bf1=npn[j] ; bf2=npn[i] ;
bf1=(bf1-bf1/13*13)+1;
bf2=(bf2-bf2/13*13)+1;
if (bf1==1) bf1=14 ; //A
if (bf2==1) bf2=14 ; //A
if (bf1<bf2) {
temp=npn[i] ;
npn[i]=npn[j];
npn[j]=temp ; }
} } //排序
px=180; py=120; //北家
num=npn[0];
cardback ();
px=305; py=120; //北家
num=npn[1];
cardback ();
px=430; py=120; //北家
num=npn[2];
cardback ();
// 东家发牌 ******
epn[0]=pnum[0];
epn[1]=pnum[4];
epn[2]=pnum[8];
for (i=0;i<3;i++){ //排序
for (j=0;j<i;j++){
bf1=epn[j] ; bf2=epn[i] ;
bf1=(bf1-bf1/13*13)+1;
bf2=(bf2-bf2/13*13)+1;
if (bf1==1) bf1=14 ; //A
if (bf2==1) bf2=14 ; //A
if (bf1<bf2) {
temp=epn[i] ;
epn[i]=epn[j];
epn[j]=temp ; }
} } //排序
px=440; py=340; //东家
num=epn[0];
cardback ();
px=510; py=340; //东家
num=epn[1];
cardback ();
px=580; py=340; //东家
num=epn[2];
cardback ();
// 西家发牌 ******
wpn[0]=pnum[2];
wpn[1]=pnum[6];
wpn[2]=pnum[10];
for (i=0;i<3;i++){ //排序
for (j=0;j<i;j++){
bf1=wpn[j] ; bf2=wpn[i] ;
bf1=(bf1-bf1/13*13)+1;
bf2=(bf2-bf2/13*13)+1;
if (bf1==1) bf1=14 ; //A
if (bf2==1) bf2=14 ; //A
if (bf1<bf2) {
temp=wpn[i] ;
wpn[i]=wpn[j];
wpn[j]=temp ; }
} } //排序
px=30; py=340; //西家
num=wpn[0];
cardback ();
px=100; py=340; //西家
num=wpn[1];
cardback ();
px=170; py=340; //西家
num=wpn[2];
cardback ();
//pn=12 ; //发牌序
putbet () ; // 下注,预设 10
isdo=1 ; //启动计分
cs.Update ();
}//game3 ()
result (){ //翻牌比大小
if (isdo==0) return ; //发牌后计分,不重复计分
//**** 翻牌 显示牌面 ************
px=180; py=670; //南家 庄家
num=bpn[0];
transcards ();
px=305; py=670; //南家
num=bpn[1];
transcards ();
px=430; py=670; //南家
num=bpn[2];
transcards ();
px=180; py=120; //北家
num=npn[0];
transcards (); //显示牌面
px=305; py=120; //北家
num=npn[1];
transcards (); //显示牌面
px=430; py=120; //北家
num=npn[2];
transcards (); // cardback ();
px=440; py=340; //东家
num=epn[0];
transcards (); //显示牌面
px=510; py=340; //东家
num=epn[1];
transcards ();
px=580; py=340; //东家
num=epn[2];
transcards (); // cardback ();
px=30; py=340; //西家
num=wpn[0];
transcards (); //显示牌面
px=100; py=340; //西家
num=wpn[1];
transcards ();
px=170; py=340; //西家
num=wpn[2];
transcards ();
cs.Update ();
//计算各家得分 >> 比大小 ****
c1=bpn[0] ; c2=bpn[1] ; c3=bpn[2] ;
cal_score () ; bs=gscore ; //南家
print " 南家得分 = ", bs ;
c1=epn[0] ; c2=epn[1] ; c3=epn[2] ;
cal_score () ; us1=gscore ; //东家
print " 东家得分 = ", us1 ;
c1=npn[0] ; c2=npn[1] ; c3=npn[2] ;
cal_score () ; us2=gscore ; //北家
print " 北家得分 = ", us2 ;
c1=wpn[0] ; c2=wpn[1] ; c3=wpn[2] ;
cal_score () ; us3=gscore ; //西家
print " 西家得分 = ", us3 ;
//比分大小关键:相同对子时要比杂牌点大小
//相同对子出现的概率很小,故只比对子的大小
//都是杂牌时要逐张牌比大小,比较复杂
//如都是金花也要逐张牌比大小
num=bs ; //保留原分值
//(bs&&us n<100)为杂牌 300<n>200 为同花
//**** 计算赢家分数 ******
//** bs 南家,us1 东家 , us2 北家 , us3 西家
//庄家比东家 ********
c1=bpn[0] ; c2=bpn[1] ; c3=bpn[2] ;
c1s=(c1-c1/13*13)+1; //庄家牌点
c2s=(c2-c2/13*13)+1;
c3s=(c3-c3/13*13)+1;
if (c1s==1) c1s=14 ;
b1=epn[0] ; b2=epn[1] ; b3=epn[2] ;
b1s=(b1-b1/13*13)+1; //东家牌点
b2s=(b2-b2/13*13)+1;
b3s=(b3-b3/13*13)+1;
if (b1s==1) b1s=14 ;
if (c1s>b1s) bs=bs+30 ;
if (c1s<b1s) us1=us1+30 ;
if (c2s>b2s) bs=bs+12 ;
if (c2s<b2s) us1=us1+12 ; //} //比东家
print " ";
print " 南家得分 = ", bs ;
print " 东家得分 = ", us1 ;
if (bs<us1){
bankers=bankers-zu2 ;
users1=users1+zu2 ;
}
if (bs>=us1){
bankers=bankers+zu2 ;
users1=users1-zu2 ;
}
// 庄家比北家 ********
bs=num ; //重新计算还原分值
c1=bpn[0] ; c2=bpn[1] ; c3=bpn[2] ;
c1s=(c1-c1/13*13)+1; //庄家牌点
c2s=(c2-c2/13*13)+1;
c3s=(c3-c3/13*13)+1;
if (c1s==1) c1s=14 ;
b1=npn[0] ; b2=npn[1] ; b3=npn[2] ;
b1s=(b1-b1/13*13)+1; //北家牌点
b2s=(b2-b2/13*13)+1;
b3s=(b3-b3/13*13)+1;
if (b1s==1) b1s=14 ;
if (c1s>b1s) bs=bs+30 ;
if (c1s<b1s) us2=us2+30 ;
if (c2s>b2s) bs=bs+12 ;
if (c2s<b2s) us2=us2+12 ; // } //比北家
print " ";
print " 南家得分 = ", bs ;
print " 北家得分 = ", us2 ;
if (bs<us2){
bankers=bankers-zu3 ;
users2=users2+zu3 ;
}
if (bs>=us2){
bankers=bankers+zu3 ;
users2=users2-zu3 ;
}
// 庄家比西家 ********
bs=num ; //重新计算还原分值
c1=bpn[0] ; c2=bpn[1] ; c3=bpn[2] ;
c1s=(c1-c1/13*13)+1; //庄家牌点
c2s=(c2-c2/13*13)+1;
c3s=(c3-c3/13*13)+1;
if (c1s==1) c1s=14 ;
b1=wpn[0] ; b2=wpn[1] ; b3=wpn[2] ;
b1s=(b1-b1/13*13)+1; //西家牌点
b2s=(b2-b2/13*13)+1;
b3s=(b3-b3/13*13)+1;
if (b1s==1) b1s=14 ;
if (c1s>b1s) bs=bs+30 ;
if (c1s<b1s) us3=us3+30 ;
if (c2s>b2s) bs=bs+12 ;
if (c2s<b2s) us3=us3+12 ; // } //比西家
print " ";
print " 南家得分 = ", bs ;
print " 西家得分 = ", us3 ;
if (bs<us3){
bankers=bankers-zu4 ;
users3=users3+zu4 ;
}
if (bs>=us3){
bankers=bankers+zu4 ;
users3=users3-zu4 ;
}
//更新显示分数
showscore :
cs.SetColor (255,0,120,0); //clear text
cs.DrawRect (250,20,550,70);
cs.DrawRect (20,480,700,530);
cs.DrawRect (250,810,550,860);
//*******显示"庄家"...文字及分数
ss=intToString (bankers);
s=intToString (zu1);
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=450; sy=520; tsize=40;
print_t ();
ss=intToString (users2);
s=intToString (zu3);
t$="北家 "+" "+ss+" "+s ;
sx=235; sy=60; tsize=40;
print_t ();
ss=intToString (users3);
s=intToString (zu4);
t$="西家 "+" "+ss+" "+s ;
sx=30; sy=520; tsize=40;
print_t ();
//******************
cs.Update ();
isdo=0; //翻牌计分后不重复计分
}//result ()
//**** 计分规则:
// 杂花 235 吃豹子 600
// 豹子AAA=......>222 500+
// 金花顺(同花顺)AKQ=...>32A 300+
// 金花(同花)♠♠♠ A...2 200+
// 顺子 AKA ==> 32A 100+
// 散牌 按牌面计分 A +计 14分... 2 +计 2分
cal_score (){
//计算分数,输入为c1,c2,c3, 输出 gscore
//int c1s,c2s,c3s ;
//为计分: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 ;
// 计算各家总分,豹子金花顺子对子加权
// 杂牌计分较复杂,要逐张牌比大小
// A23 19, KQ10 35, 差值16
// 若是3张杂牌或同花则对比加权比大小,
gscore=c1s+c2s+c3s ; //3张牌合计分
if (c1s==c2s&&c1s==c3s){ //豹子
gscore=gscore+500 ; }
if (csh1==csh2&&csh1==csh3){ //金花
gscore=gscore+300 ; }
if (c1s>3||c2s>3||c3s>3) { //3 以上 A 作 14点
if (c1s==1) c1s=14 ; //♠金花顺子
if (c2s==1) c2s=14 ;
if (c3s==1) c3s=14 ;
if (c3s==(c2s+1)&&c2s==(c1s-2)){
gscore=gscore+200 ; } }
if (c3s==(c2s-1)&&c2s==(c1s-1)){ //顺子
gscore=gscore+200 ; }
if (c1s==c2s||c1s==c3s||c2s==c3s){ //对子
if (c1s==c2s||c1s==c3s) gscore=c1s*2+100 ;
if (c1s==c3s||c2s==c3s) gscore=c3s*2+100 ; }
// 若有豹子则 杂花 235 吃豹子
if (bs>600){ // 庄家有豹子
if (csh1>csh2||csh1<csh3){ //杂花
if (gscore==10) gscore=gscore+700 ; } }
// **** 测试:显示牌面 ********
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 ()
print_t (){ //打印标题提示等文字
//** 参数 sx,sy, ss0=$, tsize=text size
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 ()
print_t1 (){ //打印标题提示等文字
//** 参数 sx,sy, ss0=$, tsize=text size
cs.SetFillMode (1);//0不填色,1填色
cs.SetTextStyle (1); //0正常,1粗体
ss0=t$ ;
cs.SetTextSize (tsize);
cs.SetColor (255,0,20,100);
cs.DrawText (ss0,sx+3,sy+4);
cs.SetColor (255,20,250,20);
cs.DrawText (ss0,sx,sy);
cs.SetFillMode (0);//0不填色,1填色
cs.SetColor (255,250,0,0);
cs.DrawText (ss0,sx,sy);
cs.SetFillMode (1);//0不填色,1填色
cs.Update ();
}//print _t1 ()
myToolBarProc(int nBtn,int nContext){
if(nBtn==100){//redeal 重新开始
setDisplay (1);
redeal ();
}
if(nBtn==101){//发牌
setDisplay (1);
shuffle_cards ();
renewscreen ();
game3 () ;
}
if(nBtn==102){//切换玩家
setDisplay (1);
change_id () ;
}
if(nBtn==103){//翻牌结算
setDisplay (1);
add_bet () ;
}
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 ();
game3 () ;
}
if(nMen==202){ //停牌
setDisplay (1);
isdo=1 ;
}
if (nMen==203){ //翻牌结算
result ();
}
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()
//纸牌游戏《炸金花》V.1.1.0 设计制作,用时5天
// 2022年9月16日完成于上海