少年啊,来一发昆特吗(四)——AI的编写

来源:互联网 发布:八皇后问题c语言 用栈 编辑:程序博客网 时间:2024/06/02 19:21

这类纸牌游戏的常用算法通常是博弈树算法,具体的博弈树算法与A*算法的思想比较相似,就是对AI的行动有一个评估值,评估值越高,这手牌的打法就最好,评估值要怎么定,就要看游戏了,纸牌游戏的目的很明确就是赢过对手,也就是玩家,那么对于昆特牌来说估值最高的就是使自己的力量在结束时比玩家的力量高,所以首先需要对整个游戏中所有纸牌类型做个分类,并给予它们相应的估值,当然越高代表行动越正确


在昆特牌中总共有领导技能,普通单位牌,间谍技能牌,提升力量牌,医生牌,天气牌,特殊牌等几种类型的牌型,接下来就是对这几种牌型进行评估,

1.首先,对于我自己玩昆特牌的经验来说,手牌数就是生命,能增加手牌数的一般有间谍,医生,领导技能,其中间谍和几个特殊领导技能相当于白抽一张卡,自然权值定到最高。

2.医生设为稍高,因为医生要增加手牌数的话必须是墓地中有间谍的情况,不过因为医生相当于一次出两张牌,权值也可以稍微定高点。

3.领导技能不会减手牌数量并且相当于放空一回合,但是领导技能可能会对牌的力量值产生影响,所以此时的权值需要对场上力量值进行比对,再定,相当于一个内部比分,如果出牌后力量比玩家大就定位高权值,如果比力量小,就定位低权值。

4.提升力量牌权值比上述3个定位低,也需要对场上的力量进行比对后,定义权值

5.天气牌,会使某一个攻击队列,力量全部变为1,所以也需要判断后,在赋给权值。

6.特殊牌有诱饵和灼烧,这两种如果场上有间谍,则诱饵牌可以权值设为最高,没有则设为低,灼烧,如果场上最高是敌方的牌,则最高,反之,则低。

有了上面这个简单的分类,接下来的ai编写就会非常简便了,也就是对手中的每张牌进行上述的分析,然后选择拿出权值最高的那组,如果权值相同,就在进行内部判断,拿出权值最高的,如果手上的权值有一半等于1,则选择弃权,保留卡牌到下一句,如果是决胜局就死磕,下面是一个简单的ai分析出牌的源代码,要增强ai的话,可以考虑在基础上添加对玩家手卡的分析,通过类似于迷宫寻径的方式找出权值最高的那条路,因为时间关系,源代码里面并没有做到这个地步

int   *pNum=new   int[enemeyhandarray->count()]; 
int i=0;
//分析完毕后进入出牌判断
//如果npc近战力量小于玩家近战力量,则出冰冻牌
//优先判断应该出单位卡,还是特殊卡,还是天气卡
//总和力量值玩家大时
//enemypow>=pow的权值为1,场上牌数量多出一张则权值为2,手牌数量不减少权值为3,手牌数量增加权值为4,pow>enemypow则权值为
Object *item=NULL;
CCARRAY_FOREACH(enemeyhandarray,item){
Dictionary *dic=(Dictionary *)item;
if(((String *)dic->objectForKey("type"))->getCString()!="weather"&&((String *)dic->objectForKey("type"))->getCString()!="special"){
 if(((String *)dic->objectForKey("Ability"))->getCString()=="----"){
               //当无能力时且卡牌为单位卡时,仅加算卡牌力量
 auto power=atoi(((String *)dic->objectForKey("power"))->getCString());
 if(((String *)dic->objectForKey("type"))->getCString()=="hero"){
 if(enemypow+power>pow){
 pNum[i]=1;
 }else{
 pNum[i]=0;
 }
 }else {
 if(((String *)dic->objectForKey("attackrange"))->getCString()=="shortrange"){
 if(frostflag==true){
 if(epowerups>=2){
 power=1*2+(epowerups-2)*10;
 }else if(epowerups>0&&epowerups<1){
 power=1+(epowerups)*10;
 }else{
 power=1;
 }
 if(enemypow+power>pow){
 pNum[i]=1;
 }else{
 pNum[i]=0;
 }


 }else{
 if(epowerups>=2){
 power=power*2+(epowerups-2)*10;
 }else if(epowerups>0&&epowerups<1){
 power=power+(epowerups)*10;
 }
 if(enemypow+power>pow){
 pNum[i]=1;
 }else{
 pNum[i]=0;
 }


 }
 }else if(((String *)dic->objectForKey("attackrange"))->getCString()=="longrange"){
 auto power=atoi(((String *)dic->objectForKey("power"))->getCString());
 if(fogflag==true){
 if(epowerupl>=2){
 power=1*2+(epowerupl-2)*10;
 }else if(epowerupl>0&&epowerupl<1){
 power=1+(epowerupl)*10;
 }else{
 power=1;
 }
 if(enemypow+power>pow){
 pNum[i]=1;
 }else{
 pNum[i]=0;
 }


 }else{
 if(epowerupl>=2){
 power=power*2+(epowerupl-2)*10;
 }else if(epowerupl>0&&epowerupl<1){
 power=power+(epowerupl)*10;
 }
 if(enemypow+power>pow){
 pNum[i]=1;
 }else{
 pNum[i]=0;
 }


 }
 }else  if(((String *)dic->objectForKey("attackrange"))->getCString()=="shortrange"){
 auto power=atoi(((String *)dic->objectForKey("power"))->getCString());
 if(frostflag==true){
 if(epowerups>=2){
 power=1*2+(epowerups-2)*10;
 }else if(epowerups>0&&epowerups<1){
 power=1+(epowerups)*10;
 }else{
 power=1;
 }
 if(enemypow+power>pow){
 pNum[i]=1;
 }else{
 pNum[i]=0;
 }


 }else{
 if(epowerups>=2){
 power=power*2+(epowerups-2)*10;
 }else if(epowerups>0&&epowerups<1){
 power=power+(epowerups)*10;
 }
 if(enemypow+power>pow){
 pNum[i]=1;
 }else{
 pNum[i]=0;
 }


 }
 }else if(((String *)dic->objectForKey("attackrange"))->getCString()=="siegerange"){
 auto power=atoi(((String *)dic->objectForKey("power"))->getCString());
 if(rainflag==true){
 if(epowerupsiege>=2){
 power=1*2+(epowerupsiege-2)*10;
 }else if(epowerupsiege>0&&epowerupsiege<1){
 power=1+(epowerupsiege)*10;
 }else{
 power=1;
 }
 if(enemypow+power>pow){
 pNum[i]=1;
 }else{
 pNum[i]=0;
 }


 }else{
 if(epowerupsiege>=2){
 power=power*2+(epowerupsiege-2)*10;
 }else if(epowerupsiege>0&&epowerupsiege<1){
 power=power+(epowerupsiege)*10;
 }
 if(enemypow+power>pow){
 pNum[i]=1;
 }else{
 pNum[i]=0;
 }


 }
 }
 }
 }else{
                  //卡牌附加能力时
 //间谍能力时权值+4
 if(((String *)dic->objectForKey("Ability"))->getCString()=="spy"){
 pNum[i]=4;


 }else if(((String *)dic->objectForKey("Ability"))->getCString()=="doctor"){
 pNum[i]=2;


 }else if(((String *)dic->objectForKey("Ability"))->getCString()=="powerup"){
 //只有一张近战的卡片是力量双倍
 auto power=atoi(((String *)dic->objectForKey("power"))->getCString());
 if(frostflag==true){
 if(epowerups>=2){
 power=1*2+(epowerups-2)*10;


 }else if(epowerups>0&&epowerups<1){
 power=1+(epowerups-2)*10+enemyshortpow;
 }else{
 power=1+enemyshortpow;
 }
 if(enemypow+power>=pow){
 pNum[i]=1;
 }else{
 pNum[i]=0;
 }
 }else{
  if(epowerups>=2){
 power=power*2+(epowerups-2)*10;


 }else if(epowerups>0&&epowerups<1){
 power=power+(epowerups-2)*10+enemyshortpow;
 }else{
 power=power+enemyshortpow;
 }
 if(enemypow+power>=pow){
 pNum[i]=1;
 }else{
 pNum[i]=0;
 }


 }
 }else if(((String *)dic->objectForKey("Ability"))->getCString()=="sibling"){
 //如果为团结力量则考虑是否有同名卡,且发动后的力量是否大于pow
   //只有一张近战的卡片是力量双倍
 auto power=atoi(((String *)dic->objectForKey("power"))->getCString());
 if(((String *)dic->objectForKey("attackrange"))->getCString()=="shortrange"){
 auto layer=(Layer *)this->getChildByName("enemyshortlayer");
 auto sp=layer->getChildren();
 int Siblingtimes=0;//强化几次
 for(auto a:sp){
 GWentCard *child=(GWentCard *)a;
 if(((String *)dic->objectForKey("cardname"))->getCString()==child->getCardName()){
 Siblingtimes++;
 }
 }
 //如果强化两次
 if(Siblingtimes!=0){
 if(frostflag==true){
 if(epowerups>=2){
 power=1*2+(epowerups-2)*10;
 }else if(epowerups>0&&epowerups<1){
 power=1+(epowerups)*10;
 }else{
 power=1;
 }
 }else{
 if(epowerups>=2){
 power=(power*2*Siblingtimes*(Siblingtimes+1))*2-(power*2*Siblingtimes)+(epowerups-2)*10;
 }else if(epowerups>0&&epowerups<1){
 power=power*2*Siblingtimes*2+(epowerups)*10;
 }


 }
 


 }
 if(enemypow+power>=pow){
  pNum[i]=1;


 }else{
 pNum[i]=0;


 }
 }else if(((String *)dic->objectForKey("attackrange"))->getCString()=="longrange"){
 auto layer=(Layer *)this->getChildByName("enemylonglayer");
 auto sp=layer->getChildren();
 int Siblingtimes=0;//强化几次
 for(auto a:sp){
 GWentCard *child=(GWentCard *)a;
 if(((String *)dic->objectForKey("cardname"))->getCString()==child->getCardName()){
 Siblingtimes++;
 }
 }
 //如果强化两次
 if(Siblingtimes!=0){
 if(fogflag==true){
 if(epowerupl>=2){
 power=1*2+(epowerupl-2)*10;
 }else if(epowerupl>0&&epowerupl<1){
 power=1+(epowerupl)*10;
 }else{
 power=1;
 }
 }else{
 if(epowerupl>=2){
 power=(power*2*Siblingtimes*(Siblingtimes+1))*2-(power*2*Siblingtimes)+(epowerupl-2)*10;
 }else if(epowerupl>0&&epowerupl<1){
 power=power*2*Siblingtimes*2+(epowerups)*10;
 }


 }
 


 }
 if(enemypow+power>=pow){
  pNum[i]=1;


 }else{
 pNum[i]=0;


 }
 }else if(((String *)dic->objectForKey("attackrange"))->getCString()=="siegerange"){
  auto layer=(Layer *)this->getChildByName("enemysiegelayer");
 auto sp=layer->getChildren();
 int Siblingtimes=0;//强化几次
 for(auto a:sp){
 GWentCard *child=(GWentCard *)a;
 if(((String *)dic->objectForKey("cardname"))->getCString()==child->getCardName()){
 Siblingtimes++;
 }
 }
 //如果强化两次
 if(Siblingtimes!=0){
 if(rainflag==true){
 if(epowerupsiege>=2){
 power=1*2+(epowerupsiege-2)*10;
 }else if(epowerupsiege>0&&epowerupsiege<1){
 power=1+(epowerupsiege)*10;
 }else{
 power=1;
 }
 }else{
 if(epowerupsiege>=2){
 power=(power*2*Siblingtimes*(Siblingtimes+1))*2-(power*2*Siblingtimes)+(epowerupsiege-2)*10;
 }else if(epowerupsiege>0&&epowerupsiege<1){
 power=power*2*Siblingtimes*2+(epowerupsiege)*10;
 }


 }  
 }
 if(enemypow+power>=pow){
  pNum[i]=1;


 }else{
 pNum[i]=0;


 }


 }
 }else if(((String *)dic->objectForKey("Ability"))->getCString()=="spowerup"){
 //如果为提升士气,且发动后的力量是否大于pow
 pNum[i]=1;
 }else if(((String *)dic->objectForKey("Ability"))->getCString()=="unit"){
 //如果为提升士气,且发动后的力量是否大于pow
 pNum[i]=1;
 }else if(((String *)dic->objectForKey("Ability"))->getCString()=="Scorch"){
 //如果为提升士气,且发动后的力量是否大于pow
 pNum[i]=1;
 }




 }
              


}else{
//如果是天气牌或者特殊牌
if(((String *)dic->objectForKey("type"))->getCString()=="special"){
//如果是powerup卡牌的话
if(((String *)dic->objectForKey("Ability"))->getCString()=="powerup"){
auto maxPow=enemypow+enemyshortpow;
if(enemypow+enemyshortpow>=pow){
pNum[i]=1;
EnemypowerupRange="shortrange";
}else{
pNum[i]=0;
EnemypowerupRange="shortrange";
}
if(enemypow+enemylongpow>=pow){
if(enemypow+enemylongpow>maxPow){
pNum[i]=1;
   EnemypowerupRange="longrange";
maxPow=enemypow+enemylongpow;
}
}
if(enemypow+enemysiegepow>=pow){
if(enemypow+enemysiegepow>maxPow){
                           pNum[i]=1;
  EnemypowerupRange="siegerange";
}

}
       



}else if(((String *)dic->objectForKey("Ability"))->getCString()=="destroy"){
pNum[i]=1;


}else if(((String *)dic->objectForKey("Ability"))->getCString()=="replace"){
pNum[i]=3;
auto shortlayer=(Layer *)this->getChildByName("enemyshortlayer");
auto longlayer=(Layer *)this->getChildByName("enemylonglayer");
auto siegelayer=(Layer *)this->getChildByName("enemysiegelayer");
Array *all=Array::create();
auto sp=shortlayer->getChildren();
for(auto a:sp){
GWentCard *child=(GWentCard *)a;
all->addObject(child);
}
sp=longlayer->getChildren();
for(auto a:sp){
GWentCard *child=(GWentCard *)a;
all->addObject(child);
}
sp=siegelayer->getChildren();
for(auto a:sp){
GWentCard *child=(GWentCard *)a;
all->addObject(child);
}
               Object *it=NULL;
CCARRAY_FOREACH(all,it){
GWentCard *card=(GWentCard *)it;
if(card->getAbility()=="spy"){
setEnemyReplaced(card);
break;
}else if(card->getAbility()=="doctor"){
setEnemyReplaced(card);
break;
}else if(card->getAbility()=="Scorch"){
setEnemyReplaced(card);
break;
}


}
}
}else if(((String *)dic->objectForKey("type"))->getCString()=="weather"){
if(((String *)dic->objectForKey("cardname"))->getCString()=="Biting-Frost"){
if(frostflag=true){
pNum[i]=0;
}else{
auto layer =(Layer *)this->getChildByName("enemyshortlayer");
auto otherlayer =(Layer *)this->getChildByName("shortlayer");
int epow=0;
int eotherpow=0;
auto sp=layer->getChildren();
for(auto a:sp){
GWentCard *child=(GWentCard *)a;
if(child->getType()!="hero"&&child->getType()!="special"){
epow=epow+1;


}else{
epow=epow+child->getNewPower();


}


}
sp=otherlayer->getChildren();
for(auto a:sp){
GWentCard *child=(GWentCard *)a;
if(child->getType()!="hero"&&child->getType()!="special"){
eotherpow=eotherpow+1;


}else{
eotherpow=eotherpow+child->getNewPower();


}


}
if(pow-shortpow+eotherpow<=enemypow-enemyshortpow+epow){


pNum[i]=1;
}else{


pNum[i]=0;
}




}


}else if(((String *)dic->objectForKey("cardname"))->getCString()=="impenetrable-fog"){
if(fogflag=true){
pNum[i]=0;
}else{
auto layer =(Layer *)this->getChildByName("enemylonglayer");
auto otherlayer =(Layer *)this->getChildByName("longlayer");
int epow=0;
int eotherpow=0;
auto sp=layer->getChildren();
for(auto a:sp){
GWentCard *child=(GWentCard *)a;
if(child->getType()!="hero"&&child->getType()!="special"){
epow=epow+1;


}else{
epow=epow+child->getNewPower();


}


}
sp=otherlayer->getChildren();
for(auto a:sp){
GWentCard *child=(GWentCard *)a;
if(child->getType()!="hero"&&child->getType()!="special"){
eotherpow=eotherpow+1;


}else{
eotherpow=eotherpow+child->getNewPower();


}


}
if(pow-longpow+eotherpow<=enemypow-enemylongpow+epow){


pNum[i]=1;
}else{


pNum[i]=0;
}




}




}else if(((String *)dic->objectForKey("cardname"))->getCString()=="Torrential-Rain"){


if(rainflag=true){
pNum[i]=0;
}else{
auto layer =(Layer *)this->getChildByName("enemysiegelayer");
auto otherlayer =(Layer *)this->getChildByName("siegelayer");
int epow=0;
int eotherpow=0;
auto sp=layer->getChildren();
for(auto a:sp){
GWentCard *child=(GWentCard *)a;
if(child->getType()!="hero"&&child->getType()!="special"){
epow=epow+1;


}else{
epow=epow+child->getNewPower();


}


}
sp=otherlayer->getChildren();
for(auto a:sp){
GWentCard *child=(GWentCard *)a;
if(child->getType()!="hero"&&child->getType()!="special"){
eotherpow=eotherpow+1;


}else{
eotherpow=eotherpow+child->getNewPower();


}


}
if(pow-siegepow+eotherpow<=enemypow-enemysiegepow+epow){


pNum[i]=1;
}else{


pNum[i]=0;
}




}


}else if(((String *)dic->objectForKey("cardname"))->getCString()=="Clear-Weather"){
if(frostflag!=true&&fogflag!=true&&rainflag!=true){
pNum[i]=0;


}else{
pNum[i]=1;


}


}


}
}
i++;


}
int zeronumber=0;//记录权值为0的操作,如果全为0则弃权
int max=pNum[0];
int outPosition=0;
for(int i=0;i<enemeyhandarray->count();i++){
if(pNum[i]==0){
zeronumber++;


}
if(max<=pNum[i]){
max=pNum[i];
outPosition=i;


}
}
if(qiquanflag==true&&enemypow>pow){
return NULL;
}
if(zeronumber>enemeyhandarray->count()/2){
return NULL;
}
Dictionary *cardDic=(Dictionary *)enemeyhandarray->objectAtIndex(outPosition);
cardDic->retain();
enemeyhandarray->removeObject(cardDic);
GWentCard *card=GWentCard::create(cardDic);
card->setGameMain(this);
card->setBType(3);
card->setScale(0.26);
return card;



0 0
原创粉丝点击