| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 7269 人关注过本帖
标题:用C语言(控制台)写个斗地主程序(不需要人机对战)
只看楼主 加入收藏
vandychan
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
等 级:贵宾
威 望:18
帖 子:2296
专家分:6418
注 册:2010-8-20
收藏
得分:0 
哎 好好说话啊

到底是“出来混迟早要还”还是“杀人放火金腰带”?
2010-09-11 20:53
cacker
该用户已被删除
收藏
得分:0 
回复 14楼 Windy0Winll
提示: 作者被禁止或删除 内容自动屏蔽
2010-09-11 22:08
sunyh1999
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:14
帖 子:1178
专家分:3032
注 册:2009-5-17
收藏
得分:0 
先写个发牌:
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
int menu()
{
int choice;
printf("1 发牌/0 退出:");
scanf("%d",&choice);
return choice;
}
void main( void )
{ int i1, j, total; int *iArr; int tag = 0; char* pok_C[] = { "黑桃", "红桃", "梅花", "方块" }; char* pok_N[] = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
if(!menu())
exit(0);
total = 52; srand( (unsigned)time( NULL ) );
iArr = (int*)malloc(total*sizeof(int));
for( i1=0; i1<total; i1++ )
{ iArr[i1]=rand()%total; if( i1==0 ) continue;
do { tag = 0; for( j=0; j<i1; j++ ) if( iArr[j] == iArr[i1] )
 { iArr[i1]=rand()%total; tag = 1; } } while( tag==1 ); }
for( i1=0; i1<total; i1++ )
 { printf("%s%s\t",pok_C[iArr[i1]%4],pok_N[iArr[i1]%13]);
 if(i1%4==3)
 printf("\n");

 }
free(iArr);
 }

欢迎来到我的博客:http://blog..cn/noisunyuhong
2010-09-12 14:54
sunyh1999
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:14
帖 子:1178
专家分:3032
注 册:2009-5-17
收藏
得分:0 
洗牌:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct card {
int cdhs; //1,2,3,4
int point; //1,2,..13;
} CARD;

CARD cards[52];
void main()
{
int i,j,k,n;
int x[52],y;
int flag[52];
char p[13][5]={"2","3","4","5","6","7","8","9","10","J","Q","K","A"};
// char p[13][5]={"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
// char h[4][5] = {"S","H","D","C"};
char h[4][5] = {"D","C","H","S"};
// char h[4][6] = {'\06','\03','\05','\04'};

for (j=0;j<4;j++){
for (i=0;i<13;i++){
cards[j*13+i].cdhs= j %4 ;
cards[j*13+i].point= i %13;
}};



for (i=0;i<52;i++) flag[i]= -1;
srand((unsigned)time(NULL));
n=0;
while(1) {
y = (int) (   (float)rand() / ((float)(RAND_MAX))  * 53.0);
if  (y < 52 && y >= 0) { if ( flag[y] == -1)
  { x[n]=y; flag[y]=1;n++; if (n>=52)break; };
}; // end if
};

for (k=0;k<4;k++)
for (i=0;i<12;i++)
for(j=i;j<13;j++){
if (x[i+k*13]< x[j+k*13]){y=x[i+k*13];x[i+k*13]=x[j+k*13];x[j+k*13]=y;};
}
printf("Person-1: ");
for (i=0;i<13;i++){ printf("%s%s ",h[cards[x[i]].cdhs],p[cards[x[i]].point]);
}
printf("\nPerson-2: ");
for (i=13;i<26;i++){ printf("%s%s ",h[cards[x[i]].cdhs],p[cards[x[i]].point]);
}
printf("\nPerson-3: ");
for (i=26;i<39;i++){ printf("%s%s ",h[cards[x[i]].cdhs],p[cards[x[i]].point]);
}
printf("\nPerson-4: ");
for (i=39;i<52;i++){ printf("%s%s ",h[cards[x[i]].cdhs],p[cards[x[i]].point]);
}
printf("\n");
system("pause");
}

欢迎来到我的博客:http://blog..cn/noisunyuhong
2010-09-12 14:55
sunyh1999
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:14
帖 子:1178
专家分:3032
注 册:2009-5-17
收藏
得分:0 
再写个抽牌比大小的game,其实没什么技术含量,出牌就是个srand and rand和删除操作还要记录牌的张数,每次判断,直到0牌为止,其他无难。
#include<stdlib.h>
#include<time.h>
#include<stdio.h>
#include<math.h>
void main()
{
int times=0,winA=0,winB=0;
int su1,si1,su2,si2;
char *suit[4]={"黑","红","梅","方"};
char size[13]={'A','2','3','4','5','6','7','8','9','10','J','Q','K'};
char siA,siB;
char *suA;
char *suB;
do
{
do
{
srand((unsigned)time(NULL));
su1=rand()%4;
si1=rand()%13;
srand((unsigned)time(NULL));
su2=rand()%4;
si2=rand()%13;
}
while(su1==su2);
suA=suit[su1];
siA=size[si1];
suB=suit[su2];
siB=size[si2];
if(si1>si2)
{
winA++;
times++;
}
else if(si1<si2)
{
winB++;
times++;
}
else if(si1==si2)
times++;

printf("选手A的牌为:%s%c;\n选手B的牌为:%s%c;\n",suA,siA,suB,siB);
}
while(times<3);
if(winA>winB)
{
printf("选手A获胜");
}
else if(winA<winB)
{
printf("选手B获胜");
}
else if(winA==winB)
{
printf("平局");
}
getchar();
}

欢迎来到我的博客:http://blog..cn/noisunyuhong
2010-09-12 14:57
Windy0Winll
Rank: 2
来 自:走了
等 级:等待验证会员
帖 子:71
专家分:90
注 册:2010-8-26
收藏
得分:0 
呵呵,版主大人,斗地主还有平局?是不是3个人都同意不玩了,就是平局?



回22楼:
看了楼主的附件,感觉写得不错,思路挺清晰的。


其实,我觉得出牌也不难。我们通过字符输入字符来确认(10用A表示),比如我们要出5 5 6 6 7 7,那么我们输入556677,然后我们把这个字符串存到字符数组cards里面,在输入的时候我们就判断是否有非法字符输入,如'B'。

出牌时检查类型时,这时候每个字符都是表示的一张牌了,下面是我的伪代码:
程序代码:
int cardType[2];//记录牌的类型和主体部分最小单张


static const short table[128] = {           /*****   牌的大小表  ****/
       ['1']=14,15,['3']=3,4,5,6,7,8,9,     /**  A 2 3 4 5 6 7 8 9 **/
       ['A']=10,['J']=11,['K']=13,['Q']=12, /** 10 J K Q,用A表示10 **/
       ['W']=17,['w']=16,                   /**    大王,小王      **/
       };


int sub = 0,  Len =0;// 分别表示 用来访问card数组的下标  和 连对顺子等的长度
int card [12] =  {0},//出的牌
    count[12]  = {0};//对应上面的张数 

if  ( !table[cards[0]] )  {*cardType = 0; return 1;} //空牌,表示不出牌,合法牌
if  ( !table[cards[1]] )
    {
    *cardType = (1U <<4),  //单张
    cardTpye[1]=table[cards[1]]; //记录单张的大小
    return 1;//返回合法牌
    }

*card = *cards;//第一张牌
for ( sub=0,--cards; !table[ *++cards ] ;  )  //错误的出牌方法 基本上在这个循环里被淘汰了,还有就是为下面switch确定 牌的实际类型 做了必要的准备工作
    {
    if  (  card[sub] == *cards  )
        {
        ++len[sub];
        continue;
        }   
    else{
        card[++sub] = *cards;
        ++ count[sub];
       
        if  (  sub<2  ) ;
        else if (  (Len)  )
            {
            if  (  (len[Len-1]<=len[sub-1])  ||  (2*Len<=sub)  )  return 0;//带的某种牌的张数比主体部分的还多,或者带的牌种类太多了错误的出法
            } 
        else if (  (len[sub-2] == len[sub-1])  )
            {
            if  (  table[card[sub-1]] - table[card[sub-2]] != 1  )  return 0;//错误的出法
            }
        else{
            Len = sub-1;
            } 
   
        }//if card[sub]...else  
    }//for


 
  if  (  len[Len-1] <= len[sub]  )  return 0;//非法出法

  switch( len[Len-1] )
        {
     case 1:
           if  (  (len==2)  &&  (card[0]=='w')  &&  (card[1]=='W')  )
               {
              *cardType    = 9;      //炸弹,对鬼
               cardType[1] = table[ *card ];
               return 1;
               }
           else if  (  (Len>=5)  &&  (*card+Len<table['2']  )//顺子 最小长度为5,且顺子做多能到A
              {
             *cardType    = (2U <<4)+Len;  //顺子
              cardType[1] = table[ *card ];
              return 1; 
              }
           else{ 
               return 0;  
               }
           break;
     case 2:
           if  (  (Len==1)  &&  (sub==0)  )
               {
              *cardType    = (3U <<4);  //对子 ,这里其实也可以不乘以32的
               cardType[1] = table[ *card ];
               return 1;  
               }
           else if (  (Len>=3) && (*card+Len<table['2'])  ) //连对最少要3对,最多可以到A,所以要比2小
              {
             *cardType    = (4U <<4)+Len;  //连对 ,这里其实也可以不乘以32的
              cardType[1] = table[ *card ];
              return 1;              
              }
          else{
              retrun 0;
              }
          break;
     case 3:
          if  (  (Len==1)  &&  (sub==0)  )
              {
             *cardType    = (5U <<4);  //三张
              cardType[1] = table[ *card ];
              return 1;  
              }
          else if  (  (*card+Len<table['2'])  && !( (sub>1)&&(card[sub-1]=='w')&&(card[sub]=='W') )  )不能带一对鬼
             {
            *cardType    = (6U <<4)+Len;  //连三张
             cardType[1] = table[ *card ];
             return 1;
             }
         else{
             return 0;
             }
        break;
     case 4:
          if  (  (Len==1)  &&  (sub==0)  )
              {
             *cardType    = 9; //炸弹
              cardType[1] = table[ *card ];
              return  1;
              }
          else if (  (Len==1)  &&  (sub==1)  )
              {
             *cardType    = (7U <<4); //四张带牌,可以带单张,一对,三张
              cardType[1] = table[ *card ];
              return   1; 
              }
          else if (  (Len>1)  &&  (*card+Len<table['2'])  )
              {
             *cardType    = (8U <<4) + Len; //连4张
              cardType[1] = table[ *card ];
              return    1;
              }
          else{
              return 0;
              }
         break;
    default:
         break;              
        }
      
/*

 *  基本牌的类型:(  实际类型(炸弹的为9 ,非法牌的为-1) = 基本类型*32 + 长度  )

 *  空牌:0         单张:1        顺子:2        对子:3         连对:4       

 *  三张:5       连三张:6  四张(带牌):7      连四张:8         炸弹:9

 */

对于比较大小,有了上面更简单了。

 //对于空类型的牌可以和任何类型的牌匹配,在实现的时候注意一下就好了


 //若果上面返回0,则是不合常规的牌

 //如果 刚出的牌的类型 和 将要出的牌类型不匹配
         //如果将要出的类型是9(炸弹),这是可以出的牌
         //否则牌不匹配

 //如果 刚出的牌的类型 和将要出的牌类型 匹配
         //检查两者的 cardType[1]这的属性是不是后者比前者大,只有大才可以出牌


对于上面的伪代码我没有很严谨的去检查,有可能有些小错误,不过思路应该是可行的。
还有就是,有一些比较牌的规则我并不清楚,所以那只是我自己凭自己的感觉写的。

[ 本帖最后由 Windy0Winll 于 2010-9-13 18:04 编辑 ]

悄悄地来。。。 然后悄悄地走。。。。。。
2010-09-12 16:51
sunyh1999
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:14
帖 子:1178
专家分:3032
注 册:2009-5-17
收藏
得分:0 
我只是打个比方呀,让楼主思路开阔一点

欢迎来到我的博客:http://blog..cn/noisunyuhong
2010-09-12 17:24
Windy0Winll
Rank: 2
来 自:走了
等 级:等待验证会员
帖 子:71
专家分:90
注 册:2010-8-26
收藏
得分:0 
几天以后我要补考了,还没开始复习。这几天不能来论坛了。

悄悄地来。。。 然后悄悄地走。。。。。。
2010-09-12 17:31
cacker
该用户已被删除
收藏
得分:0 
提示: 作者被禁止或删除 内容自动屏蔽
2010-09-12 20:43
cacker
该用户已被删除
收藏
得分:0 
回复 25楼 sunyh1999
提示: 作者被禁止或删除 内容自动屏蔽
2010-09-12 22:43
快速回复:用C语言(控制台)写个斗地主程序(不需要人机对战)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.075765 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved