Merge pull request #580 from PZ157/PR-Branch

部分技能ai优化
This commit is contained in:
Spmario233 2023-10-26 22:46:08 +08:00 committed by GitHub
commit 88c0a2e112
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 127 additions and 82 deletions

View File

@ -99,69 +99,62 @@ game.import('card',function(lib,game,ui,get,ai,_status){
}, },
ai:{ ai:{
basic:{ basic:{
useful:function(card,i){ useful:(card,i)=>{
if(_status.event.player.hp>1){ if(_status.event.player.hp>1){
if(i==0) return 4; if(i===0) return 4;
return 1; return 1;
} }
if(i==0) return 7.3; if(i===0) return 7.3;
return 3; return 3;
}, },
value:function(card,player,i){ value:(card,player,i)=>{
if(player.hp>1){ if(player.hp>1){
if(i==0) return 5; if(i===0) return 5;
return 1; return 1;
} }
if(i==0) return 7.3; if(i===0) return 7.3;
return 3; return 3;
}, }
}, },
order:function(){ order:()=>{
return get.order({name:'sha'})+0.2; if(_status.event.dying) return 9;
let sha=get.order({name:'sha'});
if(sha>0) return sha+0.2;
return 0;
}, },
result:{ result:{
target:function(player,target){ target:(player,target)=>{
if(target&&target.isDying()) return 2; if(target&&target.isDying()) return 2;
if(target&&!target.isPhaseUsing()) return 0; if(!target || target._jiu_temp || !target.isPhaseUsing()) return 0;
if(lib.config.mode=='stone'&&!player.isMin()){ if(!target.getCardUsable('sha') || lib.config.mode==='stone'&&!player.isMin()&&player.getActCount()+1>=player.actcount) return 0;
if(player.getActCount()+1>=player.actcount) return 0; let shas = player.getCards('hs',card=>get.name(card)==='sha'&&!ui.selected.cards.includes(card)), card;
} if(!shas.length || !target.hasSha() || shas.length>1&&(target.getCardUsable('sha')>1 || target.countCards('hs','zhuge'))) return 0;
var shas=player.getCards('h','sha'); target._jiu_temp = true;
if(shas.length>1&&(player.getCardUsable('sha')>1||player.countCards('h','zhuge'))){ shas.sort((a,b)=>get.order(b)-get.order(a));
return 0; for(let i=0; i<shas.length; i++){
} let tars = [];
shas.sort(function(a,b){ if(lib.filter.filterCard(shas[i],target)) tars = game.filterPlayer(current=>{
return get.order(b)-get.order(a); return get.attitude(target,current)<0&&target.canUse(shas[i],current,null,true)&&!current.hasSkillTag('filterDamage',null,{
}) player:target,
var card; card:shas[i],
if(shas.length){ jiu:true
for(var i=0;i<shas.length;i++){ })&&get.effect(current,shas[i],target)>0;
if(lib.filter.filterCard(shas[i],target)){ });
card=shas[i];break; if(!tars.length) continue;
} tars.sort((a,b)=>{
} return get.effect(b,shas[i],target)-get.effect(a,shas[i],target);
} });
else if(player.hasSha()&&player.needsToDiscard()){ if(!tars[0].mayHaveShan(player,'use') || target.hasSkillTag('directHit_ai',true,{
if(player.countCards('h','hufu')!=1){ target:tars[0],
card={name:'sha'}; card:shas[i]
} },true) || target.needsToDiscard()>Math.max(0,3-target.hp)){
} delete target._jiu_temp;
if(card){
if(game.hasPlayer(function(current){
return (get.attitude(target,current)<0&&
target.canUse(card,current,null,true)&&
!current.hasSkillTag('filterDamage',null,{
player:player,
card:card,
jiu:true,
})&&
get.effect(current,card,target)>0);
})){
return 1; return 1;
} }
} }
delete target._jiu_temp;
return 0; return 0;
}, }
}, },
tag:{ tag:{
save:1, save:1,

View File

@ -1169,14 +1169,14 @@ game.import('card',function(lib,game,ui,get,ai,_status){
if(event.shaRequired>1&&player.countCards('h','sha')<event.shaRequired) return 0; if(event.shaRequired>1&&player.countCards('h','sha')<event.shaRequired) return 0;
if(event.player==target){ if(event.player==target){
if(player.hasSkill('naman')) return -1; if(player.hasSkill('naman')) return -1;
if(get.attitude(target,player)<0||event.player.hp<=1){ if(get.attitude(target,player)<0||event.player.hp<=1&&get.damageEffect(target,player,event.player)<get.damageEffect(player,target,event.player)){
return get.order(card); return get.order(card);
} }
return -1; return -1;
} }
else{ else{
if(target.hasSkill('naman')) return -1; if(target.hasSkill('naman')) return -1;
if(get.attitude(player,target)<0||event.player.hp<=1){ if(get.attitude(player,target)<0||event.player.hp<=1&&get.damageEffect(target,player,event.player)>get.damageEffect(player,target,event.player)){
return get.order(card); return get.order(card);
} }
return -1; return -1;

View File

@ -1156,8 +1156,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){
ai:{ ai:{
effect:{ effect:{
player:function(card,player,target){ player:function(card,player,target){
if(ui.selected.targets.length) return; if(player!==target&&get.type2(card)==='trick'){
if(player!=target&&get.type2(card)=='trick') return [1,0,1,-2]; let tars=[target];
if(ui.selected.targets.length) tars.addArray(ui.selected.targets.filter(i=>i!==player&&i!==target));
if(tars.length<2) return [1,0,1,-2];
return [1,0,1,-2/tars.length];
}
}, },
}, },
}, },

View File

@ -1637,6 +1637,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){
}, },
order:10, order:10,
result:{player:1}, result:{player:1},
effect:{
target:(card,player,target)=>{
if(card.name==='sha'&&target.getExpansions('ddddongcha_effect').length<2&&lib.skill['dddzhijie'].hiddenCard(target,'shan')) return [1,1,1,-get.sgn(get.attitude(player,_status.currentPhase))];
}
}
}, },
subSkill:{ subSkill:{
draw:{ draw:{

View File

@ -5143,6 +5143,25 @@ game.import('character',function(lib,game,ui,get,ai,_status){
content:function(){ content:function(){
player.removeMark('renjie',1); player.removeMark('renjie',1);
player.addTempSkill('rewansha'); player.addTempSkill('rewansha');
},
ai:{
order:()=>{
let player=_status.event.player;
if(game.hasPlayer(current=>{
if(player===current||current.hp>1||get.attitude(player,current)>=0) return false;
return player.inRange(current)&&player.countCards('hs','sha')&&player.getCardUsable('sha')||
player.countCards('hs',card=>get.name(card)!=='sha'&&get.tag(card,'damage'))>1;
}) return 9.2;
return 0;
},
result:{
player:1
},
effect:{
player:(card,player,target)=>{
if(player.hasSkill('rewansha')&&target.hp<=1&&get.tag(card,'damage')) return [1,0,1.5,-1.5];
}
}
} }
}, },
jilue_zhiheng:{ jilue_zhiheng:{

View File

@ -11287,10 +11287,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){
content:function(){ content:function(){
'step 0' 'step 0'
player.chooseTarget(get.prompt('zhongzuo'),'令一名角色摸两张牌。若其已受伤,则你摸一张牌。').set('ai',function(target){ player.chooseTarget(get.prompt('zhongzuo'),'令一名角色摸两张牌。若其已受伤,则你摸一张牌。').set('ai',function(target){
if(target.hasSkillTag('nogain')&&target!=_status.currentPhase) return target.isDamaged()?0:1; if(target.hasSkillTag('nogain')) return target.isDamaged()?0:1;
var att=get.attitude(_status.event.player,target); let att=get.attitude(_status.event.player,target);
if(target.isDamaged()) att=att*1.2; if(att<=0) return 0;
return att; if(target.isDamaged()) return 1+att/5;
return att/5;
}); });
'step 1' 'step 1'
if(result.bool){ if(result.bool){

View File

@ -1382,13 +1382,20 @@ game.import('character',function(lib,game,ui,get,ai,_status){
ai:{ ai:{
order:13, order:13,
result:{ result:{
target:function(player,target){ target:(player,target)=>{
if(target.getEquip('bagua')||target.getEquip('rewrite_bagua')) return 0; if(target.getEquip('bagua')||target.getEquip('rewrite_bagua')) return 0;
var hs=player.countCards('h',function(card){ let hs=player.countCards('h',card=>{
return ['sha','juedou'].contains(card.name)&&get.effect(target,card,player,player)!=0; if(!get.tag(card,'damage')||get.effect(target,card,player,player)<=0) return 0;
if(get.name(card,player)==='sha'){
if(target.getEquip('bagua')) return 0.5;
if(target.getEquip('rewrite_bagua')) return 0.25;
}
return 1;
}),ts=target.hp+target.hujia+game.countPlayer(current=>{
if(get.attitude(current,target)>0) return current.countCards('hs')/8;
return 0;
}); });
var ts=target.hp; if(hs>=ts) return -hs;
if(hs>=ts&&ts>1) return -1;
return 0; return 0;
}, },
}, },

View File

@ -3331,16 +3331,13 @@ game.import('character',function(lib,game,ui,get,ai,_status){
effect:{ effect:{
target:function(card,player,target){ target:function(card,player,target){
if(_status.luanchou_judging) return; if(_status.luanchou_judging) return;
_status.luanchou_judging=true;
if(get.tag(card,'damage')&&target.hasMark('luanchou')){ if(get.tag(card,'damage')&&target.hasMark('luanchou')){
var other=game.findPlayer(function(current){ var other=game.findPlayer(function(current){
return current!=target&&current.hasMark('luanchou')&&current.hp>target.hp&&(!current.storage.counttrigger||!current.storage.counttrigger.gonghuan); return current!=target&&current.hasMark('luanchou')&&current.hp>target.hp&&(!current.storage.counttrigger||!current.storage.counttrigger.gonghuan);
}); });
if(!other){ if(!other) return;
delete _status.luanchou_judging; _status.luanchou_judging=true;
return; var eff=[0,0,0,get.damageEffect(other,player,player,get.nature(card))/get.attitude(player,player)];
};
var eff=[0,0,0,get.damageEffect(other,player,target,get.nature(card))];
delete _status.luanchou_judging; delete _status.luanchou_judging;
return eff; return eff;
} }

View File

@ -13185,6 +13185,24 @@ game.import('character',function(lib,game,ui,get,ai,_status){
content:function(){ content:function(){
trigger.num--; trigger.num--;
}, },
ai:{
effect:{
target:function(card,player,target){
if(typeof card=='object'&&target.storage.gx_chongyingshenfu_effect&&target.getStorage('gx_chongyingshenfu_effect').includes(card.name)&&!target.hasSkillTag('unequip2')&&
get.itemtype(player)!=='player'||!player.hasSkillTag('jueqing',false,target)&&!player.hasSkillTag('unequip',false,{
name:card.name,
target:target,
card:card,
}))){
if(player&&player.hasSkillTag('damageBonus',true,{
target:target,
card:card
})) return 0.5;
return 'zeroplayertarget';
}
}
}
},
onremove:true, onremove:true,
intro:{ intro:{
content:'受到$造成的伤害-1', content:'受到$造成的伤害-1',

View File

@ -11671,9 +11671,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){
filter:function(event,player){ filter:function(event,player){
return event.getParent().name=='sha'; return event.getParent().name=='sha';
}, },
check:function(event,player){
return player.isDamaged();
},
content:function(){ content:function(){
'step 0' 'step 0'
player.judge(function(card){ player.judge(function(card){
@ -11720,14 +11717,15 @@ game.import('character',function(lib,game,ui,get,ai,_status){
var next=player.chooseToDiscard('he',function(card,player){ var next=player.chooseToDiscard('he',function(card,player){
return card!=player.getEquip('pyzhuren_diamond'); return card!=player.getEquip('pyzhuren_diamond');
},get.prompt(event.name,trigger.player),'弃置一张牌,令即将对其造成的伤害+1'); },get.prompt(event.name,trigger.player),'弃置一张牌,令即将对其造成的伤害+1');
next.set('target',trigger.player);
next.ai=function(card){ next.ai=function(card){
if(_status.event.goon) return 6-get.value(card); if(_status.event.goon) return 30/(1+_status.event.target.hp)-get.value(card);
return -1; return -1;
}; };
next.set('goon',get.attitude(player,trigger.player)<0&&!trigger.player.hasSkillTag('filterDamage',null,{ next.set('goon',get.attitude(player,trigger.player)<0&&!trigger.player.hasSkillTag('filterDamage',null,{
player:player, player:player,
card:trigger.card, card:trigger.card,
})); })&&get.damageEffect(trigger.player,player,player,trigger.nature)>0);
next.logSkill=[event.name,trigger.player]; next.logSkill=[event.name,trigger.player];
'step 1' 'step 1'
if(result.bool) trigger.num++; if(result.bool) trigger.num++;
@ -11803,10 +11801,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
jueqing:true, jueqing:true,
unequip_ai:true, unequip_ai:true,
skillTagFilter:function(player,tag,arg){ skillTagFilter:function(player,tag,arg){
if(tag=='unequip_ai'){ if(tag=='unequip_ai') return arg&&arg.name==='sha;
if(arg&&arg.name=='sha'&&get.color(arg.card)=='black') return true;
return false;
}
} }
}, },
}, },

View File

@ -2597,7 +2597,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
return get.name(card) === 'tao' || get.name(card) === 'jiu'; return get.name(card) === 'tao' || get.name(card) === 'jiu';
}), }),
att = get.attitude(_status.event.player, event.player), att = get.attitude(_status.event.player, event.player),
eff = get.damageEffect(event.player, player, _status.event.player, event.nature), eff = get.damageEffect(event.player, player, _status.event.player, get.natureList(event)),
fd = event.player.hasSkillTag('filterDamage', null, { fd = event.player.hasSkillTag('filterDamage', null, {
player: player, player: player,
card: event.card card: event.card
@ -2605,7 +2605,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
hp = player.hp + tj; hp = player.hp + tj;
if(player.storage.tairan2) hp -= player.storage.tairan2; if(player.storage.tairan2) hp -= player.storage.tairan2;
if(eff <= 0 || fd || att >= -2 || Math.abs(hp) <= 1) return false; if(eff <= 0 || fd || att >= -2 || Math.abs(hp) <= 1) return false;
if(hp > 2 || event.player.isLinked() && event.nature && eff > 0) return true; if(hp > 2 || eff > 0 && event.player.isLinked() && event.hasNature()) return true;
return !event.player.countCards('hs') || event.player.hp > 2 * event.num && !event.player.hasSkillTag('maixie'); return !event.player.countCards('hs') || event.player.hp > 2 * event.num && !event.player.hasSkillTag('maixie');
}, },
logTarget:'player', logTarget:'player',

View File

@ -28275,13 +28275,16 @@
if(this.hasSkillTag('respondShan',true,null,true)) return true; if(this.hasSkillTag('respondShan',true,null,true)) return true;
return this.hasUsableCard('shan'); return this.hasUsableCard('shan');
} }
mayHaveSha(viewer,type){ mayHaveSha(viewer,type,ignore){
if((this.hp>2||!this.isZhu&&this.hp>1)&&this.hasSkillTag('respondSha',true,type,true)) return true; if((this.hp>2||!this.isZhu&&this.hp>1)&&this.hasSkillTag('respondSha',true,type,true)) return true;
if(get.itemtype(viewer)!=='player') viewer=_status.event.player; if(get.itemtype(viewer)!=='player') viewer=_status.event.player;
let cards; let cards,selected=get.copy(ui.selected.cards);
if(get.itemtype(ignore)==='cards') selected.addArray(ignore);
else if(get.itemtype(ignore)==='card') selected.add(ignore);
if(this===viewer||get.itemtype(viewer)==='player'&&viewer.hasSkillTag('viewHandcard',null,this,true)) cards=this.getCards('h'); if(this===viewer||get.itemtype(viewer)==='player'&&viewer.hasSkillTag('viewHandcard',null,this,true)) cards=this.getCards('h');
else cards=this.getShownCards(); else cards=this.getShownCards();
if(cards.some(card=>{ if(cards.some(card=>{
if(selected.includes(card)) return false;
let name=get.name(card,this); let name=get.name(card,this);
if(name=='sha'||name=='hufu'||name=='yuchanqian'){ if(name=='sha'||name=='hufu'||name=='yuchanqian'){
if(type==='use') return lib.filter.cardEnabled(card,this); if(type==='use') return lib.filter.cardEnabled(card,this);
@ -28290,17 +28293,20 @@
} }
return false; return false;
})) return true; })) return true;
let hs=this.getCards('hs').removeArray(cards).length; let hs=this.getCards('hs').filter(i=>!cards.includes(i)&&!selected.includes(i)).length;
if(hs===0) return false; if(hs===0) return false;
return Math.pow(hs+(this.isPhaseUsing()?6:4),2)>100*_status.event.getRand('mayHaveSha'); return Math.pow(hs+(this.isPhaseUsing()?6:4),2)>100*_status.event.getRand('mayHaveSha');
} }
mayHaveShan(viewer,type){ mayHaveShan(viewer,type,ignore){
if((this.hp>2||!this.isZhu&&this.hp>1)&&this.hasSkillTag('respondShan',true,type,true)) return true; if((this.hp>2||!this.isZhu&&this.hp>1)&&this.hasSkillTag('respondShan',true,type,true)) return true;
if(get.itemtype(viewer)!=='player') viewer=_status.event.player; if(get.itemtype(viewer)!=='player') viewer=_status.event.player;
let cards; let cards,selected=get.copy(ui.selected.cards);
if(get.itemtype(ignore)==='cards') selected.addArray(ignore);
else if(get.itemtype(ignore)==='card') selected.add(ignore);
if(this===viewer||get.itemtype(viewer)==='player'&&viewer.hasSkillTag('viewHandcard',null,this,true)) cards=this.getCards('h'); if(this===viewer||get.itemtype(viewer)==='player'&&viewer.hasSkillTag('viewHandcard',null,this,true)) cards=this.getCards('h');
else cards=this.getShownCards(); else cards=this.getShownCards();
if(cards.some(card=>{ if(cards.some(card=>{
if(selected.includes(card)) return false;
let name=get.name(card,this); let name=get.name(card,this);
if(name==='shan'||name==='hufu'){ if(name==='shan'||name==='hufu'){
if(type==='use') return lib.filter.cardEnabled(card,this); if(type==='use') return lib.filter.cardEnabled(card,this);
@ -28309,7 +28315,7 @@
} }
return false; return false;
})) return true; })) return true;
let hs=this.getCards('hs').removeArray(cards).length; let hs=this.getCards('hs').filter(i=>!cards.includes(i)&&!selected.includes(i)).length;
if(hs===0) return false; if(hs===0) return false;
return Math.pow(hs+(this.isPhaseUsing()?3:5),2)>100*_status.event.getRand('mayHaveShan'); return Math.pow(hs+(this.isPhaseUsing()?3:5),2)>100*_status.event.getRand('mayHaveShan');
} }