C語言寫的“鬥牛”遊戲原始碼
/*建立二人鬥牛遊戲的程式*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
/*牌的資料結構*/
typedef struct
{
char face[4];
int num;
}FACE;
/*建立返回牌結果的資料結構*/
typedef struct
{
int result; //點數
int max; //最大的那張牌
int number; //如果多張牌時返回
int numberzhi;
}PAIRESULT;
/*建立總共紙牌初始函式*/
void inition(FACE zong[])
{
int i;
for(i=1;i<=4;i++)
{
strcpy(zong[i].face,"3");
zong[i].num=0;
}
for(i=5;i<=8;i++)
{
strcpy(zong[i].face,"4");
zong[i].num=1;
}
for(i=9;i<=12;i++)
{
strcpy(zong[i].face,"5");
zong[i].num=2;
}
for(i=13;i<=16;i++)
{
strcpy(zong[i].face,"6");
zong[i].num=3;
}
for(i=17;i<=20;i++)
{
strcpy(zong[i].face,"7");
zong[i].num=4;
}
for(i=21;i<=24;i++)
{
strcpy(zong[i].face,"8");
zong[i].num=5;
}
for(i=25;i<=28;i++)
{
strcpy(zong[i].face,"9");
zong[i].num=6;
}
for(i=29;i<=32;i++)
{
strcpy(zong[i].face,"10");
zong[i].num=7;
}
for(i=33;i<=36;i++)
{
strcpy(zong[i].face,"J");
zong[i].num=8;
}
for(i=37;i<=40;i++)
{
strcpy(zong[i].face,"Q");
zong[i].num=9;
}
for(i=41;i<=44;i++)
{
strcpy(zong[i].face,"K");
zong[i].num=10;
}
for(i=45;i<=48;i++)
{
strcpy(zong[i].face,"A");
zong[i].num=11;
}
for(i=49;i<=52;i++)
{
strcpy(zong[i].face,"2");
zong[i].num=12;
}
}
/*建立輸出函式*/
void output(int n,FACE zong[],int k)
{
int i;
printf("/n");
if(k==2)
printf("這是玩家的牌/n");
else
printf("這是莊家的牌/n");
for(i=1;i<=n;i++)
printf("%s ",zong[i].face);
printf("/n");
}
/*建立洗牌函式*/
void xipai(FACE zong[])
{
int i,j;
long k;
FACE temp;
srand(time(NULL));
for(k=1;k<1000;k++)
{
i=1+rand()%52;
j=1+rand()%52;
temp=zong[i];
zong[i]=zong[j];
zong[j]=temp;
}
}
/*建立發牌函式*/
void fapai(FACE zong[],FACE player1[],FACE player2[])
{
int i=1,c1=1,c2=1;
for(i=1;i<=10;)
{
player1[c1++]=zong[i++];
player2[c2++]=zong[i++];
}
}
/*建立牌的排序函式*/
void paisort(FACE player[])
{
FACE temp;
int i,j;
for(i=0;i<4;i++)
for(j=1;j<=4-i;j++)
if(player[j].num>player[j+1].num)
{
temp=player[j];
player[j]=player[j+1];
player[j+1]=temp;
}
}
/*建立只有三張非紙牌的函式*/
int san(int a2[])
{
if((a2[0]+a2[1]+a2[2])%10==0)//三張牌和為十的倍數時
return 10;
else //沒有牛時
{
/*以下是有兩張牌和為10時*/
if(a2[0]+a2[1]==10) return a2[2];
if(a2[0]+a2[2]==10) return a2[1];
if(a2[1]+a2[2]==10) return a2[0];
else
return 0;
}
}
/*建立有四張非花牌時的函式*/
int si(int a[])
{
if((a[0]+a[1]+a[2])%10==0) //其中有三張牌和為10的倍數時
return a[3];
if((a[0]+a[1]+a[3])%10==0)
return a[2];
if((a[0]+a[2]+a[3])%10==0)
return a[1];
if((a[3]+a[1]+a[2])%10==0)
return a[0];
/*以下是有兩張牌和為1*/
else
{
if(a[0]+a[1]==10&&a[2]+a[3]==10)
return 10;
if(a[0]+a[1]==10&&a[2]+a[3]!=10)
return (a[2]+a[3])%10;
if(a[0]+a[2]==10&&a[1]+a[3]==10)
return 10;
if(a[0]+a[2]==10&&a[1]+a[3]!=10)
return (a[1]+a[3])%10;
if(a[0]+a[3]==10&&a[2]+a[1]==10)
return 10;
if(a[0]+a[3]==10&&a[2]+a[1]!=10)
return (a[2]+a[1])%10;
if(a[1]+a[2]==10&&a[0]+a[3]==10)
return 10;
if(a[1]+a[2]==10&&a[0]+a[3]!=10)
return (a[0]+a[3])%10;
if(a[1]+a[3]==10&&a[0]+a[2]==10)
return 10;
if(a[1]+a[3]==10&&a[0]+a[2]!=10)
return (a[2]+a[0])%10;
if(a[2]+a[3]==10&&a[0]+a[1]==10)
return 10;
if(a[2]+a[3]==10&&a[0]+a[1]!=10)
return (a[0]+a[1])%10;
/*若無法湊出十時,點為零*/
else
return 0;
}
}
/*若無張牌都為非花牌,即五張非花牌時,若要有點數,必須用三張牌來湊點數*/
int wu(int a[])
{
if((a[0]+a[1]+a[2])%10==0&&a[3]+a[4]==10)
return 10;
if((a[0]+a[1]+a[2])%10==0&&a[3]+a[4]!=10)
return (a[3]+a[4])%10;
if((a[0]+a[1]+a[3])%10==0&&a[2]+a[4]==10)
return 10;
if((a[0]+a[1]+a[3])%10==0&&a[2]+a[4]!=10)
return (a[2]+a[4])%10;
if((a[0]+a[1]+a[4])%10==0&&a[2]+a[3]==10)
return 10;
if((a[0]+a[1]+a[4])%10==0&&a[2]+a[3]!=10)
return (a[2]+a[3])%10;
if((a[0]+a[2]+a[3])%10==0&&a[1]+a[4]==10)
return 10;
if((a[0]+a[2]+a[3])%10==0&&a[1]+a[4]!=10)
return (a[1]+a[4])%10;
if((a[0]+a[2]+a[4])%10==0&&a[1]+a[3]==10)
return 10;
if((a[0]+a[2]+a[4])%10==0&&a[1]+a[3]!=10)
return (a[1]+a[3])%10;
if((a[0]+a[4]+a[3])%10==0&&a[2]+a[1]==10)
return 10;
if((a[0]+a[4]+a[3])%10==0&&a[2]+a[1]!=10)
return (a[2]+a[1])%10;
if((a[2]+a[1]+a[3])%10==0&&a[4]+a[0]==10)
return 10;
if((a[2]+a[1]+a[3])%10==0&&a[0]+a[4]!=10)
return (a[0]+a[4])%10;
if((a[2]+a[1]+a[4])%10==0&&a[0]+a[3]==10)
return 10;
if((a[2]+a[1]+a[4])%10==0&&a[0]+a[3]!=10)
return (a[0]+a[3])%10;
if((a[4]+a[1]+a[3])%10==0&&a[2]+a[0]==10)
return 10;
if((a[4]+a[1]+a[3])%10==0&&a[2]+a[0]!=10)
return (a[2]+a[0])%10;
if((a[2]+a[4]+a[3])%10==0&&a[0]+a[1]==10)
return 10;
if((a[2]+a[4]+a[3])%10==0&&a[0]+a[1]!=10)
return (a[0]+a[1])%10;
else
return 0;
}
/*建立求最大值的函式*/
int searchmaxpai(FACE player[])
{
int a[7]={0},i,max;
for(i=1;i<=5;i++)
{
if(player[i].num>=11)
a[i]=player[i].num-13;
else
a[i]=player[i].num;
}
for(max=a[1],i=1;i<=5;i++)
if(max<a[i])
max=a[i];
return max;
}
/*建立計算有幾張重複牌的函式*/
void countrepeat(int a[],int n,int b[])
{
int k[5]={0},i=0,j=0,temp=0;
for(i=0;i<n;i++)
{
temp=a[i];
for(j=0;j<n;j++)
if(temp==a[j])
k[i]++;
}
for(i=0;i<n;i++)
{
if(k[i]>=3)
{
b[0]=k[i]; //b[0]儲存重複數目
b[1]=a[i];
break;//b[1]儲存對應的值
}
}
}
/*建立計算牌的點數的函式,這是遊戲的核心演算法*/
PAIRESULT jisuan(FACE player[],PAIRESULT finalresult)
{
int a1[5]={0},c1=0;//用於儲存10,J,Q,K的花牌表示的值
int a[2]={-1,-1};
int a2[5]={0},c2=0; //用於儲存非花牌表示的值
int i;
for(i=1;i<=5;i++) //總共5次
{
if(player[i].num>=7&&player[i].num<=10) //如果是花牌時
a1[c1++]=player[i].num+3;
else
if(player[i].num>=0&&player[i].num<=6)//如果是3-9時
a2[c2++]=player[i].num+3;
else
a2[c2++]=player[i].num-10; //如果是A或2時
} //完成對牌的分類儲存
/*以下對非花牌進行計算點數*/
switch(c2)
{
case 0 : finalresult.result=10;break; //都是花牌時
case 1 : finalresult.result=a2[0];break; //只有一張非花牌時
/*只有二張非零牌時*/
case 2 : {if(a2[0]+a2[1]==10)
finalresult.result=10;
else
finalresult.result=(a2[0]+a2[1])%10;
}break;
/*以下是由三張非花牌時*/
case 3 : finalresult.result=san(a2);break;
/*以下是四張非花牌時*/
case 4 : finalresult.result=si(a2);break;
/*以下是五張非花牌時*/
case 5 : finalresult.result=wu(a2);break;
}
finalresult.max=searchmaxpai(player); //最大牌的值,便於點數相同時比較大小
/*以下對有可能有的多張牌進行處理,儲存最多的牌*/
if(c1>=3)
{
countrepeat(a1,c1,a);
if(a[0]>=3)
{
finalresult.number=a[0]+1; //如果是花牌有多張時倍數更大
finalresult.numberzhi=a[1];
}
}
else
if(c2>=3)
{
countrepeat(a2,c2,a);
if(a[0]>=3)
{
finalresult.number=a[0];
finalresult.numberzhi=a[1];
}
}
else
finalresult.number=finalresult.numberzhi=-1;
return finalresult;
}
PAIRESULT build()
{
PAIRESULT final;
final.max=-1,
final.number=-1;
final.result=final.numberzhi=-1;
return final;
}
/*建立牌的比較函式,a[0]總金錢,a[1]表示押金*/
int compare(PAIRESULT final1,PAIRESULT final2,int a[])
{
int t=a[0];
/*做如下規定,四張相同牌,20,三張相同牌15倍,五張即四張花牌時25被*/
/*相同牌時莊家牌大*/
switch(final1.number)
{
case 5 : {if(final2.number==5&&final1.numberzhi>=final2.numberzhi)
{
a[0]=a[0]-a[1]*25;
break;
}
if(final2.number==5&&final1.numberzhi<final2.numberzhi)
{
a[0]=a[0]+a[1]*25;
break;
}
else
{
a[0]=a[0]-a[1]*25;
break;
}
};
case 4 : { if(final2.number==5)
{
a[0]=a[0]+a[1]*25;
break;
}
if(final2.number==4&&final1.numberzhi>=final2.numberzhi)
{
a[0]=a[0]-a[1]*20;
break;
}
if(final2.number==4&&final1.numberzhi<final2.numberzhi)
{
a[0]=a[0]+a[1]*20;
break;
}
else
{
a[0]=a[0]-a[1]*20;
break;
}
}
case 3 : { if(final2.number==5)
{
a[0]=a[0]+a[1]*25;
break;
}
if(final2.number==4)
{
a[0]=a[0]+a[1]*20;
break;
}
if(final2.number==3&&final1.numberzhi<final2.numberzhi)
{
a[0]=a[0]+a[1]*15;
break;
}
else
{
a[0]=a[0]-a[1]*15;
break;
}
};
case -1 : {
if(final2.number==5)
{
a[0]=a[0]+a[1]*25;
break;
}
if(final2.number==4)
{
a[0]=a[0]+a[1]*20;
break;
}
if(final2.number==3)
{
a[0]=a[0]+a[1]*15;
break;
}
if(final1.result>final2.result)//莊家牌大時
{
if(final1.result==10)
{
a[0]=a[0]-a[1]*3;
break;
}
if(final1.result>=7&&final1.result<=9)
{
a[0]=a[0]-a[1]*2;
break;
}
if(final1.result<7)
{
a[0]=a[0]-a[1];
break;
}
}
else
if(final1.result<final2.result)//玩家牌大時
{
if(final2.result==10)
{
a[0]=a[0]+a[1]*3;
break;
}
if(final2.result>=7&&final2.result<=9)
{
a[0]=a[0]+a[1]*2;
break;
}
if(final2.result<7)
{
a[0]=a[0]+a[1];
break;
}
}
else
{ if(final1.result==10&&final1.max>=final2.max)
{
a[0]=a[0]-a[1]*3;
break;
}
if(final1.result==10&&final1.max<final2.max)
{
a[0]=a[0]+a[1]*3;
break;
}
if(final1.result>=7&&final1.result<=9&&final1.max>=final2.max)
{
a[0]=a[0]-a[1]*2;
break;
}
if(final1.result>=7&&final1.result<=9&&final1.max<final2.max)
{
a[0]=a[0]+a[1]*2;
break;
}
if(final1.result<7&&final1.max>=final2.max)
{
a[0]=a[0]-a[1];
break;
}
if(final1.result<7&&final1.max<final2.max)
{
a[0]=a[0]+a[1];
break;
}
}
}
}
return a[0]-t;
}
void menu()
{
printf("/t/t/t歡迎來到“歡樂鬥牛”遊戲/n");
printf("請按數字鍵選擇/n");
printf("/t1:開始遊戲/n");
printf("/t2:遊戲規則/n");
printf("/t3:離開遊戲/n");
}
/*建立遊戲規則函式*/
void instruction()
{
printf("/t鬥牛也屬於紙牌遊戲,該遊戲中游戲為莊家,你為玩家./n");
printf("/t遊戲開始時系統送你100遊戲幣,輸完時遊戲結束.");
printf("/t規則簡要如下:/n");
printf( "/t每人有五張牌,比較點數,點數大者勝。計算點數時10、J、Q、/n");
printf("/tK為花牌,用非花牌計算點數,若五張牌中沒有一張花牌,任意用/n");
printf("/t其中三張湊成10的倍數,如果不能,則點數為零,如果能湊成,用/n");
printf("/t另外兩張之和除以十,餘數為點數。若有花牌時,可以用其中兩張/n");
printf("/t或三張牌湊成10的倍數,如果能,結果為其餘牌之和除以10的餘數/n");
printf("/t(餘數為零點數為10)。不能時,點數為零。當點數相同時,以牌/n");
printf("/t面值大者勝./n");
printf("/t0-6點倍率為1,7-9點倍率為2,10點倍率為3/n");
printf("/t三張相同面值的非花牌,倍率15,四張20/n");
printf("/t三張相同面值的花牌,倍率20,四張25/n");
printf("/t賭博有害家庭健康,該遊戲僅供娛樂/n");
}
int main()
{
FACE zong[52];//總共的48張紙牌
PAIRESULT final1=build(),final2=build();//牌的結果
FACE player1[5],player2[5]; //用於儲存兩個玩家的牌,player1是莊家,player2是玩家
inition(zong);
int flag,a[2]={100,0},count=1,defen;
char ch;
/*以下是遊戲選單*/
menu();
scanf("%d",&flag);
while(flag<1||flag>3)
{
printf("數字輸入錯誤,請重新輸入/n");
scanf("%d",flag);
}
while(flag!=1)
{
if(flag==3)
exit(0);
else
if(flag==2)
{
instruction();
menu();
scanf("%d",&flag);
}
}
if(flag==1)
{
printf("/t/t現在開始遊戲/n");
printf("/t/t系統先送你100遊戲幣,當遊戲幣不大於零時遊戲結束/n");
while(1)
{
printf("/t/t/t/t第%d局/n",count);
printf("請下注(1-10遊戲幣),目前你的遊戲幣為%d/n",a[0]);
while(1)
{
scanf(" %d",&a[1]);
if(a[1]>0&&a[1]<=10)
break;
else
printf("輸入資料範圍不對,請重新選擇/n");
}
xipai(zong); //洗牌
fapai(zong,player1,player2); //發牌
paisort(player1); output(5,player1,1); //莊家的牌,先排序在現實牌
paisort(player2); output(5,player2,2); //玩家的牌,先排序在顯現牌
final1=jisuan(player1,final1); //計算點數
final2=jisuan(player2,final2); //計算點數
defen=compare(final1,final2,a);
if(final1.number>=3&&final1.numberzhi>=11)
printf("/t莊家有%d張牌相同/n",(final1.number-1));
else
if(final1.number>=3&&final1.numberzhi<11)
printf("/t莊家有%d張牌相同/n",final1.number);
else
printf("/t莊家牌的點數: %d/n",final1.result);
if(final2.number>=3&&final2.numberzhi>=11)
printf("恭喜你,你有%d張牌相同/n",(final2.number-1));
else
if(final2.number>=3&&final2.numberzhi<11)
printf("恭喜你,你有%d張牌相同/n",final2.number);
else
if(final2.result==10)
printf("/t/t你牛了,牛氣沖天/n");
else
if(final2.result>=7&&final2.result<=9)
printf("/t/t你進套了,點數:%d/n",final2.result);
else
printf("/t/t你的點數:%d/n",final2.result);
if(defen>0)
printf("/t本局你勝,得分:%d/n",defen);
else
if(defen==0)
printf("/t本局平局/n");
else
printf("/t本局你輸了,再接再厲,得分:%d/n",defen);
printf("/t/t/t/t總遊戲幣:%d/n",a[0]);
if(a[0]<=0)
break;
else
{
printf("/t/t繼續C(continue)/t/t退出遊戲E(end)/n");
scanf(" %c",&ch);
if(ch=='e')
break;
else
{
count++;
final1=final2=build();
}
}
}
}
if(a[0]==100)
printf("/t遊戲結果平局/n");
else
if(a[0]>100)
printf("/t恭喜你,你贏的遊戲幣%d/n",a[0]-100);
else
printf("/t再接再厲,你輸了遊戲幣%d/n",100-a[0]);
return 0;
}