台式电脑

电脑版斗地主怎么样玩的(简单AI之斗地主电脑出牌C语言实现篇,日常装逼日常飞,飞到垃圾堆)

斗地主机器出牌核心代码简单AI之斗地主电脑出牌C语言实现篇,日常装逼日常飞,飞到垃圾堆

更多精彩,关注私信“代码”惊喜

运行展示简单AI之斗地主电脑出牌C语言实现篇,日常装逼日常飞,飞到垃圾堆

更多精彩,关注私信“代码”惊喜

完整代码

#define_CRT_SECURE_NO_WARNINGS

#include

#include

#include

#include

#defineArr_Len(arr)(sizeof(arr)/sizeof(arr[0]))

#definemaxn18

/*

1.出牌方式以-1结束

一对8的出发:88-1

*/

intcod[maxn]={0};

intmycod[maxn];

intchu[maxn];

intrtmp[maxn]={0},mtmp[maxn]={0};

intmx,mn;

structLianD

{

inten;//连对结尾的牌号

intdu;//最接近的度数

intcnt;//连对的个数

inttem;//临时存储的结尾牌号

//复制值函数

voidcopfun(structLianD*Ld){

Ld->cnt=cnt;

Ld->du=du;

Ld->en=en;

Ld->tem=tem;

}

//初始化

voidinit(){

en=du=cnt=tem=0;

}

};

enumAlgTyNn{

ShunZi=1,

LianDui

};

intcmp(constvoid*arg,constvoid*brg){

int*ar=(int*)arg;

int*br=(int*)brg;

return*ar-*br;

}

voidinit(){

inti,hopg,cnt=0;

memset(mycod,0,sizeof(mycod));

mycod[cnt]=17;

for(i=3;i<16; i++)

cod[i]=4;

cod[16]=1;//一对王

cod[17]=1;

srand(time(NULL));

while(cnt

hopg=rand()%maxn;

if(hopg>0&&cod[hopg]>0){

cod[hopg]--;

mycod[++cnt]=hopg;

}

}

qsort(mycod+1,cnt-1,sizeof(mycod-1),cmp);

}

//对方输出

voidinputs(){

intcnt=0;

memset(chu,0,sizeof(chu));

while(1){

scanf("%d",&chu[++cnt]);

if(chu[cnt]<0) break;

}

chu[0]=cnt-1;//最开头放置纸牌的数目

}

//打印剩余

voidoutput(){

printf("\n剩牌系:\n");

//剩余牌系

intcont=0;

for(intj=3;j

cont+=mtmp[j];

for(intk=0;k

printf("%d",j);

}

}

mtmp[0]=cont;

printf("\t剩牌数:[%d]",mtmp[0]);

puts("");

}

//计数排序

voidconnt(int*tmp,constintss[]){

//memset(tmp,0,sizeof(tmp));

tmp[0]=ss[0];

for(inti=1;i<= ss[0]; i++)

tmp[ss[i]]++;//计数排序

}

//判断是否有炸弹或者王炸

voidZhaDan(){

for(inti=3;i

if(mtmp[i]==4){

printf("%d%d%d%d",i,i,i,i);

mtmp[i]-=4;

output();

return;

}

if(mtmp[16]==1&&mtmp[17]==1){

printf("%d%d",16,17);

mtmp[16]=mtmp[17]=0;

output();

return;

}

puts("没有牌能压过!");

return;

}

//如果是连对处理方案

voidAlgLDOrShZi(intvar){

inti=mn+1,len=mx-mn+1,kk=0;

structLianDLd,Tmpld;

Ld.init();

//时间复杂度为0(n^2)

for(i=mn+1;i<15; i++){

Tmpld.init();

Tmpld.tem=i;

for(intj=i;j

if(mtmp[j]>=var){

if(mtmp[j]==var){

Tmpld.du++;

}

Tmpld.cnt++;

}

else{

Tmpld.init();

Tmpld.tem=j+1;

}

if(Tmpld.cnt==len){

Tmpld.en=Tmpld.tem;

if(Ld.en==0||Ld.du

Tmpld.copfun(&Ld);

break;

}

}

}

if(Ld.cnt==len){

puts("提示:");

for(i=Ld.en;i

mtmp[i]-=var;

kk=0;

while(kk++

printf("%d",i);

}

output();

}

else{

//寻求炸弹或者王炸

ZhaDan();

}

}

//三带的处理情况

voidAlgShanDai(){

intpos=0,cnt=0,res=0,fcnt=0;

intmcnt=0,mpos=0;

//分析牌型

for(inti=mn;i<= mx; i++){

if(rtmp[i]==3){

pos=i;

cnt++;

}

elseif(rtmp[i]>0){

res+=rtmp[i];//统计剩余牌的数量

fcnt++;

}

}

if((fcnt==cnt&&res%cnt==0)||(fcnt

else{

puts("输出的牌不符合规则!请重新输出:");

return;

}

res/=cnt;

for(inti=pos-cnt+2;i<= pos; i++){

if(rtmp[i]!=3){

puts("输出的牌不符合规则!请重新输出:");

return;

}

}

//如果为三带情况即cnt=1

for(inti=pos-cnt+2;i<17; i++){

if(mtmp[i]==3){

mpos=i;

mcnt++;

}

else

mcnt=0;

if(mcnt==cnt)break;

}

//查询副牌是否能够满足

if(mcnt==cnt){

//说明有解决方案

intstpos=mpos-cnt+1;

intsrc[maxn]={0},tt=0;

booltag=false;

for(inti=3;i<17; i++){

//满足不再连续范围之内的即可333444不能为3,4

if(impos){

if(mtmp[i]>=res){

for(intkk=0;kk

src[tt++]=i;

if(tt==cnt){

tag=true;

break;

}

}

}

}

if(tag)break;

}

if(tt==cnt){

//则解决方案为

intmstpos=mpos-cnt+1;

for(inti=mstpos;i<= mpos; i++){

printf("%d%d%d",i,i,i);

mtmp[i]-=3;

}

//打印副牌

for(inti=0;i

for(intk=0;k

printf("%d",src[i]);

}

mtmp[src[i]]-=res;

}

output();//打印剩余牌

}

}

else{

//查询是否有炸弹

ZhaDan();

}

}

//四带情况

voidAlgSiDai(){

if(chu[0]>4)ZhaDan();

else{

for(inti=chu[1]+1;i<15; i++){

if(mtmp[i]==4){

printf("%d%d%d%d",i,i,i,i);

mtmp[i]-=4;

output();

return;

}

}

if(mtmp[16]==1&&mtmp[17]==1){

printf("%d%d",16,17);

mtmp[16]=mtmp[17]=0;

output();

return;

}

puts("没有牌能压过!");

return;

}

}

//对子的情况

voidAlgDuiZi(){

for(inti=chu[1]+1;i<16; i++)

{

if(mtmp[i]>1&&mtmp[i]<4){

printf("%d%d\n",i,i);

mtmp[i]-=2;

output();

return;

}

}

ZhaDan();

}

//对于个子的情况

voidAlgGreZi(){

for(inti=chu[1]+1;i<18; i++)

{

if(mtmp[i]>0&&mtmp[i]<4){

printf("%d\n",i);

mtmp[i]-=1;

output();

return;

}

}

ZhaDan();

}

//查询对应的方案

//对子

boolIsDuiZi(){

if(chu[0]==2)//则必定是对子

returntrue;

returnfalse;

}

//个子

boolIsGreZi(){

if(chu[0]==1)//则必定是对子

returntrue;

returnfalse;

}

//判断是否是顺子

boolIsShunZi(){

//顺子的条件

if(chu[0]>4){

if((mx-mn+1==chu[0])&&mx<15)

returntrue;

}

returnfalse;

}

//判断是否是连对

boolIsLianDui(){

if(chu[0]>5&&mx<15){

for(inti=mn;i<= mx; i++)

if(rtmp[i]!=LianDui)

returnfalse;

returntrue;

}

returnfalse;

}

//判断是否是三带

boolIsShanDai(){

for(inti=mn;i<= mx; i++)

if(rtmp[i]==3)

returntrue;

returnfalse;

}

//判断是否是四带或者炸弹

boolIsSiDai(){

for(inti=mn;i<= mx; i++)

if(rtmp[i]==4)

returntrue;

returnfalse;

}

//统计判断

voidAlgMxn(){

//求最大值,最小值

for(inti=3;i<= 17; i++)

if(rtmp[i]>0){

mn=i;

break;

}

for(inti=17;i>=3;i--)

if(rtmp[i]>0){

mx=i;

break;

}

}

voidprint(){

inti;

for(i=1;i<17; i++)

printf("%d",mycod[i]);

printf("%d\n",mycod[17]);

}

//检测出牌方

boolchecked(){

for(inti=1;i

if(cod[i]

returnfalse;

}

if(IsGreZi()

||IsDuiZi()

||IsShunZi()

||IsSiDai()

||IsShanDai()){

for(inti=1;i<= chu[0]; i++){

cod[chu[i]]--;

}

}

returntrue;

//如果为一对王

if(chu[0]==2&&mtmp[16]==1&&mtmp[17]==1)

returntrue;

returnfalse;

}

intmain(intargc,char*argv)

{

init();

memset(mtmp,0,sizeof(mtmp));

connt(mtmp,mycod);

print();

while(true){

printf("请出牌:\n");

while(1){

inputs();

memset(rtmp,0,sizeof(rtmp));

connt(rtmp,chu);

AlgMxn();

if(checked())break;

else

puts("输出的牌不符合规则!请重新输出:");

}

//如果满足顺子

if(IsGreZi())

电脑版斗地主怎么样玩的(简单AI之斗地主电脑出牌C语言实现篇,日常装逼日常飞,飞到垃圾堆)

AlgGreZi();

else

if(IsDuiZi())

AlgDuiZi();

else

if(IsShunZi())

AlgLDOrShZi(ShunZi);

else

if(IsLianDui())

AlgLDOrShZi(LianDui);//对于连对的情况

else

if(IsShanDai())

AlgShanDai();

else

if(IsSiDai())

AlgSiDai();

if(mtmp[0]<1){

puts("恭喜你,win!");

break;

};

}

return0;

}

相关新闻

返回顶部