From ddef565c2f784ad6288d93f01e59da5038d8bb6d Mon Sep 17 00:00:00 2001 From: jdistro07 Date: Sat, 9 Dec 2023 23:15:36 +0800 Subject: [PATCH 01/21] WIP: 1, Fix Cooclock 2. Fix FIeld Spell activation 3, Pot of Prosperity script --- Decks/AI_BudgetLabrynths.ydk | 73 ++++++ Game/AI/Decks/BudgetLabrynths.cs | 428 +++++++++++++++++++++++++++++++ WindBot.csproj | 3 + WindBot.sln | 4 +- 4 files changed, 506 insertions(+), 2 deletions(-) create mode 100644 Decks/AI_BudgetLabrynths.ydk create mode 100644 Game/AI/Decks/BudgetLabrynths.cs diff --git a/Decks/AI_BudgetLabrynths.ydk b/Decks/AI_BudgetLabrynths.ydk new file mode 100644 index 00000000..4a8d5ff0 --- /dev/null +++ b/Decks/AI_BudgetLabrynths.ydk @@ -0,0 +1,73 @@ +#created by SkildX +#main +27204311 +81497285 +81497285 +81497285 +2347656 +1225009 +1225009 +1225009 +37629703 +37629703 +37629703 +14558127 +14558127 +14558127 +74018812 +74018812 +74018812 +2511 +84211599 +84211599 +84211599 +33407125 +33407125 +33407125 +5380979 +5380979 +5380979 +15693423 +15693423 +15693423 +54974237 +82956214 +82956214 +82956214 +94192409 +94192409 +94192409 +40605147 +40605147 +40605147 +#extra +80532587 +80532587 +21123811 +21123811 +21123811 +98506199 +98506199 +98506199 +10019086 +10019086 +2857636 +71607202 +71607202 +65741786 +41999284 +!side +27204311 +27204311 +91800273 +91800273 +91800273 +24508238 +24508238 +24508238 +69895264 +69895264 +69895264 +10045474 +10045474 +10045474 diff --git a/Game/AI/Decks/BudgetLabrynths.cs b/Game/AI/Decks/BudgetLabrynths.cs new file mode 100644 index 00000000..7e5573a4 --- /dev/null +++ b/Game/AI/Decks/BudgetLabrynths.cs @@ -0,0 +1,428 @@ +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Remoting.Messaging; +using System.Security.Policy; +using System.Text; +using System.Web.Management; +using WindBot; +using WindBot.Game; +using WindBot.Game.AI; +using YGOSharp.OCGWrapper; +using YGOSharp.OCGWrapper.Enums; + +namespace WindBot.Game.AI.Decks +{ + [Deck("BudgetLabrynths", "AI_BudgetLabrynths")] + public class BudgetLabrynths : DefaultExecutor + { + public BudgetLabrynths(GameAI ai, Duel duel) + : base(ai, duel) + { + AddExecutor(ExecutorType.GoToBattlePhase, EvenlyMatchedActivate); + AddExecutor(ExecutorType.Activate); + + AddExecutor(ExecutorType.Activate, CardID.NIBIRU); + AddExecutor(ExecutorType.Activate, CardID.LADY_LABRYNTH, LadyLabrynthActivate); + AddExecutor(ExecutorType.Repos, CardID.LADY_LABRYNTH, LadyLabrynthRepos); + + AddExecutor(ExecutorType.Activate, CardID.LOVELY_LABRYNTH, LovelyLabrynthEffect); + + AddExecutor(ExecutorType.Summon, CardID.ARIANNA); + AddExecutor(ExecutorType.Activate, CardID.ARIANNA, AriannaEffect); + + AddExecutor(ExecutorType.SpSummon, CardID.MUCKRACKER, MuckarackerLinkSummon); + AddExecutor(ExecutorType.Activate, CardID.MUCKRACKER, MuckarackerEffect); + + + AddExecutor(ExecutorType.Activate, CardID.STOVIE_TORBIE, StovieTorbieEffect); + AddExecutor(ExecutorType.Activate, CardID.CHANDRAGLIER, ChandraglierEffect); + + AddExecutor(ExecutorType.Activate, CardID.ASH_BLOSSOM, AshBlossomActivate); + + AddExecutor(ExecutorType.Activate, CardID.POT_OF_PROSPERITY); + AddExecutor(ExecutorType.Activate, CardID.LABRYNTH_LABYRINTH); + + AddExecutor(ExecutorType.SpellSet, CardID.WELCOME_LABYRINTH); + + AddExecutor(ExecutorType.Activate, CardID.COOCLOCK, CooclockEffect); + + AddExecutor(ExecutorType.Activate, CardID.WELCOME_LABYRINTH, WelcomeLabrynthActivate); + + AddExecutor(ExecutorType.SpellSet, CardID.DOGMATIKA_PUNISHMENT); + AddExecutor(ExecutorType.Activate, CardID.DOGMATIKA_PUNISHMENT, DogmatikaPunishmentActivate); + + AddExecutor(ExecutorType.SpellSet, CardID.COMPULSORY_EVACUATION_DEVICE); + AddExecutor(ExecutorType.Activate, CardID.COMPULSORY_EVACUATION_DEVICE, CompulsoryEvacuationDeviceActivate); + + AddExecutor(ExecutorType.SpellSet, CardID.SOLEMN_STRIKE); + AddExecutor(ExecutorType.Activate, CardID.SOLEMN_STRIKE, SolemnStrikeActivate); + + AddExecutor(ExecutorType.SpellSet, CardID.ERADICATOR_EPIDEMIC_VIRUS, EradicatorSet); + AddExecutor(ExecutorType.Activate, CardID.ERADICATOR_EPIDEMIC_VIRUS); + + AddExecutor(ExecutorType.Activate, CardID.ELDER_ENTITY_NTSS, ElderEntityNtssEffect); + + } + + private bool MuckarackerEffect() + { + int[] bossMonsters = new int[] + { + CardID.LADY_LABRYNTH, + CardID.LOVELY_LABRYNTH + }; + + int[] other_prefferedMonsters = new int[] + { + CardID.ARIANNA, + CardID.STOVIE_TORBIE + }; + + if (Bot.HasInGraveyard(CardID.LOVELY_LABRYNTH) || Bot.HasInGraveyard(CardID.LADY_LABRYNTH)) + { + AI.SelectCard(bossMonsters); + return true; + } + else + { + AI.SelectCard(other_prefferedMonsters); + return true; + } + } + + private bool MuckarackerLinkSummon() + { + int bot_Monsters = Bot.MonsterZone.GetMatchingCards(card => card.Level < 4).Count(); + int bot_HandCards = Bot.Hand.Count(); + + if (bot_Monsters >= 2 && bot_HandCards > 1) + return true; + + return false; + } + + private bool AshBlossomActivate() + { + if (!(Duel.LastChainPlayer == 0)) return true; + return false; + } + + private bool EradicatorSet() + { + + if (Duel.Phase == DuelPhase.Main2) + { + IList tributes = Bot.MonsterZone.GetMatchingCards(card => card.HasAttribute(CardAttribute.Dark) && card.Attack > 2500); + + if (tributes.Count > 0) + return true; + } + + return false; + } + + private bool ElderEntityNtssEffect() + { + ClientCard backrow_target = Util.GetBestEnemySpell(); + ClientCard monster_target = Util.GetProblematicEnemyMonster(); + + if (Util.GetBestEnemySpell() != null) AI.SelectCard(backrow_target); + else AI.SelectNextCard(monster_target); + + return true; + } + + private bool LadyLabrynthRepos() + { + if (Card.IsFacedown()) + return true; + if (Card.IsDefense()) + return true; + + return false; + } + + private bool LadyLabrynthActivate() + { + int[] prefferedTraps = new int[] + { + CardID.DOGMATIKA_PUNISHMENT, + CardID.COMPULSORY_EVACUATION_DEVICE + }; + + IList enemySpellZone = Enemy.SpellZone.GetMatchingCards(card => + card.HasType(CardType.Spell) + || card.HasType(CardType.Trap) + || card.HasPosition(CardPosition.FaceDown) + ); + + if (!Bot.HasInMonstersZone(CardID.LOVELY_LABRYNTH)) AI.SelectCard(CardID.WELCOME_LABYRINTH); + else if (enemySpellZone.Count() > 1 && Bot.HasInMonstersZone(CardID.LOVELY_LABRYNTH)) AI.SelectCard(CardID.ERADICATOR_EPIDEMIC_VIRUS); + else AI.SelectCard(prefferedTraps); + return true; + } + + private bool EvenlyMatchedActivate() + { + return Bot.HasInHand(CardID.EVENLY_MATCHED) && Duel.Turn >= 2 && Enemy.GetFieldCount() >= 2 && Bot.GetFieldCount() == 0; + } + + private bool DogmatikaPunishmentActivate() + { + ClientCard problemMonster = Util.GetProblematicEnemyMonster(); + + if (problemMonster != null) + { + IList threatMonster = Enemy.MonsterZone.GetMatchingCards(card => card.IsCode(problemMonster.Id) && card.Attack > 2000); + + if (threatMonster.Count() > 0) + { + if (Duel.LastChainPlayer == 0 && Util.GetLastChainCard().IsCode(CardID.COMPULSORY_EVACUATION_DEVICE)) + { + return false; + } + + return true; + } + } + + return false; + } + + private bool StovieTorbieEffect() + { + IList stovie_copies = Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.STOVIE_TORBIE)); + + + if (Bot.HasInHand(CardID.CHANDRAGLIER) || stovie_copies.Count() > 0) + { + IList cost_candidates = Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.STOVIE_TORBIE) || card.IsCode(CardID.CHANDRAGLIER)); + cost_candidates.Select(x => x.Id).ToArray(); + + AI.SelectCard(cost_candidates); + AI.SelectNextCard(CardID.WELCOME_LABYRINTH); + + return true; + } + + return false; + } + + public override CardPosition OnSelectPosition(int cardId, IList positions) + { + if (cardId == 27204312 || cardId == CardID.STOVIE_TORBIE || cardId == CardID.ARIANNA) + { + return CardPosition.FaceUpDefence; + } + else if (cardId == CardID.LADY_LABRYNTH || cardId == CardID.LOVELY_LABRYNTH) + { + return CardPosition.FaceUpAttack; + } + return base.OnSelectPosition(cardId, positions); + } + + private bool SolemnStrikeActivate() + { + ClientCard problemCard = Util.GetProblematicEnemyMonster(); + + if(Duel.LastChainPlayer == 0) + return false; + + if (problemCard != null) + return true; + + return false; + } + + private bool LovelyLabrynthEffect() + { + int[] supportTraps = new int[] { + CardID.WELCOME_LABYRINTH, + CardID.COMPULSORY_EVACUATION_DEVICE, + CardID.DOGMATIKA_PUNISHMENT + }; + + if (Bot.HasInGraveyard(CardID.ERADICATOR_EPIDEMIC_VIRUS)) + AI.SelectCard(CardID.ERADICATOR_EPIDEMIC_VIRUS); + else + AI.SelectCard(supportTraps); + + return true; + } + + private bool CompulsoryEvacuationDeviceActivate() + { + ClientCard enemyBestMonster = Util.GetBestEnemyMonster(); + + if (enemyBestMonster != null) + { + if (Duel.LastChainPlayer == 0 && ( + Util.GetLastChainCard().IsCode(CardID.DOGMATIKA_PUNISHMENT) + || Util.GetLastChainCard().IsCode(CardID.COMPULSORY_EVACUATION_DEVICE) + || Util.GetLastChainCard().IsCode(CardID.ELDER_ENTITY_NTSS)) + ) + { + return false; + } + + return true; + } + + + + + + return false; + } + + public bool isEvenlyMatchedOnHand() + { + return Bot.HasInHand(CardID.EVENLY_MATCHED); + } + + public bool WelcomeLabrynthActivate() + { + int[] prefferedMonsters = new int[] { + CardID.LADY_LABRYNTH, + CardID.LOVELY_LABRYNTH + }; + + if (Bot.HasInHandOrInSpellZone(CardID.LABRYNTH_LABYRINTH) && Enemy.GetFieldCount() == 0) + { + AI.SelectYesNo(false); + return false; + } + else + { + AI.SelectCard(prefferedMonsters); + + AI.SelectYesNo(true); + + ClientCard backrow_problem = Util.GetBestEnemySpell(); + ClientCard monster_target = Util.GetProblematicEnemyMonster(); + + if (backrow_problem != null) AI.SelectNextCard(backrow_problem); + else AI.SelectNextCard(monster_target); + } + + return true; + } + + public bool AriannaEffect() + { + int[] prefferedCards = new int[] { + CardID.LABRYNTH_LABYRINTH, + CardID.COOCLOCK, + CardID.STOVIE_TORBIE + }; + + if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH)) + AI.SelectCard(CardID.WELCOME_LABYRINTH); + else if (Bot.Deck.GetMatchingCards(card => card.IsCode(CardID.COOCLOCK)).Count() > 0) + AI.SelectCard(CardID.COOCLOCK); + else + AI.SelectCard(prefferedCards); + + return true; + } + + public bool CooclockEffect() + { + IList faceUp_Monsters = Bot.MonsterZone.GetMatchingCards(card => + card.IsCode(CardID.LOVELY_LABRYNTH) + || card.IsCode(CardID.LADY_LABRYNTH) + || card.IsCode(CardID.STOVIE_TORBIE) + || card.IsCode(CardID.ARIANNA) + || card.IsCode(CardID.CHANDRAGLIER) + ); + + IList support_Traps = Bot.SpellZone.GetMatchingCards(card => card.IsCode(CardID.WELCOME_LABYRINTH) || card.IsCode(CardID.ERADICATOR_EPIDEMIC_VIRUS) || card.IsCode(CardID.ERADICATOR_EPIDEMIC_VIRUS)); + + if (Bot.HasInHand(CardID.COOCLOCK) && faceUp_Monsters.Count() > 0 || support_Traps.Count > 0) + { + return true; + } + + if (Bot.HasInGraveyard(CardID.COOCLOCK)) + { + return true; + } + + return false; + } + + public bool ChandraglierEffect() + { + if (Duel.LastChainPlayer == 0 && Util.GetLastChainCard().IsCode(CardID.STOVIE_TORBIE)) + return false; + + // check hand for cost candidate + IList copy_chandraglier = Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.CHANDRAGLIER)); + IList copy_stovie = Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.STOVIE_TORBIE)); + + int[] prefferedCards = new int[] { + CardID.WELCOME_LABYRINTH, + CardID.LABRYNTH_LABYRINTH, + }; + + IList cost_candidates = new List(); + + // Chandraglier + foreach (var cost in copy_chandraglier) + { + cost_candidates.Add(cost.Id); + } + + // Stovie + foreach (var cost in copy_stovie) + { + cost_candidates.Add(cost.Id); + } + + if (copy_chandraglier.Count > 0 || copy_stovie.Count() > 0 || Bot.SpellZone.GetMatchingCards(card => card.HasType(CardType.Trap)).Count() == 0) + { + AI.SelectCard(cost_candidates); + AI.SelectNextCard(prefferedCards); + return true; + } + + return false; + } + + public class CardID + { + // MAIN DECK + public const int NIBIRU = 27204311; + public const int LADY_LABRYNTH = 81497285; + public const int LOVELY_LABRYNTH = 2347656; + public const int ARIANNA = 1225009; + public const int CHANDRAGLIER = 37629703; + public const int ASH_BLOSSOM = 14558127; + public const int STOVIE_TORBIE = 74018812; + public const int COOCLOCK = 2511; + + // spells and traps + public const int POT_OF_PROSPERITY = 84211599; + public const int LABRYNTH_LABYRINTH = 33407125; + public const int WELCOME_LABYRINTH = 5380979; + public const int EVENLY_MATCHED = 15693423; + public const int DOGMATIKA_PUNISHMENT = 82956214; + public const int COMPULSORY_EVACUATION_DEVICE = 94192409; + public const int SOLEMN_STRIKE = 40605147; + public const int ERADICATOR_EPIDEMIC_VIRUS = 54974237; + + // EXTRA DECK + public const int ELDER_ENTITY_NTSS = 80532587; + public const int COMSIC_BLAZAR_DRAGON = 21123811; + public const int WIND_PEGASUS_IGNISTER = 98506199; + public const int TRIBRIGADE_ARMS_BUCEPHALUS_II = 10019086; + public const int KNIGHTMARE_PHEONIX = 2857636; + public const int MUCKRACKER = 71607202; + public const int IP_MASQUERENA = 65741786; + public const int LINKURIBOH = 41999284; + + } + } +} diff --git a/WindBot.csproj b/WindBot.csproj index 5b50096e..74ec951e 100644 --- a/WindBot.csproj +++ b/WindBot.csproj @@ -57,6 +57,7 @@ + @@ -138,6 +139,8 @@ PreserveNewest + + PreserveNewest diff --git a/WindBot.sln b/WindBot.sln index 721077a1..ab5ded86 100644 --- a/WindBot.sln +++ b/WindBot.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.960 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34316.72 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindBot", "WindBot.csproj", "{3E7FAF67-A27D-4A61-B161-93AD4414183E}" EndProject From 2d7202724ebe11ccc43659accd247729f16ee167 Mon Sep 17 00:00:00 2001 From: jdistro07 Date: Sun, 10 Dec 2023 17:05:30 +0800 Subject: [PATCH 02/21] WIP: fix overcommiting when setting traps --- Game/AI/Decks/BudgetLabrynths.cs | 254 +++++++++++++++++++++---------- 1 file changed, 172 insertions(+), 82 deletions(-) diff --git a/Game/AI/Decks/BudgetLabrynths.cs b/Game/AI/Decks/BudgetLabrynths.cs index 7e5573a4..e7a58111 100644 --- a/Game/AI/Decks/BudgetLabrynths.cs +++ b/Game/AI/Decks/BudgetLabrynths.cs @@ -20,35 +20,39 @@ public class BudgetLabrynths : DefaultExecutor public BudgetLabrynths(GameAI ai, Duel duel) : base(ai, duel) { + AddExecutor(ExecutorType.Activate, CardID.NIBIRU); + AddExecutor(ExecutorType.GoToBattlePhase, EvenlyMatchedActivate); AddExecutor(ExecutorType.Activate); - AddExecutor(ExecutorType.Activate, CardID.NIBIRU); - AddExecutor(ExecutorType.Activate, CardID.LADY_LABRYNTH, LadyLabrynthActivate); - AddExecutor(ExecutorType.Repos, CardID.LADY_LABRYNTH, LadyLabrynthRepos); + AddExecutor(ExecutorType.Activate, CardID.POT_OF_PROSPERITY); // TODO - AddExecutor(ExecutorType.Activate, CardID.LOVELY_LABRYNTH, LovelyLabrynthEffect); + AddExecutor(ExecutorType.Activate, CardID.STOVIE_TORBIE, StovieTorbieEffect); + + AddExecutor(ExecutorType.Summon, CardID.CHANDRAGLIER, ChandraglierSummon); + AddExecutor(ExecutorType.Activate, CardID.CHANDRAGLIER, ChandraglierEffect); + + AddExecutor(ExecutorType.Activate, CardID.COOCLOCK, CooclockEffect); AddExecutor(ExecutorType.Summon, CardID.ARIANNA); AddExecutor(ExecutorType.Activate, CardID.ARIANNA, AriannaEffect); + AddExecutor(ExecutorType.Repos, CardID.ARIANNA, AriannaRepos); - AddExecutor(ExecutorType.SpSummon, CardID.MUCKRACKER, MuckarackerLinkSummon); - AddExecutor(ExecutorType.Activate, CardID.MUCKRACKER, MuckarackerEffect); + AddExecutor(ExecutorType.SpellSet, CardID.WELCOME_LABYRINTH); + AddExecutor(ExecutorType.Activate, CardID.WELCOME_LABYRINTH, WelcomeLabrynthActivate); - AddExecutor(ExecutorType.Activate, CardID.STOVIE_TORBIE, StovieTorbieEffect); - AddExecutor(ExecutorType.Activate, CardID.CHANDRAGLIER, ChandraglierEffect); + AddExecutor(ExecutorType.Activate, CardID.LABRYNTH_LABYRINTH, LabrynthLabyrinthActivate); - AddExecutor(ExecutorType.Activate, CardID.ASH_BLOSSOM, AshBlossomActivate); - - AddExecutor(ExecutorType.Activate, CardID.POT_OF_PROSPERITY); - AddExecutor(ExecutorType.Activate, CardID.LABRYNTH_LABYRINTH); + AddExecutor(ExecutorType.Activate, CardID.LADY_LABRYNTH, LadyLabrynthActivate); + AddExecutor(ExecutorType.Repos, CardID.LADY_LABRYNTH, LadyLabrynthRepos); - AddExecutor(ExecutorType.SpellSet, CardID.WELCOME_LABYRINTH); + AddExecutor(ExecutorType.Activate, CardID.LOVELY_LABRYNTH, LovelyLabrynthEffect); - AddExecutor(ExecutorType.Activate, CardID.COOCLOCK, CooclockEffect); + AddExecutor(ExecutorType.Summon, CardID.MUCKRACKER, MuckarackerLinkSummon); + AddExecutor(ExecutorType.Activate, CardID.MUCKRACKER, MuckarackerEffect); - AddExecutor(ExecutorType.Activate, CardID.WELCOME_LABYRINTH, WelcomeLabrynthActivate); + AddExecutor(ExecutorType.Activate, CardID.ASH_BLOSSOM, AshBlossomActivate); AddExecutor(ExecutorType.SpellSet, CardID.DOGMATIKA_PUNISHMENT); AddExecutor(ExecutorType.Activate, CardID.DOGMATIKA_PUNISHMENT, DogmatikaPunishmentActivate); @@ -60,10 +64,69 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardID.SOLEMN_STRIKE, SolemnStrikeActivate); AddExecutor(ExecutorType.SpellSet, CardID.ERADICATOR_EPIDEMIC_VIRUS, EradicatorSet); - AddExecutor(ExecutorType.Activate, CardID.ERADICATOR_EPIDEMIC_VIRUS); + AddExecutor(ExecutorType.Activate, CardID.ERADICATOR_EPIDEMIC_VIRUS, EradicatorActivate); + AddExecutor(ExecutorType.Activate, CardID.WIND_PEGASUS_IGNISTER, WindPegasusIngisterEffect); AddExecutor(ExecutorType.Activate, CardID.ELDER_ENTITY_NTSS, ElderEntityNtssEffect); + } + + private bool AriannaRepos() + { + bool enemyAdvantage = Util.IsAllEnemyBetter(true); + if ((Card.HasPosition(CardPosition.FaceUpAttack) || Card.HasPosition(CardPosition.FaceDown)) && enemyAdvantage) return true; + else if (Card.HasPosition(CardPosition.FaceUpDefence) && !enemyAdvantage) return true; + + return false; + } + + private bool WindPegasusIngisterEffect() + { + ClientCard card = Util.GetBestEnemyCard(); + + if (card != null) + { + AI.SelectCard(card); + return true; + } + + return false; + } + + private bool EradicatorActivate() + { + if (Bot.SpellZone.GetMatchingCards(card => card.IsCode(CardID.LABRYNTH_LABYRINTH) && card.IsFaceup()).Count() > 0) + { + AI.SelectCard(CardID.LADY_LABRYNTH); + return true; + } + else + { + AI.SelectCard(CardID.LADY_LABRYNTH); + return true; + } + } + + private bool ChandraglierSummon() + { + return Bot.HasInHand(CardID.COOCLOCK) && Bot.HasInSpellZone(CardID.WELCOME_LABYRINTH); + } + + private bool LabrynthLabyrinthActivate() + { + if (SpellActivate()) return true; + else + { + ClientCard card = Util.GetLastChainCard(); + if (card != null && card.Controller == 0 && card.Id == CardID.LABRYNTH_LABYRINTH) return false; + + return true; + } + } + + private bool SpellActivate() + { + return Card.Location == CardLocation.Hand || (Card.Location == CardLocation.SpellZone && Card.IsFacedown()); } private bool MuckarackerEffect() @@ -111,7 +174,6 @@ private bool AshBlossomActivate() private bool EradicatorSet() { - if (Duel.Phase == DuelPhase.Main2) { IList tributes = Bot.MonsterZone.GetMatchingCards(card => card.HasAttribute(CardAttribute.Dark) && card.Attack > 2500); @@ -146,6 +208,8 @@ private bool LadyLabrynthRepos() private bool LadyLabrynthActivate() { + if (Util.GetProblematicEnemyCard() != null && Bot.SpellZone.GetMatchingCards(card => card.HasPosition(CardPosition.FaceDown)).Count() == 0) return false; + int[] prefferedTraps = new int[] { CardID.DOGMATIKA_PUNISHMENT, @@ -173,19 +237,27 @@ private bool DogmatikaPunishmentActivate() { ClientCard problemMonster = Util.GetProblematicEnemyMonster(); + int[] preffered_cost = new int[] + { + CardID.ELDER_ENTITY_NTSS, + CardID.TRIBRIGADE_ARMS_BUCEPHALUS_II, + CardID.WIND_PEGASUS_IGNISTER, + CardID.COMSIC_BLAZAR_DRAGON + }; + if (problemMonster != null) { - IList threatMonster = Enemy.MonsterZone.GetMatchingCards(card => card.IsCode(problemMonster.Id) && card.Attack > 2000); + if(Enemy.GetFieldCount() > 0) + AI.SelectCard(CardID.ELDER_ENTITY_NTSS); + else + AI.SelectCard(CardID.WIND_PEGASUS_IGNISTER); - if (threatMonster.Count() > 0) - { - if (Duel.LastChainPlayer == 0 && Util.GetLastChainCard().IsCode(CardID.COMPULSORY_EVACUATION_DEVICE)) - { - return false; - } + AI.SelectNextCard(problemMonster); - return true; - } + if (Duel.LastChainPlayer == 0 && Util.GetLastChainCard().IsCode(CardID.COMPULSORY_EVACUATION_DEVICE)) + return false; + + return true; } return false; @@ -193,19 +265,38 @@ private bool DogmatikaPunishmentActivate() private bool StovieTorbieEffect() { - IList stovie_copies = Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.STOVIE_TORBIE)); - - - if (Bot.HasInHand(CardID.CHANDRAGLIER) || stovie_copies.Count() > 0) + if (Card.Location == CardLocation.Hand && !Bot.HasInGraveyard(CardID.STOVIE_TORBIE)) { - IList cost_candidates = Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.STOVIE_TORBIE) || card.IsCode(CardID.CHANDRAGLIER)); - cost_candidates.Select(x => x.Id).ToArray(); + // Look for duplicate copies of the same card or Chandraglier and use them as materials. + IList cost_candidates = Bot.Hand.GetMatchingCards(card => + card.IsCode(CardID.CHANDRAGLIER) + || card.IsCode(CardID.STOVIE_TORBIE) + || card.IsCode(CardID.LOVELY_LABRYNTH) + || card.IsCode(CardID.NIBIRU) + ); + + IList hand_fieldSpell = Bot.Hand.GetMatchingCards(card => card.HasType(CardType.Field)); + if (hand_fieldSpell.Count() > 1) + { + foreach (var fs in hand_fieldSpell) + { + cost_candidates.Add(fs); + } + } - AI.SelectCard(cost_candidates); - AI.SelectNextCard(CardID.WELCOME_LABYRINTH); + // Get the next Labrynth spell and trap + if (cost_candidates.Count() > 0) + { + AI.SelectCard(cost_candidates.Select(x => x.Id).ToArray()); - return true; - } + if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH) && Bot.MonsterZone.GetMatchingCards(card => card.HasType(CardType.Monster)).Count() > 1) + AI.SelectNextCard(CardID.WELCOME_LABYRINTH); + else + AI.SelectNextCard(CardID.LABRYNTH_LABYRINTH); + + return true; + } + } else if(Card.Location == CardLocation.Grave) return true; return false; } @@ -259,10 +350,12 @@ private bool CompulsoryEvacuationDeviceActivate() if (enemyBestMonster != null) { if (Duel.LastChainPlayer == 0 && ( - Util.GetLastChainCard().IsCode(CardID.DOGMATIKA_PUNISHMENT) - || Util.GetLastChainCard().IsCode(CardID.COMPULSORY_EVACUATION_DEVICE) - || Util.GetLastChainCard().IsCode(CardID.ELDER_ENTITY_NTSS)) - ) + Util.GetLastChainCard().IsCode(CardID.DOGMATIKA_PUNISHMENT) + || Util.GetLastChainCard().IsCode(CardID.COMPULSORY_EVACUATION_DEVICE) + || Util.GetLastChainCard().IsCode(CardID.ELDER_ENTITY_NTSS) + || Util.GetLastChainCard().IsCode(CardID.WELCOME_LABYRINTH) + ) + ) { return false; } @@ -284,20 +377,27 @@ public bool isEvenlyMatchedOnHand() public bool WelcomeLabrynthActivate() { - int[] prefferedMonsters = new int[] { + int[] preferredMonsters = new int[] + { CardID.LADY_LABRYNTH, CardID.LOVELY_LABRYNTH }; - if (Bot.HasInHandOrInSpellZone(CardID.LABRYNTH_LABYRINTH) && Enemy.GetFieldCount() == 0) - { - AI.SelectYesNo(false); - return false; - } - else - { - AI.SelectCard(prefferedMonsters); + AI.SelectCard(preferredMonsters); + if (Bot.HasInMonstersZone(CardID.LADY_LABRYNTH)) + AI.SelectCard(CardID.LOVELY_LABRYNTH); + else if (Bot.HasInMonstersZone(CardID.LOVELY_LABRYNTH)) + AI.SelectCard(CardID.LADY_LABRYNTH); + else AI.SelectCard(CardID.LADY_LABRYNTH); + + // Labrynth Labyrinth add effect when Welcome Labrynth is activated + if (Duel.LastChainPlayer == 0 + && Util.GetLastChainCard().IsCode(CardID.WELCOME_LABYRINTH) + && Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH) + && Enemy.GetFieldCount() > 0 + ) + { AI.SelectYesNo(true); ClientCard backrow_problem = Util.GetBestEnemySpell(); @@ -312,18 +412,21 @@ public bool WelcomeLabrynthActivate() public bool AriannaEffect() { - int[] prefferedCards = new int[] { - CardID.LABRYNTH_LABYRINTH, + int[] other_prefferedCards = new int[] { CardID.COOCLOCK, CardID.STOVIE_TORBIE }; if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH)) AI.SelectCard(CardID.WELCOME_LABYRINTH); - else if (Bot.Deck.GetMatchingCards(card => card.IsCode(CardID.COOCLOCK)).Count() > 0) - AI.SelectCard(CardID.COOCLOCK); + else if ( + Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH) + && Bot.Deck.GetMatchingCards(card => card.IsCode(CardID.COOCLOCK)).Count() > 0 + && Bot.MonsterZone.GetMatchingCards(card => card.HasPosition(CardPosition.FaceUp)).Count() > 0 + ) + AI.SelectCard(CardID.LABRYNTH_LABYRINTH); else - AI.SelectCard(prefferedCards); + AI.SelectCard(other_prefferedCards); return true; } @@ -355,38 +458,25 @@ public bool CooclockEffect() public bool ChandraglierEffect() { - if (Duel.LastChainPlayer == 0 && Util.GetLastChainCard().IsCode(CardID.STOVIE_TORBIE)) - return false; - - // check hand for cost candidate - IList copy_chandraglier = Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.CHANDRAGLIER)); - IList copy_stovie = Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.STOVIE_TORBIE)); - - int[] prefferedCards = new int[] { - CardID.WELCOME_LABYRINTH, - CardID.LABRYNTH_LABYRINTH, - }; - - IList cost_candidates = new List(); - - // Chandraglier - foreach (var cost in copy_chandraglier) + if (Card.Location == CardLocation.Hand) { - cost_candidates.Add(cost.Id); - } + // Look for duplicate copies of the same card or Chandraglier and use them as materials. + IList cost_candidates = Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.CHANDRAGLIER) || card.IsCode(CardID.STOVIE_TORBIE) || card.IsCode(CardID.LOVELY_LABRYNTH) || card.IsCode(CardID.NIBIRU)); - // Stovie - foreach (var cost in copy_stovie) - { - cost_candidates.Add(cost.Id); - } + // Get the next Labrynth spell and trap + if (cost_candidates.Count() > 0) + { + AI.SelectCard(cost_candidates.Select(x => x.Id).ToArray()); - if (copy_chandraglier.Count > 0 || copy_stovie.Count() > 0 || Bot.SpellZone.GetMatchingCards(card => card.HasType(CardType.Trap)).Count() == 0) - { - AI.SelectCard(cost_candidates); - AI.SelectNextCard(prefferedCards); - return true; + if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH) && Bot.MonsterZone.GetMatchingCards(card => card.HasType(CardType.Monster)).Count() > 1) + AI.SelectNextCard(CardID.WELCOME_LABYRINTH); + else + AI.SelectNextCard(CardID.LABRYNTH_LABYRINTH); + + return true; + } } + else if (Card.Location == CardLocation.Grave) return true; return false; } From f5a17684ce87251c939af40373ff3e30ae03bf12 Mon Sep 17 00:00:00 2001 From: jdistro07 Date: Sun, 10 Dec 2023 22:29:16 +0800 Subject: [PATCH 03/21] - fixed furniture not activating - Improved Dogmatika activation behaviour - Improvements on Welcome Labrynth special summon TODO: 1. Pot of Prosperity improvements 2. Fix behaviour of bot activating Field spell repeatedly in one phase. 3. Fix Arianna summoning behaviour --- Game/AI/Decks/BudgetLabrynths.cs | 182 ++++++++++++++++++++----------- 1 file changed, 117 insertions(+), 65 deletions(-) diff --git a/Game/AI/Decks/BudgetLabrynths.cs b/Game/AI/Decks/BudgetLabrynths.cs index e7a58111..811ecdff 100644 --- a/Game/AI/Decks/BudgetLabrynths.cs +++ b/Game/AI/Decks/BudgetLabrynths.cs @@ -32,15 +32,17 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.Summon, CardID.CHANDRAGLIER, ChandraglierSummon); AddExecutor(ExecutorType.Activate, CardID.CHANDRAGLIER, ChandraglierEffect); + AddExecutor(ExecutorType.SpellSet, CardID.WELCOME_LABYRINTH); + AddExecutor(ExecutorType.Activate, CardID.WELCOME_LABYRINTH, WelcomeLabrynthActivate); + AddExecutor(ExecutorType.Activate, CardID.COOCLOCK, CooclockEffect); - AddExecutor(ExecutorType.Summon, CardID.ARIANNA); + AddExecutor(ExecutorType.Summon, CardID.ARIANNA, AriannaSummon); AddExecutor(ExecutorType.Activate, CardID.ARIANNA, AriannaEffect); AddExecutor(ExecutorType.Repos, CardID.ARIANNA, AriannaRepos); - - AddExecutor(ExecutorType.SpellSet, CardID.WELCOME_LABYRINTH); - AddExecutor(ExecutorType.Activate, CardID.WELCOME_LABYRINTH, WelcomeLabrynthActivate); + AddExecutor(ExecutorType.SpellSet, CardID.DOGMATIKA_PUNISHMENT, DogmatikaSet); + AddExecutor(ExecutorType.Activate, CardID.DOGMATIKA_PUNISHMENT, DogmatikaPunishmentActivate); AddExecutor(ExecutorType.Activate, CardID.LABRYNTH_LABYRINTH, LabrynthLabyrinthActivate); @@ -54,10 +56,7 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardID.ASH_BLOSSOM, AshBlossomActivate); - AddExecutor(ExecutorType.SpellSet, CardID.DOGMATIKA_PUNISHMENT); - AddExecutor(ExecutorType.Activate, CardID.DOGMATIKA_PUNISHMENT, DogmatikaPunishmentActivate); - - AddExecutor(ExecutorType.SpellSet, CardID.COMPULSORY_EVACUATION_DEVICE); + AddExecutor(ExecutorType.SpellSet, CardID.COMPULSORY_EVACUATION_DEVICE, CompulsoryEvacDeviceSet); AddExecutor(ExecutorType.Activate, CardID.COMPULSORY_EVACUATION_DEVICE, CompulsoryEvacuationDeviceActivate); AddExecutor(ExecutorType.SpellSet, CardID.SOLEMN_STRIKE); @@ -70,6 +69,48 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardID.ELDER_ENTITY_NTSS, ElderEntityNtssEffect); } + private bool LadyLabrynthActivated = false; + + private bool CompulsoryEvacDeviceSet() + { + ClientCard problemMonster = Util.GetProblematicEnemyMonster(); + + if (!Bot.HasInSpellZone(CardID.DOGMATIKA_PUNISHMENT)) + { + if (problemMonster != null) return true; + else if (ProtectLadyLabrynth()) return true; + } + + + return false; + } + + private bool AriannaSummon() + { + ClientCard threatCard = Util.GetProblematicEnemyMonster(); + + if (threatCard != null && Util.IsAllEnemyBetter()) return false; + else return true; + } + + private bool DogmatikaSet() + { + ClientCard problemMonster = Util.GetProblematicEnemyMonster(); + + if (!Bot.HasInSpellZone(CardID.DOGMATIKA_PUNISHMENT)) + { + if (problemMonster != null) return true; + else if (problemMonster == null && ProtectLadyLabrynth()) return true; + } + + return false; + } + + public bool ProtectLadyLabrynth() + { + return Bot.HasInMonstersZone(CardID.LADY_LABRYNTH); + } + private bool AriannaRepos() { bool enemyAdvantage = Util.IsAllEnemyBetter(true); @@ -114,6 +155,26 @@ private bool ChandraglierSummon() private bool LabrynthLabyrinthActivate() { + if (ActivateDescription == Util.GetStringId(CardID.LABRYNTH_LABYRINTH, 0)) + { + // Labrynth Labyrinth add effect when Welcome Labrynth is activated + if (Duel.LastChainPlayer == 0 + && Util.GetLastChainCard().IsCode(CardID.WELCOME_LABYRINTH) + && Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH) + && Enemy.GetFieldCount() > 0 + ) + { + AI.SelectYesNo(true); + + ClientCard backrow_problem = Util.GetBestEnemySpell(); + ClientCard monster_target = Util.GetProblematicEnemyMonster(); + + if (backrow_problem != null) AI.SelectNextCard(backrow_problem); + else AI.SelectNextCard(monster_target); + } + else return false; + } + if (SpellActivate()) return true; else { @@ -225,6 +286,9 @@ private bool LadyLabrynthActivate() if (!Bot.HasInMonstersZone(CardID.LOVELY_LABRYNTH)) AI.SelectCard(CardID.WELCOME_LABYRINTH); else if (enemySpellZone.Count() > 1 && Bot.HasInMonstersZone(CardID.LOVELY_LABRYNTH)) AI.SelectCard(CardID.ERADICATOR_EPIDEMIC_VIRUS); else AI.SelectCard(prefferedTraps); + + LadyLabrynthActivated = true; + return true; } @@ -268,26 +332,24 @@ private bool StovieTorbieEffect() if (Card.Location == CardLocation.Hand && !Bot.HasInGraveyard(CardID.STOVIE_TORBIE)) { // Look for duplicate copies of the same card or Chandraglier and use them as materials. - IList cost_candidates = Bot.Hand.GetMatchingCards(card => - card.IsCode(CardID.CHANDRAGLIER) - || card.IsCode(CardID.STOVIE_TORBIE) - || card.IsCode(CardID.LOVELY_LABRYNTH) - || card.IsCode(CardID.NIBIRU) - ); - - IList hand_fieldSpell = Bot.Hand.GetMatchingCards(card => card.HasType(CardType.Field)); - if (hand_fieldSpell.Count() > 1) - { - foreach (var fs in hand_fieldSpell) - { - cost_candidates.Add(fs); - } - } + List cost_candidates = new List(); + + if (Bot.HasInHand(CardID.CHANDRAGLIER)) + cost_candidates.Add(CardID.CHANDRAGLIER); + else if (Bot.HasInHand(CardID.LOVELY_LABRYNTH)) + cost_candidates.Add(CardID.LOVELY_LABRYNTH); + else if (Bot.HasInHand(CardID.LABRYNTH_LABYRINTH) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.LABRYNTH_LABYRINTH)).Count() > 1) + cost_candidates.Add(CardID.LABRYNTH_LABYRINTH); + else if (Bot.HasInHand(CardID.STOVIE_TORBIE) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.STOVIE_TORBIE)).Count() > 1) + cost_candidates.Add(CardID.LABRYNTH_LABYRINTH); + else if (Duel.Turn > 2) + cost_candidates.Add(CardID.NIBIRU); + else cost_candidates.AddRange(new List() { CardID.POT_OF_PROSPERITY }); // Get the next Labrynth spell and trap if (cost_candidates.Count() > 0) { - AI.SelectCard(cost_candidates.Select(x => x.Id).ToArray()); + AI.SelectCard(cost_candidates); if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH) && Bot.MonsterZone.GetMatchingCards(card => card.HasType(CardType.Monster)).Count() > 1) AI.SelectNextCard(CardID.WELCOME_LABYRINTH); @@ -301,6 +363,11 @@ private bool StovieTorbieEffect() return false; } + public override void OnNewTurn() + { + LadyLabrynthActivated = false; + } + public override CardPosition OnSelectPosition(int cardId, IList positions) { if (cardId == 27204312 || cardId == CardID.STOVIE_TORBIE || cardId == CardID.ARIANNA) @@ -377,35 +444,17 @@ public bool isEvenlyMatchedOnHand() public bool WelcomeLabrynthActivate() { - int[] preferredMonsters = new int[] - { - CardID.LADY_LABRYNTH, - CardID.LOVELY_LABRYNTH - }; + List preferred_Monsters = new List(); - AI.SelectCard(preferredMonsters); + if (Bot.HasInHandOrHasInMonstersZone(CardID.LADY_LABRYNTH)) + preferred_Monsters.Add(CardID.LOVELY_LABRYNTH); + else if (Bot.HasInHandOrInGraveyard(CardID.LOVELY_LABRYNTH) || Bot.HasInHandOrHasInMonstersZone(CardID.LOVELY_LABRYNTH)) + preferred_Monsters.Add(CardID.LADY_LABRYNTH); + else if (Bot.HasInMonstersZone(CardID.LADY_LABRYNTH) || Bot.HasInMonstersZone(CardID.LOVELY_LABRYNTH)) + preferred_Monsters.Add(CardID.ARIANNA); + else preferred_Monsters.AddRange(new List { CardID.STOVIE_TORBIE }); - if (Bot.HasInMonstersZone(CardID.LADY_LABRYNTH)) - AI.SelectCard(CardID.LOVELY_LABRYNTH); - else if (Bot.HasInMonstersZone(CardID.LOVELY_LABRYNTH)) - AI.SelectCard(CardID.LADY_LABRYNTH); - else AI.SelectCard(CardID.LADY_LABRYNTH); - - // Labrynth Labyrinth add effect when Welcome Labrynth is activated - if (Duel.LastChainPlayer == 0 - && Util.GetLastChainCard().IsCode(CardID.WELCOME_LABYRINTH) - && Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH) - && Enemy.GetFieldCount() > 0 - ) - { - AI.SelectYesNo(true); - - ClientCard backrow_problem = Util.GetBestEnemySpell(); - ClientCard monster_target = Util.GetProblematicEnemyMonster(); - - if (backrow_problem != null) AI.SelectNextCard(backrow_problem); - else AI.SelectNextCard(monster_target); - } + AI.SelectCard(preferred_Monsters); return true; } @@ -441,32 +490,35 @@ public bool CooclockEffect() || card.IsCode(CardID.CHANDRAGLIER) ); - IList support_Traps = Bot.SpellZone.GetMatchingCards(card => card.IsCode(CardID.WELCOME_LABYRINTH) || card.IsCode(CardID.ERADICATOR_EPIDEMIC_VIRUS) || card.IsCode(CardID.ERADICATOR_EPIDEMIC_VIRUS)); - - if (Bot.HasInHand(CardID.COOCLOCK) && faceUp_Monsters.Count() > 0 || support_Traps.Count > 0) - { - return true; - } - - if (Bot.HasInGraveyard(CardID.COOCLOCK)) - { - return true; - } + if (Card.Location == CardLocation.Hand || Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH)) return true; + else if (Card.Location == CardLocation.Grave) return true; return false; } public bool ChandraglierEffect() { - if (Card.Location == CardLocation.Hand) + if (Card.Location == CardLocation.Hand && !Bot.HasInGraveyard(CardID.CHANDRAGLIER)) { // Look for duplicate copies of the same card or Chandraglier and use them as materials. - IList cost_candidates = Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.CHANDRAGLIER) || card.IsCode(CardID.STOVIE_TORBIE) || card.IsCode(CardID.LOVELY_LABRYNTH) || card.IsCode(CardID.NIBIRU)); + List cost_candidates = new List(); + + if (Bot.HasInHand(CardID.CHANDRAGLIER) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.CHANDRAGLIER)).Count() > 1) + cost_candidates.Add(CardID.CHANDRAGLIER); + else if (Bot.HasInHand(CardID.LOVELY_LABRYNTH)) + cost_candidates.Add(CardID.LOVELY_LABRYNTH); + else if (Bot.HasInHand(CardID.LABRYNTH_LABYRINTH) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.LABRYNTH_LABYRINTH)).Count() > 1) + cost_candidates.Add(CardID.LABRYNTH_LABYRINTH); + else if (Bot.HasInHand(CardID.STOVIE_TORBIE) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.STOVIE_TORBIE)).Count() > 1) + cost_candidates.Add(CardID.LABRYNTH_LABYRINTH); + else if (Duel.Turn > 2) + cost_candidates.Add(CardID.NIBIRU); + else cost_candidates.AddRange(new List() { CardID.POT_OF_PROSPERITY }); // Get the next Labrynth spell and trap if (cost_candidates.Count() > 0) { - AI.SelectCard(cost_candidates.Select(x => x.Id).ToArray()); + AI.SelectCard(cost_candidates); if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH) && Bot.MonsterZone.GetMatchingCards(card => card.HasType(CardType.Monster)).Count() > 1) AI.SelectNextCard(CardID.WELCOME_LABYRINTH); From 4c08f20a978e043722e8e217ddaae0b47f91f2bf Mon Sep 17 00:00:00 2001 From: jdistro07 Date: Tue, 12 Dec 2023 22:49:29 +0800 Subject: [PATCH 04/21] Improvements: 1. Dogmatika Punishment behaviour 2. Furniture behaviours. 3. Ntss targeting To fix: 1. excessive usage of Field Spell 2. Field spell destroy one card behaviour 3, Welcome Labrynth over-commiting behaviour --- Game/AI/Decks/BudgetLabrynths.cs | 102 ++++++++++++++++++------------- 1 file changed, 61 insertions(+), 41 deletions(-) diff --git a/Game/AI/Decks/BudgetLabrynths.cs b/Game/AI/Decks/BudgetLabrynths.cs index 811ecdff..47b0ebf8 100644 --- a/Game/AI/Decks/BudgetLabrynths.cs +++ b/Game/AI/Decks/BudgetLabrynths.cs @@ -1,6 +1,7 @@ using Microsoft.Win32; using System; using System.Collections.Generic; +using System.Diagnostics.Eventing.Reader; using System.Linq; using System.Runtime.Remoting.Messaging; using System.Security.Policy; @@ -37,10 +38,13 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardID.COOCLOCK, CooclockEffect); - AddExecutor(ExecutorType.Summon, CardID.ARIANNA, AriannaSummon); + AddExecutor(ExecutorType.Summon, CardID.ARIANNA); AddExecutor(ExecutorType.Activate, CardID.ARIANNA, AriannaEffect); AddExecutor(ExecutorType.Repos, CardID.ARIANNA, AriannaRepos); + AddExecutor(ExecutorType.SpSummon, CardID.MUCKRACKER, MuckarackerLinkSummon); + AddExecutor(ExecutorType.Activate, CardID.MUCKRACKER, MuckarackerEffect); + AddExecutor(ExecutorType.SpellSet, CardID.DOGMATIKA_PUNISHMENT, DogmatikaSet); AddExecutor(ExecutorType.Activate, CardID.DOGMATIKA_PUNISHMENT, DogmatikaPunishmentActivate); @@ -51,9 +55,6 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardID.LOVELY_LABRYNTH, LovelyLabrynthEffect); - AddExecutor(ExecutorType.Summon, CardID.MUCKRACKER, MuckarackerLinkSummon); - AddExecutor(ExecutorType.Activate, CardID.MUCKRACKER, MuckarackerEffect); - AddExecutor(ExecutorType.Activate, CardID.ASH_BLOSSOM, AshBlossomActivate); AddExecutor(ExecutorType.SpellSet, CardID.COMPULSORY_EVACUATION_DEVICE, CompulsoryEvacDeviceSet); @@ -85,14 +86,6 @@ private bool CompulsoryEvacDeviceSet() return false; } - private bool AriannaSummon() - { - ClientCard threatCard = Util.GetProblematicEnemyMonster(); - - if (threatCard != null && Util.IsAllEnemyBetter()) return false; - else return true; - } - private bool DogmatikaSet() { ClientCard problemMonster = Util.GetProblematicEnemyMonster(); @@ -123,7 +116,7 @@ private bool AriannaRepos() private bool WindPegasusIngisterEffect() { - ClientCard card = Util.GetBestEnemyCard(); + ClientCard card = Util.GetBestEnemyMonster(); if (card != null) { @@ -158,19 +151,36 @@ private bool LabrynthLabyrinthActivate() if (ActivateDescription == Util.GetStringId(CardID.LABRYNTH_LABYRINTH, 0)) { // Labrynth Labyrinth add effect when Welcome Labrynth is activated - if (Duel.LastChainPlayer == 0 - && Util.GetLastChainCard().IsCode(CardID.WELCOME_LABYRINTH) - && Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH) - && Enemy.GetFieldCount() > 0 - ) + if (Card.Controller == 0 && Util.GetLastChainCard() != null) { - AI.SelectYesNo(true); + if (Util.GetLastChainCard().IsCode(CardID.WELCOME_LABYRINTH) && Bot.GetFieldCount() > 0) + { + AI.SelectYesNo(true); + + ClientCard problemCard = Util.GetBestEnemyCard(); + + if (problemCard != null) AI.SelectNextCard(problemCard); + } + else + AI.SelectYesNo(false); - ClientCard backrow_problem = Util.GetBestEnemySpell(); - ClientCard monster_target = Util.GetProblematicEnemyMonster(); - if (backrow_problem != null) AI.SelectNextCard(backrow_problem); - else AI.SelectNextCard(monster_target); + } + else if (Card.Controller == 0 && Util.GetLastChainCard() != null) + { + if (Util.GetLastChainCard().IsCode(CardID.COMPULSORY_EVACUATION_DEVICE)) + { + List prefferedMonsters = new List(); + + if (Bot.HasInMonstersZone(CardID.LADY_LABRYNTH) && Bot.HasInHandOrInGraveyard(CardID.LOVELY_LABRYNTH)) + prefferedMonsters.Add(CardID.LOVELY_LABRYNTH); + else if (Bot.HasInMonstersZone(CardID.LOVELY_LABRYNTH) && Bot.HasInGraveyard(CardID.LADY_LABRYNTH)) + prefferedMonsters.Add(CardID.LADY_LABRYNTH); + else if (!Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardID.LOVELY_LABRYNTH) && !Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardID.LADY_LABRYNTH)) + prefferedMonsters.AddRange(new List { CardID.ARIANNA, CardID.STOVIE_TORBIE, CardID.CHANDRAGLIER }); + + AI.SelectCard(prefferedMonsters); + } } else return false; } @@ -187,7 +197,7 @@ private bool LabrynthLabyrinthActivate() private bool SpellActivate() { - return Card.Location == CardLocation.Hand || (Card.Location == CardLocation.SpellZone && Card.IsFacedown()); + return Card.Location == CardLocation.Hand || (Card.Location == CardLocation.SpellZone && Card.IsFacedown()) && !Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH); } private bool MuckarackerEffect() @@ -283,7 +293,11 @@ private bool LadyLabrynthActivate() || card.HasPosition(CardPosition.FaceDown) ); - if (!Bot.HasInMonstersZone(CardID.LOVELY_LABRYNTH)) AI.SelectCard(CardID.WELCOME_LABYRINTH); + if (!Bot.HasInMonstersZone(CardID.LOVELY_LABRYNTH)) + { + if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH)) AI.SelectCard(CardID.WELCOME_LABYRINTH); + else AI.SelectCard(CardID.ERADICATOR_EPIDEMIC_VIRUS); + } else if (enemySpellZone.Count() > 1 && Bot.HasInMonstersZone(CardID.LOVELY_LABRYNTH)) AI.SelectCard(CardID.ERADICATOR_EPIDEMIC_VIRUS); else AI.SelectCard(prefferedTraps); @@ -301,17 +315,9 @@ private bool DogmatikaPunishmentActivate() { ClientCard problemMonster = Util.GetProblematicEnemyMonster(); - int[] preffered_cost = new int[] - { - CardID.ELDER_ENTITY_NTSS, - CardID.TRIBRIGADE_ARMS_BUCEPHALUS_II, - CardID.WIND_PEGASUS_IGNISTER, - CardID.COMSIC_BLAZAR_DRAGON - }; - if (problemMonster != null) { - if(Enemy.GetFieldCount() > 0) + if(Enemy.IsFieldEmpty()) AI.SelectCard(CardID.ELDER_ENTITY_NTSS); else AI.SelectCard(CardID.WIND_PEGASUS_IGNISTER); @@ -351,14 +357,24 @@ private bool StovieTorbieEffect() { AI.SelectCard(cost_candidates); - if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH) && Bot.MonsterZone.GetMatchingCards(card => card.HasType(CardType.Monster)).Count() > 1) + if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH)) AI.SelectNextCard(CardID.WELCOME_LABYRINTH); else AI.SelectNextCard(CardID.LABRYNTH_LABYRINTH); return true; } - } else if(Card.Location == CardLocation.Grave) return true; + } + else if (Card.Location == CardLocation.Grave) + { + if (Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH)) + return true; + } + else if (Card.Location == CardLocation.MonsterZone) + { + if (Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH)) + return true; + } return false; } @@ -370,7 +386,7 @@ public override void OnNewTurn() public override CardPosition OnSelectPosition(int cardId, IList positions) { - if (cardId == 27204312 || cardId == CardID.STOVIE_TORBIE || cardId == CardID.ARIANNA) + if (cardId == 27204312 || cardId == CardID.STOVIE_TORBIE) { return CardPosition.FaceUpDefence; } @@ -378,6 +394,11 @@ public override CardPosition OnSelectPosition(int cardId, IList po { return CardPosition.FaceUpAttack; } + else if ((cardId == CardID.ARIANNA || cardId == CardID.CHANDRAGLIER) && !Util.IsAllEnemyBetter()) + { + return CardPosition.FaceUpAttack; + } + return base.OnSelectPosition(cardId, positions); } @@ -448,11 +469,10 @@ public bool WelcomeLabrynthActivate() if (Bot.HasInHandOrHasInMonstersZone(CardID.LADY_LABRYNTH)) preferred_Monsters.Add(CardID.LOVELY_LABRYNTH); - else if (Bot.HasInHandOrInGraveyard(CardID.LOVELY_LABRYNTH) || Bot.HasInHandOrHasInMonstersZone(CardID.LOVELY_LABRYNTH)) + else if (Bot.HasInHandOrInGraveyard(CardID.LOVELY_LABRYNTH) || !Bot.HasInHandOrHasInMonstersZone(CardID.LOVELY_LABRYNTH) || Bot.MonsterZone.GetMatchingCards(card => card.HasType(CardType.Monster)).Count() == 0) preferred_Monsters.Add(CardID.LADY_LABRYNTH); else if (Bot.HasInMonstersZone(CardID.LADY_LABRYNTH) || Bot.HasInMonstersZone(CardID.LOVELY_LABRYNTH)) preferred_Monsters.Add(CardID.ARIANNA); - else preferred_Monsters.AddRange(new List { CardID.STOVIE_TORBIE }); AI.SelectCard(preferred_Monsters); @@ -490,7 +510,7 @@ public bool CooclockEffect() || card.IsCode(CardID.CHANDRAGLIER) ); - if (Card.Location == CardLocation.Hand || Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH)) return true; + if (Card.Location == CardLocation.Hand || Bot.HasInSpellZone(CardID.WELCOME_LABYRINTH)) return true; else if (Card.Location == CardLocation.Grave) return true; return false; @@ -520,7 +540,7 @@ public bool ChandraglierEffect() { AI.SelectCard(cost_candidates); - if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH) && Bot.MonsterZone.GetMatchingCards(card => card.HasType(CardType.Monster)).Count() > 1) + if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH)) AI.SelectNextCard(CardID.WELCOME_LABYRINTH); else AI.SelectNextCard(CardID.LABRYNTH_LABYRINTH); From ddf5c92d089bb5ef7b20e6aa66f79a9699aaabe8 Mon Sep 17 00:00:00 2001 From: jdistro07 Date: Wed, 13 Dec 2023 22:31:06 +0800 Subject: [PATCH 05/21] -Improvement to added effect on welcome Labrynth -improvement to Cooclock --- Game/AI/Decks/BudgetLabrynths.cs | 161 +++++++++++++++++-------------- 1 file changed, 86 insertions(+), 75 deletions(-) diff --git a/Game/AI/Decks/BudgetLabrynths.cs b/Game/AI/Decks/BudgetLabrynths.cs index 47b0ebf8..ce46f359 100644 --- a/Game/AI/Decks/BudgetLabrynths.cs +++ b/Game/AI/Decks/BudgetLabrynths.cs @@ -33,11 +33,11 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.Summon, CardID.CHANDRAGLIER, ChandraglierSummon); AddExecutor(ExecutorType.Activate, CardID.CHANDRAGLIER, ChandraglierEffect); + AddExecutor(ExecutorType.Activate, CardID.COOCLOCK, CooclockEffect); + AddExecutor(ExecutorType.SpellSet, CardID.WELCOME_LABYRINTH); AddExecutor(ExecutorType.Activate, CardID.WELCOME_LABYRINTH, WelcomeLabrynthActivate); - AddExecutor(ExecutorType.Activate, CardID.COOCLOCK, CooclockEffect); - AddExecutor(ExecutorType.Summon, CardID.ARIANNA); AddExecutor(ExecutorType.Activate, CardID.ARIANNA, AriannaEffect); AddExecutor(ExecutorType.Repos, CardID.ARIANNA, AriannaRepos); @@ -71,6 +71,8 @@ public BudgetLabrynths(GameAI ai, Duel duel) } private bool LadyLabrynthActivated = false; + private bool WelcomeLabrynthActivated = false; + private bool CompulsoryEvacDeviceSet() { @@ -131,14 +133,17 @@ private bool EradicatorActivate() { if (Bot.SpellZone.GetMatchingCards(card => card.IsCode(CardID.LABRYNTH_LABYRINTH) && card.IsFaceup()).Count() > 0) { + ClientCard target = Util.GetBestEnemySpell(); + + // Tribute AI.SelectCard(CardID.LADY_LABRYNTH); + + if (target.HasType(CardType.Spell)) AI.SelectOption(0); + else AI.SelectOption(1); + return true; } - else - { - AI.SelectCard(CardID.LADY_LABRYNTH); - return true; - } + else return false; } private bool ChandraglierSummon() @@ -148,91 +153,63 @@ private bool ChandraglierSummon() private bool LabrynthLabyrinthActivate() { - if (ActivateDescription == Util.GetStringId(CardID.LABRYNTH_LABYRINTH, 0)) - { - // Labrynth Labyrinth add effect when Welcome Labrynth is activated - if (Card.Controller == 0 && Util.GetLastChainCard() != null) - { - if (Util.GetLastChainCard().IsCode(CardID.WELCOME_LABYRINTH) && Bot.GetFieldCount() > 0) - { - AI.SelectYesNo(true); - - ClientCard problemCard = Util.GetBestEnemyCard(); - - if (problemCard != null) AI.SelectNextCard(problemCard); - } - else - AI.SelectYesNo(false); - - - } - else if (Card.Controller == 0 && Util.GetLastChainCard() != null) - { - if (Util.GetLastChainCard().IsCode(CardID.COMPULSORY_EVACUATION_DEVICE)) - { - List prefferedMonsters = new List(); - - if (Bot.HasInMonstersZone(CardID.LADY_LABRYNTH) && Bot.HasInHandOrInGraveyard(CardID.LOVELY_LABRYNTH)) - prefferedMonsters.Add(CardID.LOVELY_LABRYNTH); - else if (Bot.HasInMonstersZone(CardID.LOVELY_LABRYNTH) && Bot.HasInGraveyard(CardID.LADY_LABRYNTH)) - prefferedMonsters.Add(CardID.LADY_LABRYNTH); - else if (!Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardID.LOVELY_LABRYNTH) && !Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardID.LADY_LABRYNTH)) - prefferedMonsters.AddRange(new List { CardID.ARIANNA, CardID.STOVIE_TORBIE, CardID.CHANDRAGLIER }); - - AI.SelectCard(prefferedMonsters); - } - } - else return false; - } - if (SpellActivate()) return true; - else - { - ClientCard card = Util.GetLastChainCard(); - if (card != null && card.Controller == 0 && card.Id == CardID.LABRYNTH_LABYRINTH) return false; - - return true; - } + else return false; } private bool SpellActivate() { - return Card.Location == CardLocation.Hand || (Card.Location == CardLocation.SpellZone && Card.IsFacedown()) && !Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH); + return Card.Location == CardLocation.Hand || (Card.Location == CardLocation.SpellZone && Card.IsFacedown()) && Bot.GetFieldSpellCard() == null; } private bool MuckarackerEffect() { - int[] bossMonsters = new int[] + if (Duel.Phase == DuelPhase.Main2) { - CardID.LADY_LABRYNTH, - CardID.LOVELY_LABRYNTH - }; + int[] bossMonsters = new int[] + { + CardID.LADY_LABRYNTH, + CardID.LOVELY_LABRYNTH + }; - int[] other_prefferedMonsters = new int[] - { + int[] other_prefferedMonsters = new int[] + { CardID.ARIANNA, CardID.STOVIE_TORBIE - }; + }; - if (Bot.HasInGraveyard(CardID.LOVELY_LABRYNTH) || Bot.HasInGraveyard(CardID.LADY_LABRYNTH)) - { - AI.SelectCard(bossMonsters); - return true; - } - else - { - AI.SelectCard(other_prefferedMonsters); - return true; + if (Bot.HasInGraveyard(CardID.LOVELY_LABRYNTH) || Bot.HasInGraveyard(CardID.LADY_LABRYNTH)) + { + AI.SelectCard(bossMonsters); + return true; + } + else + { + AI.SelectCard(other_prefferedMonsters); + return true; + } } + + return false; } private bool MuckarackerLinkSummon() { - int bot_Monsters = Bot.MonsterZone.GetMatchingCards(card => card.Level < 4).Count(); + int bot_Monsters = Bot.MonsterZone.GetMatchingCards(card => card.Level <= 4).Count(); int bot_HandCards = Bot.Hand.Count(); - if (bot_Monsters >= 2 && bot_HandCards > 1) + int[] materials = new int[] + { + CardID.STOVIE_TORBIE, + CardID.CHANDRAGLIER, + CardID.ARIANNA + }; + + if (bot_HandCards > 2) + { + AI.SelectMaterials(materials); return true; + } return false; } @@ -357,9 +334,9 @@ private bool StovieTorbieEffect() { AI.SelectCard(cost_candidates); - if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH)) + if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH) && Bot.HasInHandOrInSpellZone(CardID.LABRYNTH_LABYRINTH)) AI.SelectNextCard(CardID.WELCOME_LABYRINTH); - else + else if(!Bot.HasInHandOrInSpellZone(CardID.LABRYNTH_LABYRINTH) && Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH)) AI.SelectNextCard(CardID.LABRYNTH_LABYRINTH); return true; @@ -382,6 +359,7 @@ private bool StovieTorbieEffect() public override void OnNewTurn() { LadyLabrynthActivated = false; + WelcomeLabrynthActivated = false; } public override CardPosition OnSelectPosition(int cardId, IList positions) @@ -476,6 +454,30 @@ public bool WelcomeLabrynthActivate() AI.SelectCard(preferred_Monsters); + WelcomeLabrynthActivated = true; + + // Added destroy one card effect by Labrynth Labirynth to Welcome Labrynth + if (Card.Location == CardLocation.SpellZone) + { + if (ActivateDescription == Util.GetStringId(CardID.WELCOME_LABYRINTH, 0)) + { + ClientCard problemCard = Util.GetBestEnemyCard(); + + if (problemCard != null && Enemy.GetFieldCount() > 0) + { + AI.SelectYesNo(true); + AI.SelectNextCard(problemCard); + + return true; + } + else + { + AI.SelectYesNo(false); + return false; + }; + } + } + return true; } @@ -502,6 +504,10 @@ public bool AriannaEffect() public bool CooclockEffect() { + + if (Duel.LastChainPlayer == 0 && (Util.GetLastChainCard().IsCode(CardID.CHANDRAGLIER) || Util.GetLastChainCard().IsCode(CardID.STOVIE_TORBIE))) + return false; + IList faceUp_Monsters = Bot.MonsterZone.GetMatchingCards(card => card.IsCode(CardID.LOVELY_LABRYNTH) || card.IsCode(CardID.LADY_LABRYNTH) @@ -510,8 +516,13 @@ public bool CooclockEffect() || card.IsCode(CardID.CHANDRAGLIER) ); - if (Card.Location == CardLocation.Hand || Bot.HasInSpellZone(CardID.WELCOME_LABYRINTH)) return true; - else if (Card.Location == CardLocation.Grave) return true; + if (Card.Location == CardLocation.Hand || Bot.HasInSpellZone(CardID.WELCOME_LABYRINTH) && !WelcomeLabrynthActivated) return true; + else if (Card.Location == CardLocation.Grave) + { + AI.SelectOption(0); // first dialogue + AI.SelectOption(0); // choose add Cooclock to hand + return true; + }; return false; } @@ -540,7 +551,7 @@ public bool ChandraglierEffect() { AI.SelectCard(cost_candidates); - if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH)) + if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH) && Bot.HasInHandOrInSpellZone(CardID.LABRYNTH_LABYRINTH)) AI.SelectNextCard(CardID.WELCOME_LABYRINTH); else AI.SelectNextCard(CardID.LABRYNTH_LABYRINTH); From 1ac23faf7f7bf94883a02a8e7fa5932bb7a76b1f Mon Sep 17 00:00:00 2001 From: jdistro07 Date: Thu, 14 Dec 2023 21:16:00 +0800 Subject: [PATCH 06/21] Fixes on Field spell activation and prioritization of furnitures of searching field spell from deck. Fixes on Cooclock behaviour --- Game/AI/Decks/BudgetLabrynths.cs | 37 ++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/Game/AI/Decks/BudgetLabrynths.cs b/Game/AI/Decks/BudgetLabrynths.cs index ce46f359..de63e1e9 100644 --- a/Game/AI/Decks/BudgetLabrynths.cs +++ b/Game/AI/Decks/BudgetLabrynths.cs @@ -82,8 +82,8 @@ private bool CompulsoryEvacDeviceSet() { if (problemMonster != null) return true; else if (ProtectLadyLabrynth()) return true; + else if (Bot.GetFieldCount() == 0) return true; } - return false; } @@ -96,6 +96,7 @@ private bool DogmatikaSet() { if (problemMonster != null) return true; else if (problemMonster == null && ProtectLadyLabrynth()) return true; + else if (Bot.GetFieldCount() == 0) return true; } return false; @@ -153,8 +154,13 @@ private bool ChandraglierSummon() private bool LabrynthLabyrinthActivate() { - if (SpellActivate()) return true; - else return false; + //if (SpellActivate()) return true; + //else return false; + + if (!Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH)) return true; + else if (Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH) && Card.Location == CardLocation.SpellZone && Card.IsFacedown()) return true; + + return false; } private bool SpellActivate() @@ -275,8 +281,10 @@ private bool LadyLabrynthActivate() if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH)) AI.SelectCard(CardID.WELCOME_LABYRINTH); else AI.SelectCard(CardID.ERADICATOR_EPIDEMIC_VIRUS); } - else if (enemySpellZone.Count() > 1 && Bot.HasInMonstersZone(CardID.LOVELY_LABRYNTH)) AI.SelectCard(CardID.ERADICATOR_EPIDEMIC_VIRUS); - else AI.SelectCard(prefferedTraps); + else if (enemySpellZone.Count() > 1 && Bot.HasInMonstersZone(CardID.LOVELY_LABRYNTH)) + AI.SelectCard(CardID.ERADICATOR_EPIDEMIC_VIRUS); + else + AI.SelectCard(prefferedTraps); LadyLabrynthActivated = true; @@ -336,10 +344,13 @@ private bool StovieTorbieEffect() if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH) && Bot.HasInHandOrInSpellZone(CardID.LABRYNTH_LABYRINTH)) AI.SelectNextCard(CardID.WELCOME_LABYRINTH); - else if(!Bot.HasInHandOrInSpellZone(CardID.LABRYNTH_LABYRINTH) && Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH)) + else if (Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH) && Bot.HasInHandOrInSpellZone(CardID.LABRYNTH_LABYRINTH)) + return false; + else + { AI.SelectNextCard(CardID.LABRYNTH_LABYRINTH); - - return true; + return true; + } } } else if (Card.Location == CardLocation.Grave) @@ -364,7 +375,7 @@ public override void OnNewTurn() public override CardPosition OnSelectPosition(int cardId, IList positions) { - if (cardId == 27204312 || cardId == CardID.STOVIE_TORBIE) + if (cardId == 27204312 || cardId == CardID.STOVIE_TORBIE || cardId == CardID.COOCLOCK) { return CardPosition.FaceUpDefence; } @@ -553,13 +564,17 @@ public bool ChandraglierEffect() if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH) && Bot.HasInHandOrInSpellZone(CardID.LABRYNTH_LABYRINTH)) AI.SelectNextCard(CardID.WELCOME_LABYRINTH); + else if (Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH) && Bot.HasInHandOrInSpellZone(CardID.LABRYNTH_LABYRINTH)) + return false; else + { AI.SelectNextCard(CardID.LABRYNTH_LABYRINTH); - - return true; + return true; + } } } else if (Card.Location == CardLocation.Grave) return true; + else if (Card.Location == CardLocation.MonsterZone && Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH)) return true; return false; } From 6a91b80d41567c4e0cce80717dfae295b9d02cc0 Mon Sep 17 00:00:00 2001 From: jdistro07 Date: Sat, 16 Dec 2023 00:18:56 +0800 Subject: [PATCH 07/21] -Fixes on PR issues -Fixed bot wasting FIeld spells -Fixes on Cooclock -Added Knightmare Pheonix executor -Fixes on Muckracker -Improvements on Eradicator abuse -Utilized default executors for Ash and Solemn Strike -Furniture activation behaviour improvements --- Game/AI/Decks/BudgetLabrynths.cs | 274 +++++++++++++++++++++---------- WindBot.csproj | 2 - WindBot.sln | 4 +- libWindbot.csproj | 3 + 4 files changed, 194 insertions(+), 89 deletions(-) diff --git a/Game/AI/Decks/BudgetLabrynths.cs b/Game/AI/Decks/BudgetLabrynths.cs index de63e1e9..633d2b92 100644 --- a/Game/AI/Decks/BudgetLabrynths.cs +++ b/Game/AI/Decks/BudgetLabrynths.cs @@ -1,16 +1,6 @@ -using Microsoft.Win32; using System; using System.Collections.Generic; -using System.Diagnostics.Eventing.Reader; using System.Linq; -using System.Runtime.Remoting.Messaging; -using System.Security.Policy; -using System.Text; -using System.Web.Management; -using WindBot; -using WindBot.Game; -using WindBot.Game.AI; -using YGOSharp.OCGWrapper; using YGOSharp.OCGWrapper.Enums; namespace WindBot.Game.AI.Decks @@ -28,16 +18,18 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardID.POT_OF_PROSPERITY); // TODO - AddExecutor(ExecutorType.Activate, CardID.STOVIE_TORBIE, StovieTorbieEffect); - - AddExecutor(ExecutorType.Summon, CardID.CHANDRAGLIER, ChandraglierSummon); - AddExecutor(ExecutorType.Activate, CardID.CHANDRAGLIER, ChandraglierEffect); + AddExecutor(ExecutorType.Activate, CardID.LABRYNTH_LABYRINTH, LabrynthLabyrinthActivate); AddExecutor(ExecutorType.Activate, CardID.COOCLOCK, CooclockEffect); AddExecutor(ExecutorType.SpellSet, CardID.WELCOME_LABYRINTH); AddExecutor(ExecutorType.Activate, CardID.WELCOME_LABYRINTH, WelcomeLabrynthActivate); + AddExecutor(ExecutorType.Activate, CardID.STOVIE_TORBIE, StovieTorbieEffect); + + AddExecutor(ExecutorType.Summon, CardID.CHANDRAGLIER, ChandraglierSummon); + AddExecutor(ExecutorType.Activate, CardID.CHANDRAGLIER, ChandraglierEffect); + AddExecutor(ExecutorType.Summon, CardID.ARIANNA); AddExecutor(ExecutorType.Activate, CardID.ARIANNA, AriannaEffect); AddExecutor(ExecutorType.Repos, CardID.ARIANNA, AriannaRepos); @@ -48,31 +40,107 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.SpellSet, CardID.DOGMATIKA_PUNISHMENT, DogmatikaSet); AddExecutor(ExecutorType.Activate, CardID.DOGMATIKA_PUNISHMENT, DogmatikaPunishmentActivate); - AddExecutor(ExecutorType.Activate, CardID.LABRYNTH_LABYRINTH, LabrynthLabyrinthActivate); - AddExecutor(ExecutorType.Activate, CardID.LADY_LABRYNTH, LadyLabrynthActivate); AddExecutor(ExecutorType.Repos, CardID.LADY_LABRYNTH, LadyLabrynthRepos); AddExecutor(ExecutorType.Activate, CardID.LOVELY_LABRYNTH, LovelyLabrynthEffect); - AddExecutor(ExecutorType.Activate, CardID.ASH_BLOSSOM, AshBlossomActivate); + AddExecutor(ExecutorType.Activate, CardID.ASH_BLOSSOM, DefaultAshBlossomAndJoyousSpring); AddExecutor(ExecutorType.SpellSet, CardID.COMPULSORY_EVACUATION_DEVICE, CompulsoryEvacDeviceSet); AddExecutor(ExecutorType.Activate, CardID.COMPULSORY_EVACUATION_DEVICE, CompulsoryEvacuationDeviceActivate); AddExecutor(ExecutorType.SpellSet, CardID.SOLEMN_STRIKE); - AddExecutor(ExecutorType.Activate, CardID.SOLEMN_STRIKE, SolemnStrikeActivate); + AddExecutor(ExecutorType.Activate, CardID.SOLEMN_STRIKE, DefaultSolemnStrike); AddExecutor(ExecutorType.SpellSet, CardID.ERADICATOR_EPIDEMIC_VIRUS, EradicatorSet); AddExecutor(ExecutorType.Activate, CardID.ERADICATOR_EPIDEMIC_VIRUS, EradicatorActivate); AddExecutor(ExecutorType.Activate, CardID.WIND_PEGASUS_IGNISTER, WindPegasusIngisterEffect); AddExecutor(ExecutorType.Activate, CardID.ELDER_ENTITY_NTSS, ElderEntityNtssEffect); + + AddExecutor(ExecutorType.SpSummon, CardID.KNIGHTMARE_PHEONIX, KnightmarePheonix_LinkSummon); + AddExecutor(ExecutorType.SpSummon, CardID.KNIGHTMARE_PHEONIX, KnightmarePheonix_Effect); + } + + private bool KnightmarePheonix_Effect() + { + List cost = PrefferedDiscardCost(); + + ClientCard target = Util.GetBestEnemySpell(); + + if (target != null) + { + AI.SelectCard(cost); // discard cost + AI.SelectNextCard(target); + + return true; + } + + return false; + } + + private bool KnightmarePheonix_LinkSummon() + { + if(!Bot.HasInHandOrInSpellZoneOrInGraveyard(CardID.ERADICATOR_EPIDEMIC_VIRUS) && Util.GetBestEnemySpell() != null && Duel.Phase == DuelPhase.Main2) + return false; + + if(Bot.MonsterZone.GetMatchingCards(card => card.Level <= 4).Count() < 2) + return false; + + int[] materials = new int[] + { + CardID.STOVIE_TORBIE, + CardID.CHANDRAGLIER, + CardID.ARIANNA, + CardID.COOCLOCK + }; + + AI.SelectMaterials(materials); + + return true; } private bool LadyLabrynthActivated = false; private bool WelcomeLabrynthActivated = false; + private List PrefferedDiscardCost() + { + List cost_candidates = new List(); + + if (Bot.HasInHand(CardID.CHANDRAGLIER) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.CHANDRAGLIER)).Count() > 1) + cost_candidates.Add(CardID.CHANDRAGLIER); + else if (Bot.HasInHand(CardID.LOVELY_LABRYNTH)) + cost_candidates.Add(CardID.LOVELY_LABRYNTH); + else if (Bot.HasInHand(CardID.LABRYNTH_LABYRINTH) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.LABRYNTH_LABYRINTH)).Count() > 1) + cost_candidates.Add(CardID.LABRYNTH_LABYRINTH); + else if (Bot.HasInHand(CardID.STOVIE_TORBIE) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.STOVIE_TORBIE)).Count() > 1) + cost_candidates.Add(CardID.LABRYNTH_LABYRINTH); + else if (Duel.Turn > 2) + cost_candidates.Add(CardID.NIBIRU); + else cost_candidates.AddRange(new List() { CardID.POT_OF_PROSPERITY }); + + return cost_candidates; + } + + private int EradicatorOption() + { + int hand_enemySpells = Enemy.Hand.GetMatchingCards(card => card.HasType(CardType.Spell)).Count(); + int deck_enemySpells = Enemy.Deck.GetMatchingCards(card => card.HasType(CardType.Spell)).Count(); + int grave_enemySpells = Enemy.Graveyard.GetMatchingCards(card => card.HasType(CardType.Spell)).Count(); + + + int hand_enemyTraps = Enemy.Hand.GetMatchingCards(card => card.HasType(CardType.Trap)).Count(); + int deck_enemyTraps = Enemy.Deck.GetMatchingCards(card => card.HasType(CardType.Trap)).Count(); + int grave_enemyTraps = Enemy.Graveyard.GetMatchingCards(card => card.HasType(CardType.Trap)).Count(); + + + int overallSpells = hand_enemySpells + deck_enemySpells + grave_enemySpells; + int overallTraps = hand_enemyTraps + deck_enemyTraps + grave_enemyTraps; + + if (overallSpells > overallTraps) return 0; // Spells + else return 1; // Traps + } private bool CompulsoryEvacDeviceSet() { @@ -80,9 +148,8 @@ private bool CompulsoryEvacDeviceSet() if (!Bot.HasInSpellZone(CardID.DOGMATIKA_PUNISHMENT)) { - if (problemMonster != null) return true; - else if (ProtectLadyLabrynth()) return true; - else if (Bot.GetFieldCount() == 0) return true; + if (problemMonster != null || ProtectLadyLabrynth() || Bot.GetFieldCount() == 0) + return true; } return false; @@ -132,15 +199,23 @@ private bool WindPegasusIngisterEffect() private bool EradicatorActivate() { - if (Bot.SpellZone.GetMatchingCards(card => card.IsCode(CardID.LABRYNTH_LABYRINTH) && card.IsFaceup()).Count() > 0) + if (Bot.HasInMonstersZone(CardID.LADY_LABRYNTH)) { ClientCard target = Util.GetBestEnemySpell(); // Tribute AI.SelectCard(CardID.LADY_LABRYNTH); - if (target.HasType(CardType.Spell)) AI.SelectOption(0); - else AI.SelectOption(1); + if (target != null) + { + if (target.HasType(CardType.Spell)) AI.SelectOption(0); + else AI.SelectOption(1); + } + else // if there are no backrows, decide if their build is more on spells or traps + { + int option = EradicatorOption(); + AI.SelectOption(option); + } return true; } @@ -149,54 +224,56 @@ private bool EradicatorActivate() private bool ChandraglierSummon() { - return Bot.HasInHand(CardID.COOCLOCK) && Bot.HasInSpellZone(CardID.WELCOME_LABYRINTH); + if (Bot.Deck.GetMatchingCards(card => card.IsCode(CardID.WELCOME_LABYRINTH)).Count() == 0) + return true; + + return false; } private bool LabrynthLabyrinthActivate() { - //if (SpellActivate()) return true; - //else return false; + if (Card.Location == CardLocation.SpellZone && Card.IsFaceup()) // special summon labrynth monster effect + { + if (ActivateDescription == Util.GetStringId(CardID.LABRYNTH_LABYRINTH, 0)) + { + if (Bot.HasInGraveyard(CardID.LOVELY_LABRYNTH)) + AI.SelectCard(CardID.LOVELY_LABRYNTH); + else if((Bot.HasInGraveyard(CardID.LADY_LABRYNTH))) + AI.SelectCard(CardID.LADY_LABRYNTH); - if (!Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH)) return true; - else if (Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH) && Card.Location == CardLocation.SpellZone && Card.IsFacedown()) return true; + return true; + } - return false; - } + return false; + } + else + { + if (!Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH)) return true; + else if (Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH) && Card.Location == CardLocation.SpellZone && Card.IsFacedown()) return true; - private bool SpellActivate() - { - return Card.Location == CardLocation.Hand || (Card.Location == CardLocation.SpellZone && Card.IsFacedown()) && Bot.GetFieldSpellCard() == null; + return false; + } } private bool MuckarackerEffect() { - if (Duel.Phase == DuelPhase.Main2) + int[] prefferedMonsters = new int[] { - int[] bossMonsters = new int[] - { - CardID.LADY_LABRYNTH, - CardID.LOVELY_LABRYNTH - }; + CardID.LOVELY_LABRYNTH, + CardID.LADY_LABRYNTH + }; - int[] other_prefferedMonsters = new int[] - { - CardID.ARIANNA, - CardID.STOVIE_TORBIE - }; + List cost = PrefferedDiscardCost(); + + if (cost.Count() > 0 && Bot.HasInGraveyard(CardID.LADY_LABRYNTH) || Bot.HasInGraveyard(CardID.LOVELY_LABRYNTH)) + { + AI.SelectCard(prefferedMonsters); + AI.SelectNextCard(cost); + + return true; + } else return false; - if (Bot.HasInGraveyard(CardID.LOVELY_LABRYNTH) || Bot.HasInGraveyard(CardID.LADY_LABRYNTH)) - { - AI.SelectCard(bossMonsters); - return true; - } - else - { - AI.SelectCard(other_prefferedMonsters); - return true; - } - } - return false; } private bool MuckarackerLinkSummon() @@ -208,10 +285,11 @@ private bool MuckarackerLinkSummon() { CardID.STOVIE_TORBIE, CardID.CHANDRAGLIER, - CardID.ARIANNA + CardID.ARIANNA, + CardID.COOCLOCK }; - if (bot_HandCards > 2) + if (bot_HandCards >= 1 && !Bot.HasInMonstersZone(CardID.MUCKRACKER)) { AI.SelectMaterials(materials); return true; @@ -276,15 +354,9 @@ private bool LadyLabrynthActivate() || card.HasPosition(CardPosition.FaceDown) ); - if (!Bot.HasInMonstersZone(CardID.LOVELY_LABRYNTH)) - { - if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH)) AI.SelectCard(CardID.WELCOME_LABYRINTH); - else AI.SelectCard(CardID.ERADICATOR_EPIDEMIC_VIRUS); - } - else if (enemySpellZone.Count() > 1 && Bot.HasInMonstersZone(CardID.LOVELY_LABRYNTH)) + if(!Bot.HasInHandOrInSpellZoneOrInGraveyard(CardID.ERADICATOR_EPIDEMIC_VIRUS)) AI.SelectCard(CardID.ERADICATOR_EPIDEMIC_VIRUS); - else - AI.SelectCard(prefferedTraps); + else AI.SelectCard(prefferedTraps); LadyLabrynthActivated = true; @@ -302,7 +374,7 @@ private bool DogmatikaPunishmentActivate() if (problemMonster != null) { - if(Enemy.IsFieldEmpty()) + if(!Enemy.IsFieldEmpty() && Enemy.GetFieldCount() > 1) AI.SelectCard(CardID.ELDER_ENTITY_NTSS); else AI.SelectCard(CardID.WIND_PEGASUS_IGNISTER); @@ -342,11 +414,12 @@ private bool StovieTorbieEffect() { AI.SelectCard(cost_candidates); - if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH) && Bot.HasInHandOrInSpellZone(CardID.LABRYNTH_LABYRINTH)) + if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH)) + { AI.SelectNextCard(CardID.WELCOME_LABYRINTH); - else if (Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH) && Bot.HasInHandOrInSpellZone(CardID.LABRYNTH_LABYRINTH)) - return false; - else + return true; + } + else if (!Bot.HasInHandOrInSpellZone(CardID.LABRYNTH_LABYRINTH)) { AI.SelectNextCard(CardID.LABRYNTH_LABYRINTH); return true; @@ -361,7 +434,21 @@ private bool StovieTorbieEffect() else if (Card.Location == CardLocation.MonsterZone) { if (Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH)) + { + int remaining_welcomes = Bot.Deck.GetMatchingCards(card => card.IsCode(CardID.WELCOME_LABYRINTH)).Count(); + + if (remaining_welcomes > 0) + { + AI.SelectNextCard(CardID.WELCOME_LABYRINTH); + return true; + } + else return false; + } + else + { + AI.SelectNextCard(CardID.LABRYNTH_LABYRINTH); return true; + } } return false; @@ -398,7 +485,7 @@ private bool SolemnStrikeActivate() if(Duel.LastChainPlayer == 0) return false; - if (problemCard != null) + if (problemCard != null && Duel.LastChainPlayer == 1) return true; return false; @@ -437,13 +524,11 @@ private bool CompulsoryEvacuationDeviceActivate() return false; } + AI.SelectCard(enemyBestMonster); + return true; } - - - - return false; } @@ -456,7 +541,7 @@ public bool WelcomeLabrynthActivate() { List preferred_Monsters = new List(); - if (Bot.HasInHandOrHasInMonstersZone(CardID.LADY_LABRYNTH)) + if (Bot.HasInHandOrHasInMonstersZone(CardID.LADY_LABRYNTH) || Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardID.LADY_LABRYNTH)) preferred_Monsters.Add(CardID.LOVELY_LABRYNTH); else if (Bot.HasInHandOrInGraveyard(CardID.LOVELY_LABRYNTH) || !Bot.HasInHandOrHasInMonstersZone(CardID.LOVELY_LABRYNTH) || Bot.MonsterZone.GetMatchingCards(card => card.HasType(CardType.Monster)).Count() == 0) preferred_Monsters.Add(CardID.LADY_LABRYNTH); @@ -516,7 +601,7 @@ public bool AriannaEffect() public bool CooclockEffect() { - if (Duel.LastChainPlayer == 0 && (Util.GetLastChainCard().IsCode(CardID.CHANDRAGLIER) || Util.GetLastChainCard().IsCode(CardID.STOVIE_TORBIE))) + if (Duel.Player != 0 && Duel.Phase != DuelPhase.Main1) return false; IList faceUp_Monsters = Bot.MonsterZone.GetMatchingCards(card => @@ -527,7 +612,8 @@ public bool CooclockEffect() || card.IsCode(CardID.CHANDRAGLIER) ); - if (Card.Location == CardLocation.Hand || Bot.HasInSpellZone(CardID.WELCOME_LABYRINTH) && !WelcomeLabrynthActivated) return true; + if (Card.Location == CardLocation.Hand || Bot.HasInSpellZone(CardID.WELCOME_LABYRINTH) && !WelcomeLabrynthActivated && Duel.Phase == DuelPhase.Main1) + return true; else if (Card.Location == CardLocation.Grave) { AI.SelectOption(0); // first dialogue @@ -562,11 +648,12 @@ public bool ChandraglierEffect() { AI.SelectCard(cost_candidates); - if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH) && Bot.HasInHandOrInSpellZone(CardID.LABRYNTH_LABYRINTH)) + if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH)) + { AI.SelectNextCard(CardID.WELCOME_LABYRINTH); - else if (Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH) && Bot.HasInHandOrInSpellZone(CardID.LABRYNTH_LABYRINTH)) - return false; - else + return true; + } + else if (!Bot.HasInHandOrInSpellZone(CardID.LABRYNTH_LABYRINTH)) { AI.SelectNextCard(CardID.LABRYNTH_LABYRINTH); return true; @@ -574,7 +661,24 @@ public bool ChandraglierEffect() } } else if (Card.Location == CardLocation.Grave) return true; - else if (Card.Location == CardLocation.MonsterZone && Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH)) return true; + else if (Card.Location == CardLocation.MonsterZone) + { + if (Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH)) + { + int remaining_welcomes = Bot.Deck.GetMatchingCards(card => card.IsCode(CardID.WELCOME_LABYRINTH)).Count(); + + if (remaining_welcomes > 0) + { + AI.SelectNextCard(CardID.WELCOME_LABYRINTH); + return true; + } else return false; + } + else + { + AI.SelectNextCard(CardID.LABRYNTH_LABYRINTH); + return true; + } + }; return false; } diff --git a/WindBot.csproj b/WindBot.csproj index 74ec951e..5fc87aed 100644 --- a/WindBot.csproj +++ b/WindBot.csproj @@ -139,8 +139,6 @@ PreserveNewest - - PreserveNewest diff --git a/WindBot.sln b/WindBot.sln index ab5ded86..20b5494c 100644 --- a/WindBot.sln +++ b/WindBot.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.8.34316.72 +# Visual Studio Version 15 +VisualStudioVersion = 15.0.28307.960 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindBot", "WindBot.csproj", "{3E7FAF67-A27D-4A61-B161-93AD4414183E}" EndProject diff --git a/libWindbot.csproj b/libWindbot.csproj index 87a79a85..e5d226d8 100644 --- a/libWindbot.csproj +++ b/libWindbot.csproj @@ -45,6 +45,9 @@ + + + From 3dc5f2543834e054c50e7543c7c65203c4cd1e07 Mon Sep 17 00:00:00 2001 From: jdistro07 Date: Sat, 16 Dec 2023 00:42:52 +0800 Subject: [PATCH 08/21] Removed duplicate Deck.cs on libWinbot --- libWindbot.csproj | 2 -- 1 file changed, 2 deletions(-) diff --git a/libWindbot.csproj b/libWindbot.csproj index e5d226d8..1a5735ec 100644 --- a/libWindbot.csproj +++ b/libWindbot.csproj @@ -47,8 +47,6 @@ - - From db9b901a99ca3bf9f2d7ffa7dc2b8c9123536457 Mon Sep 17 00:00:00 2001 From: jdistro07 Date: Sat, 16 Dec 2023 00:45:24 +0800 Subject: [PATCH 09/21] readed ewxecutor to libWinbot --- libWindbot.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/libWindbot.csproj b/libWindbot.csproj index 1a5735ec..0c60b922 100644 --- a/libWindbot.csproj +++ b/libWindbot.csproj @@ -47,6 +47,7 @@ + From 112831942c28050e08f88522db3acabdd2add044 Mon Sep 17 00:00:00 2001 From: jdistro07 Date: Sat, 16 Dec 2023 01:20:22 +0800 Subject: [PATCH 10/21] temporarily removed chages to lib winbot --- libWindbot.csproj | 2 -- 1 file changed, 2 deletions(-) diff --git a/libWindbot.csproj b/libWindbot.csproj index 0c60b922..87a79a85 100644 --- a/libWindbot.csproj +++ b/libWindbot.csproj @@ -45,9 +45,7 @@ - - From e2c0cdf0caa9af1124d7c3f340341ea22d21cf4e Mon Sep 17 00:00:00 2001 From: Edoardo Lolletti Date: Fri, 15 Dec 2023 18:33:59 +0100 Subject: [PATCH 11/21] Update libWindbot.csproj --- libWindbot.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/libWindbot.csproj b/libWindbot.csproj index 87a79a85..66963909 100644 --- a/libWindbot.csproj +++ b/libWindbot.csproj @@ -55,6 +55,7 @@ + From 4fc15691a6a59422222a9f96610dc878b5e5f187 Mon Sep 17 00:00:00 2001 From: Edoardo Lolletti Date: Fri, 15 Dec 2023 18:49:57 +0100 Subject: [PATCH 12/21] Rename CardID to CardId --- Game/AI/Decks/BudgetLabrynths.cs | 302 +++++++++++++++---------------- 1 file changed, 151 insertions(+), 151 deletions(-) diff --git a/Game/AI/Decks/BudgetLabrynths.cs b/Game/AI/Decks/BudgetLabrynths.cs index 633d2b92..02a7a7ae 100644 --- a/Game/AI/Decks/BudgetLabrynths.cs +++ b/Game/AI/Decks/BudgetLabrynths.cs @@ -11,56 +11,56 @@ public class BudgetLabrynths : DefaultExecutor public BudgetLabrynths(GameAI ai, Duel duel) : base(ai, duel) { - AddExecutor(ExecutorType.Activate, CardID.NIBIRU); + AddExecutor(ExecutorType.Activate, CardId.NIBIRU); AddExecutor(ExecutorType.GoToBattlePhase, EvenlyMatchedActivate); AddExecutor(ExecutorType.Activate); - AddExecutor(ExecutorType.Activate, CardID.POT_OF_PROSPERITY); // TODO + AddExecutor(ExecutorType.Activate, CardId.POT_OF_PROSPERITY); // TODO - AddExecutor(ExecutorType.Activate, CardID.LABRYNTH_LABYRINTH, LabrynthLabyrinthActivate); + AddExecutor(ExecutorType.Activate, CardId.LABRYNTH_LABYRINTH, LabrynthLabyrinthActivate); - AddExecutor(ExecutorType.Activate, CardID.COOCLOCK, CooclockEffect); + AddExecutor(ExecutorType.Activate, CardId.COOCLOCK, CooclockEffect); - AddExecutor(ExecutorType.SpellSet, CardID.WELCOME_LABYRINTH); - AddExecutor(ExecutorType.Activate, CardID.WELCOME_LABYRINTH, WelcomeLabrynthActivate); + AddExecutor(ExecutorType.SpellSet, CardId.WELCOME_LABYRINTH); + AddExecutor(ExecutorType.Activate, CardId.WELCOME_LABYRINTH, WelcomeLabrynthActivate); - AddExecutor(ExecutorType.Activate, CardID.STOVIE_TORBIE, StovieTorbieEffect); + AddExecutor(ExecutorType.Activate, CardId.STOVIE_TORBIE, StovieTorbieEffect); - AddExecutor(ExecutorType.Summon, CardID.CHANDRAGLIER, ChandraglierSummon); - AddExecutor(ExecutorType.Activate, CardID.CHANDRAGLIER, ChandraglierEffect); + AddExecutor(ExecutorType.Summon, CardId.CHANDRAGLIER, ChandraglierSummon); + AddExecutor(ExecutorType.Activate, CardId.CHANDRAGLIER, ChandraglierEffect); - AddExecutor(ExecutorType.Summon, CardID.ARIANNA); - AddExecutor(ExecutorType.Activate, CardID.ARIANNA, AriannaEffect); - AddExecutor(ExecutorType.Repos, CardID.ARIANNA, AriannaRepos); + AddExecutor(ExecutorType.Summon, CardId.ARIANNA); + AddExecutor(ExecutorType.Activate, CardId.ARIANNA, AriannaEffect); + AddExecutor(ExecutorType.Repos, CardId.ARIANNA, AriannaRepos); - AddExecutor(ExecutorType.SpSummon, CardID.MUCKRACKER, MuckarackerLinkSummon); - AddExecutor(ExecutorType.Activate, CardID.MUCKRACKER, MuckarackerEffect); + AddExecutor(ExecutorType.SpSummon, CardId.MUCKRACKER, MuckarackerLinkSummon); + AddExecutor(ExecutorType.Activate, CardId.MUCKRACKER, MuckarackerEffect); - AddExecutor(ExecutorType.SpellSet, CardID.DOGMATIKA_PUNISHMENT, DogmatikaSet); - AddExecutor(ExecutorType.Activate, CardID.DOGMATIKA_PUNISHMENT, DogmatikaPunishmentActivate); + AddExecutor(ExecutorType.SpellSet, CardId.DOGMATIKA_PUNISHMENT, DogmatikaSet); + AddExecutor(ExecutorType.Activate, CardId.DOGMATIKA_PUNISHMENT, DogmatikaPunishmentActivate); - AddExecutor(ExecutorType.Activate, CardID.LADY_LABRYNTH, LadyLabrynthActivate); - AddExecutor(ExecutorType.Repos, CardID.LADY_LABRYNTH, LadyLabrynthRepos); + AddExecutor(ExecutorType.Activate, CardId.LADY_LABRYNTH, LadyLabrynthActivate); + AddExecutor(ExecutorType.Repos, CardId.LADY_LABRYNTH, LadyLabrynthRepos); - AddExecutor(ExecutorType.Activate, CardID.LOVELY_LABRYNTH, LovelyLabrynthEffect); + AddExecutor(ExecutorType.Activate, CardId.LOVELY_LABRYNTH, LovelyLabrynthEffect); - AddExecutor(ExecutorType.Activate, CardID.ASH_BLOSSOM, DefaultAshBlossomAndJoyousSpring); + AddExecutor(ExecutorType.Activate, CardId.ASH_BLOSSOM, DefaultAshBlossomAndJoyousSpring); - AddExecutor(ExecutorType.SpellSet, CardID.COMPULSORY_EVACUATION_DEVICE, CompulsoryEvacDeviceSet); - AddExecutor(ExecutorType.Activate, CardID.COMPULSORY_EVACUATION_DEVICE, CompulsoryEvacuationDeviceActivate); + AddExecutor(ExecutorType.SpellSet, CardId.COMPULSORY_EVACUATION_DEVICE, CompulsoryEvacDeviceSet); + AddExecutor(ExecutorType.Activate, CardId.COMPULSORY_EVACUATION_DEVICE, CompulsoryEvacuationDeviceActivate); - AddExecutor(ExecutorType.SpellSet, CardID.SOLEMN_STRIKE); - AddExecutor(ExecutorType.Activate, CardID.SOLEMN_STRIKE, DefaultSolemnStrike); + AddExecutor(ExecutorType.SpellSet, CardId.SOLEMN_STRIKE); + AddExecutor(ExecutorType.Activate, CardId.SOLEMN_STRIKE, DefaultSolemnStrike); - AddExecutor(ExecutorType.SpellSet, CardID.ERADICATOR_EPIDEMIC_VIRUS, EradicatorSet); - AddExecutor(ExecutorType.Activate, CardID.ERADICATOR_EPIDEMIC_VIRUS, EradicatorActivate); + AddExecutor(ExecutorType.SpellSet, CardId.ERADICATOR_EPIDEMIC_VIRUS, EradicatorSet); + AddExecutor(ExecutorType.Activate, CardId.ERADICATOR_EPIDEMIC_VIRUS, EradicatorActivate); - AddExecutor(ExecutorType.Activate, CardID.WIND_PEGASUS_IGNISTER, WindPegasusIngisterEffect); - AddExecutor(ExecutorType.Activate, CardID.ELDER_ENTITY_NTSS, ElderEntityNtssEffect); + AddExecutor(ExecutorType.Activate, CardId.WIND_PEGASUS_IGNISTER, WindPegasusIngisterEffect); + AddExecutor(ExecutorType.Activate, CardId.ELDER_ENTITY_NTSS, ElderEntityNtssEffect); - AddExecutor(ExecutorType.SpSummon, CardID.KNIGHTMARE_PHEONIX, KnightmarePheonix_LinkSummon); - AddExecutor(ExecutorType.SpSummon, CardID.KNIGHTMARE_PHEONIX, KnightmarePheonix_Effect); + AddExecutor(ExecutorType.SpSummon, CardId.KNIGHTMARE_PHEONIX, KnightmarePheonix_LinkSummon); + AddExecutor(ExecutorType.SpSummon, CardId.KNIGHTMARE_PHEONIX, KnightmarePheonix_Effect); } private bool KnightmarePheonix_Effect() @@ -82,7 +82,7 @@ private bool KnightmarePheonix_Effect() private bool KnightmarePheonix_LinkSummon() { - if(!Bot.HasInHandOrInSpellZoneOrInGraveyard(CardID.ERADICATOR_EPIDEMIC_VIRUS) && Util.GetBestEnemySpell() != null && Duel.Phase == DuelPhase.Main2) + if(!Bot.HasInHandOrInSpellZoneOrInGraveyard(CardId.ERADICATOR_EPIDEMIC_VIRUS) && Util.GetBestEnemySpell() != null && Duel.Phase == DuelPhase.Main2) return false; if(Bot.MonsterZone.GetMatchingCards(card => card.Level <= 4).Count() < 2) @@ -90,10 +90,10 @@ private bool KnightmarePheonix_LinkSummon() int[] materials = new int[] { - CardID.STOVIE_TORBIE, - CardID.CHANDRAGLIER, - CardID.ARIANNA, - CardID.COOCLOCK + CardId.STOVIE_TORBIE, + CardId.CHANDRAGLIER, + CardId.ARIANNA, + CardId.COOCLOCK }; AI.SelectMaterials(materials); @@ -108,17 +108,17 @@ private List PrefferedDiscardCost() { List cost_candidates = new List(); - if (Bot.HasInHand(CardID.CHANDRAGLIER) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.CHANDRAGLIER)).Count() > 1) - cost_candidates.Add(CardID.CHANDRAGLIER); - else if (Bot.HasInHand(CardID.LOVELY_LABRYNTH)) - cost_candidates.Add(CardID.LOVELY_LABRYNTH); - else if (Bot.HasInHand(CardID.LABRYNTH_LABYRINTH) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.LABRYNTH_LABYRINTH)).Count() > 1) - cost_candidates.Add(CardID.LABRYNTH_LABYRINTH); - else if (Bot.HasInHand(CardID.STOVIE_TORBIE) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.STOVIE_TORBIE)).Count() > 1) - cost_candidates.Add(CardID.LABRYNTH_LABYRINTH); + if (Bot.HasInHand(CardId.CHANDRAGLIER) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.CHANDRAGLIER)).Count() > 1) + cost_candidates.Add(CardId.CHANDRAGLIER); + else if (Bot.HasInHand(CardId.LOVELY_LABRYNTH)) + cost_candidates.Add(CardId.LOVELY_LABRYNTH); + else if (Bot.HasInHand(CardId.LABRYNTH_LABYRINTH) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.LABRYNTH_LABYRINTH)).Count() > 1) + cost_candidates.Add(CardId.LABRYNTH_LABYRINTH); + else if (Bot.HasInHand(CardId.STOVIE_TORBIE) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.STOVIE_TORBIE)).Count() > 1) + cost_candidates.Add(CardId.LABRYNTH_LABYRINTH); else if (Duel.Turn > 2) - cost_candidates.Add(CardID.NIBIRU); - else cost_candidates.AddRange(new List() { CardID.POT_OF_PROSPERITY }); + cost_candidates.Add(CardId.NIBIRU); + else cost_candidates.AddRange(new List() { CardId.POT_OF_PROSPERITY }); return cost_candidates; } @@ -146,7 +146,7 @@ private bool CompulsoryEvacDeviceSet() { ClientCard problemMonster = Util.GetProblematicEnemyMonster(); - if (!Bot.HasInSpellZone(CardID.DOGMATIKA_PUNISHMENT)) + if (!Bot.HasInSpellZone(CardId.DOGMATIKA_PUNISHMENT)) { if (problemMonster != null || ProtectLadyLabrynth() || Bot.GetFieldCount() == 0) return true; @@ -159,7 +159,7 @@ private bool DogmatikaSet() { ClientCard problemMonster = Util.GetProblematicEnemyMonster(); - if (!Bot.HasInSpellZone(CardID.DOGMATIKA_PUNISHMENT)) + if (!Bot.HasInSpellZone(CardId.DOGMATIKA_PUNISHMENT)) { if (problemMonster != null) return true; else if (problemMonster == null && ProtectLadyLabrynth()) return true; @@ -171,7 +171,7 @@ private bool DogmatikaSet() public bool ProtectLadyLabrynth() { - return Bot.HasInMonstersZone(CardID.LADY_LABRYNTH); + return Bot.HasInMonstersZone(CardId.LADY_LABRYNTH); } private bool AriannaRepos() @@ -199,12 +199,12 @@ private bool WindPegasusIngisterEffect() private bool EradicatorActivate() { - if (Bot.HasInMonstersZone(CardID.LADY_LABRYNTH)) + if (Bot.HasInMonstersZone(CardId.LADY_LABRYNTH)) { ClientCard target = Util.GetBestEnemySpell(); // Tribute - AI.SelectCard(CardID.LADY_LABRYNTH); + AI.SelectCard(CardId.LADY_LABRYNTH); if (target != null) { @@ -224,7 +224,7 @@ private bool EradicatorActivate() private bool ChandraglierSummon() { - if (Bot.Deck.GetMatchingCards(card => card.IsCode(CardID.WELCOME_LABYRINTH)).Count() == 0) + if (Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.WELCOME_LABYRINTH)).Count() == 0) return true; return false; @@ -234,12 +234,12 @@ private bool LabrynthLabyrinthActivate() { if (Card.Location == CardLocation.SpellZone && Card.IsFaceup()) // special summon labrynth monster effect { - if (ActivateDescription == Util.GetStringId(CardID.LABRYNTH_LABYRINTH, 0)) + if (ActivateDescription == Util.GetStringId(CardId.LABRYNTH_LABYRINTH, 0)) { - if (Bot.HasInGraveyard(CardID.LOVELY_LABRYNTH)) - AI.SelectCard(CardID.LOVELY_LABRYNTH); - else if((Bot.HasInGraveyard(CardID.LADY_LABRYNTH))) - AI.SelectCard(CardID.LADY_LABRYNTH); + if (Bot.HasInGraveyard(CardId.LOVELY_LABRYNTH)) + AI.SelectCard(CardId.LOVELY_LABRYNTH); + else if((Bot.HasInGraveyard(CardId.LADY_LABRYNTH))) + AI.SelectCard(CardId.LADY_LABRYNTH); return true; } @@ -248,8 +248,8 @@ private bool LabrynthLabyrinthActivate() } else { - if (!Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH)) return true; - else if (Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH) && Card.Location == CardLocation.SpellZone && Card.IsFacedown()) return true; + if (!Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH)) return true; + else if (Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH) && Card.Location == CardLocation.SpellZone && Card.IsFacedown()) return true; return false; } @@ -259,13 +259,13 @@ private bool MuckarackerEffect() { int[] prefferedMonsters = new int[] { - CardID.LOVELY_LABRYNTH, - CardID.LADY_LABRYNTH + CardId.LOVELY_LABRYNTH, + CardId.LADY_LABRYNTH }; List cost = PrefferedDiscardCost(); - - if (cost.Count() > 0 && Bot.HasInGraveyard(CardID.LADY_LABRYNTH) || Bot.HasInGraveyard(CardID.LOVELY_LABRYNTH)) + + if (cost.Count() > 0 && Bot.HasInGraveyard(CardId.LADY_LABRYNTH) || Bot.HasInGraveyard(CardId.LOVELY_LABRYNTH)) { AI.SelectCard(prefferedMonsters); AI.SelectNextCard(cost); @@ -283,13 +283,13 @@ private bool MuckarackerLinkSummon() int[] materials = new int[] { - CardID.STOVIE_TORBIE, - CardID.CHANDRAGLIER, - CardID.ARIANNA, - CardID.COOCLOCK + CardId.STOVIE_TORBIE, + CardId.CHANDRAGLIER, + CardId.ARIANNA, + CardId.COOCLOCK }; - if (bot_HandCards >= 1 && !Bot.HasInMonstersZone(CardID.MUCKRACKER)) + if (bot_HandCards >= 1 && !Bot.HasInMonstersZone(CardId.MUCKRACKER)) { AI.SelectMaterials(materials); return true; @@ -344,8 +344,8 @@ private bool LadyLabrynthActivate() int[] prefferedTraps = new int[] { - CardID.DOGMATIKA_PUNISHMENT, - CardID.COMPULSORY_EVACUATION_DEVICE + CardId.DOGMATIKA_PUNISHMENT, + CardId.COMPULSORY_EVACUATION_DEVICE }; IList enemySpellZone = Enemy.SpellZone.GetMatchingCards(card => @@ -354,8 +354,8 @@ private bool LadyLabrynthActivate() || card.HasPosition(CardPosition.FaceDown) ); - if(!Bot.HasInHandOrInSpellZoneOrInGraveyard(CardID.ERADICATOR_EPIDEMIC_VIRUS)) - AI.SelectCard(CardID.ERADICATOR_EPIDEMIC_VIRUS); + if(!Bot.HasInHandOrInSpellZoneOrInGraveyard(CardId.ERADICATOR_EPIDEMIC_VIRUS)) + AI.SelectCard(CardId.ERADICATOR_EPIDEMIC_VIRUS); else AI.SelectCard(prefferedTraps); LadyLabrynthActivated = true; @@ -365,7 +365,7 @@ private bool LadyLabrynthActivate() private bool EvenlyMatchedActivate() { - return Bot.HasInHand(CardID.EVENLY_MATCHED) && Duel.Turn >= 2 && Enemy.GetFieldCount() >= 2 && Bot.GetFieldCount() == 0; + return Bot.HasInHand(CardId.EVENLY_MATCHED) && Duel.Turn >= 2 && Enemy.GetFieldCount() >= 2 && Bot.GetFieldCount() == 0; } private bool DogmatikaPunishmentActivate() @@ -375,78 +375,78 @@ private bool DogmatikaPunishmentActivate() if (problemMonster != null) { if(!Enemy.IsFieldEmpty() && Enemy.GetFieldCount() > 1) - AI.SelectCard(CardID.ELDER_ENTITY_NTSS); + AI.SelectCard(CardId.ELDER_ENTITY_NTSS); else - AI.SelectCard(CardID.WIND_PEGASUS_IGNISTER); + AI.SelectCard(CardId.WIND_PEGASUS_IGNISTER); AI.SelectNextCard(problemMonster); - if (Duel.LastChainPlayer == 0 && Util.GetLastChainCard().IsCode(CardID.COMPULSORY_EVACUATION_DEVICE)) + if (Duel.LastChainPlayer == 0 && Util.GetLastChainCard().IsCode(CardId.COMPULSORY_EVACUATION_DEVICE)) return false; return true; } - + return false; } private bool StovieTorbieEffect() { - if (Card.Location == CardLocation.Hand && !Bot.HasInGraveyard(CardID.STOVIE_TORBIE)) + if (Card.Location == CardLocation.Hand && !Bot.HasInGraveyard(CardId.STOVIE_TORBIE)) { // Look for duplicate copies of the same card or Chandraglier and use them as materials. List cost_candidates = new List(); - if (Bot.HasInHand(CardID.CHANDRAGLIER)) - cost_candidates.Add(CardID.CHANDRAGLIER); - else if (Bot.HasInHand(CardID.LOVELY_LABRYNTH)) - cost_candidates.Add(CardID.LOVELY_LABRYNTH); - else if (Bot.HasInHand(CardID.LABRYNTH_LABYRINTH) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.LABRYNTH_LABYRINTH)).Count() > 1) - cost_candidates.Add(CardID.LABRYNTH_LABYRINTH); - else if (Bot.HasInHand(CardID.STOVIE_TORBIE) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.STOVIE_TORBIE)).Count() > 1) - cost_candidates.Add(CardID.LABRYNTH_LABYRINTH); + if (Bot.HasInHand(CardId.CHANDRAGLIER)) + cost_candidates.Add(CardId.CHANDRAGLIER); + else if (Bot.HasInHand(CardId.LOVELY_LABRYNTH)) + cost_candidates.Add(CardId.LOVELY_LABRYNTH); + else if (Bot.HasInHand(CardId.LABRYNTH_LABYRINTH) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.LABRYNTH_LABYRINTH)).Count() > 1) + cost_candidates.Add(CardId.LABRYNTH_LABYRINTH); + else if (Bot.HasInHand(CardId.STOVIE_TORBIE) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.STOVIE_TORBIE)).Count() > 1) + cost_candidates.Add(CardId.LABRYNTH_LABYRINTH); else if (Duel.Turn > 2) - cost_candidates.Add(CardID.NIBIRU); - else cost_candidates.AddRange(new List() { CardID.POT_OF_PROSPERITY }); + cost_candidates.Add(CardId.NIBIRU); + else cost_candidates.AddRange(new List() { CardId.POT_OF_PROSPERITY }); // Get the next Labrynth spell and trap if (cost_candidates.Count() > 0) { AI.SelectCard(cost_candidates); - if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH)) + if (!Bot.HasInHandOrInSpellZone(CardId.WELCOME_LABYRINTH)) { - AI.SelectNextCard(CardID.WELCOME_LABYRINTH); + AI.SelectNextCard(CardId.WELCOME_LABYRINTH); return true; } - else if (!Bot.HasInHandOrInSpellZone(CardID.LABRYNTH_LABYRINTH)) + else if (!Bot.HasInHandOrInSpellZone(CardId.LABRYNTH_LABYRINTH)) { - AI.SelectNextCard(CardID.LABRYNTH_LABYRINTH); + AI.SelectNextCard(CardId.LABRYNTH_LABYRINTH); return true; } } } else if (Card.Location == CardLocation.Grave) { - if (Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH)) + if (Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH)) return true; } else if (Card.Location == CardLocation.MonsterZone) { - if (Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH)) + if (Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH)) { - int remaining_welcomes = Bot.Deck.GetMatchingCards(card => card.IsCode(CardID.WELCOME_LABYRINTH)).Count(); + int remaining_welcomes = Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.WELCOME_LABYRINTH)).Count(); if (remaining_welcomes > 0) { - AI.SelectNextCard(CardID.WELCOME_LABYRINTH); + AI.SelectNextCard(CardId.WELCOME_LABYRINTH); return true; } else return false; } else { - AI.SelectNextCard(CardID.LABRYNTH_LABYRINTH); + AI.SelectNextCard(CardId.LABRYNTH_LABYRINTH); return true; } } @@ -460,22 +460,22 @@ public override void OnNewTurn() WelcomeLabrynthActivated = false; } - public override CardPosition OnSelectPosition(int cardId, IList positions) + public override CardPosition OnSelectPosition(int CardId, IList positions) { - if (cardId == 27204312 || cardId == CardID.STOVIE_TORBIE || cardId == CardID.COOCLOCK) + if (CardId == 27204312 || CardId == CardId.STOVIE_TORBIE || CardId == CardId.COOCLOCK) { return CardPosition.FaceUpDefence; } - else if (cardId == CardID.LADY_LABRYNTH || cardId == CardID.LOVELY_LABRYNTH) + else if (CardId == CardId.LADY_LABRYNTH || CardId == CardId.LOVELY_LABRYNTH) { return CardPosition.FaceUpAttack; } - else if ((cardId == CardID.ARIANNA || cardId == CardID.CHANDRAGLIER) && !Util.IsAllEnemyBetter()) + else if ((CardId == CardId.ARIANNA || CardId == CardId.CHANDRAGLIER) && !Util.IsAllEnemyBetter()) { return CardPosition.FaceUpAttack; } - return base.OnSelectPosition(cardId, positions); + return base.OnSelectPosition(CardId, positions); } private bool SolemnStrikeActivate() @@ -494,13 +494,13 @@ private bool SolemnStrikeActivate() private bool LovelyLabrynthEffect() { int[] supportTraps = new int[] { - CardID.WELCOME_LABYRINTH, - CardID.COMPULSORY_EVACUATION_DEVICE, - CardID.DOGMATIKA_PUNISHMENT + CardId.WELCOME_LABYRINTH, + CardId.COMPULSORY_EVACUATION_DEVICE, + CardId.DOGMATIKA_PUNISHMENT }; - if (Bot.HasInGraveyard(CardID.ERADICATOR_EPIDEMIC_VIRUS)) - AI.SelectCard(CardID.ERADICATOR_EPIDEMIC_VIRUS); + if (Bot.HasInGraveyard(CardId.ERADICATOR_EPIDEMIC_VIRUS)) + AI.SelectCard(CardId.ERADICATOR_EPIDEMIC_VIRUS); else AI.SelectCard(supportTraps); @@ -514,10 +514,10 @@ private bool CompulsoryEvacuationDeviceActivate() if (enemyBestMonster != null) { if (Duel.LastChainPlayer == 0 && ( - Util.GetLastChainCard().IsCode(CardID.DOGMATIKA_PUNISHMENT) - || Util.GetLastChainCard().IsCode(CardID.COMPULSORY_EVACUATION_DEVICE) - || Util.GetLastChainCard().IsCode(CardID.ELDER_ENTITY_NTSS) - || Util.GetLastChainCard().IsCode(CardID.WELCOME_LABYRINTH) + Util.GetLastChainCard().IsCode(CardId.DOGMATIKA_PUNISHMENT) + || Util.GetLastChainCard().IsCode(CardId.COMPULSORY_EVACUATION_DEVICE) + || Util.GetLastChainCard().IsCode(CardId.ELDER_ENTITY_NTSS) + || Util.GetLastChainCard().IsCode(CardId.WELCOME_LABYRINTH) ) ) { @@ -534,19 +534,19 @@ private bool CompulsoryEvacuationDeviceActivate() public bool isEvenlyMatchedOnHand() { - return Bot.HasInHand(CardID.EVENLY_MATCHED); + return Bot.HasInHand(CardId.EVENLY_MATCHED); } public bool WelcomeLabrynthActivate() { List preferred_Monsters = new List(); - if (Bot.HasInHandOrHasInMonstersZone(CardID.LADY_LABRYNTH) || Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardID.LADY_LABRYNTH)) - preferred_Monsters.Add(CardID.LOVELY_LABRYNTH); - else if (Bot.HasInHandOrInGraveyard(CardID.LOVELY_LABRYNTH) || !Bot.HasInHandOrHasInMonstersZone(CardID.LOVELY_LABRYNTH) || Bot.MonsterZone.GetMatchingCards(card => card.HasType(CardType.Monster)).Count() == 0) - preferred_Monsters.Add(CardID.LADY_LABRYNTH); - else if (Bot.HasInMonstersZone(CardID.LADY_LABRYNTH) || Bot.HasInMonstersZone(CardID.LOVELY_LABRYNTH)) - preferred_Monsters.Add(CardID.ARIANNA); + if (Bot.HasInHandOrHasInMonstersZone(CardId.LADY_LABRYNTH) || Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardId.LADY_LABRYNTH)) + preferred_Monsters.Add(CardId.LOVELY_LABRYNTH); + else if (Bot.HasInHandOrInGraveyard(CardId.LOVELY_LABRYNTH) || !Bot.HasInHandOrHasInMonstersZone(CardId.LOVELY_LABRYNTH) || Bot.MonsterZone.GetMatchingCards(card => card.HasType(CardType.Monster)).Count() == 0) + preferred_Monsters.Add(CardId.LADY_LABRYNTH); + else if (Bot.HasInMonstersZone(CardId.LADY_LABRYNTH) || Bot.HasInMonstersZone(CardId.LOVELY_LABRYNTH)) + preferred_Monsters.Add(CardId.ARIANNA); AI.SelectCard(preferred_Monsters); @@ -555,7 +555,7 @@ public bool WelcomeLabrynthActivate() // Added destroy one card effect by Labrynth Labirynth to Welcome Labrynth if (Card.Location == CardLocation.SpellZone) { - if (ActivateDescription == Util.GetStringId(CardID.WELCOME_LABYRINTH, 0)) + if (ActivateDescription == Util.GetStringId(CardId.WELCOME_LABYRINTH, 0)) { ClientCard problemCard = Util.GetBestEnemyCard(); @@ -580,18 +580,18 @@ public bool WelcomeLabrynthActivate() public bool AriannaEffect() { int[] other_prefferedCards = new int[] { - CardID.COOCLOCK, - CardID.STOVIE_TORBIE + CardId.COOCLOCK, + CardId.STOVIE_TORBIE }; - if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH)) - AI.SelectCard(CardID.WELCOME_LABYRINTH); + if (!Bot.HasInHandOrInSpellZone(CardId.WELCOME_LABYRINTH)) + AI.SelectCard(CardId.WELCOME_LABYRINTH); else if ( - Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH) - && Bot.Deck.GetMatchingCards(card => card.IsCode(CardID.COOCLOCK)).Count() > 0 + Bot.HasInHandOrInSpellZone(CardId.WELCOME_LABYRINTH) + && Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.COOCLOCK)).Count() > 0 && Bot.MonsterZone.GetMatchingCards(card => card.HasPosition(CardPosition.FaceUp)).Count() > 0 ) - AI.SelectCard(CardID.LABRYNTH_LABYRINTH); + AI.SelectCard(CardId.LABRYNTH_LABYRINTH); else AI.SelectCard(other_prefferedCards); @@ -605,14 +605,14 @@ public bool CooclockEffect() return false; IList faceUp_Monsters = Bot.MonsterZone.GetMatchingCards(card => - card.IsCode(CardID.LOVELY_LABRYNTH) - || card.IsCode(CardID.LADY_LABRYNTH) - || card.IsCode(CardID.STOVIE_TORBIE) - || card.IsCode(CardID.ARIANNA) - || card.IsCode(CardID.CHANDRAGLIER) + card.IsCode(CardId.LOVELY_LABRYNTH) + || card.IsCode(CardId.LADY_LABRYNTH) + || card.IsCode(CardId.STOVIE_TORBIE) + || card.IsCode(CardId.ARIANNA) + || card.IsCode(CardId.CHANDRAGLIER) ); - if (Card.Location == CardLocation.Hand || Bot.HasInSpellZone(CardID.WELCOME_LABYRINTH) && !WelcomeLabrynthActivated && Duel.Phase == DuelPhase.Main1) + if (Card.Location == CardLocation.Hand || Bot.HasInSpellZone(CardId.WELCOME_LABYRINTH) && !WelcomeLabrynthActivated && Duel.Phase == DuelPhase.Main1) return true; else if (Card.Location == CardLocation.Grave) { @@ -626,36 +626,36 @@ public bool CooclockEffect() public bool ChandraglierEffect() { - if (Card.Location == CardLocation.Hand && !Bot.HasInGraveyard(CardID.CHANDRAGLIER)) + if (Card.Location == CardLocation.Hand && !Bot.HasInGraveyard(CardId.CHANDRAGLIER)) { // Look for duplicate copies of the same card or Chandraglier and use them as materials. List cost_candidates = new List(); - if (Bot.HasInHand(CardID.CHANDRAGLIER) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.CHANDRAGLIER)).Count() > 1) - cost_candidates.Add(CardID.CHANDRAGLIER); - else if (Bot.HasInHand(CardID.LOVELY_LABRYNTH)) - cost_candidates.Add(CardID.LOVELY_LABRYNTH); - else if (Bot.HasInHand(CardID.LABRYNTH_LABYRINTH) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.LABRYNTH_LABYRINTH)).Count() > 1) - cost_candidates.Add(CardID.LABRYNTH_LABYRINTH); - else if (Bot.HasInHand(CardID.STOVIE_TORBIE) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardID.STOVIE_TORBIE)).Count() > 1) - cost_candidates.Add(CardID.LABRYNTH_LABYRINTH); + if (Bot.HasInHand(CardId.CHANDRAGLIER) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.CHANDRAGLIER)).Count() > 1) + cost_candidates.Add(CardId.CHANDRAGLIER); + else if (Bot.HasInHand(CardId.LOVELY_LABRYNTH)) + cost_candidates.Add(CardId.LOVELY_LABRYNTH); + else if (Bot.HasInHand(CardId.LABRYNTH_LABYRINTH) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.LABRYNTH_LABYRINTH)).Count() > 1) + cost_candidates.Add(CardId.LABRYNTH_LABYRINTH); + else if (Bot.HasInHand(CardId.STOVIE_TORBIE) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.STOVIE_TORBIE)).Count() > 1) + cost_candidates.Add(CardId.LABRYNTH_LABYRINTH); else if (Duel.Turn > 2) - cost_candidates.Add(CardID.NIBIRU); - else cost_candidates.AddRange(new List() { CardID.POT_OF_PROSPERITY }); + cost_candidates.Add(CardId.NIBIRU); + else cost_candidates.AddRange(new List() { CardId.POT_OF_PROSPERITY }); // Get the next Labrynth spell and trap if (cost_candidates.Count() > 0) { AI.SelectCard(cost_candidates); - if (!Bot.HasInHandOrInSpellZone(CardID.WELCOME_LABYRINTH)) + if (!Bot.HasInHandOrInSpellZone(CardId.WELCOME_LABYRINTH)) { - AI.SelectNextCard(CardID.WELCOME_LABYRINTH); + AI.SelectNextCard(CardId.WELCOME_LABYRINTH); return true; } - else if (!Bot.HasInHandOrInSpellZone(CardID.LABRYNTH_LABYRINTH)) + else if (!Bot.HasInHandOrInSpellZone(CardId.LABRYNTH_LABYRINTH)) { - AI.SelectNextCard(CardID.LABRYNTH_LABYRINTH); + AI.SelectNextCard(CardId.LABRYNTH_LABYRINTH); return true; } } @@ -663,19 +663,19 @@ public bool ChandraglierEffect() else if (Card.Location == CardLocation.Grave) return true; else if (Card.Location == CardLocation.MonsterZone) { - if (Bot.HasInSpellZone(CardID.LABRYNTH_LABYRINTH)) + if (Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH)) { - int remaining_welcomes = Bot.Deck.GetMatchingCards(card => card.IsCode(CardID.WELCOME_LABYRINTH)).Count(); + int remaining_welcomes = Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.WELCOME_LABYRINTH)).Count(); if (remaining_welcomes > 0) { - AI.SelectNextCard(CardID.WELCOME_LABYRINTH); + AI.SelectNextCard(CardId.WELCOME_LABYRINTH); return true; } else return false; } else { - AI.SelectNextCard(CardID.LABRYNTH_LABYRINTH); + AI.SelectNextCard(CardId.LABRYNTH_LABYRINTH); return true; } }; @@ -683,7 +683,7 @@ public bool ChandraglierEffect() return false; } - public class CardID + public class CardId { // MAIN DECK public const int NIBIRU = 27204311; From 3a8aff3ad3d054d04d8a344f6efa424f6175d077 Mon Sep 17 00:00:00 2001 From: Edoardo Lolletti Date: Fri, 15 Dec 2023 19:04:08 +0100 Subject: [PATCH 13/21] Rename variable name --- Game/AI/Decks/BudgetLabrynths.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Game/AI/Decks/BudgetLabrynths.cs b/Game/AI/Decks/BudgetLabrynths.cs index 02a7a7ae..ceda54b5 100644 --- a/Game/AI/Decks/BudgetLabrynths.cs +++ b/Game/AI/Decks/BudgetLabrynths.cs @@ -460,22 +460,22 @@ public override void OnNewTurn() WelcomeLabrynthActivated = false; } - public override CardPosition OnSelectPosition(int CardId, IList positions) + public override CardPosition OnSelectPosition(int CardID, IList positions) { - if (CardId == 27204312 || CardId == CardId.STOVIE_TORBIE || CardId == CardId.COOCLOCK) + if (CardID == 27204312 || CardID == CardId.STOVIE_TORBIE || CardID == CardId.COOCLOCK) { return CardPosition.FaceUpDefence; } - else if (CardId == CardId.LADY_LABRYNTH || CardId == CardId.LOVELY_LABRYNTH) + else if (CardID == CardId.LADY_LABRYNTH || CardID == CardId.LOVELY_LABRYNTH) { return CardPosition.FaceUpAttack; } - else if ((CardId == CardId.ARIANNA || CardId == CardId.CHANDRAGLIER) && !Util.IsAllEnemyBetter()) + else if ((CardID == CardId.ARIANNA || CardID == CardId.CHANDRAGLIER) && !Util.IsAllEnemyBetter()) { return CardPosition.FaceUpAttack; } - return base.OnSelectPosition(CardId, positions); + return base.OnSelectPosition(CardID, positions); } private bool SolemnStrikeActivate() From 146d7426099532861ee01c3ca6b452035bdd8fb8 Mon Sep 17 00:00:00 2001 From: jdistro07 Date: Sat, 16 Dec 2023 11:10:57 +0800 Subject: [PATCH 14/21] Added Budget Labrynths to bot.json --- Game/AI/Decks/BudgetLabrynths.cs | 2 +- bots.json | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Game/AI/Decks/BudgetLabrynths.cs b/Game/AI/Decks/BudgetLabrynths.cs index ceda54b5..72bf1d8a 100644 --- a/Game/AI/Decks/BudgetLabrynths.cs +++ b/Game/AI/Decks/BudgetLabrynths.cs @@ -5,7 +5,7 @@ namespace WindBot.Game.AI.Decks { - [Deck("BudgetLabrynths", "AI_BudgetLabrynths")] + [Deck("Budget Labrynths", "AI_BudgetLabrynths")] public class BudgetLabrynths : DefaultExecutor { public BudgetLabrynths(GameAI ai, Duel duel) diff --git a/bots.json b/bots.json index 145f1bd5..2dc530b2 100644 --- a/bots.json +++ b/bots.json @@ -256,5 +256,11 @@ "deck": "[ImaginaryArk]", "difficulty": 2, "masterRules": [ 7 ] + }, + { + "name": "Budget Labrynths", + "deck": "Budget Labrynths", + "difficulty": 2, + "masterRules": [ 3, 4, 5 ] } ] From 3bfff7cdd4463a6ace67a9aadf0a9c6dd93c9983 Mon Sep 17 00:00:00 2001 From: jdistro07 Date: Sat, 16 Dec 2023 14:13:33 +0800 Subject: [PATCH 15/21] - Fixes on furniture behaviours - Optimized activation timing of Welcome Labrynth - Fixes on link monster summoning and activations --- Game/AI/Decks/BudgetLabrynths.cs | 103 ++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 28 deletions(-) diff --git a/Game/AI/Decks/BudgetLabrynths.cs b/Game/AI/Decks/BudgetLabrynths.cs index 72bf1d8a..14623c96 100644 --- a/Game/AI/Decks/BudgetLabrynths.cs +++ b/Game/AI/Decks/BudgetLabrynths.cs @@ -5,7 +5,7 @@ namespace WindBot.Game.AI.Decks { - [Deck("Budget Labrynths", "AI_BudgetLabrynths")] + [Deck("BudgetLabrynths", "AI_BudgetLabrynths")] public class BudgetLabrynths : DefaultExecutor { public BudgetLabrynths(GameAI ai, Duel duel) @@ -20,11 +20,11 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.LABRYNTH_LABYRINTH, LabrynthLabyrinthActivate); - AddExecutor(ExecutorType.Activate, CardId.COOCLOCK, CooclockEffect); - - AddExecutor(ExecutorType.SpellSet, CardId.WELCOME_LABYRINTH); + AddExecutor(ExecutorType.SpellSet, CardId.WELCOME_LABYRINTH, WelcomeLabrynthSet); AddExecutor(ExecutorType.Activate, CardId.WELCOME_LABYRINTH, WelcomeLabrynthActivate); + AddExecutor(ExecutorType.Activate, CardId.COOCLOCK, CooclockEffect); + AddExecutor(ExecutorType.Activate, CardId.STOVIE_TORBIE, StovieTorbieEffect); AddExecutor(ExecutorType.Summon, CardId.CHANDRAGLIER, ChandraglierSummon); @@ -63,6 +63,11 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.SpSummon, CardId.KNIGHTMARE_PHEONIX, KnightmarePheonix_Effect); } + private bool WelcomeLabrynthSet() + { + return !Bot.HasInSpellZone(CardId.WELCOME_LABYRINTH); + } + private bool KnightmarePheonix_Effect() { List cost = PrefferedDiscardCost(); @@ -82,12 +87,18 @@ private bool KnightmarePheonix_Effect() private bool KnightmarePheonix_LinkSummon() { - if(!Bot.HasInHandOrInSpellZoneOrInGraveyard(CardId.ERADICATOR_EPIDEMIC_VIRUS) && Util.GetBestEnemySpell() != null && Duel.Phase == DuelPhase.Main2) + if(!Bot.HasInSpellZone(CardId.ERADICATOR_EPIDEMIC_VIRUS) && Util.GetBestEnemySpell() != null && Duel.Phase == DuelPhase.Main2) return false; if(Bot.MonsterZone.GetMatchingCards(card => card.Level <= 4).Count() < 2) return false; + if(Bot.Hand.Count() == 0) + return false; + + if (Enemy.SpellZone.Count() == 0) + return false; + int[] materials = new int[] { CardId.STOVIE_TORBIE, @@ -224,7 +235,7 @@ private bool EradicatorActivate() private bool ChandraglierSummon() { - if (Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.WELCOME_LABYRINTH)).Count() == 0) + if (Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.WELCOME_LABYRINTH)).Count() == 0 || Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH)) return true; return false; @@ -271,9 +282,35 @@ private bool MuckarackerEffect() AI.SelectNextCard(cost); return true; - } else return false; + } + + if (Card.Location == CardLocation.MonsterZone) + { + if (ActivateDescription == Util.GetStringId(CardId.MUCKRACKER, 0)) + { + List cost_candidates = new List(); + if (Enemy.BattlingMonster != null) + { + if (Enemy.BattlingMonster.IsCode(CardId.LOVELY_LABRYNTH) || Enemy.BattlingMonster.IsCode(CardId.LOVELY_LABRYNTH)) + { + cost_candidates.AddRange(new List() { + CardId.CHANDRAGLIER, + CardId.STOVIE_TORBIE, + CardId.COOCLOCK, + CardId.ARIANNA + }); + + AI.SelectCard(cost_candidates); + + return true; + } + return false; + } + } + } + return false; } private bool MuckarackerLinkSummon() @@ -410,11 +447,15 @@ private bool StovieTorbieEffect() else cost_candidates.AddRange(new List() { CardId.POT_OF_PROSPERITY }); // Get the next Labrynth spell and trap - if (cost_candidates.Count() > 0) + if (Duel.Player == 0) + { + if (cost_candidates.Count() > 0) { AI.SelectCard(cost_candidates); - if (!Bot.HasInHandOrInSpellZone(CardId.WELCOME_LABYRINTH)) + int remaining_welcomes = Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.WELCOME_LABYRINTH)).Count(); + + if (!Bot.HasInHandOrInSpellZone(CardId.WELCOME_LABYRINTH) && remaining_welcomes > 0) { AI.SelectNextCard(CardId.WELCOME_LABYRINTH); return true; @@ -425,6 +466,7 @@ private bool StovieTorbieEffect() return true; } } + } } else if (Card.Location == CardLocation.Grave) { @@ -539,14 +581,16 @@ public bool isEvenlyMatchedOnHand() public bool WelcomeLabrynthActivate() { + if(Duel.Player == 0 && !(Duel.Phase == DuelPhase.Main1 || Duel.Phase == DuelPhase.Main2)) + return true; + List preferred_Monsters = new List(); - if (Bot.HasInHandOrHasInMonstersZone(CardId.LADY_LABRYNTH) || Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardId.LADY_LABRYNTH)) + if (Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardId.LADY_LABRYNTH) || Duel.IsFirst) preferred_Monsters.Add(CardId.LOVELY_LABRYNTH); - else if (Bot.HasInHandOrInGraveyard(CardId.LOVELY_LABRYNTH) || !Bot.HasInHandOrHasInMonstersZone(CardId.LOVELY_LABRYNTH) || Bot.MonsterZone.GetMatchingCards(card => card.HasType(CardType.Monster)).Count() == 0) + else if (Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardId.LOVELY_LABRYNTH)) preferred_Monsters.Add(CardId.LADY_LABRYNTH); - else if (Bot.HasInMonstersZone(CardId.LADY_LABRYNTH) || Bot.HasInMonstersZone(CardId.LOVELY_LABRYNTH)) - preferred_Monsters.Add(CardId.ARIANNA); + else preferred_Monsters.Add(CardId.ARIANNA); AI.SelectCard(preferred_Monsters); @@ -601,9 +645,6 @@ public bool AriannaEffect() public bool CooclockEffect() { - if (Duel.Player != 0 && Duel.Phase != DuelPhase.Main1) - return false; - IList faceUp_Monsters = Bot.MonsterZone.GetMatchingCards(card => card.IsCode(CardId.LOVELY_LABRYNTH) || card.IsCode(CardId.LADY_LABRYNTH) @@ -612,7 +653,7 @@ public bool CooclockEffect() || card.IsCode(CardId.CHANDRAGLIER) ); - if (Card.Location == CardLocation.Hand || Bot.HasInSpellZone(CardId.WELCOME_LABYRINTH) && !WelcomeLabrynthActivated && Duel.Phase == DuelPhase.Main1) + if (Card.Location == CardLocation.Hand && Bot.HasInSpellZone(CardId.WELCOME_LABYRINTH) && !WelcomeLabrynthActivated && Duel.Player == 0) return true; else if (Card.Location == CardLocation.Grave) { @@ -644,19 +685,25 @@ public bool ChandraglierEffect() else cost_candidates.AddRange(new List() { CardId.POT_OF_PROSPERITY }); // Get the next Labrynth spell and trap - if (cost_candidates.Count() > 0) - { - AI.SelectCard(cost_candidates); - if (!Bot.HasInHandOrInSpellZone(CardId.WELCOME_LABYRINTH)) - { - AI.SelectNextCard(CardId.WELCOME_LABYRINTH); - return true; - } - else if (!Bot.HasInHandOrInSpellZone(CardId.LABRYNTH_LABYRINTH)) + if (Duel.Player == 0) + { + if (cost_candidates.Count() > 0) { - AI.SelectNextCard(CardId.LABRYNTH_LABYRINTH); - return true; + AI.SelectCard(cost_candidates); + + int remaining_welcomes = Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.WELCOME_LABYRINTH)).Count(); + + if (!Bot.HasInHandOrInSpellZone(CardId.WELCOME_LABYRINTH) && remaining_welcomes > 0) + { + AI.SelectNextCard(CardId.WELCOME_LABYRINTH); + return true; + } + else if (!Bot.HasInHandOrInSpellZone(CardId.LABRYNTH_LABYRINTH)) + { + AI.SelectNextCard(CardId.LABRYNTH_LABYRINTH); + return true; + } } } } From 1c6b327ddb384e8601c17e95343a16e8f36c504e Mon Sep 17 00:00:00 2001 From: jdistro07 Date: Sat, 16 Dec 2023 15:09:59 +0800 Subject: [PATCH 16/21] Optimizations to play workflow order Optimized furniture activations --- Game/AI/Decks/BudgetLabrynths.cs | 86 ++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 32 deletions(-) diff --git a/Game/AI/Decks/BudgetLabrynths.cs b/Game/AI/Decks/BudgetLabrynths.cs index 14623c96..c1db593e 100644 --- a/Game/AI/Decks/BudgetLabrynths.cs +++ b/Game/AI/Decks/BudgetLabrynths.cs @@ -11,56 +11,71 @@ public class BudgetLabrynths : DefaultExecutor public BudgetLabrynths(GameAI ai, Duel duel) : base(ai, duel) { - AddExecutor(ExecutorType.Activate, CardId.NIBIRU); + // Break board + AddExecutor(ExecutorType.Activate, CardId.NIBIRU); AddExecutor(ExecutorType.GoToBattlePhase, EvenlyMatchedActivate); AddExecutor(ExecutorType.Activate); - AddExecutor(ExecutorType.Activate, CardId.POT_OF_PROSPERITY); // TODO - - AddExecutor(ExecutorType.Activate, CardId.LABRYNTH_LABYRINTH, LabrynthLabyrinthActivate); - + // Setup + AddExecutor(ExecutorType.Activate, CardId.POT_OF_PROSPERITY); AddExecutor(ExecutorType.SpellSet, CardId.WELCOME_LABYRINTH, WelcomeLabrynthSet); - AddExecutor(ExecutorType.Activate, CardId.WELCOME_LABYRINTH, WelcomeLabrynthActivate); - - AddExecutor(ExecutorType.Activate, CardId.COOCLOCK, CooclockEffect); + // Activate furnitures to supplement board setup AddExecutor(ExecutorType.Activate, CardId.STOVIE_TORBIE, StovieTorbieEffect); - - AddExecutor(ExecutorType.Summon, CardId.CHANDRAGLIER, ChandraglierSummon); AddExecutor(ExecutorType.Activate, CardId.CHANDRAGLIER, ChandraglierEffect); + //Labrynth Spell Traps + AddExecutor(ExecutorType.Activate, CardId.LABRYNTH_LABYRINTH, LabrynthLabyrinthActivate); + AddExecutor(ExecutorType.Activate, CardId.COOCLOCK, CooclockEffect); + + // Monster summons and effects + AddExecutor(ExecutorType.Summon, CardId.CHANDRAGLIER, FunitureSummon); + AddExecutor(ExecutorType.Summon, CardId.CHANDRAGLIER, FunitureSummon); AddExecutor(ExecutorType.Summon, CardId.ARIANNA); AddExecutor(ExecutorType.Activate, CardId.ARIANNA, AriannaEffect); - AddExecutor(ExecutorType.Repos, CardId.ARIANNA, AriannaRepos); - - AddExecutor(ExecutorType.SpSummon, CardId.MUCKRACKER, MuckarackerLinkSummon); - AddExecutor(ExecutorType.Activate, CardId.MUCKRACKER, MuckarackerEffect); - - AddExecutor(ExecutorType.SpellSet, CardId.DOGMATIKA_PUNISHMENT, DogmatikaSet); - AddExecutor(ExecutorType.Activate, CardId.DOGMATIKA_PUNISHMENT, DogmatikaPunishmentActivate); + // Monster Activations AddExecutor(ExecutorType.Activate, CardId.LADY_LABRYNTH, LadyLabrynthActivate); - AddExecutor(ExecutorType.Repos, CardId.LADY_LABRYNTH, LadyLabrynthRepos); - AddExecutor(ExecutorType.Activate, CardId.LOVELY_LABRYNTH, LovelyLabrynthEffect); - AddExecutor(ExecutorType.Activate, CardId.ASH_BLOSSOM, DefaultAshBlossomAndJoyousSpring); + // Link monsters summon and effects + AddExecutor(ExecutorType.SpSummon, CardId.MUCKRACKER, MuckarackerLinkSummon); + AddExecutor(ExecutorType.Activate, CardId.MUCKRACKER, MuckarackerEffect); + AddExecutor(ExecutorType.SpSummon, CardId.KNIGHTMARE_PHEONIX, KnightmarePheonix_LinkSummon); + AddExecutor(ExecutorType.SpSummon, CardId.KNIGHTMARE_PHEONIX, KnightmarePheonix_Effect); + + // Backrow setup + AddExecutor(ExecutorType.SpellSet, CardId.DOGMATIKA_PUNISHMENT, DogmatikaSet); AddExecutor(ExecutorType.SpellSet, CardId.COMPULSORY_EVACUATION_DEVICE, CompulsoryEvacDeviceSet); AddExecutor(ExecutorType.Activate, CardId.COMPULSORY_EVACUATION_DEVICE, CompulsoryEvacuationDeviceActivate); - + AddExecutor(ExecutorType.SpellSet, CardId.ERADICATOR_EPIDEMIC_VIRUS, EradicatorSet); AddExecutor(ExecutorType.SpellSet, CardId.SOLEMN_STRIKE); - AddExecutor(ExecutorType.Activate, CardId.SOLEMN_STRIKE, DefaultSolemnStrike); - AddExecutor(ExecutorType.SpellSet, CardId.ERADICATOR_EPIDEMIC_VIRUS, EradicatorSet); + // Backrow activations + AddExecutor(ExecutorType.Activate, CardId.DOGMATIKA_PUNISHMENT, DogmatikaPunishmentActivate); AddExecutor(ExecutorType.Activate, CardId.ERADICATOR_EPIDEMIC_VIRUS, EradicatorActivate); + AddExecutor(ExecutorType.Activate, CardId.WELCOME_LABYRINTH, WelcomeLabrynthActivate); + AddExecutor(ExecutorType.Activate, CardId.SOLEMN_STRIKE, DefaultSolemnStrike); - AddExecutor(ExecutorType.Activate, CardId.WIND_PEGASUS_IGNISTER, WindPegasusIngisterEffect); + // GY effects AddExecutor(ExecutorType.Activate, CardId.ELDER_ENTITY_NTSS, ElderEntityNtssEffect); + AddExecutor(ExecutorType.Activate, CardId.WIND_PEGASUS_IGNISTER, WindPegasusIngisterEffect); + + // Finalize monster positions + AddExecutor(ExecutorType.Repos, CardId.LADY_LABRYNTH, LadyLabrynthRepos); + AddExecutor(ExecutorType.Repos, CardId.ARIANNA, AriannaRepos); + - AddExecutor(ExecutorType.SpSummon, CardId.KNIGHTMARE_PHEONIX, KnightmarePheonix_LinkSummon); - AddExecutor(ExecutorType.SpSummon, CardId.KNIGHTMARE_PHEONIX, KnightmarePheonix_Effect); + } + + private bool FunitureSummon() + { + if (Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.WELCOME_LABYRINTH)).Count() == 0 || Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH)) + return true; + + return false; } private bool WelcomeLabrynthSet() @@ -114,6 +129,7 @@ private bool KnightmarePheonix_LinkSummon() private bool LadyLabrynthActivated = false; private bool WelcomeLabrynthActivated = false; + private bool ArrianaActivated = false; private List PrefferedDiscardCost() { @@ -326,7 +342,7 @@ private bool MuckarackerLinkSummon() CardId.COOCLOCK }; - if (bot_HandCards >= 1 && !Bot.HasInMonstersZone(CardId.MUCKRACKER)) + if (bot_HandCards >= 1 && !Bot.HasInMonstersZone(CardId.MUCKRACKER) && bot_Monsters > 1) { AI.SelectMaterials(materials); return true; @@ -441,7 +457,7 @@ private bool StovieTorbieEffect() else if (Bot.HasInHand(CardId.LABRYNTH_LABYRINTH) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.LABRYNTH_LABYRINTH)).Count() > 1) cost_candidates.Add(CardId.LABRYNTH_LABYRINTH); else if (Bot.HasInHand(CardId.STOVIE_TORBIE) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.STOVIE_TORBIE)).Count() > 1) - cost_candidates.Add(CardId.LABRYNTH_LABYRINTH); + cost_candidates.Add(CardId.STOVIE_TORBIE); else if (Duel.Turn > 2) cost_candidates.Add(CardId.NIBIRU); else cost_candidates.AddRange(new List() { CardId.POT_OF_PROSPERITY }); @@ -500,6 +516,7 @@ public override void OnNewTurn() { LadyLabrynthActivated = false; WelcomeLabrynthActivated = false; + ArrianaActivated = false; } public override CardPosition OnSelectPosition(int CardID, IList positions) @@ -586,11 +603,14 @@ public bool WelcomeLabrynthActivate() List preferred_Monsters = new List(); - if (Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardId.LADY_LABRYNTH) || Duel.IsFirst) + if (!Bot.HasInMonstersZoneOrInGraveyard(CardId.LOVELY_LABRYNTH)) preferred_Monsters.Add(CardId.LOVELY_LABRYNTH); - else if (Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardId.LOVELY_LABRYNTH)) + + if (!Bot.HasInHandOrHasInMonstersZone(CardId.LADY_LABRYNTH)) preferred_Monsters.Add(CardId.LADY_LABRYNTH); - else preferred_Monsters.Add(CardId.ARIANNA); + + if(Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardId.LADY_LABRYNTH) && Bot.HasInMonstersZoneOrInGraveyard(CardId.LOVELY_LABRYNTH) || ArrianaActivated != false) + preferred_Monsters.Add(CardId.ARIANNA); AI.SelectCard(preferred_Monsters); @@ -639,6 +659,8 @@ public bool AriannaEffect() else AI.SelectCard(other_prefferedCards); + ArrianaActivated = true; + return true; } @@ -679,7 +701,7 @@ public bool ChandraglierEffect() else if (Bot.HasInHand(CardId.LABRYNTH_LABYRINTH) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.LABRYNTH_LABYRINTH)).Count() > 1) cost_candidates.Add(CardId.LABRYNTH_LABYRINTH); else if (Bot.HasInHand(CardId.STOVIE_TORBIE) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.STOVIE_TORBIE)).Count() > 1) - cost_candidates.Add(CardId.LABRYNTH_LABYRINTH); + cost_candidates.Add(CardId.STOVIE_TORBIE); else if (Duel.Turn > 2) cost_candidates.Add(CardId.NIBIRU); else cost_candidates.AddRange(new List() { CardId.POT_OF_PROSPERITY }); From 5adecf8d2193623ddfb15308f1b569e4b6d48e87 Mon Sep 17 00:00:00 2001 From: jdistro07 Date: Sun, 17 Dec 2023 03:17:44 +0800 Subject: [PATCH 17/21] - Tweaked deck build - Improvements on furnitures - Cooclock fixes - Fixes on link summoning flow - Pot of prosperity executor - Card random placement with imperm avoidance TODO: 1. Knigtmare Unicorn Executor --- Decks/AI_BudgetLabrynths.ydk | 28 +-- Game/AI/Decks/BudgetLabrynths.cs | 375 +++++++++++++++++++++---------- 2 files changed, 261 insertions(+), 142 deletions(-) diff --git a/Decks/AI_BudgetLabrynths.ydk b/Decks/AI_BudgetLabrynths.ydk index 4a8d5ff0..22923bf9 100644 --- a/Decks/AI_BudgetLabrynths.ydk +++ b/Decks/AI_BudgetLabrynths.ydk @@ -1,7 +1,9 @@ #created by SkildX #main 27204311 -81497285 +9822220 +9822220 +9822220 81497285 81497285 2347656 @@ -20,8 +22,6 @@ 2511 84211599 84211599 -84211599 -33407125 33407125 33407125 5380979 @@ -41,33 +41,19 @@ 40605147 40605147 #extra +99267151 +11765832 +11765832 80532587 80532587 21123811 -21123811 -21123811 -98506199 -98506199 98506199 10019086 10019086 +38342335 2857636 71607202 71607202 65741786 41999284 !side -27204311 -27204311 -91800273 -91800273 -91800273 -24508238 -24508238 -24508238 -69895264 -69895264 -69895264 -10045474 -10045474 -10045474 diff --git a/Game/AI/Decks/BudgetLabrynths.cs b/Game/AI/Decks/BudgetLabrynths.cs index c1db593e..e922d15a 100644 --- a/Game/AI/Decks/BudgetLabrynths.cs +++ b/Game/AI/Decks/BudgetLabrynths.cs @@ -18,7 +18,8 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate); // Setup - AddExecutor(ExecutorType.Activate, CardId.POT_OF_PROSPERITY); + AddExecutor(ExecutorType.Activate, CardId.POT_OF_PROSPERITY, PotOfProsperityActivate); + AddExecutor(ExecutorType.Activate, CardId.LORD_OF_HEAVENLY_PRISON, LordOfHeavenlyPrisonActivate); AddExecutor(ExecutorType.SpellSet, CardId.WELCOME_LABYRINTH, WelcomeLabrynthSet); // Activate furnitures to supplement board setup @@ -41,17 +42,18 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.ASH_BLOSSOM, DefaultAshBlossomAndJoyousSpring); // Link monsters summon and effects + AddExecutor(ExecutorType.SpSummon, CardId.KNIGHTMARE_PHEONIX, KnightmarePheonix_LinkSummon); + AddExecutor(ExecutorType.Activate, CardId.KNIGHTMARE_PHEONIX, KnightmarePheonix_Effect); AddExecutor(ExecutorType.SpSummon, CardId.MUCKRACKER, MuckarackerLinkSummon); AddExecutor(ExecutorType.Activate, CardId.MUCKRACKER, MuckarackerEffect); - AddExecutor(ExecutorType.SpSummon, CardId.KNIGHTMARE_PHEONIX, KnightmarePheonix_LinkSummon); - AddExecutor(ExecutorType.SpSummon, CardId.KNIGHTMARE_PHEONIX, KnightmarePheonix_Effect); // Backrow setup + AddExecutor(ExecutorType.SpellSet, EvenlyMatchedSet); AddExecutor(ExecutorType.SpellSet, CardId.DOGMATIKA_PUNISHMENT, DogmatikaSet); AddExecutor(ExecutorType.SpellSet, CardId.COMPULSORY_EVACUATION_DEVICE, CompulsoryEvacDeviceSet); AddExecutor(ExecutorType.Activate, CardId.COMPULSORY_EVACUATION_DEVICE, CompulsoryEvacuationDeviceActivate); AddExecutor(ExecutorType.SpellSet, CardId.ERADICATOR_EPIDEMIC_VIRUS, EradicatorSet); - AddExecutor(ExecutorType.SpellSet, CardId.SOLEMN_STRIKE); + AddExecutor(ExecutorType.SpellSet, CardId.SOLEMN_STRIKE, SolemnStrikeSet); // Backrow activations AddExecutor(ExecutorType.Activate, CardId.DOGMATIKA_PUNISHMENT, DogmatikaPunishmentActivate); @@ -62,12 +64,139 @@ public BudgetLabrynths(GameAI ai, Duel duel) // GY effects AddExecutor(ExecutorType.Activate, CardId.ELDER_ENTITY_NTSS, ElderEntityNtssEffect); AddExecutor(ExecutorType.Activate, CardId.WIND_PEGASUS_IGNISTER, WindPegasusIngisterEffect); + AddExecutor(ExecutorType.Activate, CardId.TRIBRIGADE_ARMS_BUCEPHALUS_II, TririgadeArmsEffect); + AddExecutor(ExecutorType.Activate, CardId.GARURA); // Finalize monster positions AddExecutor(ExecutorType.Repos, CardId.LADY_LABRYNTH, LadyLabrynthRepos); AddExecutor(ExecutorType.Repos, CardId.ARIANNA, AriannaRepos); + } + + private bool EvenlyMatchedSet() + { + if(Util.IsAllEnemyBetter() && Bot.Hand.GetCardCount(CardId.EVENLY_MATCHED) > 1 && Bot.GetFieldCount() != 0 && ProtectLadyLabrynth()) + return true; + return false; + } + + private bool SolemnStrikeSet() + { + if (Card.Location == CardLocation.Hand) + { + AI.SelectPlace(SelectSTPlace(Card, true)); + return true; + } + return true; + } + + private bool WelcomeLabrynthActivated = false; + private bool ArrianaActivated = false; + private bool LadyLabrynthActivated = false; + + List Impermanence_list = new List(); + + public override void OnSelectChain(IList cards) + { + foreach (var imperm in cards.GetMatchingCards(card => card.IsCode(10045474))) + { + Impermanence_list.Add(10045474); // Imperm ID + } + + base.OnSelectChain(cards); + } + + public int SelectSTPlace(ClientCard card = null, bool avoid_Impermanence = false) + { + List list = new List { 0, 1, 2, 3, 4 }; + 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; + } + foreach (int seq in list) + { + int zone = (int)System.Math.Pow(2, seq); + if (Bot.SpellZone[seq] == null) + { + if (card != null && card.Location == CardLocation.Hand && avoid_Impermanence && Impermanence_list.Contains(seq)) continue; + return zone; + }; + } + return 0; + } + + private bool PotOfProsperityActivate() + { + if (Bot.ExtraDeck.Count <= 3) return false; + + int[] cost = new int[] { + CardId.IP_MASQUERENA, + CardId.LINKURIBOH, + CardId.MUCKRACKER, + CardId.KNIGHTMARE_UNICORN, + CardId.KNIGHTMARE_PHEONIX, + CardId.COSMIC_BLAZAR_DRAGON + }; + + AI.SelectCard(cost); + + List prefferedCard = new List(); + + if (!Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardId.WELCOME_LABYRINTH)) + prefferedCard.Add(CardId.WELCOME_LABYRINTH); + else if (!Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardId.LADY_LABRYNTH)) + prefferedCard.Add(CardId.LADY_LABRYNTH); + else if (!Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardId.ERADICATOR_EPIDEMIC_VIRUS)) + prefferedCard.Add(CardId.ERADICATOR_EPIDEMIC_VIRUS); + else if (Enemy.GetFieldCount() > 1 && Bot.HasInExtra(CardId.ELDER_ENTITY_NTSS) && !Bot.HasInHandOrInGraveyard(CardId.DOGMATIKA_PUNISHMENT)) + prefferedCard.Add(CardId.DOGMATIKA_PUNISHMENT); + else if (Enemy.GetFieldCount() > 1 && Bot.HasInExtra(CardId.ELDER_ENTITY_NTSS) && !Bot.HasInHandOrInGraveyard(CardId.COMPULSORY_EVACUATION_DEVICE) && Bot.HasInMonstersZone(CardId.LOVELY_LABRYNTH) && Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH)) + prefferedCard.Add(CardId.COMPULSORY_EVACUATION_DEVICE); + else if (!Bot.HasInHand(CardId.ASH_BLOSSOM)) + prefferedCard.Add(CardId.ASH_BLOSSOM); + else if (!Bot.HasInHandOrHasInMonstersZone(CardId.ARIANNA)) + prefferedCard.Add(CardId.ARIANNA); + else if (!Bot.HasInHandOrInSpellZone(CardId.LABRYNTH_LABYRINTH)) + prefferedCard.Add(CardId.LABRYNTH_LABYRINTH); + else if (!Bot.HasInHandOrInSpellZone(CardId.LABRYNTH_LABYRINTH)) + prefferedCard.Add(CardId.LABRYNTH_LABYRINTH); + else if (Bot.GetFieldCount() <= 1 && Util.IsAllEnemyBetter()) + prefferedCard.Add(CardId.EVENLY_MATCHED); + + AI.SelectNextCard(prefferedCard); + + if (Card.Location == CardLocation.Hand) + { + AI.SelectPlace(SelectSTPlace(Card, true)); + } + + return true; + } + + private bool LordOfHeavenlyPrisonActivate() + { + if (Card.Location == CardLocation.Hand && Duel.Player == 0) + { + if (Util.GetLastChainCard() != null) + { + if (Util.GetLastChainCard().HasType(CardType.Spell) || Util.GetLastChainCard().HasType(CardType.Trap)) + return false; + } + + return true; + } + return false; + } + + private bool TririgadeArmsEffect() + { + AI.SelectCard(CardId.GARURA); + return true; } private bool FunitureSummon() @@ -80,6 +209,11 @@ private bool FunitureSummon() private bool WelcomeLabrynthSet() { + if (Card.Location == CardLocation.Hand) + { + AI.SelectPlace(SelectSTPlace(Card, true)); + } + return !Bot.HasInSpellZone(CardId.WELCOME_LABYRINTH); } @@ -102,34 +236,30 @@ private bool KnightmarePheonix_Effect() private bool KnightmarePheonix_LinkSummon() { - if(!Bot.HasInSpellZone(CardId.ERADICATOR_EPIDEMIC_VIRUS) && Util.GetBestEnemySpell() != null && Duel.Phase == DuelPhase.Main2) - return false; - - if(Bot.MonsterZone.GetMatchingCards(card => card.Level <= 4).Count() < 2) - return false; - - if(Bot.Hand.Count() == 0) + if(Util.GetBestEnemySpell() == null) return false; - if (Enemy.SpellZone.Count() == 0) - return false; - - int[] materials = new int[] + if ((Bot.HasInMonstersZone(CardId.CHANDRAGLIER) + || Bot.HasInMonstersZone(CardId.STOVIE_TORBIE) + || Bot.HasInMonstersZone(CardId.COOCLOCK)) + && Bot.MonsterZone.Count() > 1 + && Bot.Hand.Count() > 1 + ) { - CardId.STOVIE_TORBIE, - CardId.CHANDRAGLIER, - CardId.ARIANNA, - CardId.COOCLOCK - }; + int[] materials = new int[] + { + CardId.STOVIE_TORBIE, + CardId.CHANDRAGLIER, + CardId.COOCLOCK + }; - AI.SelectMaterials(materials); + AI.SelectMaterials(materials); - return true; - } + return true; + } - private bool LadyLabrynthActivated = false; - private bool WelcomeLabrynthActivated = false; - private bool ArrianaActivated = false; + return false; + } private List PrefferedDiscardCost() { @@ -143,6 +273,8 @@ private List PrefferedDiscardCost() cost_candidates.Add(CardId.LABRYNTH_LABYRINTH); else if (Bot.HasInHand(CardId.STOVIE_TORBIE) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.STOVIE_TORBIE)).Count() > 1) cost_candidates.Add(CardId.LABRYNTH_LABYRINTH); + else if (Bot.HasInHand(CardId.LORD_OF_HEAVENLY_PRISON) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.LORD_OF_HEAVENLY_PRISON)).Count() > 1) + cost_candidates.Add(CardId.LORD_OF_HEAVENLY_PRISON); else if (Duel.Turn > 2) cost_candidates.Add(CardId.NIBIRU); else cost_candidates.AddRange(new List() { CardId.POT_OF_PROSPERITY }); @@ -154,19 +286,16 @@ private int EradicatorOption() { int hand_enemySpells = Enemy.Hand.GetMatchingCards(card => card.HasType(CardType.Spell)).Count(); int deck_enemySpells = Enemy.Deck.GetMatchingCards(card => card.HasType(CardType.Spell)).Count(); - int grave_enemySpells = Enemy.Graveyard.GetMatchingCards(card => card.HasType(CardType.Spell)).Count(); - int hand_enemyTraps = Enemy.Hand.GetMatchingCards(card => card.HasType(CardType.Trap)).Count(); int deck_enemyTraps = Enemy.Deck.GetMatchingCards(card => card.HasType(CardType.Trap)).Count(); - int grave_enemyTraps = Enemy.Graveyard.GetMatchingCards(card => card.HasType(CardType.Trap)).Count(); - int overallSpells = hand_enemySpells + deck_enemySpells + grave_enemySpells; - int overallTraps = hand_enemyTraps + deck_enemyTraps + grave_enemyTraps; + int overallSpells = hand_enemySpells + deck_enemySpells; + int overallTraps = hand_enemyTraps + deck_enemyTraps; - if (overallSpells > overallTraps) return 0; // Spells - else return 1; // Traps + if (overallSpells > overallTraps) return 1; // Spells + else return 2; // Traps } private bool CompulsoryEvacDeviceSet() @@ -175,8 +304,15 @@ private bool CompulsoryEvacDeviceSet() if (!Bot.HasInSpellZone(CardId.DOGMATIKA_PUNISHMENT)) { - if (problemMonster != null || ProtectLadyLabrynth() || Bot.GetFieldCount() == 0) + if (problemMonster != null || ProtectLadyLabrynth() || Bot.GetFieldCount() <= 1) + { + if (Card.Location == CardLocation.Hand) + { + AI.SelectPlace(SelectSTPlace(Card, true)); + } + return true; + } } return false; @@ -188,7 +324,12 @@ private bool DogmatikaSet() if (!Bot.HasInSpellZone(CardId.DOGMATIKA_PUNISHMENT)) { - if (problemMonster != null) return true; + if (Card.Location == CardLocation.Hand) + { + AI.SelectPlace(SelectSTPlace(Card, true)); + } + + if (problemMonster != null || Bot.GetFieldCount() <= 1) return true; else if (problemMonster == null && ProtectLadyLabrynth()) return true; else if (Bot.GetFieldCount() == 0) return true; } @@ -235,8 +376,8 @@ private bool EradicatorActivate() if (target != null) { - if (target.HasType(CardType.Spell)) AI.SelectOption(0); - else AI.SelectOption(1); + if (target.HasType(CardType.Spell)) AI.SelectOption(1); + else AI.SelectOption(2); } else // if there are no backrows, decide if their build is more on spells or traps { @@ -300,6 +441,7 @@ private bool MuckarackerEffect() return true; } + // Protect Key MOnsters if (Card.Location == CardLocation.MonsterZone) { if (ActivateDescription == Util.GetStringId(CardId.MUCKRACKER, 0)) @@ -314,10 +456,11 @@ private bool MuckarackerEffect() CardId.CHANDRAGLIER, CardId.STOVIE_TORBIE, CardId.COOCLOCK, - CardId.ARIANNA + CardId.ARIANNA, + CardId.MUCKRACKER }); - AI.SelectCard(cost_candidates); + AI.SelectThirdCard(cost_candidates); return true; } @@ -339,15 +482,20 @@ private bool MuckarackerLinkSummon() CardId.STOVIE_TORBIE, CardId.CHANDRAGLIER, CardId.ARIANNA, - CardId.COOCLOCK + CardId.COOCLOCK, + CardId.KNIGHTMARE_PHEONIX, + CardId.KNIGHTMARE_UNICORN }; - if (bot_HandCards >= 1 && !Bot.HasInMonstersZone(CardId.MUCKRACKER) && bot_Monsters > 1) + if (bot_HandCards >= 1 && !Bot.HasInMonstersZone(CardId.MUCKRACKER) && (Bot.HasInMonstersZoneOrInGraveyard(CardId.LADY_LABRYNTH) || Bot.HasInMonstersZoneOrInGraveyard(CardId.LOVELY_LABRYNTH))) { AI.SelectMaterials(materials); return true; } + if (Bot.HasInMonstersZone(CardId.STOVIE_TORBIE) && Bot.HasInMonstersZone(CardId.CHANDRAGLIER)) + return true; + return false; } @@ -364,7 +512,13 @@ private bool EradicatorSet() IList tributes = Bot.MonsterZone.GetMatchingCards(card => card.HasAttribute(CardAttribute.Dark) && card.Attack > 2500); if (tributes.Count > 0) - return true; + { + if (Card.Location == CardLocation.Hand) + { + AI.SelectPlace(SelectSTPlace(Card, true)); + return true; + } + } } return false; @@ -407,8 +561,13 @@ private bool LadyLabrynthActivate() || card.HasPosition(CardPosition.FaceDown) ); - if(!Bot.HasInHandOrInSpellZoneOrInGraveyard(CardId.ERADICATOR_EPIDEMIC_VIRUS)) + if (!Bot.HasInHandOrInSpellZoneOrInGraveyard(CardId.ERADICATOR_EPIDEMIC_VIRUS)) + { + ClientCard eradicator = Bot.Deck.GetFirstMatchingCard(card => card.IsCode(CardId.ERADICATOR_EPIDEMIC_VIRUS)); AI.SelectCard(CardId.ERADICATOR_EPIDEMIC_VIRUS); + AI.SelectPlace(SelectSTPlace(eradicator, true)); + } + else AI.SelectCard(prefferedTraps); LadyLabrynthActivated = true; @@ -418,6 +577,11 @@ private bool LadyLabrynthActivate() private bool EvenlyMatchedActivate() { + if (Card.Location == CardLocation.Hand) + { + AI.SelectPlace(SelectSTPlace(Card, true)); + } + return Bot.HasInHand(CardId.EVENLY_MATCHED) && Duel.Turn >= 2 && Enemy.GetFieldCount() >= 2 && Bot.GetFieldCount() == 0; } @@ -427,10 +591,19 @@ private bool DogmatikaPunishmentActivate() if (problemMonster != null) { - if(!Enemy.IsFieldEmpty() && Enemy.GetFieldCount() > 1) + if (!Enemy.IsFieldEmpty() && Enemy.GetFieldCount() > 1) AI.SelectCard(CardId.ELDER_ENTITY_NTSS); else - AI.SelectCard(CardId.WIND_PEGASUS_IGNISTER); + { + List prefferedMonsters = new List + { + CardId.WIND_PEGASUS_IGNISTER, + CardId.TRIBRIGADE_ARMS_BUCEPHALUS_II + }; + + AI.SelectCard(prefferedMonsters); + } + AI.SelectNextCard(problemMonster); @@ -445,71 +618,7 @@ private bool DogmatikaPunishmentActivate() private bool StovieTorbieEffect() { - if (Card.Location == CardLocation.Hand && !Bot.HasInGraveyard(CardId.STOVIE_TORBIE)) - { - // Look for duplicate copies of the same card or Chandraglier and use them as materials. - List cost_candidates = new List(); - - if (Bot.HasInHand(CardId.CHANDRAGLIER)) - cost_candidates.Add(CardId.CHANDRAGLIER); - else if (Bot.HasInHand(CardId.LOVELY_LABRYNTH)) - cost_candidates.Add(CardId.LOVELY_LABRYNTH); - else if (Bot.HasInHand(CardId.LABRYNTH_LABYRINTH) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.LABRYNTH_LABYRINTH)).Count() > 1) - cost_candidates.Add(CardId.LABRYNTH_LABYRINTH); - else if (Bot.HasInHand(CardId.STOVIE_TORBIE) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.STOVIE_TORBIE)).Count() > 1) - cost_candidates.Add(CardId.STOVIE_TORBIE); - else if (Duel.Turn > 2) - cost_candidates.Add(CardId.NIBIRU); - else cost_candidates.AddRange(new List() { CardId.POT_OF_PROSPERITY }); - - // Get the next Labrynth spell and trap - if (Duel.Player == 0) - { - if (cost_candidates.Count() > 0) - { - AI.SelectCard(cost_candidates); - - int remaining_welcomes = Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.WELCOME_LABYRINTH)).Count(); - - if (!Bot.HasInHandOrInSpellZone(CardId.WELCOME_LABYRINTH) && remaining_welcomes > 0) - { - AI.SelectNextCard(CardId.WELCOME_LABYRINTH); - return true; - } - else if (!Bot.HasInHandOrInSpellZone(CardId.LABRYNTH_LABYRINTH)) - { - AI.SelectNextCard(CardId.LABRYNTH_LABYRINTH); - return true; - } - } - } - } - else if (Card.Location == CardLocation.Grave) - { - if (Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH)) - return true; - } - else if (Card.Location == CardLocation.MonsterZone) - { - if (Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH)) - { - int remaining_welcomes = Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.WELCOME_LABYRINTH)).Count(); - - if (remaining_welcomes > 0) - { - AI.SelectNextCard(CardId.WELCOME_LABYRINTH); - return true; - } - else return false; - } - else - { - AI.SelectNextCard(CardId.LABRYNTH_LABYRINTH); - return true; - } - } - - return false; + return FurnitureActivation(); } public override void OnNewTurn() @@ -559,7 +668,12 @@ private bool LovelyLabrynthEffect() }; if (Bot.HasInGraveyard(CardId.ERADICATOR_EPIDEMIC_VIRUS)) + { + ClientCard eradicator = Bot.Deck.GetFirstMatchingCard(card => card.IsCode(CardId.ERADICATOR_EPIDEMIC_VIRUS)); AI.SelectCard(CardId.ERADICATOR_EPIDEMIC_VIRUS); + AI.SelectPlace(SelectSTPlace(eradicator, true)); + } + else AI.SelectCard(supportTraps); @@ -637,6 +751,10 @@ public bool WelcomeLabrynthActivate() }; } } + else if (Card.Location == CardLocation.Grave) + { + AI.SelectPlace(SelectSTPlace(Card, true)); + } return true; } @@ -675,7 +793,11 @@ public bool CooclockEffect() || card.IsCode(CardId.CHANDRAGLIER) ); - if (Card.Location == CardLocation.Hand && Bot.HasInSpellZone(CardId.WELCOME_LABYRINTH) && !WelcomeLabrynthActivated && Duel.Player == 0) + if (Card.Location == CardLocation.Hand + && (Bot.HasInSpellZone(CardId.WELCOME_LABYRINTH) || Bot.HasInSpellZone(CardId.ERADICATOR_EPIDEMIC_VIRUS)) + && !WelcomeLabrynthActivated + && Duel.Player == 0 + && Bot.MonsterZone.GetMatchingCards(card => card.HasRace(CardRace.Fiend)).Count() > 0) return true; else if (Card.Location == CardLocation.Grave) { @@ -689,7 +811,12 @@ public bool CooclockEffect() public bool ChandraglierEffect() { - if (Card.Location == CardLocation.Hand && !Bot.HasInGraveyard(CardId.CHANDRAGLIER)) + return FurnitureActivation(); + } + + public bool FurnitureActivation() + { + if (Card.Location == CardLocation.Hand && Duel.Phase == DuelPhase.Main1 || Duel.Phase == DuelPhase.Main2) { // Look for duplicate copies of the same card or Chandraglier and use them as materials. List cost_candidates = new List(); @@ -702,9 +829,11 @@ public bool ChandraglierEffect() cost_candidates.Add(CardId.LABRYNTH_LABYRINTH); else if (Bot.HasInHand(CardId.STOVIE_TORBIE) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.STOVIE_TORBIE)).Count() > 1) cost_candidates.Add(CardId.STOVIE_TORBIE); + else if (Bot.HasInHand(CardId.LORD_OF_HEAVENLY_PRISON) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.LORD_OF_HEAVENLY_PRISON)).Count() > 1) + cost_candidates.Add(CardId.LORD_OF_HEAVENLY_PRISON); else if (Duel.Turn > 2) cost_candidates.Add(CardId.NIBIRU); - else cost_candidates.AddRange(new List() { CardId.POT_OF_PROSPERITY }); + else cost_candidates.AddRange(new List() { CardId.POT_OF_PROSPERITY, CardId.COOCLOCK }); // Get the next Labrynth spell and trap @@ -714,18 +843,17 @@ public bool ChandraglierEffect() { AI.SelectCard(cost_candidates); - int remaining_welcomes = Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.WELCOME_LABYRINTH)).Count(); + int deck_remaining_welcomes = Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.WELCOME_LABYRINTH)).Count(); - if (!Bot.HasInHandOrInSpellZone(CardId.WELCOME_LABYRINTH) && remaining_welcomes > 0) + if (!Bot.HasInSpellZone(CardId.WELCOME_LABYRINTH)) { AI.SelectNextCard(CardId.WELCOME_LABYRINTH); - return true; + AI.SelectPlace(SelectSTPlace(Bot.Deck.GetFirstMatchingCard(card => card.IsCode(CardId.WELCOME_LABYRINTH)), true)); } else if (!Bot.HasInHandOrInSpellZone(CardId.LABRYNTH_LABYRINTH)) - { AI.SelectNextCard(CardId.LABRYNTH_LABYRINTH); - return true; - } + + return true; } } } @@ -740,7 +868,8 @@ public bool ChandraglierEffect() { AI.SelectNextCard(CardId.WELCOME_LABYRINTH); return true; - } else return false; + } + else return false; } else { @@ -763,6 +892,7 @@ public class CardId public const int ASH_BLOSSOM = 14558127; public const int STOVIE_TORBIE = 74018812; public const int COOCLOCK = 2511; + public const int LORD_OF_HEAVENLY_PRISON = 9822220; // spells and traps public const int POT_OF_PROSPERITY = 84211599; @@ -776,13 +906,16 @@ public class CardId // EXTRA DECK public const int ELDER_ENTITY_NTSS = 80532587; - public const int COMSIC_BLAZAR_DRAGON = 21123811; + public const int COSMIC_BLAZAR_DRAGON = 21123811; public const int WIND_PEGASUS_IGNISTER = 98506199; public const int TRIBRIGADE_ARMS_BUCEPHALUS_II = 10019086; public const int KNIGHTMARE_PHEONIX = 2857636; public const int MUCKRACKER = 71607202; public const int IP_MASQUERENA = 65741786; public const int LINKURIBOH = 41999284; + public const int GARURA = 11765832; + public const int FIVE_HEADED_DRAGON = 99267150; + public const int KNIGHTMARE_UNICORN = 38342335; } } From aa440882a15fe859ac2554a602c120bed36ff56e Mon Sep 17 00:00:00 2001 From: jdistro07 Date: Sun, 17 Dec 2023 14:31:43 +0800 Subject: [PATCH 18/21] Budget Labrynth v1.0 - Improvements on combo consistency - Fixes on Welcome Labrynth timing with Labrynth Labrynth - Fixed furniture wasting Field spell if no more Welcome Labrynth is left on deck - Imrpovements on Muckracker protection strat - fixed traps not setting when Lady Labrynth is on field --- Game/AI/Decks/BudgetLabrynths.cs | 102 +++++++++++++++++++++++++------ 1 file changed, 83 insertions(+), 19 deletions(-) diff --git a/Game/AI/Decks/BudgetLabrynths.cs b/Game/AI/Decks/BudgetLabrynths.cs index e922d15a..df71a1cd 100644 --- a/Game/AI/Decks/BudgetLabrynths.cs +++ b/Game/AI/Decks/BudgetLabrynths.cs @@ -44,6 +44,8 @@ public BudgetLabrynths(GameAI ai, Duel duel) // Link monsters summon and effects AddExecutor(ExecutorType.SpSummon, CardId.KNIGHTMARE_PHEONIX, KnightmarePheonix_LinkSummon); AddExecutor(ExecutorType.Activate, CardId.KNIGHTMARE_PHEONIX, KnightmarePheonix_Effect); + AddExecutor(ExecutorType.SpSummon, CardId.KNIGHTMARE_UNICORN, KnightmareUnicorn_LinkSummon); + AddExecutor(ExecutorType.Activate, CardId.KNIGHTMARE_UNICORN, KnightmareUnicornEffect); AddExecutor(ExecutorType.SpSummon, CardId.MUCKRACKER, MuckarackerLinkSummon); AddExecutor(ExecutorType.Activate, CardId.MUCKRACKER, MuckarackerEffect); @@ -54,6 +56,8 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.COMPULSORY_EVACUATION_DEVICE, CompulsoryEvacuationDeviceActivate); AddExecutor(ExecutorType.SpellSet, CardId.ERADICATOR_EPIDEMIC_VIRUS, EradicatorSet); AddExecutor(ExecutorType.SpellSet, CardId.SOLEMN_STRIKE, SolemnStrikeSet); + AddExecutor(ExecutorType.SpellSet, CardId.EVENLY_MATCHED, EvenlyMatchedSet); + // Backrow activations AddExecutor(ExecutorType.Activate, CardId.DOGMATIKA_PUNISHMENT, DogmatikaPunishmentActivate); @@ -72,9 +76,56 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.Repos, CardId.ARIANNA, AriannaRepos); } + private bool KnightmareUnicornEffect() + { + IList cost = PrefferedDiscardCost(); + ClientCard target = Util.GetBestEnemyCard(true, true); + + if (target != null) + { + // Discard cost + AI.SelectCard(cost); + + // Target enemy best card + AI.SelectNextCard(target); + + return true; + } + + return false; + } + + private bool KnightmareUnicorn_LinkSummon() + { + if (Util.IsAllEnemyBetter()) + { + int bot_HandCards = Bot.Hand.Count(); + + int[] materials = new int[] + { + CardId.STOVIE_TORBIE, + CardId.CHANDRAGLIER, + CardId.ARIANNA, + CardId.COOCLOCK, + CardId.KNIGHTMARE_PHEONIX + }; + + if ((Bot.HasInMonstersZone(CardId.STOVIE_TORBIE) || Bot.HasInMonstersZone(CardId.CHANDRAGLIER) || Bot.HasInMonstersZone(CardId.COOCLOCK)) + && (Bot.HasInMonstersZone(CardId.ARIANNA) || Bot.HasInMonstersZone(CardId.KNIGHTMARE_PHEONIX)) + && bot_HandCards >= 2 + ) + { + AI.SelectMaterials(materials); + return true; + } + } + + return false; + } + private bool EvenlyMatchedSet() { - if(Util.IsAllEnemyBetter() && Bot.Hand.GetCardCount(CardId.EVENLY_MATCHED) > 1 && Bot.GetFieldCount() != 0 && ProtectLadyLabrynth()) + if(ProtectLadyLabrynth()) return true; return false; @@ -330,7 +381,7 @@ private bool DogmatikaSet() } if (problemMonster != null || Bot.GetFieldCount() <= 1) return true; - else if (problemMonster == null && ProtectLadyLabrynth()) return true; + else if (ProtectLadyLabrynth()) return true; else if (Bot.GetFieldCount() == 0) return true; } @@ -339,7 +390,7 @@ private bool DogmatikaSet() public bool ProtectLadyLabrynth() { - return Bot.HasInMonstersZone(CardId.LADY_LABRYNTH); + return Bot.HasInMonstersZone(CardId.LADY_LABRYNTH) && Bot.SpellZone.Count() == 0; } private bool AriannaRepos() @@ -509,15 +560,10 @@ private bool EradicatorSet() { if (Duel.Phase == DuelPhase.Main2) { - IList tributes = Bot.MonsterZone.GetMatchingCards(card => card.HasAttribute(CardAttribute.Dark) && card.Attack > 2500); - - if (tributes.Count > 0) + if (Bot.HasInMonstersZone(CardId.LADY_LABRYNTH)) { - if (Card.Location == CardLocation.Hand) - { - AI.SelectPlace(SelectSTPlace(Card, true)); - return true; - } + AI.SelectPlace(SelectSTPlace(Card, true)); + return true; } } @@ -682,7 +728,7 @@ private bool LovelyLabrynthEffect() private bool CompulsoryEvacuationDeviceActivate() { - ClientCard enemyBestMonster = Util.GetBestEnemyMonster(); + ClientCard enemyBestMonster = Util.GetBestEnemyMonster(true, false); if (enemyBestMonster != null) { @@ -713,16 +759,21 @@ public bool isEvenlyMatchedOnHand() public bool WelcomeLabrynthActivate() { if(Duel.Player == 0 && !(Duel.Phase == DuelPhase.Main1 || Duel.Phase == DuelPhase.Main2)) - return true; + return false; + + // Let Labrynth Labyrinth resolve before activating welcome + if (Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH) && Duel.CurrentChain.Count() > 0) + { + if (Duel.CurrentChain.ContainsCardWithId(CardId.LABRYNTH_LABYRINTH)) + return false; + } List preferred_Monsters = new List(); if (!Bot.HasInMonstersZoneOrInGraveyard(CardId.LOVELY_LABRYNTH)) preferred_Monsters.Add(CardId.LOVELY_LABRYNTH); - if (!Bot.HasInHandOrHasInMonstersZone(CardId.LADY_LABRYNTH)) preferred_Monsters.Add(CardId.LADY_LABRYNTH); - if(Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardId.LADY_LABRYNTH) && Bot.HasInMonstersZoneOrInGraveyard(CardId.LOVELY_LABRYNTH) || ArrianaActivated != false) preferred_Monsters.Add(CardId.ARIANNA); @@ -735,7 +786,7 @@ public bool WelcomeLabrynthActivate() { if (ActivateDescription == Util.GetStringId(CardId.WELCOME_LABYRINTH, 0)) { - ClientCard problemCard = Util.GetBestEnemyCard(); + ClientCard problemCard = Util.GetBestEnemyCard(false,true); if (problemCard != null && Enemy.GetFieldCount() > 0) { @@ -816,8 +867,19 @@ public bool ChandraglierEffect() public bool FurnitureActivation() { + if (Util.GetLastChainCard() != null) + { + if (Util.GetLastChainCard().IsCode(CardId.CHANDRAGLIER) + || Util.GetLastChainCard().IsCode(CardId.STOVIE_TORBIE) + || Util.GetLastChainCard().IsCode(CardId.LABRYNTH_LABYRINTH)) + return false; + } + if (Card.Location == CardLocation.Hand && Duel.Phase == DuelPhase.Main1 || Duel.Phase == DuelPhase.Main2) { + if (Bot.Hand.GetCardCount(CardId.WELCOME_LABYRINTH) == 0 && Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH)) + return false; + // Look for duplicate copies of the same card or Chandraglier and use them as materials. List cost_candidates = new List(); @@ -843,17 +905,19 @@ public bool FurnitureActivation() { AI.SelectCard(cost_candidates); - int deck_remaining_welcomes = Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.WELCOME_LABYRINTH)).Count(); - if (!Bot.HasInSpellZone(CardId.WELCOME_LABYRINTH)) { AI.SelectNextCard(CardId.WELCOME_LABYRINTH); AI.SelectPlace(SelectSTPlace(Bot.Deck.GetFirstMatchingCard(card => card.IsCode(CardId.WELCOME_LABYRINTH)), true)); + return true; } else if (!Bot.HasInHandOrInSpellZone(CardId.LABRYNTH_LABYRINTH)) + { AI.SelectNextCard(CardId.LABRYNTH_LABYRINTH); + return true; + } - return true; + return false; } } } From 519d4e976c05e7350d2fe4a18822e095218f1802 Mon Sep 17 00:00:00 2001 From: jdistro07 Date: Sat, 9 Mar 2024 19:04:23 +0800 Subject: [PATCH 19/21] - Fixed chainblock strategy - Optimized furniture activations - Fixes on Muckracker WIP: 1. Furniture activation when in monster zone. --- Game/AI/Decks/BudgetLabrynths.cs | 367 ++++++++++++++++++------------- 1 file changed, 208 insertions(+), 159 deletions(-) diff --git a/Game/AI/Decks/BudgetLabrynths.cs b/Game/AI/Decks/BudgetLabrynths.cs index df71a1cd..ecb4ce58 100644 --- a/Game/AI/Decks/BudgetLabrynths.cs +++ b/Game/AI/Decks/BudgetLabrynths.cs @@ -1,6 +1,8 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Web.UI; using YGOSharp.OCGWrapper.Enums; namespace WindBot.Game.AI.Decks @@ -8,9 +10,20 @@ namespace WindBot.Game.AI.Decks [Deck("BudgetLabrynths", "AI_BudgetLabrynths")] public class BudgetLabrynths : DefaultExecutor { + private bool WelcomeLabrynth_GraveActivated = true; + private bool WelcomeLabrynthActivated = false; + private bool ArrianaActivated = false; + private bool LadyLabrynthActivated = false; + + //Chain target variables + private bool LovelyIsChainTarget = false; + private bool LadyIsChainTarget = false; + public BudgetLabrynths(GameAI ai, Duel duel) : base(ai, duel) { + // Negates + AddExecutor(ExecutorType.Activate, CardId.ASH_BLOSSOM, DefaultAshBlossomAndJoyousSpring); // Break board AddExecutor(ExecutorType.Activate, CardId.NIBIRU); @@ -22,24 +35,25 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.LORD_OF_HEAVENLY_PRISON, LordOfHeavenlyPrisonActivate); AddExecutor(ExecutorType.SpellSet, CardId.WELCOME_LABYRINTH, WelcomeLabrynthSet); - // Activate furnitures to supplement board setup + // Furntures AddExecutor(ExecutorType.Activate, CardId.STOVIE_TORBIE, StovieTorbieEffect); + AddExecutor(ExecutorType.Activate, CardId.CHANDRAGLIER, ChandraglierEffect); //Labrynth Spell Traps AddExecutor(ExecutorType.Activate, CardId.LABRYNTH_LABYRINTH, LabrynthLabyrinthActivate); AddExecutor(ExecutorType.Activate, CardId.COOCLOCK, CooclockEffect); - // Monster summons and effects - AddExecutor(ExecutorType.Summon, CardId.CHANDRAGLIER, FunitureSummon); + // Monster summons AddExecutor(ExecutorType.Summon, CardId.CHANDRAGLIER, FunitureSummon); - AddExecutor(ExecutorType.Summon, CardId.ARIANNA); - AddExecutor(ExecutorType.Activate, CardId.ARIANNA, AriannaEffect); + AddExecutor(ExecutorType.Summon, CardId.STOVIE_TORBIE, FunitureSummon); + AddExecutor(ExecutorType.Summon, CardId.ARIANNA, AriannaSummon); // Monster Activations AddExecutor(ExecutorType.Activate, CardId.LADY_LABRYNTH, LadyLabrynthActivate); + AddExecutor(ExecutorType.Activate, CardId.LADY_LABRYNTH, Hand_LadyLabrynthActivate); AddExecutor(ExecutorType.Activate, CardId.LOVELY_LABRYNTH, LovelyLabrynthEffect); - AddExecutor(ExecutorType.Activate, CardId.ASH_BLOSSOM, DefaultAshBlossomAndJoyousSpring); + AddExecutor(ExecutorType.Activate, CardId.ARIANNA, AriannaEffect); // Link monsters summon and effects AddExecutor(ExecutorType.SpSummon, CardId.KNIGHTMARE_PHEONIX, KnightmarePheonix_LinkSummon); @@ -58,13 +72,18 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.SpellSet, CardId.SOLEMN_STRIKE, SolemnStrikeSet); AddExecutor(ExecutorType.SpellSet, CardId.EVENLY_MATCHED, EvenlyMatchedSet); - // Backrow activations AddExecutor(ExecutorType.Activate, CardId.DOGMATIKA_PUNISHMENT, DogmatikaPunishmentActivate); AddExecutor(ExecutorType.Activate, CardId.ERADICATOR_EPIDEMIC_VIRUS, EradicatorActivate); AddExecutor(ExecutorType.Activate, CardId.WELCOME_LABYRINTH, WelcomeLabrynthActivate); + AddExecutor(ExecutorType.Activate, CardId.WELCOME_LABYRINTH, Grave_WelcomeLabrynthActivate); AddExecutor(ExecutorType.Activate, CardId.SOLEMN_STRIKE, DefaultSolemnStrike); + // Chainblocks + AddExecutor(ExecutorType.Activate, CardId.CHANDRAGLIER, Grave_ChandraglierEffect); + AddExecutor(ExecutorType.Activate, CardId.COOCLOCK, Grave_CooclockEffect); + AddExecutor(ExecutorType.Activate, CardId.STOVIE_TORBIE, Grave_StovieTorbieEffect); + // GY effects AddExecutor(ExecutorType.Activate, CardId.ELDER_ENTITY_NTSS, ElderEntityNtssEffect); AddExecutor(ExecutorType.Activate, CardId.WIND_PEGASUS_IGNISTER, WindPegasusIngisterEffect); @@ -76,6 +95,72 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.Repos, CardId.ARIANNA, AriannaRepos); } + private bool Grave_CooclockEffect() + { + if (Card.Location == CardLocation.Grave) + { + AI.SelectOption(0); // first dialogue + AI.SelectOption(0); // choose add Cooclock to hand + return true; + }; + + return false; + } + + private bool Grave_ChandraglierEffect() + { + return Card.Location == CardLocation.Grave; + } + + private bool Grave_StovieTorbieEffect() + { + return Card.Location == CardLocation.Grave; + } + + // Preffer to always go first + public override bool OnSelectHand() + { + return true; + } + + private bool AriannaSummon() + { + return !ArrianaActivated; + } + + private bool Hand_LadyLabrynthActivate() + { + ClientCard evenlyMatched = Bot.Hand.GetFirstMatchingCard(card => card.IsCode(CardId.EVENLY_MATCHED)); + + if (evenlyMatched != null) + { + if (Duel.CurrentChain.Contains(evenlyMatched) && evenlyMatched.Owner == 0) + return false; + } + + + if (Card.Location == CardLocation.Hand) + { + if (Duel.Player == 0) return true; + else + { + if (Duel.Phase == DuelPhase.End) return true; + } + } + + return false; + } + + private bool Grave_WelcomeLabrynthActivate() + { + if (Card.Location == CardLocation.Grave) + AI.SelectPlace(SelectSTPlace(Card, true)); + + WelcomeLabrynth_GraveActivated = true; + + return true; + } + private bool KnightmareUnicornEffect() { IList cost = PrefferedDiscardCost(); @@ -142,9 +227,7 @@ private bool SolemnStrikeSet() return true; } - private bool WelcomeLabrynthActivated = false; - private bool ArrianaActivated = false; - private bool LadyLabrynthActivated = false; + List Impermanence_list = new List(); @@ -252,7 +335,7 @@ private bool TririgadeArmsEffect() private bool FunitureSummon() { - if (Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.WELCOME_LABYRINTH)).Count() == 0 || Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH)) + if (Bot.HasInHand(CardId.COOCLOCK) && Bot.HasInHandOrInSpellZone(CardId.WELCOME_LABYRINTH)) return true; return false; @@ -260,10 +343,8 @@ private bool FunitureSummon() private bool WelcomeLabrynthSet() { - if (Card.Location == CardLocation.Hand) - { + if (Card.Location == CardLocation.Hand && !WelcomeLabrynth_GraveActivated) AI.SelectPlace(SelectSTPlace(Card, true)); - } return !Bot.HasInSpellZone(CardId.WELCOME_LABYRINTH); } @@ -441,14 +522,6 @@ private bool EradicatorActivate() else return false; } - private bool ChandraglierSummon() - { - if (Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.WELCOME_LABYRINTH)).Count() == 0 || Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH)) - return true; - - return false; - } - private bool LabrynthLabyrinthActivate() { if (Card.Location == CardLocation.SpellZone && Card.IsFaceup()) // special summon labrynth monster effect @@ -467,7 +540,7 @@ private bool LabrynthLabyrinthActivate() } else { - if (!Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH)) return true; + if (!Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH) && Bot.HasInHandOrInSpellZone(CardId.WELCOME_LABYRINTH)) return true; else if (Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH) && Card.Location == CardLocation.SpellZone && Card.IsFacedown()) return true; return false; @@ -476,15 +549,18 @@ private bool LabrynthLabyrinthActivate() private bool MuckarackerEffect() { - int[] prefferedMonsters = new int[] + List prefferedMonsters = new List { - CardId.LOVELY_LABRYNTH, - CardId.LADY_LABRYNTH + CardId.LOVELY_LABRYNTH, + CardId.LADY_LABRYNTH }; + if (!ArrianaActivated) + prefferedMonsters.Add(CardId.ARIANNA); + List cost = PrefferedDiscardCost(); - if (cost.Count() > 0 && Bot.HasInGraveyard(CardId.LADY_LABRYNTH) || Bot.HasInGraveyard(CardId.LOVELY_LABRYNTH)) + if (cost.Count() > 0 && Bot.HasInGraveyard(CardId.LADY_LABRYNTH) || Bot.HasInGraveyard(CardId.LOVELY_LABRYNTH) && !(Bot.HasInMonstersZone(CardId.LADY_LABRYNTH) && Bot.HasInMonstersZone(CardId.LOVELY_LABRYNTH))) { AI.SelectCard(prefferedMonsters); AI.SelectNextCard(cost); @@ -492,27 +568,25 @@ private bool MuckarackerEffect() return true; } - // Protect Key MOnsters - if (Card.Location == CardLocation.MonsterZone) + // Protect Key Monsters + if (LovelyIsChainTarget || LadyIsChainTarget) { if (ActivateDescription == Util.GetStringId(CardId.MUCKRACKER, 0)) { - List cost_candidates = new List(); + List cost_candidates = new List() + { + CardId.CHANDRAGLIER, + CardId.STOVIE_TORBIE, + CardId.COOCLOCK, + CardId.ARIANNA, + CardId.MUCKRACKER + }; if (Enemy.BattlingMonster != null) { if (Enemy.BattlingMonster.IsCode(CardId.LOVELY_LABRYNTH) || Enemy.BattlingMonster.IsCode(CardId.LOVELY_LABRYNTH)) { - cost_candidates.AddRange(new List() { - CardId.CHANDRAGLIER, - CardId.STOVIE_TORBIE, - CardId.COOCLOCK, - CardId.ARIANNA, - CardId.MUCKRACKER - }); - AI.SelectThirdCard(cost_candidates); - return true; } return false; @@ -525,19 +599,9 @@ private bool MuckarackerEffect() private bool MuckarackerLinkSummon() { - int bot_Monsters = Bot.MonsterZone.GetMatchingCards(card => card.Level <= 4).Count(); + IList materials = Bot.MonsterZone.GetMatchingCards(card => card.Level <= 4); int bot_HandCards = Bot.Hand.Count(); - int[] materials = new int[] - { - CardId.STOVIE_TORBIE, - CardId.CHANDRAGLIER, - CardId.ARIANNA, - CardId.COOCLOCK, - CardId.KNIGHTMARE_PHEONIX, - CardId.KNIGHTMARE_UNICORN - }; - if (bot_HandCards >= 1 && !Bot.HasInMonstersZone(CardId.MUCKRACKER) && (Bot.HasInMonstersZoneOrInGraveyard(CardId.LADY_LABRYNTH) || Bot.HasInMonstersZoneOrInGraveyard(CardId.LOVELY_LABRYNTH))) { AI.SelectMaterials(materials); @@ -593,32 +657,32 @@ private bool LadyLabrynthRepos() private bool LadyLabrynthActivate() { - if (Util.GetProblematicEnemyCard() != null && Bot.SpellZone.GetMatchingCards(card => card.HasPosition(CardPosition.FaceDown)).Count() == 0) return false; - - int[] prefferedTraps = new int[] + if (Card.Location == CardLocation.MonsterZone) { - CardId.DOGMATIKA_PUNISHMENT, - CardId.COMPULSORY_EVACUATION_DEVICE - }; + int[] prefferedTraps = new int[] + { + CardId.DOGMATIKA_PUNISHMENT, + CardId.COMPULSORY_EVACUATION_DEVICE + }; - IList enemySpellZone = Enemy.SpellZone.GetMatchingCards(card => - card.HasType(CardType.Spell) - || card.HasType(CardType.Trap) - || card.HasPosition(CardPosition.FaceDown) - ); + if (!Bot.HasInHandOrInSpellZoneOrInGraveyard(CardId.ERADICATOR_EPIDEMIC_VIRUS)) + { + ClientCard eradicator = Bot.Deck.GetFirstMatchingCard(card => card.IsCode(CardId.ERADICATOR_EPIDEMIC_VIRUS)); + AI.SelectCard(CardId.ERADICATOR_EPIDEMIC_VIRUS); + AI.SelectPlace(SelectSTPlace(eradicator, true)); + } + else if (!Bot.HasInHandOrInSpellZoneOrInGraveyard(CardId.WELCOME_LABYRINTH)) + { + ClientCard WelcomeLabrynth = Bot.Deck.GetFirstMatchingCard(card => card.IsCode(CardId.WELCOME_LABYRINTH)); + AI.SelectCard(CardId.WELCOME_LABYRINTH); + AI.SelectPlace(SelectSTPlace(WelcomeLabrynth, true)); + } + else AI.SelectCard(prefferedTraps); - if (!Bot.HasInHandOrInSpellZoneOrInGraveyard(CardId.ERADICATOR_EPIDEMIC_VIRUS)) - { - ClientCard eradicator = Bot.Deck.GetFirstMatchingCard(card => card.IsCode(CardId.ERADICATOR_EPIDEMIC_VIRUS)); - AI.SelectCard(CardId.ERADICATOR_EPIDEMIC_VIRUS); - AI.SelectPlace(SelectSTPlace(eradicator, true)); + return true; } - - else AI.SelectCard(prefferedTraps); - - LadyLabrynthActivated = true; - return true; + return false; } private bool EvenlyMatchedActivate() @@ -672,7 +736,11 @@ public override void OnNewTurn() LadyLabrynthActivated = false; WelcomeLabrynthActivated = false; ArrianaActivated = false; - } + WelcomeLabrynth_GraveActivated = false; + + LovelyIsChainTarget = false; + LadyIsChainTarget = false; + } public override CardPosition OnSelectPosition(int CardID, IList positions) { @@ -684,10 +752,15 @@ public override CardPosition OnSelectPosition(int CardID, IList po { return CardPosition.FaceUpAttack; } - else if ((CardID == CardId.ARIANNA || CardID == CardId.CHANDRAGLIER) && !Util.IsAllEnemyBetter()) + else if (CardID == CardId.CHANDRAGLIER && !Util.IsAllEnemyBetter()) { return CardPosition.FaceUpAttack; } + else if (CardID == CardId.ARIANNA) + { + if(Duel.Player != 0 || Util.IsAllEnemyBetter()) + return CardPosition.FaceUpDefence; + } return base.OnSelectPosition(CardID, positions); } @@ -707,23 +780,40 @@ private bool SolemnStrikeActivate() private bool LovelyLabrynthEffect() { - int[] supportTraps = new int[] { - CardId.WELCOME_LABYRINTH, - CardId.COMPULSORY_EVACUATION_DEVICE, - CardId.DOGMATIKA_PUNISHMENT - }; + if (Util.IsChainTarget(Card)) + LovelyIsChainTarget = true; - if (Bot.HasInGraveyard(CardId.ERADICATOR_EPIDEMIC_VIRUS)) + if (ActivateDescription == Util.GetStringId(CardId.LOVELY_LABRYNTH, 0)) { - ClientCard eradicator = Bot.Deck.GetFirstMatchingCard(card => card.IsCode(CardId.ERADICATOR_EPIDEMIC_VIRUS)); - AI.SelectCard(CardId.ERADICATOR_EPIDEMIC_VIRUS); - AI.SelectPlace(SelectSTPlace(eradicator, true)); + ClientCard problemCard = Util.GetProblematicEnemyCard(); + + if (problemCard == null || Enemy.GetHandCount() <= 3) AI.SelectOption(1); // Destroy 1 card from opponent's hand + else AI.SelectOption(2); // Destroy 1 card from opponent's field + + return true; } - else - AI.SelectCard(supportTraps); + { + int[] supportTraps = new int[] { + CardId.WELCOME_LABYRINTH, + CardId.COMPULSORY_EVACUATION_DEVICE, + CardId.DOGMATIKA_PUNISHMENT + }; - return true; + if (!Bot.HasInHandOrInSpellZone(CardId.WELCOME_LABYRINTH)) AI.SelectCard(CardId.WELCOME_LABYRINTH); + else if (!Bot.HasInHandOrInSpellZone(CardId.COMPULSORY_EVACUATION_DEVICE)) AI.SelectCard(CardId.COMPULSORY_EVACUATION_DEVICE); + else AI.SelectCard(CardId.DOGMATIKA_PUNISHMENT); + + if (Bot.HasInGraveyard(CardId.ERADICATOR_EPIDEMIC_VIRUS)) + { + ClientCard eradicator = Bot.Deck.GetFirstMatchingCard(card => card.IsCode(CardId.ERADICATOR_EPIDEMIC_VIRUS)); + AI.SelectCard(CardId.ERADICATOR_EPIDEMIC_VIRUS); + AI.SelectPlace(SelectSTPlace(eradicator, true)); + } + else AI.SelectCard(supportTraps); + + return true; + } } private bool CompulsoryEvacuationDeviceActivate() @@ -758,37 +848,29 @@ public bool isEvenlyMatchedOnHand() public bool WelcomeLabrynthActivate() { - if(Duel.Player == 0 && !(Duel.Phase == DuelPhase.Main1 || Duel.Phase == DuelPhase.Main2)) + if (Duel.Player == 0 && !(Duel.Phase == DuelPhase.Main1 || Duel.Phase == DuelPhase.Main2)) return false; - // Let Labrynth Labyrinth resolve before activating welcome + // Let Labrynth Labyrinth resolve before activating Welcome if (Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH) && Duel.CurrentChain.Count() > 0) { if (Duel.CurrentChain.ContainsCardWithId(CardId.LABRYNTH_LABYRINTH)) return false; } - List preferred_Monsters = new List(); - - if (!Bot.HasInMonstersZoneOrInGraveyard(CardId.LOVELY_LABRYNTH)) - preferred_Monsters.Add(CardId.LOVELY_LABRYNTH); - if (!Bot.HasInHandOrHasInMonstersZone(CardId.LADY_LABRYNTH)) - preferred_Monsters.Add(CardId.LADY_LABRYNTH); - if(Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardId.LADY_LABRYNTH) && Bot.HasInMonstersZoneOrInGraveyard(CardId.LOVELY_LABRYNTH) || ArrianaActivated != false) - preferred_Monsters.Add(CardId.ARIANNA); + //Special summons + if (Duel.Turn <= 2 && !ArrianaActivated && Duel.Player != 0) AI.SelectCard(CardId.ARIANNA); + else if (Bot.HasInMonstersZone(CardId.LADY_LABRYNTH)) AI.SelectCard(CardId.LOVELY_LABRYNTH); + else AI.SelectCard(CardId.LADY_LABRYNTH); - AI.SelectCard(preferred_Monsters); - - WelcomeLabrynthActivated = true; - - // Added destroy one card effect by Labrynth Labirynth to Welcome Labrynth if (Card.Location == CardLocation.SpellZone) { + // Appended effect from Labrynth Labirynth to Welcome Labrynth if (ActivateDescription == Util.GetStringId(CardId.WELCOME_LABYRINTH, 0)) { - ClientCard problemCard = Util.GetBestEnemyCard(false,true); + ClientCard problemCard = Util.GetBestEnemyMonster(false, true); - if (problemCard != null && Enemy.GetFieldCount() > 0) + if (problemCard != null || Enemy.GetMonsterCount() > 0) { AI.SelectYesNo(true); AI.SelectNextCard(problemCard); @@ -801,13 +883,11 @@ public bool WelcomeLabrynthActivate() return false; }; } - } - else if (Card.Location == CardLocation.Grave) - { - AI.SelectPlace(SelectSTPlace(Card, true)); + + WelcomeLabrynthActivated = true; } - return true; + return false; } public bool AriannaEffect() @@ -850,12 +930,6 @@ public bool CooclockEffect() && Duel.Player == 0 && Bot.MonsterZone.GetMatchingCards(card => card.HasRace(CardRace.Fiend)).Count() > 0) return true; - else if (Card.Location == CardLocation.Grave) - { - AI.SelectOption(0); // first dialogue - AI.SelectOption(0); // choose add Cooclock to hand - return true; - }; return false; } @@ -875,32 +949,29 @@ public bool FurnitureActivation() return false; } - if (Card.Location == CardLocation.Hand && Duel.Phase == DuelPhase.Main1 || Duel.Phase == DuelPhase.Main2) + if (Card.Location == CardLocation.Hand) { - if (Bot.Hand.GetCardCount(CardId.WELCOME_LABYRINTH) == 0 && Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH)) - return false; - - // Look for duplicate copies of the same card or Chandraglier and use them as materials. - List cost_candidates = new List(); - - if (Bot.HasInHand(CardId.CHANDRAGLIER) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.CHANDRAGLIER)).Count() > 1) - cost_candidates.Add(CardId.CHANDRAGLIER); - else if (Bot.HasInHand(CardId.LOVELY_LABRYNTH)) - cost_candidates.Add(CardId.LOVELY_LABRYNTH); - else if (Bot.HasInHand(CardId.LABRYNTH_LABYRINTH) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.LABRYNTH_LABYRINTH)).Count() > 1) - cost_candidates.Add(CardId.LABRYNTH_LABYRINTH); - else if (Bot.HasInHand(CardId.STOVIE_TORBIE) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.STOVIE_TORBIE)).Count() > 1) - cost_candidates.Add(CardId.STOVIE_TORBIE); - else if (Bot.HasInHand(CardId.LORD_OF_HEAVENLY_PRISON) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.LORD_OF_HEAVENLY_PRISON)).Count() > 1) - cost_candidates.Add(CardId.LORD_OF_HEAVENLY_PRISON); - else if (Duel.Turn > 2) - cost_candidates.Add(CardId.NIBIRU); - else cost_candidates.AddRange(new List() { CardId.POT_OF_PROSPERITY, CardId.COOCLOCK }); - - // Get the next Labrynth spell and trap - - if (Duel.Player == 0) + if (Duel.Phase == DuelPhase.End && !Bot.HasInHandOrInSpellZone(CardId.WELCOME_LABYRINTH)) { + // Look for duplicate copies of the same card or Chandraglier and use them as materials. + List cost_candidates = new List(); + + if (Bot.HasInHand(CardId.CHANDRAGLIER)) + cost_candidates.Add(CardId.CHANDRAGLIER); + else if (Bot.HasInHand(CardId.STOVIE_TORBIE)) + cost_candidates.Add(CardId.STOVIE_TORBIE); + else if (Bot.HasInHand(CardId.COOCLOCK)) + cost_candidates.Add(CardId.LOVELY_LABRYNTH); + else if (Bot.HasInHand(CardId.LOVELY_LABRYNTH)) + cost_candidates.Add(CardId.LOVELY_LABRYNTH); + else if (Bot.HasInHand(CardId.LABRYNTH_LABYRINTH) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.LABRYNTH_LABYRINTH)).Count() > 1) + cost_candidates.Add(CardId.LABRYNTH_LABYRINTH); + else if (Bot.HasInHand(CardId.LORD_OF_HEAVENLY_PRISON) && Bot.Hand.GetMatchingCards(card => card.IsCode(CardId.LORD_OF_HEAVENLY_PRISON)).Count() > 1) + cost_candidates.Add(CardId.LORD_OF_HEAVENLY_PRISON); + else if (Duel.Turn > 2) + cost_candidates.Add(CardId.NIBIRU); + + // Get the next Labrynth spell and trap if (cost_candidates.Count() > 0) { AI.SelectCard(cost_candidates); @@ -916,31 +987,9 @@ public bool FurnitureActivation() AI.SelectNextCard(CardId.LABRYNTH_LABYRINTH); return true; } - - return false; } } } - else if (Card.Location == CardLocation.Grave) return true; - else if (Card.Location == CardLocation.MonsterZone) - { - if (Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH)) - { - int remaining_welcomes = Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.WELCOME_LABYRINTH)).Count(); - - if (remaining_welcomes > 0) - { - AI.SelectNextCard(CardId.WELCOME_LABYRINTH); - return true; - } - else return false; - } - else - { - AI.SelectNextCard(CardId.LABRYNTH_LABYRINTH); - return true; - } - }; return false; } From cc71fc36ede70420b67457d462807a4eefa62e9b Mon Sep 17 00:00:00 2001 From: jdistro07 Date: Sat, 9 Mar 2024 21:22:32 +0800 Subject: [PATCH 20/21] - Enhancements on Muckraker - Added Monster Zone effect to Furnitures --- Game/AI/Decks/BudgetLabrynths.cs | 80 +++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 12 deletions(-) diff --git a/Game/AI/Decks/BudgetLabrynths.cs b/Game/AI/Decks/BudgetLabrynths.cs index ecb4ce58..8b99db88 100644 --- a/Game/AI/Decks/BudgetLabrynths.cs +++ b/Game/AI/Decks/BudgetLabrynths.cs @@ -2,6 +2,8 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Runtime.Remoting; +using System.Threading; using System.Web.UI; using YGOSharp.OCGWrapper.Enums; @@ -19,6 +21,11 @@ public class BudgetLabrynths : DefaultExecutor private bool LovelyIsChainTarget = false; private bool LadyIsChainTarget = false; + //Furniture Monster Zone activations + private bool MonsterZoneQE_StovieTorbieEffect = false; + private bool MonsterZoneQE_ChandraglierEffect = false; + + public BudgetLabrynths(GameAI ai, Duel duel) : base(ai, duel) { @@ -37,8 +44,9 @@ public BudgetLabrynths(GameAI ai, Duel duel) // Furntures AddExecutor(ExecutorType.Activate, CardId.STOVIE_TORBIE, StovieTorbieEffect); - + AddExecutor(ExecutorType.Activate, CardId.STOVIE_TORBIE, MonsterZone_StovieTorbieEffect); AddExecutor(ExecutorType.Activate, CardId.CHANDRAGLIER, ChandraglierEffect); + AddExecutor(ExecutorType.Activate, CardId.CHANDRAGLIER, MonsterZone_ChandraglierEffect); //Labrynth Spell Traps AddExecutor(ExecutorType.Activate, CardId.LABRYNTH_LABYRINTH, LabrynthLabyrinthActivate); @@ -95,6 +103,51 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.Repos, CardId.ARIANNA, AriannaRepos); } + public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender) + { + //Empen + if (attacker.IsCode(CardId.STOVIE_TORBIE)) + MonsterZoneQE_StovieTorbieEffect = true; + + //Slacker Magician + if (attacker.IsCode(CardId.CHANDRAGLIER)) + MonsterZoneQE_ChandraglierEffect = true; + + return base.OnPreBattleBetween(attacker, defender); + } + + private bool MonsterZone_ChandraglierEffect() + { + return FurnitureActivateQEWhenTargeted(MonsterZoneQE_ChandraglierEffect, Card); + } + + private bool FurnitureActivateQEWhenTargeted(bool activateQE, ClientCard targetedCard) + { + if (Card.Location == CardLocation.MonsterZone) + { + int available_welcomes = Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.WELCOME_LABYRINTH)).Count(); + int available_Labrynth_Labrynths = !Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH) ? 0 : Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.LABRYNTH_LABYRINTH)).Count(); + + int availableSearchables = available_welcomes + available_Labrynth_Labrynths; + + if (Util.IsChainTarget(targetedCard) && availableSearchables > 0) + return true; + + if (Enemy.BattlingMonster != null) + { + if (Enemy.BattlingMonster.IsCode(targetedCard.Id) && activateQE) + return true; + } + } + + return false; + } + + private bool MonsterZone_StovieTorbieEffect() + { + return FurnitureActivateQEWhenTargeted(MonsterZoneQE_StovieTorbieEffect, Card); + } + private bool Grave_CooclockEffect() { if (Card.Location == CardLocation.Grave) @@ -569,11 +622,9 @@ private bool MuckarackerEffect() } // Protect Key Monsters - if (LovelyIsChainTarget || LadyIsChainTarget) + if (ActivateDescription == Util.GetStringId(CardId.MUCKRACKER, 0)) { - if (ActivateDescription == Util.GetStringId(CardId.MUCKRACKER, 0)) - { - List cost_candidates = new List() + List cost_candidates = new List() { CardId.CHANDRAGLIER, CardId.STOVIE_TORBIE, @@ -582,15 +633,17 @@ private bool MuckarackerEffect() CardId.MUCKRACKER }; - if (Enemy.BattlingMonster != null) + if (Enemy.BattlingMonster != null) + { + if(LovelyIsChainTarget || LadyIsChainTarget && Duel.LastChainPlayer != 0) + return true; + + if (Enemy.BattlingMonster.IsCode(CardId.LOVELY_LABRYNTH) || Enemy.BattlingMonster.IsCode(CardId.LOVELY_LABRYNTH)) { - if (Enemy.BattlingMonster.IsCode(CardId.LOVELY_LABRYNTH) || Enemy.BattlingMonster.IsCode(CardId.LOVELY_LABRYNTH)) - { - AI.SelectThirdCard(cost_candidates); - return true; - } - return false; + AI.SelectThirdCard(cost_candidates); + return true; } + return false; } } @@ -740,6 +793,9 @@ public override void OnNewTurn() LovelyIsChainTarget = false; LadyIsChainTarget = false; + + MonsterZoneQE_StovieTorbieEffect = false; + MonsterZoneQE_ChandraglierEffect = false; } public override CardPosition OnSelectPosition(int CardID, IList positions) From 12cacb7b6c6cfd1026292982c97dcf5430d18e72 Mon Sep 17 00:00:00 2001 From: jdistro07 Date: Sat, 9 Mar 2024 21:44:29 +0800 Subject: [PATCH 21/21] Fixes on furniture monster effects while po monster zone --- Game/AI/Decks/BudgetLabrynths.cs | 39 ++++++++++++++++---------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/Game/AI/Decks/BudgetLabrynths.cs b/Game/AI/Decks/BudgetLabrynths.cs index 8b99db88..29e68c5a 100644 --- a/Game/AI/Decks/BudgetLabrynths.cs +++ b/Game/AI/Decks/BudgetLabrynths.cs @@ -103,25 +103,29 @@ public BudgetLabrynths(GameAI ai, Duel duel) AddExecutor(ExecutorType.Repos, CardId.ARIANNA, AriannaRepos); } - public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender) + private bool MonsterZone_ChandraglierEffect() { - //Empen - if (attacker.IsCode(CardId.STOVIE_TORBIE)) - MonsterZoneQE_StovieTorbieEffect = true; + if (Card.Location == CardLocation.MonsterZone) + { + int available_welcomes = Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.WELCOME_LABYRINTH)).Count(); + int available_Labrynth_Labrynths = !Bot.HasInSpellZone(CardId.LABRYNTH_LABYRINTH) ? 0 : Bot.Deck.GetMatchingCards(card => card.IsCode(CardId.LABRYNTH_LABYRINTH)).Count(); - //Slacker Magician - if (attacker.IsCode(CardId.CHANDRAGLIER)) - MonsterZoneQE_ChandraglierEffect = true; + int availableSearchables = available_welcomes + available_Labrynth_Labrynths; - return base.OnPreBattleBetween(attacker, defender); - } + if (Util.IsChainTarget(Card) && availableSearchables > 0) + return true; - private bool MonsterZone_ChandraglierEffect() - { - return FurnitureActivateQEWhenTargeted(MonsterZoneQE_ChandraglierEffect, Card); + if (Enemy.BattlingMonster != null) + { + if (Enemy.BattlingMonster.IsCode(Card.Id) && availableSearchables > 0) + return true; + } + } + + return false; } - private bool FurnitureActivateQEWhenTargeted(bool activateQE, ClientCard targetedCard) + private bool MonsterZone_StovieTorbieEffect() { if (Card.Location == CardLocation.MonsterZone) { @@ -130,12 +134,12 @@ private bool FurnitureActivateQEWhenTargeted(bool activateQE, ClientCard targete int availableSearchables = available_welcomes + available_Labrynth_Labrynths; - if (Util.IsChainTarget(targetedCard) && availableSearchables > 0) + if (Util.IsChainTarget(Card) && availableSearchables > 0) return true; if (Enemy.BattlingMonster != null) { - if (Enemy.BattlingMonster.IsCode(targetedCard.Id) && activateQE) + if (Enemy.BattlingMonster.IsCode(Card.Id) && availableSearchables > 0) return true; } } @@ -143,11 +147,6 @@ private bool FurnitureActivateQEWhenTargeted(bool activateQE, ClientCard targete return false; } - private bool MonsterZone_StovieTorbieEffect() - { - return FurnitureActivateQEWhenTargeted(MonsterZoneQE_StovieTorbieEffect, Card); - } - private bool Grave_CooclockEffect() { if (Card.Location == CardLocation.Grave)