a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > C > 正文

C語言實現(xiàn)斗地主的核心算法

2020-01-26 15:08:23
字體:
來源:轉載
供稿:網(wǎng)友

數(shù)據(jù)結構只選擇了順序表,沒有選擇鏈表,靈活性和抽象性不足,不能普適。

head.h

#ifndef     __HEAD_H__#define     __HEAD_H__#define     MAXLEVEL 15typedef 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[]={"棄權","單張","對子","王炸","骷髏","骷髏單","炸彈","骷髏對","炸帶單","順子","炸帶一對","飛機不帶","連對","飛機單","飛機帶對"};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");    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;} /*手牌信息補完*/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=" ";      }    }  }} /*打印當前玩家手牌*/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;//棄權次數(shù)  player_init();//洗牌 發(fā)牌  handcard_init();//手牌信息補完} 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表示棄權  if(game.type == 3 ){    if(game.count != 2){      printf("要不起!/n");      return 0;    }    else      return 1;  }  if(game.count !=2){    printf("出牌嗎?(y表示出牌,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;} /*放牌進入緩沖區(qū)*/static void buffer_put(){  char intput[40]={};//把字符串轉換為數(shù)字  int brr[20]={};  int i=0;  int j;  int sum;  int flag=0;  while(1){    reset();sig:  printf("請輸入要放的牌...:");    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++){//記錄出牌下標      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("號牌/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");          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;//有值則標記為1  int sig=0;//從 有到無 改標記為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)計單張,對子,三同,四同各有多少    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 對%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)//對子      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)//骷髏對         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) )//炸帶對      return 10;     else if(!one && !pair && !quattuor){//只有2個以上個三張相同 飛機不帶      if(continuum(3,triple))//所有3連續(xù)        return 11;      else return -1;    }    else if(!one && !triple && !quattuor){//連對      if(continuum(2,pair))        return 12;      else return -1;    }    else if(buffer.sum == 4*triple){//飛機單      if(continuum(3,triple))        return 13;      else return -1;     }    else if((buffer.sum == 5*triple) && (triple == pair)){//飛機對      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;  }} /*最大下標*/static int maxindex(int count){  int i;  for (i=15;i>=1;i--){    if(buffer.arr[i] == count)      return i;   }} /*獲取緩沖區(qū)牌類等級*/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");} /*回合進行中*/ //這個模塊有很大的修改空間 例如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ù)判斷是否棄權比較好 */    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("牌的等級不夠大/n");          continue;        }      }      }    else if(game.count == 2 ){//兩家棄權      annealation();      game.type = type;      game.level = level;      return ;    }    else {//除了炸彈 兩家棄權 王炸 非法 以外的合理牌類      if(type != game.type){ //不對應        printf("類型不對應/n");        continue;      }      else { //對應        if(buffer.sum != game.sum){          printf("數(shù)量不對應/n");          continue;        }        if(level < game.level|| level==game.level){          printf("牌的等級不夠大/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;} /*切換當前玩家為下家*/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();//回合進行中      printf("/n/n/n");      if(which=win())//是否產(chǎn)生勝者        break;      turn_switch();//切換出牌方  }    printf("勝負已出!勝利者是玩家%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");}

以上所述就是本文的全部內容了,希望對大家熟練應用C語言能夠有所幫助。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 黄色在线观看 | 国产一区二区在线播放 | 欧美三级电影在线播放 | 国产黄色一级片 | 自拍偷拍第一页 | 欧美成人h版在线观看 | 草视频在线 | 日韩一区二区三区在线 | 污网站免费在线观看 | 日韩精品亚洲专区在线观看 | 午夜毛片 | 在线日韩视频 | 日日撸夜夜操 | 久久综合狠狠综合久久 | 国产精品www| 国产成人精品高清久久 | 久久久久久亚洲精品 | 久久久女人 | 91免费国产 | 亚洲一区二区三区高清 | 欧美三级在线播放 | 久草视| 日本三级视频 | 日韩国产在线 | 黄色的网站免费看 | 久久精品国产亚洲精品 | 色综合久久久久 | 国产精品久久久久久久久久久久久久 | 成人国产精品久久 | 综合久久综合久久 | 超碰8| 亚洲久久在线 | 国产精品三级久久久久久电影 | 秋霞久久久 | 国产又色又爽又黄 | 黄色网在线| 国产免费中文字幕 | 精品久久精品 | 精品视频久久 | 成人免费视频在线观看 | 国产精品视频 |