Commit eec2779c authored by wind2009's avatar wind2009 Committed by GitHub

Update custom executor (#177)

parent 18b0cc48
......@@ -204,6 +204,11 @@ Name=艾克莉西娅 Deck=Swordsoul Dialog=ecclesia.zh-CN
相剑卡组。
AI_LV3 SUPPORT_MASTER_RULE_3 SUPPORT_MASTER_RULE_2020
!艾克莉西娅-教导
Name=艾克莉西娅 Deck=Dogmatika Dialog=ecclesia.zh-CN
教导卡组。
AI_LV3 SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE SUPPORT_MASTER_RULE_2020
!神数不神-刹帝利
Name=神数不神 Deck=Kashtira Dialog=Zefra.zh-CN
俱舍怒威族卡组。
......
......@@ -3,6 +3,7 @@ using System.Collections.Generic;
using WindBot;
using WindBot.Game;
using WindBot.Game.AI;
using System.Linq;
namespace WindBot.Game.AI.Decks
{
......@@ -324,23 +325,37 @@ namespace WindBot.Game.AI.Decks
public int SelectSTPlace(ClientCard card=null, bool avoid_Impermanence = false)
{
List<int> list = new List<int> { 0, 1, 2, 3, 4 };
if (card == null) card = Card;
List<int> list = new List<int>();
for (int seq = 0; seq < 5; ++seq)
{
if (Bot.SpellZone[seq] == null)
{
if (card != null && card.Location == CardLocation.Hand && avoid_Impermanence && Impermanence_list.Contains(seq)) continue;
list.Add(seq);
}
}
int n = list.Count;
while (n-- > 1)
{
int index = Program.Rand.Next(n + 1);
int temp = list[index];
list[index] = list[n];
list[n] = temp;
int index = Program.Rand.Next(list.Count);
int nextIndex = (index + Program.Rand.Next(list.Count - 1)) % list.Count;
int tempInt = list[index];
list[index] = list[nextIndex];
list[nextIndex] = tempInt;
}
foreach (int seq in list)
if (avoid_Impermanence && Bot.GetMonsters().Any(c => c.IsFaceup() && !c.IsDisabled()))
{
int zone = (int)System.Math.Pow(2, seq);
if (Bot.SpellZone[seq] == null)
foreach (int seq in list)
{
if (card != null && card.Location == CardLocation.Hand && avoid_Impermanence && Impermanence_list.Contains(seq)) continue;
return zone;
};
ClientCard enemySpell = Enemy.SpellZone[4 - seq];
if (enemySpell != null && enemySpell.IsFacedown()) continue;
return (int)System.Math.Pow(2, seq);
}
}
foreach (int seq in list)
{
return (int)System.Math.Pow(2, seq);
}
return 0;
}
......@@ -2656,6 +2671,27 @@ namespace WindBot.Game.AI.Decks
attacked_Meluseek.Clear();
}
public override void OnChaining(int player, ClientCard card)
{
if (card == null) return;
if (player == 1)
{
if (card.IsCode(_CardId.InfiniteImpermanence))
{
for (int i = 0; i < 5; ++i)
{
if (Enemy.SpellZone[i] == card)
{
Impermanence_list.Add(4-i);
break;
}
}
}
}
base.OnChaining(player, card);
}
public bool MonsterRepos()
{
if (Card.Attack == 0) return (Card.IsAttack());
......@@ -2797,7 +2833,8 @@ namespace WindBot.Game.AI.Decks
// throw all??
return null;
}
return null;
return base.OnSelectCard(cards, min, max, hint, cancelable);
}
public override CardPosition OnSelectPosition(int cardId, IList<CardPosition> positions)
......
......@@ -146,7 +146,8 @@ namespace WindBot.Game.AI.Decks
return Util.CheckSelectCount(result, cards, min, max);
}
Logger.DebugWriteLine("Use default.");
return null;
return base.OnSelectCard(cards, min, max, hint, cancelable);
}
public override IList<ClientCard> OnSelectXyzMaterial(IList<ClientCard> cards, int min, int max)
......
......@@ -2,8 +2,6 @@ using YGOSharp.OCGWrapper.Enums;
using System.Collections.Generic;
using System.Linq;
using System;
using System.CodeDom;
using System.Security.AccessControl;
namespace WindBot.Game.AI.Decks
{
......@@ -62,6 +60,7 @@ namespace WindBot.Game.AI.Decks
public const int DimensionalFissure = 81674782;
public const int BanisheroftheRadiance = 94853057;
public const int BanisheroftheLight = 61528025;
public const int GhostMournerMoonlitChill = 52038441;
}
public DogmatikaExecutor(GameAI ai, Duel duel)
......@@ -133,6 +132,7 @@ namespace WindBot.Game.AI.Decks
const int SetcodeOrcust = 0x11b;
const int SetcodeDogmatika = 0x145;
const int hintTimingMainEnd = 0x4;
const int hintDamageStep = 0x2000;
Dictionary<int, List<int>> DeckCountTable = new Dictionary<int, List<int>>{
{3, new List<int> { CardId.DogmatikaEcclesia, _CardId.AshBlossom, _CardId.MaxxC, CardId.KnightmareCorruptorIblee, CardId.NadirServant,
......@@ -1096,10 +1096,26 @@ namespace WindBot.Game.AI.Decks
base.OnMove(cardId, previousControler, previousLocation, currentControler, currentLocation);
}
public override ClientCard OnSelectAttacker(IList<ClientCard> attackers, IList<ClientCard> defenders)
public override BattlePhaseAction OnBattle(IList<ClientCard> attackers, IList<ClientCard> defenders)
{
if (attackers.Count() > 0) return attackers[attackers.Count() - 1];
return null;
if (attackers.Count() == 1 && defenders.Count() == 1)
{
if (defenders[0].IsCode(CardId.KnightmareCorruptorIblee) && !confirmLink2) return new BattlePhaseAction(BattlePhaseAction.BattleAction.ToMainPhaseTwo);
}
if (attackers.Count() > 0 && defenders.Count() > 0)
{
List<ClientCard> sortedAttacker = attackers.OrderBy(card => card.Attack).ToList();
for (int k = 0; k < sortedAttacker.Count; ++k)
{
ClientCard attacker = sortedAttacker[k];
attacker.IsLastAttacker = k == sortedAttacker.Count - 1;
BattlePhaseAction result = OnSelectAttackTarget(attacker, defenders);
if (result != null)
return result;
}
}
return base.OnBattle(attackers, defenders);
}
public override BattlePhaseAction OnSelectAttackTarget(ClientCard attacker, IList<ClientCard> defenders)
......@@ -1113,6 +1129,9 @@ namespace WindBot.Game.AI.Decks
if (attacker.RealPower > defender.RealPower)
return AI.Attack(attacker, defender);
if (attacker.RealPower == defender.RealPower && defender.IsAttack() && Bot.GetMonsterCount() >= Enemy.GetMonsterCount())
return AI.Attack(attacker, defender);
}
if (attacker.CanDirectAttack)
......@@ -1989,13 +2008,17 @@ namespace WindBot.Game.AI.Decks
ClientCard lastChainCard = Util.GetLastChainCard();
if (lastChainCard != null && lastChainCard.Controller == 1 && lastChainCard.IsMonster())
{
foreach (ClientCard chainTarget in Duel.LastChainTargets)
bool negateFlag = lastChainCard.IsCode(_CardId.EffectVeiler, CardId.GhostMournerMoonlitChill);
if (Duel.Turn > 1 || !negateFlag)
{
if (selfCasterList.Contains(chainTarget))
foreach (ClientCard chainTarget in Duel.LastChainTargets)
{
selfTarget = chainTarget;
activateFlag = true;
break;
if (selfCasterList.Contains(chainTarget) && (!negateFlag || !chainTarget.IsCode(CardId.DiabellstarTheBlackWitch)))
{
selfTarget = chainTarget;
activateFlag = true;
break;
}
}
}
}
......@@ -2022,7 +2045,8 @@ namespace WindBot.Game.AI.Decks
if (!onlyAlbaZoa)
{
List<ClientCard> toDestroyMonsterList = Enemy.GetMonsters().Where(card => card.IsFaceup()
&& card.Attack > 0 && card.Attack <= targetAttack && !currentDestroyCardList.Contains(card)).ToList();
&& card.Attack > 0 && card.Attack <= targetAttack && !currentDestroyCardList.Contains(card)
&& (Duel.Player == 1 || card != Enemy.BattlingMonster)).ToList();
if (toDestroyMonsterList.Count() > 1)
{
activateFlag = true;
......@@ -2031,7 +2055,13 @@ namespace WindBot.Game.AI.Decks
}
// decrease attack
if (Bot.UnderAttack && !onlyAlbaZoa && (Bot.BattlingMonster?.GetDefensePower() ?? 0) <= (Enemy.BattlingMonster?.GetDefensePower() ?? 0))
int botWorstPower = Util.GetWorstBotMonster()?.GetDefensePower() ?? 0;
bool decreaseFlag = Duel.Player == 1 && Enemy.GetMonsters().Any(card => card.Attack >= botWorstPower
&& card.IsMonsterHasPreventActivationEffectInBattle()) && Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2;
decreaseFlag |= (!onlyAlbaZoa || (Bot.BattlingMonster?.IsCode(CardId.DogmatikaAlbaZoa) ?? false))
&& (Bot.BattlingMonster?.GetDefensePower() ?? 0) <= (Enemy.BattlingMonster?.GetDefensePower() ?? 0)
&& Duel.LastChainPlayer != 0 && (CurrentTiming & hintDamageStep) != 0 && CurrentTiming > 0;
if (decreaseFlag)
{
activateFlag = true;
}
......@@ -2425,7 +2455,7 @@ namespace WindBot.Game.AI.Decks
if (targetCard == null || extraToDiscard == null)
{
bool check1 = DefaultOnBecomeTarget();
bool check2 = Bot.UnderAttack && (Bot.BattlingMonster?.GetDefensePower() ?? 0) <= (Enemy.BattlingMonster?.GetDefensePower() ?? 0);
bool check2 = Bot.UnderAttack && (Bot.BattlingMonster?.GetDefensePower() ?? 0) <= (Enemy.BattlingMonster?.GetDefensePower() ?? 0) && Duel.LastChainPlayer != 0;;
bool check3 = Duel.Player == 1 && Duel.Phase == DuelPhase.End && Duel.LastChainPlayer != 0;
bool check4 = Duel.Player == 1 && avoid2Monster && Enemy.GetMonsterCount() >= 2 && Duel.LastChainPlayer != 0;
Logger.DebugWriteLine("===punishment check flag: " + check1 + " " + check2 + " " + check3 + " " + check4);
......@@ -2820,7 +2850,7 @@ namespace WindBot.Game.AI.Decks
if (Card.IsAttack() && enemyBetter)
return true;
if (Card.IsDefense() && !enemyBetter && selfAttack >= Card.Defense)
if (Card.IsDefense() && !enemyBetter)
return true;
return false;
}
......
......@@ -629,25 +629,42 @@ namespace WindBot.Game.AI.Decks
/// <param name="avoidList">Whether need to avoid set in this place</param>
public void SelectSTPlace(ClientCard card = null, bool avoidImpermanence = false, List<int> avoidList = null)
{
List<int> list = new List<int> { 0, 1, 2, 3, 4 };
if (card == null) card = Card;
List<int> list = new List<int>();
for (int seq = 0; seq < 5; ++seq)
{
if (Bot.SpellZone[seq] == null)
{
if (card != null && card.Location == CardLocation.Hand && avoidImpermanence && infiniteImpermanenceList.Contains(seq)) continue;
if (avoidList != null && avoidList.Contains(seq)) continue;
list.Add(seq);
}
}
int n = list.Count;
while (n-- > 1)
{
int index = Program.Rand.Next(n + 1);
int temp = list[index];
list[index] = list[n];
list[n] = temp;
int index = Program.Rand.Next(list.Count);
int nextIndex = (index + Program.Rand.Next(list.Count - 1)) % list.Count;
int tempInt = list[index];
list[index] = list[nextIndex];
list[nextIndex] = tempInt;
}
foreach (int seq in list)
if (avoidImpermanence && Bot.GetMonsters().Any(c => c.IsFaceup() && !c.IsDisabled()))
{
int zone = (int)System.Math.Pow(2, seq);
if (Bot.SpellZone[seq] == null)
foreach (int seq in list)
{
if (card != null && card.Location == CardLocation.Hand && avoidImpermanence && infiniteImpermanenceList.Contains(seq)) continue;
if (avoidList != null && avoidList.Contains(seq)) continue;
ClientCard enemySpell = Enemy.SpellZone[4 - seq];
if (enemySpell != null && enemySpell.IsFacedown()) continue;
int zone = (int)System.Math.Pow(2, seq);
AI.SelectPlace(zone);
return;
};
}
}
foreach (int seq in list)
{
int zone = (int)System.Math.Pow(2, seq);
AI.SelectPlace(zone);
return;
}
AI.SelectPlace(0);
}
......@@ -816,6 +833,7 @@ namespace WindBot.Game.AI.Decks
public override void OnNewTurn()
{
if (Duel.Turn <= 1) calledbytheGraveCount.Clear();
enemyActivateMaxxC = false;
enemyActivateLockBird = false;
infiniteImpermanenceList.Clear();
......
......@@ -700,6 +700,7 @@ namespace WindBot.Game.AI.Decks
public override void OnNewTurn()
{
if (Duel.Turn <= 1) calledbytheGraveCount.Clear();
enemyActivateMaxxC = false;
enemyActivateLockBird = false;
......@@ -780,7 +781,17 @@ namespace WindBot.Game.AI.Decks
/// <param name="avoidList">Whether need to avoid set in this place</param>
public void SelectSTPlace(ClientCard card = null, bool avoidImpermanence = false, List<int> avoidList = null)
{
List<int> list = new List<int> { 0, 1, 2, 3, 4 };
if (card == null) card = Card;
List<int> list = new List<int>();
for (int seq = 0; seq < 5; ++seq)
{
if (Bot.SpellZone[seq] == null)
{
if (card != null && card.Location == CardLocation.Hand && avoidImpermanence && infiniteImpermanenceList.Contains(seq)) continue;
if (avoidList != null && avoidList.Contains(seq)) continue;
list.Add(seq);
}
}
int n = list.Count;
while (n-- > 1)
{
......@@ -790,16 +801,22 @@ namespace WindBot.Game.AI.Decks
list[index] = list[nextIndex];
list[nextIndex] = tempInt;
}
foreach (int seq in list)
if (avoidImpermanence && Bot.GetMonsters().Any(c => c.IsFaceup() && !c.IsDisabled()))
{
int zone = (int)System.Math.Pow(2, seq);
if (Bot.SpellZone[seq] == null)
foreach (int seq in list)
{
if (card != null && card.Location == CardLocation.Hand && avoidImpermanence && infiniteImpermanenceList.Contains(seq)) continue;
if (avoidList != null && avoidList.Contains(seq)) continue;
ClientCard enemySpell = Enemy.SpellZone[4 - seq];
if (enemySpell != null && enemySpell.IsFacedown()) continue;
int zone = (int)System.Math.Pow(2, seq);
AI.SelectPlace(zone);
return;
};
}
}
foreach (int seq in list)
{
int zone = (int)System.Math.Pow(2, seq);
AI.SelectPlace(zone);
return;
}
AI.SelectPlace(0);
}
......
......@@ -3,6 +3,7 @@ using System.Collections.Generic;
using WindBot;
using WindBot.Game;
using WindBot.Game.AI;
using System.Linq;
namespace WindBot.Game.AI.Decks
{
......@@ -67,6 +68,7 @@ namespace WindBot.Game.AI.Decks
return 1;
}
List<int> Impermanence_list = new List<int>();
bool NormalSummoned = false;
ClientCard stage_locked = null;
bool pink_ss = false;
......@@ -190,21 +192,39 @@ namespace WindBot.Game.AI.Decks
return false;
}
public int SelectSTPlace()
public int SelectSTPlace(ClientCard card = null, bool avoid_Impermanence = false)
{
List<int> list = new List<int> { 0, 1, 2, 3, 4 };
if (card == null) card = Card;
List<int> list = new List<int>();
for (int seq = 0; seq < 5; ++seq)
{
if (Bot.SpellZone[seq] == null)
{
if (card != null && card.Location == CardLocation.Hand && avoid_Impermanence && Impermanence_list.Contains(seq)) continue;
list.Add(seq);
}
}
int n = list.Count;
while (n-- > 1)
{
int index = Program.Rand.Next(n + 1);
int temp = list[index];
list[index] = list[n];
list[n] = temp;
int index = Program.Rand.Next(list.Count);
int nextIndex = (index + Program.Rand.Next(list.Count - 1)) % list.Count;
int tempInt = list[index];
list[index] = list[nextIndex];
list[nextIndex] = tempInt;
}
foreach(int seq in list)
if (avoid_Impermanence && Bot.GetMonsters().Any(c => c.IsFaceup() && !c.IsDisabled()))
{
int zone = (int)System.Math.Pow(2, seq);
if (Bot.SpellZone[seq] == null) return zone;
foreach (int seq in list)
{
ClientCard enemySpell = Enemy.SpellZone[4 - seq];
if (enemySpell != null && enemySpell.IsFacedown()) continue;
return (int)System.Math.Pow(2, seq);
}
}
foreach (int seq in list)
{
return (int)System.Math.Pow(2, seq);
}
return 0;
}
......@@ -505,7 +525,7 @@ namespace WindBot.Game.AI.Decks
if (selected == null)
return false;
AI.SelectCard(selected);
AI.SelectPlace(SelectSTPlace());
AI.SelectPlace(SelectSTPlace(Card, true));
return true;
}
......@@ -526,13 +546,13 @@ namespace WindBot.Game.AI.Decks
if (self_card.IsCode(CardId.Galaxy))
return false;
}
AI.SelectPlace(SelectSTPlace());
AI.SelectPlace(SelectSTPlace(Card, true));
return true;
}
// activate when more than 2 cards
if (Enemy.GetSpellCount() <= 1)
return false;
AI.SelectPlace(SelectSTPlace());
AI.SelectPlace(SelectSTPlace(Card, true));
return true;
}
......@@ -627,7 +647,7 @@ namespace WindBot.Game.AI.Decks
if (!spell_trap_activate()) return false;
if (Bot.Deck.Count > 15)
{
AI.SelectPlace(SelectSTPlace());
AI.SelectPlace(SelectSTPlace(Card, true));
return true;
}
return false;
......@@ -1003,7 +1023,7 @@ namespace WindBot.Game.AI.Decks
if (!spell_trap_activate()) return false;
if (Duel.Phase <= DuelPhase.Main1 && Ts_reborn())
{
AI.SelectPlace(SelectSTPlace());
AI.SelectPlace(SelectSTPlace(Card, true));
return true;
}
return false;
......@@ -1634,14 +1654,14 @@ namespace WindBot.Game.AI.Decks
{
if (enemy.IsMonsterDangerous())
{
AI.SelectPlace(SelectSTPlace());
AI.SelectPlace(SelectSTPlace(Card, true));
return true;
}
if (enemy.IsFaceup() && (enemy.GetDefensePower() > bestenemy)) bestenemy = enemy.GetDefensePower();
}
if (bestPower <= bestenemy)
{
AI.SelectPlace(SelectSTPlace());
AI.SelectPlace(SelectSTPlace(Card, true));
return true;
}
}
......@@ -1697,6 +1717,11 @@ namespace WindBot.Game.AI.Decks
public override void OnNewTurn()
{
if (Duel.Turn <= 1)
{
GraveCall_count = 0;
GraveCall_id = 0;
}
NormalSummoned = false;
stage_locked = null;
pink_ss = false;
......@@ -1705,6 +1730,7 @@ namespace WindBot.Game.AI.Decks
white_eff_used = false;
lockbird_useful = false;
lockbird_used = false;
Impermanence_list.Clear();
if (GraveCall_count > 0)
{
if (--GraveCall_count <= 0)
......@@ -1714,6 +1740,27 @@ namespace WindBot.Game.AI.Decks
}
}
public override void OnChaining(int player, ClientCard card)
{
if (card == null) return;
if (player == 1)
{
if (card.IsCode(_CardId.InfiniteImpermanence))
{
for (int i = 0; i < 5; ++i)
{
if (Enemy.SpellZone[i] == card)
{
Impermanence_list.Add(4-i);
break;
}
}
}
}
base.OnChaining(player, card);
}
public override BattlePhaseAction OnSelectAttackTarget(ClientCard attacker, IList<ClientCard> defenders)
{
ClientCard lowestattack = null;
......
......@@ -269,6 +269,7 @@ namespace WindBot.Game.AI.Decks
// new turn reset
public override void OnNewTurn()
{
if (Duel.Turn <= 1) CalledbytheGraveCount.Clear();
CrossoutDesignatorTarget = 0;
MadameVerreGainedATK = false;
summoned = false;
......@@ -858,27 +859,44 @@ namespace WindBot.Game.AI.Decks
/// <param name="card">Card to set(default current card)</param>
/// <param name="avoid_Impermanence">Whether need to avoid InfiniteImpermanence</param>
/// <param name="avoid_list">Whether need to avoid set in this place</param>
public void SelectSTPlace(ClientCard card = null, bool avoid_Impermanence = false, List<int> avoid_list=null)
public void SelectSTPlace(ClientCard card = null, bool avoid_Impermanence = false, List<int> avoid_list = null)
{
List<int> list = new List<int> { 0, 1, 2, 3, 4 };
if (card == null) card = Card;
List<int> list = new List<int>();
for (int seq = 0; seq < 5; ++seq)
{
if (Bot.SpellZone[seq] == null)
{
if (card != null && card.Location == CardLocation.Hand && avoid_Impermanence && Impermanence_list.Contains(seq)) continue;
if (avoid_list != null && avoid_list.Contains(seq)) continue;
list.Add(seq);
}
}
int n = list.Count;
while (n-- > 1)
{
int index = Program.Rand.Next(n + 1);
int temp = list[index];
list[index] = list[n];
list[n] = temp;
int index = Program.Rand.Next(list.Count);
int nextIndex = (index + Program.Rand.Next(list.Count - 1)) % list.Count;
int tempInt = list[index];
list[index] = list[nextIndex];
list[nextIndex] = tempInt;
}
foreach (int seq in list)
if (avoid_Impermanence && Bot.GetMonsters().Any(c => c.IsFaceup() && !c.IsDisabled()))
{
int zone = (int)System.Math.Pow(2, seq);
if (Bot.SpellZone[seq] == null)
foreach (int seq in list)
{
if (card != null && card.Location == CardLocation.Hand && avoid_Impermanence && Impermanence_list.Contains(seq)) continue;
if (avoid_list != null && avoid_list.Contains(seq)) continue;
ClientCard enemySpell = Enemy.SpellZone[4 - seq];
if (enemySpell != null && enemySpell.IsFacedown()) continue;
int zone = (int)System.Math.Pow(2, seq);
AI.SelectPlace(zone);
return;
};
}
}
foreach (int seq in list)
{
int zone = (int)System.Math.Pow(2, seq);
AI.SelectPlace(zone);
return;
}
AI.SelectPlace(0);
}
......
......@@ -2115,7 +2115,9 @@ namespace WindBot.Game.AI.Decks
result.AddRange(tRelease);
result.AddRange(nRelease);
}
return Func.CheckSelectCount(Util, result, cards, min, max);
IList<ClientCard> selectResult = Func.CheckSelectCount(Util, result, cards, min, max);
if (selectResult == null) return base.OnSelectCard(cards, min, max, hint, cancelable);
return selectResult;
}
private bool HasInDeck(int id)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment