C語言實(shí)現(xiàn)斗地主的核心算法
數(shù)據(jù)結(jié)構(gòu)只選擇了順序表,沒有選擇鏈表,靈活性和抽象性不足,不能普適。
head.h
#ifndef __HEAD_H__
#define __HEAD_H__
#define MAXLEVEL 15
typedef struct CARD{
int number;
int level;
char *flower;
char point;
}card;//卡
typedef struct DECK{
int top;
int arr[55];
}deck;//牌堆
typedef struct PLAYERS{
int id;
int status;
card handcard[21];
int size;
}players;//玩家
typedef struct GAMES{
int type;
int level;
int sum;
int who;
int count;
int arr[16];
}games;//桌面
typedef struct BUFFERS{
int arr[16];
int brr[20];
int sum;
}buffers;//出牌緩沖區(qū)
/*--------------------------------*/
void game_init();
void turning();
void handcard_sort();
void print();
int win();
void turn_switch();
#endif
op.c
#include<stdio.h>
#include<stdlib.h>
#include"head.h"
#include<string.h>
static int type_buffer();
static char point[]={'0','3','4','5','6','7','8','9','X','J','Q','K','A','2','w','W'};
static char *farr[]={"方片","梅花","紅桃","黑桃"};
static char* type_arr[]={"棄權(quán)","單張","對(duì)子","王炸","骷髏","骷髏單","炸彈","骷髏對(duì)","炸帶單","順子","炸帶一對(duì)","飛機(jī)不帶","連對(duì)","飛機(jī)單","飛機(jī)帶對(duì)"};
static char* sta_arr[2]={"農(nóng)民","地主"};
static players player[3];//玩家
static games game;
/*洗牌堆*/
static deck* deck_init(){
int i,j;
srand(time(0));
deck *p_deck=(deck*)malloc(sizeof(deck));
if(!p_deck){
printf("分配內(nèi)存失敗\n");
return NULL;
}
for(i=1;i<=54;i++){
p_deck->arr[i]=rand()%54;
for(j=1;j<i;j++){
if(p_deck->arr[i]==p_deck->arr[j]){
i--;
break;
}
}
}
p_deck->top=54;
return p_deck;
}
/*初始化玩家(洗牌,id,身份 手牌,總數(shù))*/
static void player_init(){
int i,j;
for(j=0;j<3;j++){
for(i=1;i<=20;i++){
player[j].handcard[i].number=100;
player[j].handcard[i].level =0;
}
}
deck *p=deck_init();
if(!p){
printf("沒有牌堆\n");
return ;
}
int which=0;
which=rand()%3;
game.who=which;
for(i=0;i<3;i++){
player[i].id=i;
if(i==which){//地主
player[i].status=1;
for(j=1;j<=20;j++){
player[i].handcard[j].number=p->arr[(p->top)--];
}
player[i].size=20;
}
else{//農(nóng)民
player[i].status=0;
for(j=1;j<=17;j++){
player[i].handcard[j].number=p->arr[(p->top)--];
}
player[i].size=17;
}
}
free(p);
p=NULL;
}
/*手牌信息補(bǔ)完*/
static void handcard_init(){
int i,j;
for(i=0;i<3;i++){
for(j=1;j<=20;j++){
int number=player[i].handcard[j].number;
int *p_level=&(player[i].handcard[j].level);
char **pp_flower=&(player[i].handcard[j].flower);
char *p_point=&(player[i].handcard[j].point);
if(number>=0&&number<=51){
*p_level=number/4+1;
*p_point=point[number/4+1];
*pp_flower=farr[number%4];
}
else if(number==52){
*p_level=14;
*p_point='w';
*pp_flower="小王";
}
else if(number==53){
*p_level=15;
*p_point='W';
*pp_flower="大王";
}
else {
*p_level=0;
*p_point=' ';
*pp_flower=" ";
}
}
}
}
/*打印當(dāng)前玩家手牌*/
void print(){
int i,j;
for(i=0;i<3;i++){
if (i!=game.who) continue;
for(j=1;j<=player[i].size;j++){
//printf("======");
if(player[i].handcard[j].number == 100){
printf(" ");
}
else {
char *p_tmp=player[i].handcard[j].flower;
printf("%s ",p_tmp);
}
}
printf("\n");
for(j=1;j<=player[i].size;j++){
if(player[i].handcard[j].number == 100){
printf(" ");
}
else {
printf(" %c ",player[i].handcard[j].point);
}
}
}
printf("\n");
for(j=1;j<=player[game.who].size;j++){
if(! (j>9))
printf("(%d) ",j);
else
printf("(%d) ",j);
}
printf("\n");
}
/*游戲初始化*/
void game_init(){
game.count=2;//棄權(quán)次數(shù)
player_init();//洗牌 發(fā)牌
handcard_init();//手牌信息補(bǔ)完
}
int fcmp(const void *pa,const void *pb){//升序
return *(int*)pa-*(int*)pb;
}
static void rehandcard_sort(players *p_player,int* p_number){//真正的排序函數(shù)
int *base=p_number;
size_t nmemb=p_player->size;
size_t size= sizeof(card);
qsort(base,20,size,fcmp);
}
void handcard_sort(){//外殼排序函數(shù)
rehandcard_sort(&player[0],&(player->handcard[1].number));
rehandcard_sort(&player[1],&((player+1)->handcard[1].number));
rehandcard_sort(&player[2],&((player+2)->handcard[1].number));
}
/*詢問是否出牌*/
static int require(){ //1表示出牌 0表示棄權(quán)
if(game.type == 3 ){
if(game.count != 2){
printf("要不起!\n");
return 0;
}
else
return 1;
}
if(game.count !=2){
printf("出牌嗎?(y表示出牌,n棄權(quán)):");
char choice;
scanf("%c",&choice);
scanf("%*[^\n]");
scanf("%*c");
if(choice == 'n' || choice == 'N'){
return 0;
}
else return 1;
}
else {
printf("繼續(xù)出牌\n");
return 1;
}
}
buffers buffer={};//出牌緩沖區(qū)
/*清空出牌緩沖區(qū)*/
static void reset(){
int a;
for(a=0;a<16;a++)
buffer.arr[a]=0;
for(a=0;a<20;a++)
buffer.brr[a]=0;
buffer.sum=0;
}
/*放牌進(jìn)入緩沖區(qū)*/
static void buffer_put(){
char intput[40]={};//把字符串轉(zhuǎn)換為數(shù)字
int brr[20]={};
int i=0;
int j;
int sum;
int flag=0;
while(1){
reset();
sig: printf("請(qǐng)輸入要放的牌...:");
fgets(intput,40,stdin);
if(strlen(intput)==39&&intput[38]!='\n'){
scanf("%*[^\n]");
scanf("%*c");
}
for(j=0,i=0,sum=0;i<strlen(intput);i++){//記錄出牌下標(biāo)
if(intput[i]>='0'&&intput[i]<='9'){
sum=sum*10+(intput[i]-'0');
flag=1;
}
else {
if(flag)
brr[j] = sum;
sum=0;
j++;
flag=0;
}
}
int k;
printf("要出: ");
for(k=0;brr[k];k++)
printf("%d ",brr[k]);
printf("號(hào)牌\n");
int who = game.who;
players* p_player=&(player[who]);
int index;
for(i=0;brr[i];i++){//記錄出的牌是什么
index=brr[i];
if(index>(p_player->size) || index<=0 ){//輸入的字符串范圍有誤
printf("輸入內(nèi)容超出范圍,重新輸入\n");
goto sig;
}
else{
int level=p_player->handcard[index].level;
++(buffer.arr[level]);
buffer.brr[i] =brr[i];
}
}
for(i=1;i<=15;i++)//記錄出了多少張牌
buffer.sum+=buffer.arr[i];
char aff= 'N';
int type = type_buffer();
if(type != -1)
printf("要出的類型是:%s\n\n",type_arr[type]);
else {
printf("不存在此類型的牌\n\n");
reset();
return;
}
printf("確定要這樣出嗎?(確定輸入y,否則按其它)");
scanf("%c",&aff);
scanf("%*[^\n]");
scanf("%*c");
if(aff == 'y' || aff =='Y')
break;
}
}
static void turnstart(){
char u;
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n==============================================================斗地主======================================================\n\n\n\n\n");
printf("輪到下一家");
scanf("%c",&u);
int i;
printf("\n\n\n\n\n\n\n牌面張數(shù)為%d張\n",game.sum);
printf("牌面類型為: %s%c\n",type_arr[game.type],point[game.level]);
printf("=============================================================%s的回合==========================================================\n\n",sta_arr[player[game.who].status]);
printf("現(xiàn)在輪到玩家%d",game.who+1);
printf(" 玩家1(%s)手牌%d ",sta_arr[player[0].status],player[0].size);if(game.who==0) printf("<=====\n");else printf("\n");
printf(" 玩家2(%s)手牌%d ",sta_arr[player[1].status],player[1].size);if(game.who == 1) printf("<=====\n"); else printf("\n");
printf(" 玩家3(%s)手牌%d ",sta_arr[player[2].status],player[2].size);if(game.who == 2) printf("<=====\n"); else printf("\n");
}
/*判斷是否連續(xù)*/
static int continuum(int num,int total){
int i,count=0;
int flag=0;//有值則標(biāo)記為1
int sig=0;//從 有到無 改標(biāo)記為1
for(i=1;i<=15;i++){
if(buffer.arr[i]==num){
if(sig)
return 0;//非連續(xù)
count++;
if(count==total)
return 1;//連續(xù)
flag=1;
}else {
if (flag)
sig=1;
}
}
}
/*獲取緩沖區(qū)牌類類型*/
static int type_buffer(){
int i, one=0,pair=0,triple=0,quattuor=0,zero=0;
for(i=1;i<=15;i++){//統(tǒng)計(jì)單張,對(duì)子,三同,四同各有多少
if(buffer.arr[i] == 1)
one++;
else if(buffer.arr[i] == 2)
pair ++;
else if(buffer.arr[i] == 3)
triple ++;
else if(buffer.arr[i] == 4)
quattuor ++;
else zero++;
}
//printf("單%d 對(duì)%d 三%d 四%d 零%d,sum%d===\n",one,pair,triple,quattuor,zero,buffer.sum);
if(!(buffer.sum)){
return -1;//非法
}
else if(buffer.sum<=5){//1~5
if(one == 1 && !pair && !triple && !quattuor)//單張
return 1;
else if(pair == 1 && !one && !triple && !quattuor)//對(duì)子
return 2;
else if(one == 2 &&buffer.arr[14]&&buffer.arr[15])//王炸
return 3;
else if(triple == 1 && !one && !pair && !quattuor) //骷髏
return 4;
else if(one ==1 && !pair && triple == 1 && !quattuor )//骷髏單
return 5;
else if(!one && !pair && !triple && quattuor == 1)//炸
return 6;
else if(!one && pair == 1 && triple == 1 && !quattuor)//骷髏對(duì)
return 7;
else if(one == 1 && !pair && !triple && !quattuor){//炸帶單
return 8;
}
else if(!pair && !triple && !quattuor && (!buffer.arr[14] && !buffer.arr[15])&& buffer.sum == 5){//順子
if( continuum(1,one))//所有1連續(xù)
return 9;
else {
return -1;
}
}
else return -1;
}
else if(buffer.sum>=6){
if((!one) && (pair == 1) && (!triple) && (quattuor == 1) )//炸帶對(duì)
return 10;
else if(!one && !pair && !quattuor){//只有2個(gè)以上個(gè)三張相同 飛機(jī)不帶
if(continuum(3,triple))//所有3連續(xù)
return 11;
else return -1;
}
else if(!one && !triple && !quattuor){//連對(duì)
if(continuum(2,pair))
return 12;
else return -1;
}
else if(buffer.sum == 4*triple){//飛機(jī)單
if(continuum(3,triple))
return 13;
else return -1;
}
else if((buffer.sum == 5*triple) && (triple == pair)){//飛機(jī)對(duì)
if(continuum(3,triple))
return 14;
else return -1;
}
else if(!pair && !triple && !quattuor &&(!buffer.arr[14] && !buffer.arr[15])){
if(continuum(1,one))
return 9;
else return -1;
}
else return -1;
}
}
/*最大下標(biāo)*/
static int maxindex(int count){
int i;
for (i=15;i>=1;i--){
if(buffer.arr[i] == count)
return i;
}
}
/*獲取緩沖區(qū)牌類等級(jí)*/
static int level_buffer(int type){
switch(type){
case 1:
return maxindex(1);
break;
case 2:
return maxindex(2);
break;
case 3:
return 15;
break;
case 4:
return maxindex(3);
break;
case 5:
return maxindex(3);
break;
case 6:
return maxindex(4);
break;
case 7:
return maxindex(3);
break;
case 8:
return maxindex(4);
break;
case 9:
return maxindex(1);
break;
case 10:
return maxindex(4);
break;
case 11:
return maxindex(3);
break;
case 12:
return maxindex(2);
break;
case 13:
return maxindex(3);
break;
case 14:
return maxindex(3);
break;
}
}
/*消減手牌*/
static void annealation(){
int i=1;
int j=0;
int who=game.who;
for(i = 1,j=0;buffer.brr[j];i++,j++){
int index = buffer.brr[j];
player[who].handcard[index].number = 100;
player[who].size = player[who].size - 1;
}
game.sum=buffer.sum;
game.count=0;
handcard_sort();
//printf("出牌成功\n");
}
/*回合進(jìn)行中*/ //這個(gè)模塊有很大的修改空間 例如return 改為break...
void turning(){
turnstart(); /* 開始階段 */
handcard_sort();
print();
int level= 0;
while(1){
if(!require()){
printf("\n\n\n\n\n\n\n\n不要\n");
game.count++;
if(game.count == 2){
game.type=0;
game.level=0;
game.sum=0;
}
return ; /* 開始階段 */
}
buffer_put(); /* 出牌階段在這函數(shù)判斷是否棄權(quán)比較好 */
int type = type_buffer();
int level=level_buffer(type);
if(type == -1){
printf("牌類非法!-----\n");
continue;
}
if(type == 3){//王炸
printf("\n\n\n\n\n王炸!!\n");
annealation();
game.type=3;
game.level=MAXLEVEL;
return ;
}
else if(type == 6){//炸彈
if(game.type != 6){
printf("\n\n\n\n炸彈\n");
annealation();
game.type = 6;
game.level = level_buffer(type);
return;
}
else {
if(level > game.level){
printf("\n\n\n\n\n壓死\n");
annealation();//消減手牌
game.type = 6;
game.level = level;
return;
}
else if(level < game.level||level == game.level){
printf("牌的等級(jí)不夠大\n");
continue;
}
}
}
else if(game.count == 2 ){//兩家棄權(quán)
annealation();
game.type = type;
game.level = level;
return ;
}
else {//除了炸彈 兩家棄權(quán) 王炸 非法 以外的合理牌類
if(type != game.type){ //不對(duì)應(yīng)
printf("類型不對(duì)應(yīng)\n");
continue;
}
else { //對(duì)應(yīng)
if(buffer.sum != game.sum){
printf("數(shù)量不對(duì)應(yīng)\n");
continue;
}
if(level < game.level|| level==game.level){
printf("牌的等級(jí)不夠大\n");
continue;
}
else if(level > game.level){
printf("\n\n\n\n\n壓死\n");
annealation();
game.type = type;
game.level = level;
return ;
}
}
}
}
}
/*0 1 2 3判斷是否是誰勝利 0表示沒有 1表示玩家一*/
int win(){
int now = game.who;
if(!player[now].size)
return now;
else return 0;
}
/*切換當(dāng)前玩家為下家*/
void turn_switch(){
int who = game.who;
who++;
game.who = who%3;
}
main.c
#include<stdio.h>
#include"head.h"
int main(){
while(1){
int which;
game_init();//初始化游戲
while(1){
turning();//回合進(jìn)行中
printf("\n\n\n");
if(which=win())//是否產(chǎn)生勝者
break;
turn_switch();//切換出牌方
}
printf("勝負(fù)已出!勝利者是玩家%d\n",which+1);
printf("是否重新游戲?(y為繼續(xù),其它退出程序):");
char choice;
scanf("%c",&choice);
scanf("%*[^\n]");
scanf("%*c");
if(choice == 'y'||choice =='Y')
continue;
break;
}
printf("謝謝試玩\n");
}
以上所述就是本文的全部?jī)?nèi)容了,希望對(duì)大家熟練應(yīng)用C語言能夠有所幫助。
欄 目:C語言
下一篇:使用Objective-C獲取IPHONE手機(jī)IMSI序列號(hào)
本文標(biāo)題:C語言實(shí)現(xiàn)斗地主的核心算法
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/3109.html
您可能感興趣的文章
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用函數(shù)刪除字符
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)式函數(shù)庫
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言中對(duì)數(shù)函數(shù)的表達(dá)式 c語言中對(duì)數(shù)怎么表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段函數(shù)
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排序法函數(shù)
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段函數(shù)
- 04-02C語言中怎么打出三角函數(shù) c語言中怎么打出三角函數(shù)的值
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求階乘


閱讀排行
- 1C語言 while語句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對(duì)數(shù)函數(shù)的表達(dá)式 c語言中對(duì)
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 04-02jquery與jsp,用jquery
- 01-10C#中split用法實(shí)例總結(jié)
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-10delphi制作wav文件的方法
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改


