From 2d643d8b04c31224ef9db7124b890691ddf5f60f Mon Sep 17 00:00:00 2001 From: SailTheWaterway <70589943+SailTheWaterway@users.noreply.github.com> Date: Tue, 30 Aug 2022 00:46:39 -0400 Subject: [PATCH 1/7] Add files via upload --- Decks/AI_Benkei.ydk | 74 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 Decks/AI_Benkei.ydk diff --git a/Decks/AI_Benkei.ydk b/Decks/AI_Benkei.ydk new file mode 100644 index 00000000..ba3bc7f6 --- /dev/null +++ b/Decks/AI_Benkei.ydk @@ -0,0 +1,74 @@ +#created by M +#main +2563463 +84430950 +84430950 +84430950 +30680659 +30680659 +30680659 +22609617 +22609617 +22609617 +21015833 +14558127 +14558127 +14558127 +3285551 +3285551 +3285551 +14532163 +14532163 +14532163 +18144506 +32807846 +49238328 +49238328 +49238328 +39568067 +14745409 +38745520 +40619825 +40619825 +40619825 +82432018 +82432018 +82432018 +83746708 +83746708 +83746708 +88610708 +88610708 +88610708 +#extra +18386170 +56910167 +27552504 +64276752 +94798725 +75215744 +21293424 +28781003 +12014404 +62709239 +83531441 +26692769 +9205573 +36609518 +58699500 +!side +55063751 +55063751 +55063751 +97268402 +97268402 +97268402 +12580477 +12580477 +12580477 +8267140 +8267140 +8267140 +10045474 +10045474 +10045474 From c8e4a5a817734f99bf34366535d6cb8a2ac2e330 Mon Sep 17 00:00:00 2001 From: SailTheWaterway <70589943+SailTheWaterway@users.noreply.github.com> Date: Tue, 30 Aug 2022 00:50:00 -0400 Subject: [PATCH 2/7] Added Ben Kei AI. --- Game/AI/Decks/BenkeiExecutor.cs | 280 ++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 Game/AI/Decks/BenkeiExecutor.cs diff --git a/Game/AI/Decks/BenkeiExecutor.cs b/Game/AI/Decks/BenkeiExecutor.cs new file mode 100644 index 00000000..105430ef --- /dev/null +++ b/Game/AI/Decks/BenkeiExecutor.cs @@ -0,0 +1,280 @@ +using YGOSharp.OCGWrapper.Enums; +using System.Collections.Generic; +using System.Linq; +using WindBot; +using WindBot.Game; +using WindBot.Game.AI; + +namespace WindBot.Game.AI.Decks +{ + [Deck("Benkei", "AI_Benkei")] + public class BenkeiExecutor : DefaultExecutor + { + public class CardId + { public const int WanderingGryphonRider = 2563463; + public const int Fateful = 39568067; + public const int Enchantress = 30680659; + public const int Aramesir = 3285551; + public const int AdventurerToken = 3285552; + public const int ReinforcementOfTheArmy = 32807846; + public const int Benkei = 84430950; + public const int PotofExtravagance = 49238328; + public const int Mataza = 22609617; + public const int Hayabusa = 21015833; + public const int LightningStorm = 14532163; + public const int Dracoback = 38745520; + public const int AxeDespair = 40619825; + public const int MaskBrutality = 82432018; + public const int MagePower = 83746708; + public const int BashingShield = 88610708; + public const int Gallatin = 14745409; + public const int Cowboy = 12014404; + } + public BenkeiExecutor(GameAI ai, Duel duel) + : base(ai, duel) + { + //Cowboy Burn + AddExecutor(ExecutorType.SpSummon, CardId.Cowboy, CowboySummon); + AddExecutor(ExecutorType.Activate, CardId.Cowboy); + //Counters + AddExecutor(ExecutorType.Activate, CardId.PotofExtravagance, PotActivate); + AddExecutor(ExecutorType.Activate, CardId.WanderingGryphonRider, GryphonEffect); + AddExecutor(ExecutorType.Activate, CardId.LightningStorm, LightningStormActivate); + AddExecutor(ExecutorType.Activate, _CardId.CosmicCyclone, DefaultCosmicCyclone); + AddExecutor(ExecutorType.Activate, _CardId.AshBlossom, DefaultAshBlossomAndJoyousSpring); + AddExecutor(ExecutorType.Activate, _CardId.EffectVeiler, DefaultEffectVeiler); + AddExecutor(ExecutorType.Activate, _CardId.InfiniteImpermanence, DefaultInfiniteImpermanence); + AddExecutor(ExecutorType.Activate, _CardId.HarpiesFeatherDuster, DefaultHarpiesFeatherDusterFirst); + AddExecutor(ExecutorType.Activate, _CardId.Raigeki, DefaultRaigeki); + AddExecutor(ExecutorType.SpSummon, _CardId.GamecieltheSeaTurtleKaiju, DefaultKaijuSpsummon); + AddExecutor(ExecutorType.Activate, _CardId.EvilswarmExcitonKnight, DefaultEvilswarmExcitonKnightEffect); + AddExecutor(ExecutorType.Activate, CardId.Dracoback, DracobackEffect); + AddExecutor(ExecutorType.Activate, CardId.Dracoback, DracobackEquip); + //OTK Setup + AddExecutor(ExecutorType.Activate, CardId.ReinforcementOfTheArmy, RotaSearch); + AddExecutor(ExecutorType.Summon, CardId.Benkei, WarriorSummon); + AddExecutor(ExecutorType.Summon, CardId.Mataza, WarriorSummon); + AddExecutor(ExecutorType.Summon, CardId.Hayabusa, WarriorSummon); + AddExecutor(ExecutorType.Activate, CardId.MagePower, WarriorEquip); + AddExecutor(ExecutorType.Activate, CardId.AxeDespair, WarriorEquip); + AddExecutor(ExecutorType.Activate, CardId.MaskBrutality, WarriorEquip); + AddExecutor(ExecutorType.Activate, CardId.BashingShield, WarriorEquip); + AddExecutor(ExecutorType.Activate, CardId.Gallatin, WarriorEquip); + //Adventurer Setup + AddExecutor(ExecutorType.Activate, CardId.Aramesir, AdventurerSummon); + AddExecutor(ExecutorType.Activate, CardId.Enchantress, EnchantressEffect); + AddExecutor(ExecutorType.Activate, CardId.Fateful, FatefulEffect); + AddExecutor(ExecutorType.Activate, CardId.WanderingGryphonRider, GryphonSummon); + //End of Main + AddExecutor(ExecutorType.SpellSet, DefaultSpellSet); + AddExecutor(ExecutorType.Repos, DefaultMonsterRepos); + } + public bool EnchantressUsed = false; + + public override void OnNewTurn() + { + EnchantressUsed = false; + } + + public override int OnSelectOption(IList options) + { + return Program.Rand.Next(options.Count); + } + + public override CardPosition OnSelectPosition(int cardId, IList positions) + { + YGOSharp.OCGWrapper.NamedCard cardData = YGOSharp.OCGWrapper.NamedCard.Get(cardId); + if (cardData != null) + { + if (cardData.Attack < 0) + return CardPosition.FaceUpAttack; + if (cardData.Attack <= 499) + return CardPosition.FaceUpDefence; + } + return 0; + } + private bool WarriorSummon() + { + if (Duel.Turn == 1) + return false; + else return true; + } + + private bool GryphonEffect() + { + if (Card.Location == CardLocation.Hand) + return false; + return Duel.LastChainPlayer == 1; + } + private bool GryphonSummon() + { + if (Card.Location != CardLocation.Hand) + return false; + if (Duel.Turn == 1) AI.SelectPosition(CardPosition.FaceUpDefence); + return Bot.HasInMonstersZone(CardId.AdventurerToken) || (Duel.Player == 0 && (Duel.LastChainPlayer == -1 || Bot.HasInSpellZone(CardId.Fateful))); + } + public bool AdventurerSummon() + { + if (Enemy.HasInGraveyard(43534808)) return false; //Token Collector + AI.SelectYesNo(true); + if (Duel.Turn == 1) AI.SelectPosition(CardPosition.FaceUpDefence); + return true; + } + private bool EnchantressEffect() + { + if (Card.Location == CardLocation.Grave) + { + AI.SelectCard(CardLocation.Deck); + EnchantressUsed = true; + return true; + } + if (ActivateDescription == Util.GetStringId(CardId.Enchantress, 0)) + { + // summon + return false; + } + else + { + // search + return !Bot.HasInHand(CardId.Aramesir) && !Bot.HasInMonstersZone(CardId.AdventurerToken); + } + } + private bool FatefulEffect() + { + if (Card.Location == CardLocation.Hand) + return false; + if (ActivateDescription == -1 || ActivateDescription == Util.GetStringId(CardId.Fateful, 1)) + { + // search equip to hand + AI.SelectOption(0); + return true; + } + else + { + // search rider or aquamancer + if (Bot.GetRemainingCount(CardId.WanderingGryphonRider, 1) == 0 || Bot.GetHandCount() == 0 || !Bot.HasInMonstersZone(CardId.AdventurerToken)) + { + AI.SelectCard(CardId.Enchantress); + if (Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardId.Enchantress)) + AI.SelectNextCard(CardId.Enchantress); + } + else + { + AI.SelectCard(CardId.WanderingGryphonRider); + } + return true; + } + } + public bool PotActivate() + { + if (SpellNegatable()) return false; + AI.SelectOption(1); + return true; + } + public bool SpellNegatable(bool isCounter = false, ClientCard target = null) + { + // target default set + if (target == null) target = Card; + // won't negate if not on field + if (target.Location != CardLocation.SpellZone && target.Location != CardLocation.Hand) return false; + + // negate judge + if (Enemy.HasInMonstersZone(99916754, true) && !isCounter) return true; //Naturia Exterio + if (target.IsSpell()) + { + if (Enemy.HasInMonstersZone(33198837, true)) return true; //Naturia Beast + if (Enemy.HasInSpellZone(61740673, true) || Enemy.HasInSpellZone(511002996, true)) return true; //Imperial Order + if (Enemy.HasInMonstersZone(37267041, true) || Bot.HasInMonstersZone(37267041, true)) return true; //Silent Swordsman + } + if (target.IsTrap()) + { + if (Enemy.HasInSpellZone(51452091, true) || Bot.HasInSpellZone(51452091, true)) return true; //Royal Decree + if (Enemy.HasInMonstersZone(73551138, true)) return true; //Gishki Emilia + if (Enemy.HasInSpellZone(37209439, true) || Bot.HasInSpellZone(37209439, true)) return true; //Dark Contract + } + // how to get here? + return false; + } + public bool RotaSearch() + { + AI.SelectCard(CardId.Benkei, CardId.Mataza, CardId.Hayabusa); + return true; + } + public bool LightningStormActivate() + { + int bestPower = 0; + foreach (ClientCard hand in Bot.Hand) + { + if (hand.IsMonster() && hand.Level <= 4 && hand.Attack > bestPower) bestPower = hand.Attack; + } + + int opt = -1; + // destroy monster + if (Enemy.MonsterZone.GetFirstMatchingCard(card => card.IsFloodgate() && card.IsAttack()) != null + || Enemy.MonsterZone.GetMatchingCardsCount(card => card.IsAttack() && card.Attack >= bestPower) >= 2) opt = 0; + // destroy spell/trap + else if (Enemy.GetSpellCount() >= 2 || Util.GetProblematicEnemySpell() != null) opt = 1; + + if (opt == -1) return false; + + // only one selection + if (Enemy.MonsterZone.GetFirstMatchingCard(card => card.IsAttack()) == null + || Enemy.GetSpellCount() == 0) + { + AI.SelectOption(0); + return true; + } + AI.SelectOption(opt); + return true; + } + private bool DracobackEffect() + { + if (Card.Location != CardLocation.SpellZone) + return false; + ClientCard target = Util.GetProblematicEnemyCard(); + AI.SelectCard(target); + return true; + } + + private bool DracobackEquip() + { + if (Card.Location == CardLocation.SpellZone) + return false; + if (Card.Location == CardLocation.Grave) + return true; + if (Bot.HasInMonstersZone(CardId.AdventurerToken, faceUp: true)) + { + AI.SelectCard(CardId.AdventurerToken); + return true; + } + return false; + } + private bool WarriorEquip() + { + if (Card.Location == CardLocation.SpellZone) + return false; + if (Duel.Turn == 1) + return false; + if (Bot.GetMonsterCount() > 0) + { + AI.SelectCard(CardId.Benkei, CardId.Mataza, CardId.Hayabusa, CardId.AdventurerToken, CardId.Enchantress); + return true; + } + return false; + } + public override bool OnSelectHand() + { + // Going second deck. + return false; + } + private bool CowboySummon() + { + if (Enemy.LifePoints <= 800 || (Bot.GetMonsterCount() >= 4 && Enemy.LifePoints <= 1600)) + { + AI.SelectPosition(CardPosition.FaceUpDefence); + return true; + } + return false; + } + } +} From e13ce0422976032aa5ab1b814d9ecd3a77f7ede5 Mon Sep 17 00:00:00 2001 From: SailTheWaterway <70589943+SailTheWaterway@users.noreply.github.com> Date: Tue, 30 Aug 2022 00:53:37 -0400 Subject: [PATCH 3/7] Added Ben Kei AI. --- bots.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bots.json b/bots.json index ea8077a4..d160e4ee 100644 --- a/bots.json +++ b/bots.json @@ -11,6 +11,12 @@ "difficulty": 3, "masterRules": [ 4, 5 ] }, + { + "name": "Ben Kei", + "deck": "Benkei", + "difficulty": 2, + "masterRules": [ 3, 4, 5 ] + }, { "name": "Blue-Eyes", "deck": "Blue-Eyes", From 4aa9d075e76f140ef7977c7bfee8500608b753f2 Mon Sep 17 00:00:00 2001 From: SailTheWaterway <70589943+SailTheWaterway@users.noreply.github.com> Date: Tue, 30 Aug 2022 00:55:28 -0400 Subject: [PATCH 4/7] Added Ben Kei AI. --- libWindbot.csproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libWindbot.csproj b/libWindbot.csproj index e4585c36..18fe7fdc 100644 --- a/libWindbot.csproj +++ b/libWindbot.csproj @@ -93,6 +93,7 @@ + @@ -145,4 +146,4 @@ if exist %25E4K_OUTPUT%25 rmdir /S /Q %25E4K_OUTPUT%25 --> - \ No newline at end of file + From a3e7f867ce08ee6bef8397c548d8207c374caa43 Mon Sep 17 00:00:00 2001 From: SailTheWaterway <70589943+SailTheWaterway@users.noreply.github.com> Date: Tue, 30 Aug 2022 00:57:17 -0400 Subject: [PATCH 5/7] Added Ben Kei AI. --- WindBot.csproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WindBot.csproj b/WindBot.csproj index ebb904a1..42b17cf1 100644 --- a/WindBot.csproj +++ b/WindBot.csproj @@ -106,6 +106,7 @@ + @@ -170,4 +171,4 @@ --> - \ No newline at end of file + From 011e21dd40cbf93d28a9c3e8349c246a24dcd52d Mon Sep 17 00:00:00 2001 From: SailTheWaterway <70589943+SailTheWaterway@users.noreply.github.com> Date: Tue, 30 Aug 2022 01:00:37 -0400 Subject: [PATCH 6/7] Added Ben Kei AI. --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2b801311..7ef28f66 100644 --- a/README.md +++ b/README.md @@ -12,15 +12,15 @@ Written in C# targeting .NET Framework 4. Use Visual Studio 2015 or newer. ## Available decks and executors * ABC * Altergeist +* Ben Kei * Blue-Eyes * Blue-Eyes Ritual * Burn * Chain Burn * Cyberse * Dark Magician -* Dragma +* Dogmatika * Dragunity -* Dragun of Red-Eyes * Frog * Gren Maju Stun * Horus @@ -32,6 +32,7 @@ Written in C# targeting .NET Framework 4. Use Visual Studio 2015 or newer. * Qliphort * R5NK * Rainbow +* Red-Eyes Dark Dragoon * Rose Scrap Synchro * Salamangreat * Sky Striker From 30532c2f3864eb52a9f5467a5966b45229ecc152 Mon Sep 17 00:00:00 2001 From: SailTheWaterway <70589943+SailTheWaterway@users.noreply.github.com> Date: Wed, 14 Dec 2022 01:03:14 -0500 Subject: [PATCH 7/7] Update BenkeiExecutor.cs --- Game/AI/Decks/BenkeiExecutor.cs | 44 ++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/Game/AI/Decks/BenkeiExecutor.cs b/Game/AI/Decks/BenkeiExecutor.cs index 105430ef..445c1824 100644 --- a/Game/AI/Decks/BenkeiExecutor.cs +++ b/Game/AI/Decks/BenkeiExecutor.cs @@ -11,7 +11,8 @@ namespace WindBot.Game.AI.Decks public class BenkeiExecutor : DefaultExecutor { public class CardId - { public const int WanderingGryphonRider = 2563463; + { + public const int WanderingGryphonRider = 2563463; public const int Fateful = 39568067; public const int Enchantress = 30680659; public const int Aramesir = 3285551; @@ -27,13 +28,13 @@ public class CardId public const int MaskBrutality = 82432018; public const int MagePower = 83746708; public const int BashingShield = 88610708; - public const int Gallatin = 14745409; + public const int Gallatin = 14745409; public const int Cowboy = 12014404; } public BenkeiExecutor(GameAI ai, Duel duel) : base(ai, duel) - { - //Cowboy Burn + { + //Cowboy Burn AddExecutor(ExecutorType.SpSummon, CardId.Cowboy, CowboySummon); AddExecutor(ExecutorType.Activate, CardId.Cowboy); //Counters @@ -55,9 +56,9 @@ public BenkeiExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Summon, CardId.Benkei, WarriorSummon); AddExecutor(ExecutorType.Summon, CardId.Mataza, WarriorSummon); AddExecutor(ExecutorType.Summon, CardId.Hayabusa, WarriorSummon); - AddExecutor(ExecutorType.Activate, CardId.MagePower, WarriorEquip); - AddExecutor(ExecutorType.Activate, CardId.AxeDespair, WarriorEquip); - AddExecutor(ExecutorType.Activate, CardId.MaskBrutality, WarriorEquip); + AddExecutor(ExecutorType.Activate, CardId.MagePower, GenericEquip); + AddExecutor(ExecutorType.Activate, CardId.AxeDespair, GenericEquip); + AddExecutor(ExecutorType.Activate, CardId.MaskBrutality, GenericEquip); AddExecutor(ExecutorType.Activate, CardId.BashingShield, WarriorEquip); AddExecutor(ExecutorType.Activate, CardId.Gallatin, WarriorEquip); //Adventurer Setup @@ -92,7 +93,7 @@ public override CardPosition OnSelectPosition(int cardId, IList po return CardPosition.FaceUpDefence; } return 0; - } + } private bool WarriorSummon() { if (Duel.Turn == 1) @@ -109,14 +110,14 @@ private bool GryphonEffect() private bool GryphonSummon() { if (Card.Location != CardLocation.Hand) - return false; + return false; if (Duel.Turn == 1) AI.SelectPosition(CardPosition.FaceUpDefence); return Bot.HasInMonstersZone(CardId.AdventurerToken) || (Duel.Player == 0 && (Duel.LastChainPlayer == -1 || Bot.HasInSpellZone(CardId.Fateful))); } public bool AdventurerSummon() { if (Enemy.HasInGraveyard(43534808)) return false; //Token Collector - AI.SelectYesNo(true); + AI.SelectYesNo(true); if (Duel.Turn == 1) AI.SelectPosition(CardPosition.FaceUpDefence); return true; } @@ -158,10 +159,6 @@ private bool FatefulEffect() if (Bot.HasInHandOrInMonstersZoneOrInGraveyard(CardId.Enchantress)) AI.SelectNextCard(CardId.Enchantress); } - else - { - AI.SelectCard(CardId.WanderingGryphonRider); - } return true; } } @@ -249,10 +246,10 @@ private bool DracobackEquip() } return false; } - private bool WarriorEquip() + private bool GenericEquip() { if (Card.Location == CardLocation.SpellZone) - return false; + return false; if (Duel.Turn == 1) return false; if (Bot.GetMonsterCount() > 0) @@ -262,11 +259,24 @@ private bool WarriorEquip() } return false; } + private bool WarriorEquip() + { + if (Card.Location == CardLocation.SpellZone) + return false; + if (Duel.Turn == 1) + return false; + if (Bot.GetMonsterCount() > 0) + { + AI.SelectCard(CardId.Benkei, CardId.Mataza, CardId.Hayabusa); + return true; + } + return false; + } public override bool OnSelectHand() { // Going second deck. return false; - } + } private bool CowboySummon() { if (Enemy.LifePoints <= 800 || (Bot.GetMonsterCount() >= 4 && Enemy.LifePoints <= 1600))