From f0c9682e0365c6dfc39aa6f788dd42beeb2a4c57 Mon Sep 17 00:00:00 2001 From: Wind2009-Louse Date: Mon, 26 Feb 2018 23:02:07 +0800 Subject: [PATCH 01/68] Update TrickstarExecutor.cs Lycoris won't activate endlessly Scapegoat's token won't turn to attack --- Game/AI/Decks/TrickstarExecutor.cs | 57 ++++++++++++++++++------------ 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/Game/AI/Decks/TrickstarExecutor.cs b/Game/AI/Decks/TrickstarExecutor.cs index e3aefe05..13179b15 100644 --- a/Game/AI/Decks/TrickstarExecutor.cs +++ b/Game/AI/Decks/TrickstarExecutor.cs @@ -64,6 +64,7 @@ public int getLinkMarker(int id) bool snake_four_s = false; bool tuner_eff_used = false; bool crystal_eff_used = false; + int red_ss_count = 0; public TrickstarExecutor(GameAI ai, Duel duel) : base(ai, duel) @@ -480,43 +481,35 @@ public bool Eater_ss() public bool Red_ss() { - if (Duel.Player == 0) + if (red_ss_count >= 9) return false; + if (LastChainPlayer == 0 && GetLastChainCard().Id == CardId.Red) { - if (LastChainPlayer == 0 && GetLastChainCard().Id == CardId.Red) + foreach (ClientCard m in Bot.GetMonsters()) { - foreach(ClientCard m in Bot.GetMonsters()) + if (AI.Utils.IsChainTarget(m)) { - if (AI.Utils.IsChainTarget(m)) - { - AI.SelectCard(m); - return true; - } + red_ss_count += 1; + AI.SelectCard(m); + return true; } } - if (LastChainPlayer == 1) return true; + } + if (LastChainPlayer == 1) return true; + if (Duel.Player == 0) + { if (AI.Utils.IsTurn1OrMain2()) return false; if (Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2) { - if (Duel.Player == 1) - { - if (!Bot.HasInHand(CardId.White) && AI.Utils.IsOneEnemyBetterThanValue(1600, true)) - { - AI.SelectPosition(CardPosition.FaceUpDefence); - } - else if (Bot.HasInHand(CardId.White) && AI.Utils.IsOneEnemyBetterThanValue(3200, true)) - { - AI.SelectPosition(CardPosition.FaceUpDefence); - } - } List self_m = Bot.GetMonsters(); ClientCard tosolve_enemy = AI.Utils.GetOneEnemyBetterThanMyBest(); foreach (ClientCard c in self_m) { - if (c.Id == CardId.Yellow || c.Id == CardId.Pink || c.Id == CardId.White) + if (IsTrickstar(c.Id)) { if (c.Attacked) { AI.SelectCard(c); + red_ss_count += 1; return true; } if (tosolve_enemy != null) @@ -524,11 +517,19 @@ public bool Red_ss() if (Bot.HasInHand(CardId.White) && c.Attack * 2 < tosolve_enemy.Attack) { AI.SelectCard(c); + red_ss_count += 1; + return true; + } + if (!Bot.HasInHand(CardId.White) && tosolve_enemy.Attack <= 3200 && c.Id == CardId.White) + { + AI.SelectCard(c); + red_ss_count += 1; return true; } if (!Bot.HasInHand(CardId.White) && c.Attack < tosolve_enemy.Attack) { AI.SelectCard(c); + red_ss_count += 1; return true; } } @@ -537,11 +538,19 @@ public bool Red_ss() } } else { - if (LastChainPlayer == 1) return true; if (Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2) { + if (!Bot.HasInHand(CardId.White) && AI.Utils.IsOneEnemyBetterThanValue(1600, true)) + { + AI.SelectPosition(CardPosition.FaceUpDefence); + } + else if (Bot.HasInHand(CardId.White) && AI.Utils.IsOneEnemyBetterThanValue(3200, true)) + { + AI.SelectPosition(CardPosition.FaceUpDefence); + } if (AI.Utils.GetOneEnemyBetterThanMyBest() != null) { + red_ss_count += 1; return true; } } @@ -916,7 +925,7 @@ public bool Safedragon_ss() ClientCard m = AI.Utils.GetProblematicEnemyMonster(); if (m == null) { - return (Enemy.GetMonsterCount() == 0 && Duel.LifePoints[1] <= 1100); + return (Enemy.GetMonsterCount() == 0 && Duel.LifePoints[1] <= 1100 && Duel.Phase < DuelPhase.Battle); } ClientCard ex_1 = Bot.MonsterZone[5]; ClientCard ex_2 = Bot.MonsterZone[6]; @@ -1067,6 +1076,7 @@ public bool Snake_eff() public bool MonsterRepos() { if (Card.Id == CardId.Eater) return false; + if (Card.Id == CardId.Sheep + 1) return false; bool enemyBetter = AI.Utils.IsAllEnemyBetter(true); if (Card.IsAttack() && enemyBetter) @@ -1089,6 +1099,7 @@ public override void OnNewTurn() pink_ss = false; snake_four_s = false; crystal_eff_used = false; + red_ss_count = 0; } public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender) From 23ca5d1bbebc20c02d81d5d59b401526bcf24216 Mon Sep 17 00:00:00 2001 From: Wind2009-Louse Date: Mon, 26 Feb 2018 23:08:45 +0800 Subject: [PATCH 02/68] Update Trickstar deck --- Decks/AI_Trickstar.ydk | 24 +- Game/AI/Decks/TrickstarExecutor.cs | 401 +++++++++++++++++++++++++---- 2 files changed, 362 insertions(+), 63 deletions(-) diff --git a/Decks/AI_Trickstar.ydk b/Decks/AI_Trickstar.ydk index b9d27395..1b07d6d5 100644 --- a/Decks/AI_Trickstar.ydk +++ b/Decks/AI_Trickstar.ydk @@ -22,8 +22,6 @@ 63845230 63845230 63845230 -5133471 -5133471 18144506 35261759 35261759 @@ -34,6 +32,8 @@ 35371948 35371948 35371948 +10813327 +10813327 21076084 83555666 40605147 @@ -42,18 +42,18 @@ 84749824 #extra 41999284 -99111753 -98558751 -50588353 -2857636 -38342335 -41999284 -74997493 +3987233 41999284 -74997493 50588353 +98558751 +74997493 2857636 -99111753 38342335 -98978921 +99111753 +31833038 +3987233 +50588353 +41999284 +9753964 +34408491 !side diff --git a/Game/AI/Decks/TrickstarExecutor.cs b/Game/AI/Decks/TrickstarExecutor.cs index 13179b15..3dd107f8 100644 --- a/Game/AI/Decks/TrickstarExecutor.cs +++ b/Game/AI/Decks/TrickstarExecutor.cs @@ -21,6 +21,7 @@ public class CardId public const int MG = 23434538; public const int Tuner = 67441435; public const int Eater = 63845230; + public const int LockBird = 94145021; public const int Feather = 18144506; public const int Galaxy = 5133471; @@ -34,27 +35,30 @@ public class CardId public const int Ring = 83555666; public const int Strike = 40605147; public const int Warn = 84749824; + public const int Grass = 10813327; public const int Linkuri = 41999284; public const int Linkspi = 98978921; public const int SafeDra = 99111753; public const int Crystal = 50588353; - public const int downer = 77058170; public const int phoneix = 2857636; public const int unicorn = 38342335; - public const int firewall = 5043010; public const int snake = 74997493; public const int borrel = 31833038; - public const int boomer = 5821478; public const int TG = 98558751; + public const int Beelze = 34408491; + public const int Abyss = 9753964; + public const int Exterio = 99916754; + + public const int Missus = 3987233; } public int getLinkMarker(int id) { if (id == CardId.borrel || id == CardId.snake) return 4; else if (id == CardId.unicorn) return 3; - else if (id == CardId.Crystal || id == CardId.phoneix || id == CardId.SafeDra) return 2; + else if (id == CardId.Crystal || id == CardId.phoneix || id == CardId.SafeDra || id == CardId.Missus) return 2; return 1; } @@ -65,6 +69,8 @@ public int getLinkMarker(int id) bool tuner_eff_used = false; bool crystal_eff_used = false; int red_ss_count = 0; + bool white_eff_used = false; + bool lockbird_useful = false; public TrickstarExecutor(GameAI ai, Duel duel) : base(ai, duel) @@ -73,9 +79,12 @@ public TrickstarExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.MG, G_act); AddExecutor(ExecutorType.Activate, CardId.Strike, DefaultSolemnStrike); AddExecutor(ExecutorType.Activate, CardId.Warn, DefaultSolemnWarning); + AddExecutor(ExecutorType.Activate, CardId.Grass, Grass_ss); AddExecutor(ExecutorType.Activate, CardId.Urara, Hand_act_eff); AddExecutor(ExecutorType.Activate, CardId.Ghost, Hand_act_eff); AddExecutor(ExecutorType.Activate, CardId.Ring, DefaultCompulsoryEvacuationDevice); + AddExecutor(ExecutorType.Activate, CardId.Abyss, Abyss_eff); + AddExecutor(ExecutorType.Activate, CardId.Exterio, Exterio_counter); // spell clean AddExecutor(ExecutorType.Activate, CardId.Stage, Stage_Lock); @@ -84,17 +93,22 @@ public TrickstarExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.TG, TG_eff); // ex_monster act + AddExecutor(ExecutorType.Activate, CardId.Beelze); + AddExecutor(ExecutorType.Activate, CardId.Missus, Missus_eff); AddExecutor(ExecutorType.Activate, CardId.Crystal, Crystal_eff); AddExecutor(ExecutorType.Activate, CardId.SafeDra, DefaultCompulsoryEvacuationDevice); AddExecutor(ExecutorType.Activate, CardId.Linkuri, Linkuri_eff); AddExecutor(ExecutorType.Activate, CardId.phoneix, Phoneix_eff); AddExecutor(ExecutorType.Activate, CardId.unicorn, Unicorn_eff); AddExecutor(ExecutorType.Activate, CardId.snake, Snake_eff); + AddExecutor(ExecutorType.Activate, CardId.borrel, Borrel_eff); AddExecutor(ExecutorType.Activate, CardId.Tuner,Tuner_eff); // ex ss AddExecutor(ExecutorType.SpSummon, CardId.snake, Snake_ss); + AddExecutor(ExecutorType.SpSummon, CardId.Missus, Missus_ss); + AddExecutor(ExecutorType.SpSummon, CardId.borrel, Borrel_ss); AddExecutor(ExecutorType.SpSummon, CardId.phoneix, Phoneix_ss); AddExecutor(ExecutorType.SpSummon, CardId.unicorn, Unicorn_ss); AddExecutor(ExecutorType.SpSummon, CardId.Crystal, Crystal_ss); @@ -108,29 +122,30 @@ public TrickstarExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.BF, BF_pos); AddExecutor(ExecutorType.Activate, CardId.Sheep, Sheep_Act); AddExecutor(ExecutorType.Activate, CardId.Eater); + AddExecutor(ExecutorType.Activate, CardId.LockBird, LockBird_act); // ts AddExecutor(ExecutorType.Activate, CardId.Stage, Stage_act); AddExecutor(ExecutorType.Activate, CardId.Pink, Pink_eff); + AddExecutor(ExecutorType.Activate, CardId.Re, Reincarnation); AddExecutor(ExecutorType.Activate, CardId.Red, Red_ss); AddExecutor(ExecutorType.Activate, CardId.Yellow, Yellow_eff); AddExecutor(ExecutorType.Activate, CardId.White, White_eff); - AddExecutor(ExecutorType.Activate, CardId.Re, Reincarnation); + AddExecutor(ExecutorType.Activate, CardId.Crown, Crown_eff); AddExecutor(ExecutorType.Summon, CardId.Yellow, Yellow_sum); AddExecutor(ExecutorType.Summon, CardId.Red, Red_sum); AddExecutor(ExecutorType.Summon, CardId.Pink, Pink_sum); // normal AddExecutor(ExecutorType.SpSummon, CardId.Eater, Eater_ss); + AddExecutor(ExecutorType.Summon, CardId.Tuner, Tuner_ns); AddExecutor(ExecutorType.Summon, CardId.Urara,Tuner_ns); AddExecutor(ExecutorType.Summon, CardId.Ghost, Tuner_ns); - AddExecutor(ExecutorType.Summon, CardId.Tuner, Tuner_ns); AddExecutor(ExecutorType.Activate, CardId.Pot, Pot_Act); AddExecutor(ExecutorType.Repos, MonsterRepos); AddExecutor(ExecutorType.SummonOrSet, CardId.Red); AddExecutor(ExecutorType.SummonOrSet, CardId.Pink); AddExecutor(ExecutorType.SpellSet, DefaultSpellSet); - } public bool Has_down_arrow(int id) @@ -147,8 +162,9 @@ public int[] Useless_List() { return new[] { - CardId.Crown, CardId.Tuner, + CardId.Grass, + CardId.Crown, CardId.Pink, CardId.Pot, CardId.BF, @@ -171,6 +187,63 @@ public int[] Useless_List() }; } + public int GetTotalATK(IList list) + { + int atk = 0; + foreach(ClientCard c in list) + { + if (c == null) continue; + atk += c.Attack; + } + return atk; + } + + public bool Grass_ss() + { + if (Bot.ExtraDeck.Count > 0) + { + IList ex = Bot.ExtraDeck; + ClientCard ex_best = null; + foreach (ClientCard ex_card in ex) + { + if (ex_best == null || ex_card.Attack > ex_best.Attack) ex_best = ex_card; + } + if (ex_best != null) { + AI.SelectCard(ex_best); + } + return true; + } + return true; + } + + public bool Abyss_eff() + { + // tuner ss + if (ActivateDescription == -1) + { + AI.SelectCard(new[] + { + CardId.Ghost, + CardId.TG, + CardId.Tuner, + CardId.Urara, + CardId.BF + }); + return true; + }; + // counter + if (!Enemy.HasInMonstersZone(CardId.Ghost) || Enemy.GetHandCount() <= 1) + { + ClientCard tosolve = AI.Utils.GetProblematicEnemyCard(); + if (tosolve != null) + { + AI.SelectCard(tosolve); + return true; + } + } + return false; + } + public bool Stage_Lock() { if (Card.Location != CardLocation.SpellZone) return false; @@ -224,24 +297,18 @@ public bool BF_pos() public bool Feather_Act() { - List spells = Enemy.GetSpells(); - foreach (ClientCard card in spells) + if (AI.Utils.GetProblematicEnemySpell() != null) { - // 有常用贴纸 - if (card.Id == 5851097 || card.Id == 30241314 || card.Id == 81674782 || card.Id == 58921041 || card.Id == 59305593) + List grave = Bot.GetGraveyardSpells(); + foreach (ClientCard self_card in grave) { - List grave = Bot.GetGraveyardSpells(); - // 墓地有银河旋风则不发动 - foreach (ClientCard self_card in grave) - { - if (self_card.Id == CardId.Galaxy) - return false; - } - return true; + if (self_card.Id == CardId.Galaxy) + return false; } + return true; } - // 2张以上才发动 - if (spells.Count <= 1) + // activate when more than 2 cards + if (Enemy.GetSpellCount() <= 1) return false; return true; } @@ -250,8 +317,8 @@ public bool Sheep_Act() { if (Duel.Player == 0) return false; if (Duel.Phase == DuelPhase.End) return true; - if (LastChainPlayer == 1 && (AI.Utils.IsChainTarget(Card) || GetLastChainCard().Id == CardId.Feather)) return true; - if (Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2) + if (LastChainPlayer == 1 && (AI.Utils.IsChainTarget(Card) || (GetLastChainCard().Id == CardId.Feather && !Bot.HasInSpellZone(CardId.Grass)))) return true; + if (Duel.Phase == DuelPhase.BattleStart) { int total_atk = 0; List enemy_monster = Enemy.GetMonsters(); @@ -396,10 +463,21 @@ public bool Pot_Act() public bool Hand_act_eff() { + if (Card.Id == CardId.Urara && Bot.HasInHand(CardId.LockBird) && Bot.HasInSpellZone(CardId.Re)) return false; if (Card.Id == CardId.Ghost && Card.Location == CardLocation.Hand && Bot.HasInMonstersZone(CardId.Ghost)) return false; return (LastChainPlayer == 1); } + public bool Exterio_counter() + { + if (LastChainPlayer == 1) + { + AI.SelectCard(Useless_List()); + return true; + } + return false; + } + public bool G_act() { return (Duel.Player == 1); @@ -481,7 +559,7 @@ public bool Eater_ss() public bool Red_ss() { - if (red_ss_count >= 9) return false; + if (red_ss_count >= 6) return false; if (LastChainPlayer == 0 && GetLastChainCard().Id == CardId.Red) { foreach (ClientCard m in Bot.GetMonsters()) @@ -506,7 +584,7 @@ public bool Red_ss() { if (IsTrickstar(c.Id)) { - if (c.Attacked) + if (c.Attacked && c.Id != CardId.Red) { AI.SelectCard(c); red_ss_count += 1; @@ -516,6 +594,7 @@ public bool Red_ss() { if (Bot.HasInHand(CardId.White) && c.Attack * 2 < tosolve_enemy.Attack) { + if (tosolve_enemy.Attack > 3200) AI.SelectPosition(CardPosition.FaceUpDefence); AI.SelectCard(c); red_ss_count += 1; return true; @@ -528,6 +607,16 @@ public bool Red_ss() } if (!Bot.HasInHand(CardId.White) && c.Attack < tosolve_enemy.Attack) { + if (!c.Attacked) + { + ClientCard badatk = Enemy.GetMonsters().GetLowestAttackMonster(); + ClientCard baddef = Enemy.GetMonsters().GetLowestDefenseMonster(); + int enemy_power = 99999; + if (badatk != null && badatk.Attack <= enemy_power) enemy_power = badatk.Attack; + if (baddef != null && baddef.Defense <= enemy_power) enemy_power = baddef.Defense; + if (c.Attack > enemy_power) return false; + } + if (tosolve_enemy.Attack > 1600) AI.SelectPosition(CardPosition.FaceUpDefence); AI.SelectCard(c); red_ss_count += 1; return true; @@ -538,6 +627,7 @@ public bool Red_ss() } } else { + if ((ChainContainsCard(53129443) || ChainContainsCard(99330325)) && ChainContainsCard(CardId.Red)) return false; if (Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2) { if (!Bot.HasInHand(CardId.White) && AI.Utils.IsOneEnemyBetterThanValue(1600, true)) @@ -560,7 +650,7 @@ public bool Red_ss() public bool Yellow_eff() { - if (!Bot.HasInHand(CardId.Stage) && !Bot.HasInSpellZone(CardId.Stage) && Bot.GetRemainingCount(CardId.Stage,3) > 0) + if (!Bot.HasInHand(CardId.Stage) && !Bot.HasInSpellZone(CardId.Stage) && Bot.GetRemainingCount(CardId.Stage, 3) > 0) { AI.SelectCard(new[] { @@ -576,7 +666,7 @@ public bool Yellow_eff() } else if (Enemy.GetMonsterCount() == 0 && !AI.Utils.IsTurn1OrMain2()) { - if (Bot.HasInGraveyard(CardId.Red) && Bot.GetRemainingCount(CardId.Pink,1)>0 && !pink_ss) + if (Bot.HasInGraveyard(CardId.Red) && Bot.GetRemainingCount(CardId.Pink, 1) > 0 && !pink_ss) { AI.SelectCard(new[] { @@ -589,7 +679,7 @@ public bool Yellow_eff() CardId.Yellow }); } - else if (Bot.HasInGraveyard(CardId.Pink) && Bot.HasInGraveyard(CardId.Red) && Bot.GetRemainingCount(CardId.Ring,1) > 0) + else if (Bot.HasInGraveyard(CardId.Pink) && Bot.HasInGraveyard(CardId.Red) && Bot.GetRemainingCount(CardId.Ring, 1) > 0) { AI.SelectCard(new[] { @@ -602,7 +692,7 @@ public bool Yellow_eff() CardId.Yellow }); } - else if (Bot.GetRemainingCount(CardId.White,2) > 0 && Duel.LifePoints[1] <= 4000) + else if (Bot.GetRemainingCount(CardId.White, 2) > 0 && Duel.LifePoints[1] <= 4000) { AI.SelectCard(new[] { @@ -673,6 +763,18 @@ public bool Yellow_eff() }); } return true; + } else if ((Bot.HasInHand(CardId.Red) || Bot.HasInHand(CardId.Stage)) && Bot.GetRemainingCount(CardId.Re,1) > 0 && Bot.HasInHand(CardId.LockBird)) { + AI.SelectCard(new[] + { + CardId.Re, + CardId.Red, + CardId.White, + CardId.Ring, + CardId.Pink, + CardId.Stage, + CardId.Yellow + }); + return true; } else { AI.SelectCard(new[] @@ -700,23 +802,37 @@ public bool White_eff() if (bestMy == null || (bestEnemyATK == null && bestEnemyDEF == null)) return false; if (bestEnemyATK != null && bestMy.Attack <= bestEnemyATK.Attack && bestMy.Attack * 2 >= bestEnemyATK.Attack) + { + white_eff_used = true; return true; + } if (bestEnemyDEF != null && bestMy.Attack <= bestEnemyDEF.Defense && bestMy.Attack * 2 >= bestEnemyDEF.Defense) + { + white_eff_used = true; return true; + } return false; } else { - if (Enemy.GetMonsterCount() == 0 && !AI.Utils.IsTurn1OrMain2()) return true; + if (Enemy.GetMonsterCount() == 0 && !AI.Utils.IsTurn1OrMain2()) { + white_eff_used = true; + return true; + } else if (Enemy.GetMonsterCount() != 0) { ClientCard tosolve = AI.Utils.GetBestEnemyMonster(true); ClientCard self_card = Bot.GetMonsters().GetHighestAttackMonster(); if (tosolve == null || self_card == null || (tosolve != null && self_card != null && !IsTrickstar(self_card.Id))) { - return (Enemy.GetMonsters().GetLowestAttackMonster() == null || + if (Enemy.GetMonsters().GetLowestAttackMonster() == null || Enemy.GetMonsters().GetLowestDefenseMonster() == null || Enemy.GetMonsters().GetLowestAttackMonster().Attack < 2000 || - Enemy.GetMonsters().GetLowestDefenseMonster().Defense < 2000); + Enemy.GetMonsters().GetLowestDefenseMonster().Defense < 2000) + { + white_eff_used = true; + return true; + } + else return false; } if (tosolve != null && self_card != null && IsTrickstar(self_card.Id)) { @@ -732,12 +848,53 @@ public bool White_eff() } } + public bool LockBird_act() + { + if (Duel.Player == 0) return false; + lockbird_useful = true; + if (Bot.HasInSpellZone(CardId.Re)) return ChainContainsCard(CardId.Re); + return true; + } + public bool Reincarnation() { if (Card.Location == CardLocation.Grave) return Ts_reborn(); + if (Bot.HasInHand(CardId.LockBird)) + { + if (lockbird_useful || AI.Utils.IsChainTarget(Card) || (Duel.Player == 1 && ChainContainsCard(CardId.Feather))) { + lockbird_useful = false; + return true; + } + return false; + } return true; } + public bool Crown_eff() + { + if (Card.Location == CardLocation.Hand) return Ts_reborn(); + if (Bot.HasInHand(CardId.Pink)) + { + AI.SelectCard(CardId.Pink); + return true; + } + if (Enemy.GetMonsterCount() == 0) + { + foreach(ClientCard hand in Bot.Hand) + { + if (hand.IsMonster() && IsTrickstar(hand.Id)) + { + if (hand.Attack >= Duel.LifePoints[1]) return true; + if (hand.Id != CardId.Yellow) + { + if (AI.Utils.GetOneEnemyBetterThanValue(hand.Attack, false) == null) return true; + } + } + } + } + return false; + } + public bool Ts_reborn() { bool can_summon = (Duel.Player == 0 && NormalSummoned); @@ -824,7 +981,11 @@ public bool Tuner_ss() { if (hand.Id == Card.Id) count += 1; } - if (count >= 2) return true; + if (count < 2) return false; + foreach(ClientCard m in Bot.GetMonsters()) + { + if (m.Id != CardId.Eater && getLinkMarker(m.Id) <= 2) return true; + } return false; } @@ -925,7 +1086,16 @@ public bool Safedragon_ss() ClientCard m = AI.Utils.GetProblematicEnemyMonster(); if (m == null) { - return (Enemy.GetMonsterCount() == 0 && Duel.LifePoints[1] <= 1100 && Duel.Phase < DuelPhase.Battle); + if (Enemy.GetMonsterCount() == 0 && Duel.LifePoints[1] <= 1100 && Duel.Phase < DuelPhase.Battle) + { + IList list = new List(); + foreach(ClientCard monster in Bot.GetMonsters()) + { + if (getLinkMarker(monster.Id) <= 2) list.Add(monster); + if (list.Count >= 2) break; + } + return (list.Count >= 2 && GetTotalATK(list) <= 1100); + } } ClientCard ex_1 = Bot.MonsterZone[5]; ClientCard ex_2 = Bot.MonsterZone[6]; @@ -953,7 +1123,17 @@ public bool Phoneix_ss() ClientCard m = AI.Utils.GetProblematicEnemySpell(); if (m == null) { - return (Enemy.GetMonsterCount() == 0 && Duel.LifePoints[1] <= 1900 && Duel.Phase == DuelPhase.Main1); + if (Enemy.GetMonsterCount() == 0 && Duel.LifePoints[1] <= 1900 && Duel.Phase == DuelPhase.Main1) + { + IList m_list = new List(); + foreach(ClientCard monster in Bot.GetMonsters()) + { + if (getLinkMarker(monster.Id) == 1) m_list.Add(monster); + if (m_list.Count == 2) break; + } + return (m_list.Count == 2 && GetTotalATK(m_list) <= 1900); + } + return false; } if (Bot.Hand.Count == 0) return false; IList targets = new List(); @@ -977,7 +1157,7 @@ public bool Phoneix_ss() { targets.Add(ex_zone); } - AI.SelectCard(targets); + AI.SelectMaterials(targets); return true; } @@ -989,13 +1169,31 @@ public bool Phoneix_eff() public bool Unicorn_ss() { ClientCard m = AI.Utils.GetProblematicEnemyCard(); + int link_count = 0; if (m == null) { - return (Enemy.GetMonsterCount() == 0 && Duel.LifePoints[1] <= 2200 && Duel.Phase == DuelPhase.Main1); + if (Enemy.GetMonsterCount() == 0 && Duel.LifePoints[1] <= 2200 && Duel.Phase == DuelPhase.Main1) + { + IList m_list = new List(); + foreach(ClientCard monster in Bot.GetMonsters()) + { + if (getLinkMarker(monster.Id) == 2) + { + link_count += 2; + m_list.Add(monster); + } else if (getLinkMarker(monster.Id) == 1) + { + link_count += 1; + m_list.Add(monster); + } + if (link_count >= 3) break; + } + return (link_count >= 3 && GetTotalATK(m_list) <= 2200); + } + return false; } if (Bot.Hand.Count == 0) return false; IList targets = new List(); - int link_count = 0; foreach (ClientCard s_m in Bot.GetMonsters()) { if (s_m.Id != CardId.Eater && getLinkMarker(s_m.Id) <= 2) @@ -1009,7 +1207,7 @@ public bool Unicorn_ss() { } } if (link_count < 3) return false; - AI.SelectCard(targets); + AI.SelectMaterials(targets); return true; } @@ -1025,19 +1223,28 @@ public bool Unicorn_eff() public bool Snake_ss() { IList targets = new List(); - foreach (ClientCard m in Bot.GetMonsters()) + // exzone fo first + foreach (ClientCard e_m in Bot.GetMonstersInExtraZone()) { - if (m.Attack < 1900 && !targets.ContainsCardWithId(m.Id)) + if (e_m.Attack < 1900 && !targets.ContainsCardWithId(e_m.Id)) { - targets.Add(m); + targets.Add(e_m); } } - if (targets.Count >= 4) + foreach (ClientCard m in Bot.GetMonstersInMainZone()) { - - AI.SelectCard(targets); - snake_four_s = true; - return true; + if (m.Attack < 1900 && !targets.ContainsCardWithId(m.Id)) + { + targets.Add(m); + } + if (targets.Count >= 4) + { + if (Duel.LifePoints[1] <= GetTotalATK(targets) && Enemy.GetMonsterCount() == 0) return false; + AI.SelectMaterials(targets); + AI.SelectYesNo(true); + snake_four_s = true; + return true; + } } return false; } @@ -1073,10 +1280,100 @@ public bool Snake_eff() return false; } + public bool Missus_ss() + { + IList material_list = new List(); + foreach(ClientCard monster in Bot.GetMonsters()) + { + if (monster.HasAttribute(CardAttribute.Earth) && getLinkMarker(monster.Id) == 1) material_list.Add(monster); + } + if (material_list.Count < 2) return false; + if (Enemy.GetMonsterCount() == 0) + { + AI.SelectMaterials(material_list); + return true; + } else if (AI.Utils.GetProblematicEnemyMonster(2000) != null && Bot.HasInExtra(CardId.borrel) && !Bot.HasInMonstersZone(CardId.Missus)) + { + AI.SelectMaterials(material_list); + return true; + } + return false; + } + + public bool Missus_eff() + { + AI.SelectCard(new[] + { + CardId.MG, + CardId.Missus, + CardId.snake + }); + return true; + } + + public bool Borrel_ss() + { + bool already_link2 = false; + IList material_list = new List(); + if (AI.Utils.GetProblematicEnemyMonster(2000) != null || (Enemy.GetMonsterCount() == 0 && Duel.Phase == DuelPhase.Main1 && Duel.LifePoints[1] <= 3000)) + { + foreach(ClientCard e_m in Bot.GetMonstersInExtraZone()) + { + if (getLinkMarker(e_m.Id) < 3) + { + if (getLinkMarker(e_m.Id) == 2) already_link2 = true; + material_list.Add(e_m); + } + } + foreach(ClientCard m in Bot.GetMonstersInMainZone()) + { + if (getLinkMarker(m.Id) < 3) + { + if (getLinkMarker(m.Id) == 2 && !already_link2) + { + already_link2 = true; + material_list.Add(m); + } else if (m.Id != CardId.Sheep + 1 && (m.Id != CardId.Eater)) + { + material_list.Add(m); + } + if ((already_link2 && material_list.Count == 3) || (!already_link2 && material_list.Count == 4)) break; + } + } + if ((already_link2 && material_list.Count == 3) || (!already_link2 && material_list.Count == 4)) + { + if (Enemy.GetMonsterCount() == 0 && Duel.Phase == DuelPhase.Main1 && Duel.LifePoints[1] <= 3000) + { + if (GetTotalATK(material_list) >= 3000) return false; + } + AI.SelectMaterials(material_list); + return true; + } + } + return false; + } + + public bool Borrel_eff() + { + if (ActivateDescription == -1) return true; + ClientCard BestEnemy = AI.Utils.GetBestEnemyMonster(true); + ClientCard WorstBot = Bot.GetMonsters().GetLowestAttackMonster(); + if (BestEnemy == null || BestEnemy.HasPosition(CardPosition.FaceDown)) return false; + if (WorstBot == null || WorstBot.HasPosition(CardPosition.FaceDown)) return false; + if (BestEnemy.Attack >= WorstBot.RealPower) + { + AI.SelectCard(BestEnemy); + return true; + } + return false; + } + public bool MonsterRepos() { - if (Card.Id == CardId.Eater) return false; - if (Card.Id == CardId.Sheep + 1) return false; + if (Card.Id == CardId.Eater && Card.IsAttack()) return false; + + if (Card.IsFaceup() && Card.IsDefense() && Card.Attack == 0) + return false; bool enemyBetter = AI.Utils.IsAllEnemyBetter(true); if (Card.IsAttack() && enemyBetter) @@ -1100,13 +1397,15 @@ public override void OnNewTurn() snake_four_s = false; crystal_eff_used = false; red_ss_count = 0; + white_eff_used = false; + lockbird_useful = false; } public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender) { if (!defender.IsMonsterHasPreventActivationEffectInBattle()) { - if (attacker.Attribute == (int)CardAttribute.Light && Bot.HasInHand(CardId.White)) + if (IsTrickstar(attacker.Id) && Bot.HasInHand(CardId.White) && !white_eff_used) attacker.RealPower = attacker.RealPower * 2; else if (attacker.Id == CardId.Eater) attacker.RealPower = 99999; From 5c955205b616d615da6c2c0476fe87ab0ffe1943 Mon Sep 17 00:00:00 2001 From: Wind2009-Louse Date: Fri, 2 Mar 2018 11:05:53 +0800 Subject: [PATCH 03/68] Update TrickstarExecutor.cs Edit OnBattle --- Game/AI/Decks/TrickstarExecutor.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Game/AI/Decks/TrickstarExecutor.cs b/Game/AI/Decks/TrickstarExecutor.cs index ffcb75e1..9c7db77c 100644 --- a/Game/AI/Decks/TrickstarExecutor.cs +++ b/Game/AI/Decks/TrickstarExecutor.cs @@ -1601,13 +1601,12 @@ public override BattlePhaseAction OnBattle(IList attackers, IList defender.RealPower || (attacker.RealPower >= defender.RealPower && j == attackers.Count - 1)) return AI.Attack(attacker, defender); From 4ca5b21aa4fb15624ac35893b418e9fcb1ca801d Mon Sep 17 00:00:00 2001 From: Wind2009-Louse Date: Mon, 19 Mar 2018 20:43:10 +0800 Subject: [PATCH 04/68] fix OnPreBattleBetween --- Game/AI/DefaultExecutor.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index e334dc76..be7029ca 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using YGOSharp.OCGWrapper.Enums; using WindBot; @@ -33,6 +33,9 @@ protected class _CardId public const int Number39Utopia = 84013237; public const int UltimayaTzolkin = 1686814; + public const int VampireFräulein = 6039967; + public const int InjectionFairyLily = 79575620; + } protected DefaultExecutor(GameAI ai, Duel duel) @@ -63,6 +66,12 @@ public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender if (defender.Id == _CardId.NumberS39UtopiaTheLightning && defender.IsAttack() && !defender.IsDisabled() && defender.HasXyzMaterial(2, _CardId.Number39Utopia)) defender.RealPower = 5000; + + if (defender.Id == _CardId.VampireFräulein && !defender.IsDisabled()) + defender.RealPower += (Duel.LifePoints[defender.Controller] > 3000) ? 3000 : (Duel.LifePoints[defender.Controller] - 100); + + if (defender.Id == _CardId.InjectionFairyLily && !defender.IsDisabled() && Duel.LifePoints[defender.Controller] > 2000) + defender.RealPower += 3000; } if (!defender.IsMonsterHasPreventActivationEffectInBattle()) From d8d91f68d6b1476ce5fa304d07c59c59f11efc3b Mon Sep 17 00:00:00 2001 From: Wind2009-Louse Date: Sun, 25 Mar 2018 20:06:05 +0800 Subject: [PATCH 05/68] Update TrickstarExecutor.cs Add DarkHole, Called by the Grave --- Game/AI/Decks/TrickstarExecutor.cs | 64 +++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/Game/AI/Decks/TrickstarExecutor.cs b/Game/AI/Decks/TrickstarExecutor.cs index 9c7db77c..e9c2d6c8 100644 --- a/Game/AI/Decks/TrickstarExecutor.cs +++ b/Game/AI/Decks/TrickstarExecutor.cs @@ -30,6 +30,8 @@ public class CardId public const int Sheep = 73915051; public const int Crown = 22159429; public const int Stage = 35371948; + public const int GraveCall = 24224830; + public const int DarkHole = 53129443; public const int Re = 21076084; public const int Ring = 83555666; @@ -75,6 +77,8 @@ public int getLinkMarker(int id) bool white_eff_used = false; bool lockbird_useful = false; bool lockbird_used = false; + int GraveCall_id = 0; + int GraveCall_count = 0; public TrickstarExecutor(GameAI ai, Duel duel) : base(ai, duel) @@ -90,10 +94,14 @@ public TrickstarExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.Abyss, Abyss_eff); AddExecutor(ExecutorType.Activate, CardId.Exterio, Exterio_counter); AddExecutor(ExecutorType.Activate, CardId.Cardian); + AddExecutor(ExecutorType.Activate, CardId.GraveCall, GraveCall_eff); + + AddExecutor(ExecutorType.Activate, CardId.DarkHole, DarkHole_eff); // spell clean AddExecutor(ExecutorType.Activate, CardId.Stage, Stage_Lock); AddExecutor(ExecutorType.Activate, CardId.Feather, Feather_Act); + AddExecutor(ExecutorType.Activate, CardId.Stage, Stage_act); AddExecutor(ExecutorType.Activate, CardId.Galaxy, GalaxyCyclone); AddExecutor(ExecutorType.Activate, CardId.TG, TG_eff); @@ -130,7 +138,6 @@ public TrickstarExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.LockBird, LockBird_act); // ts - AddExecutor(ExecutorType.Activate, CardId.Stage, Stage_act); AddExecutor(ExecutorType.Activate, CardId.Pink, Pink_eff); AddExecutor(ExecutorType.Activate, CardId.Re, Reincarnation); AddExecutor(ExecutorType.Activate, CardId.Red, Red_ss); @@ -473,6 +480,7 @@ public bool Pot_Act() public bool Hand_act_eff() { + if (GraveCall_count > 0 && GraveCall_id == Card.Id) return false; if (Card.Id == CardId.Urara && Bot.HasInHand(CardId.LockBird) && Bot.HasInSpellZone(CardId.Re)) return false; if (Card.Id == CardId.Ghost && Card.Location == CardLocation.Hand && Bot.HasInMonstersZone(CardId.Ghost)) return false; return (LastChainPlayer == 1); @@ -490,7 +498,7 @@ public bool Exterio_counter() public bool G_act() { - return (Duel.Player == 1); + return (Duel.Player == 1 && !(GraveCall_count > 0 && GraveCall_id == Card.Id)); } public bool Pink_eff() @@ -583,7 +591,7 @@ public bool Eater_eff() public bool Red_ss() { if (red_ss_count >= 6) return false; - if ((ChainContainsCard(53129443) || ChainContainsCard(99330325) || ChainContainsCard(53582587)) && ChainContainsCard(CardId.Red)) return false; + if ((ChainContainsCard(CardId.DarkHole) || ChainContainsCard(99330325) || ChainContainsCard(53582587)) && ChainContainsCard(CardId.Red)) return false; if (LastChainPlayer == 0 && GetLastChainCard().Id == CardId.Red) { foreach (ClientCard m in Bot.GetMonsters()) @@ -954,7 +962,7 @@ public bool Crown_eff() if (Duel.Phase <= DuelPhase.Main1) return Ts_reborn(); return false; } - if (Bot.HasInHand(CardId.Pink)) + if (Bot.HasInHand(CardId.Pink) && GraveCall_id != CardId.Pink) { AI.SelectCard(CardId.Pink); return true; @@ -1542,6 +1550,45 @@ public bool Borrel_eff() return false; } + public bool GraveCall_eff() + { + if (LastChainPlayer == 1) + { + Logger.DebugWriteLine(GetLastChainCard().Name.ToString()); + Logger.DebugWriteLine(GetLastChainCard().IsMonster().ToString()); + Logger.DebugWriteLine(Enemy.HasInGraveyard(GetLastChainCard().Id).ToString()); + if (GetLastChainCard().IsMonster() && Enemy.HasInGraveyard(GetLastChainCard().Id)) + { + GraveCall_id = GetLastChainCard().Id; + GraveCall_count = 2; + AI.SelectCard(GraveCall_id); + return true; + } + } + return false; + } + + public bool DarkHole_eff() + { + if (Bot.GetMonsterCount() == 0) + { + + int bestPower = -1; + foreach (ClientCard hand in Bot.Hand) + { + if (hand.IsMonster() && hand.Attack > bestPower) bestPower = hand.Attack; + } + int bestenemy = -1; + foreach (ClientCard enemy in Enemy.GetMonsters()) + { + if (enemy.IsMonsterDangerous()) return true; + if (enemy.IsFaceup() && (enemy.GetDefensePower() > bestenemy)) bestenemy = enemy.GetDefensePower(); + } + return (bestPower <= bestenemy); + } + return false; + } + public bool MonsterRepos() { if (Card.Id == CardId.Eater && Card.IsAttack()) return false; @@ -1576,6 +1623,13 @@ public override void OnNewTurn() white_eff_used = false; lockbird_useful = false; lockbird_used = false; + if (GraveCall_count > 0) + { + if (--GraveCall_count <= 0) + { + GraveCall_id = 0; + } + } } public override BattlePhaseAction OnBattle(IList attackers, IList defenders) @@ -1603,7 +1657,7 @@ public override BattlePhaseAction OnBattle(IList attackers, IList Date: Wed, 4 Apr 2018 11:54:19 +0800 Subject: [PATCH 06/68] Update AI_Trickstar.ydk 4.1 ocg forbidden deck --- Decks/AI_Trickstar.ydk | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Decks/AI_Trickstar.ydk b/Decks/AI_Trickstar.ydk index 1b07d6d5..34c4293d 100644 --- a/Decks/AI_Trickstar.ydk +++ b/Decks/AI_Trickstar.ydk @@ -2,7 +2,6 @@ #main 98169343 98169343 -9929398 61283655 61283655 61283655 @@ -11,20 +10,21 @@ 35199656 14558127 14558127 -14558127 -59438930 59438930 98700941 23434538 23434538 23434538 -67441435 +94145021 63845230 63845230 63845230 18144506 35261759 35261759 +53129443 +53129443 +53129443 73628505 73915051 73915051 @@ -42,18 +42,18 @@ 84749824 #extra 41999284 -3987233 41999284 +3987233 +2857636 50588353 98558751 -74997493 -2857636 -38342335 -99111753 +86221741 31833038 3987233 +99111753 +38342335 50588353 -41999284 9753964 +41999284 34408491 !side From 25923ed1500d9f8b6780ae160743e8871d3b35f4 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Wed, 4 Apr 2018 15:05:55 +0800 Subject: [PATCH 07/68] change Duel.LifePoints[0] to Bot.LifePoints --- Game/AI/Decks/BlueEyesExecutor.cs | 4 +-- Game/AI/Decks/BurnExecutor.cs | 2 +- Game/AI/Decks/QliphortExecutor.cs | 4 +-- Game/AI/Decks/RainbowExecutor.cs | 2 +- Game/AI/Decks/ToadallyAwesomeExecutor.cs | 4 +-- Game/AI/Decks/TrickstarExecutor.cs | 32 ++++++++++++------------ Game/AI/Decks/YosenjuExecutor.cs | 2 +- Game/AI/Decks/ZexalWeaponsExecutor.cs | 4 +-- Game/AI/DefaultExecutor.cs | 12 ++++----- Game/ClientField.cs | 2 ++ Game/Duel.cs | 2 -- Game/GameBehavior.cs | 12 ++++----- 12 files changed, 41 insertions(+), 41 deletions(-) diff --git a/Game/AI/Decks/BlueEyesExecutor.cs b/Game/AI/Decks/BlueEyesExecutor.cs index 0f3299d3..6e72ee35 100644 --- a/Game/AI/Decks/BlueEyesExecutor.cs +++ b/Game/AI/Decks/BlueEyesExecutor.cs @@ -855,7 +855,7 @@ private bool SoulChargeEffect() int space = 5 - Bot.GetMonstersInMainZone().Count; if (count < space) count = space; - if (count < 2 || Duel.LifePoints[0] < count*1000) + if (count < 2 || Bot.LifePoints < count*1000) return false; if (Duel.Turn != 1) { @@ -872,7 +872,7 @@ private bool SoulChargeEffect() { defence += monster.GetDefensePower(); } - if (attack - defence > Duel.LifePoints[1]) + if (attack - defence > Enemy.LifePoints) return false; } AI.SelectCard(new[] diff --git a/Game/AI/Decks/BurnExecutor.cs b/Game/AI/Decks/BurnExecutor.cs index 9789970e..1bba76f9 100644 --- a/Game/AI/Decks/BurnExecutor.cs +++ b/Game/AI/Decks/BurnExecutor.cs @@ -90,7 +90,7 @@ private bool SwordsOfRevealingLight() private bool SupremacyBerry() { - return Duel.LifePoints[0] < Duel.LifePoints[1]; + return Bot.LifePoints < Enemy.LifePoints; } private bool PoisonOfTheOldMan() diff --git a/Game/AI/Decks/QliphortExecutor.cs b/Game/AI/Decks/QliphortExecutor.cs index 76ff383c..6fddbad9 100644 --- a/Game/AI/Decks/QliphortExecutor.cs +++ b/Game/AI/Decks/QliphortExecutor.cs @@ -161,7 +161,7 @@ private bool NormalSummon() private bool SkillDrainEffect() { - return (Duel.LifePoints[0] > 1000) && DefaultUniqueTrap(); + return (Bot.LifePoints > 1000) && DefaultUniqueTrap(); } private bool PotOfDualityEffect() @@ -315,7 +315,7 @@ private bool ScoutEffect() { AI.SelectCard(HighScaleCards); } - return Duel.LifePoints[0] > 800; + return Bot.LifePoints > 800; } private bool StealthEffect() diff --git a/Game/AI/Decks/RainbowExecutor.cs b/Game/AI/Decks/RainbowExecutor.cs index 47f9b52f..be0b01c2 100644 --- a/Game/AI/Decks/RainbowExecutor.cs +++ b/Game/AI/Decks/RainbowExecutor.cs @@ -267,7 +267,7 @@ private bool NormalSummon() private bool GagagaCowboySummon() { - if (Duel.LifePoints[1] <= 800) + if (Enemy.LifePoints <= 800) { AI.SelectPosition(CardPosition.FaceUpDefence); return true; diff --git a/Game/AI/Decks/ToadallyAwesomeExecutor.cs b/Game/AI/Decks/ToadallyAwesomeExecutor.cs index bd04293c..476652c3 100644 --- a/Game/AI/Decks/ToadallyAwesomeExecutor.cs +++ b/Game/AI/Decks/ToadallyAwesomeExecutor.cs @@ -117,7 +117,7 @@ public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender if (!defender.IsMonsterHasPreventActivationEffectInBattle()) { if (attacker.Id == CardId.SkyCavalryCentaurea && !attacker.IsDisabled() && attacker.HasXyzMaterial()) - attacker.RealPower = Duel.LifePoints[0] + attacker.Attack; + attacker.RealPower = Bot.LifePoints + attacker.Attack; } return base.OnPreBattleBetween(attacker, defender); } @@ -506,7 +506,7 @@ private bool DaigustoPhoenixSummon() { defence += monster.GetDefensePower(); } - if (attack - 2000 - defence > Duel.LifePoints[1] && !AI.Utils.IsOneEnemyBetter(true)) + if (attack - 2000 - defence > Enemy.LifePoints && !AI.Utils.IsOneEnemyBetter(true)) return true; } return false; diff --git a/Game/AI/Decks/TrickstarExecutor.cs b/Game/AI/Decks/TrickstarExecutor.cs index 3dd107f8..c3477b91 100644 --- a/Game/AI/Decks/TrickstarExecutor.cs +++ b/Game/AI/Decks/TrickstarExecutor.cs @@ -326,7 +326,7 @@ public bool Sheep_Act() { if (m.IsAttack() && !m.Attacked) total_atk += m.Attack; } - if (total_atk >= Duel.LifePoints[0]) return true; + if (total_atk >= Bot.LifePoints) return true; } return false; } @@ -349,7 +349,7 @@ public bool Stage_act() stage_locked = null; return true; } - else if (Duel.LifePoints[1] <= 1000 && !pink_ss) + else if (Enemy.LifePoints <= 1000 && !pink_ss) { AI.SelectCard(new[] { @@ -415,7 +415,7 @@ public bool Stage_act() stage_locked = null; return true; } - else if (Duel.LifePoints[1] <= 1000 && !pink_ss) + else if (Enemy.LifePoints <= 1000 && !pink_ss) { AI.SelectCard(new[] { @@ -487,15 +487,15 @@ public bool Pink_eff() { if (Card.Location == CardLocation.Hand) { - if ((Duel.LifePoints[1] <= 1000 && Bot.HasInSpellZone(CardId.Stage)) - || Duel.LifePoints[1] <= 800 + if ((Enemy.LifePoints <= 1000 && Bot.HasInSpellZone(CardId.Stage)) + || Enemy.LifePoints <= 800 || (!NormalSummoned && Bot.HasInGraveyard(CardId.Red)) ) { pink_ss = true; return true; } - else if (Enemy.GetMonsterCount() > 0 && (AI.Utils.GetBestEnemyMonster().Attack - 800 >= Duel.LifePoints[0])) return false; + else if (Enemy.GetMonsterCount() > 0 && (AI.Utils.GetBestEnemyMonster().Attack - 800 >= Bot.LifePoints)) return false; pink_ss = true; return true; } @@ -692,7 +692,7 @@ public bool Yellow_eff() CardId.Yellow }); } - else if (Bot.GetRemainingCount(CardId.White, 2) > 0 && Duel.LifePoints[1] <= 4000) + else if (Bot.GetRemainingCount(CardId.White, 2) > 0 && Enemy.LifePoints <= 4000) { AI.SelectCard(new[] { @@ -884,7 +884,7 @@ public bool Crown_eff() { if (hand.IsMonster() && IsTrickstar(hand.Id)) { - if (hand.Attack >= Duel.LifePoints[1]) return true; + if (hand.Attack >= Enemy.LifePoints) return true; if (hand.Id != CardId.Yellow) { if (AI.Utils.GetOneEnemyBetterThanValue(hand.Attack, false) == null) return true; @@ -938,7 +938,7 @@ public bool Yellow_sum() public bool Red_sum() { - if ((Enemy.GetMonsterCount() == 0 && Duel.LifePoints[1] <= 1800) || (Duel.Turn == 1 && Bot.HasInHand(CardId.Re))) + if ((Enemy.GetMonsterCount() == 0 && Enemy.LifePoints <= 1800) || (Duel.Turn == 1 && Bot.HasInHand(CardId.Re))) { NormalSummoned = true; return true; @@ -948,7 +948,7 @@ public bool Red_sum() public bool Pink_sum() { - if (Duel.LifePoints[1] <= 1000) + if (Enemy.LifePoints <= 1000) { NormalSummoned = true; return true; @@ -1086,7 +1086,7 @@ public bool Safedragon_ss() ClientCard m = AI.Utils.GetProblematicEnemyMonster(); if (m == null) { - if (Enemy.GetMonsterCount() == 0 && Duel.LifePoints[1] <= 1100 && Duel.Phase < DuelPhase.Battle) + if (Enemy.GetMonsterCount() == 0 && Enemy.LifePoints <= 1100 && Duel.Phase < DuelPhase.Battle) { IList list = new List(); foreach(ClientCard monster in Bot.GetMonsters()) @@ -1123,7 +1123,7 @@ public bool Phoneix_ss() ClientCard m = AI.Utils.GetProblematicEnemySpell(); if (m == null) { - if (Enemy.GetMonsterCount() == 0 && Duel.LifePoints[1] <= 1900 && Duel.Phase == DuelPhase.Main1) + if (Enemy.GetMonsterCount() == 0 && Enemy.LifePoints <= 1900 && Duel.Phase == DuelPhase.Main1) { IList m_list = new List(); foreach(ClientCard monster in Bot.GetMonsters()) @@ -1172,7 +1172,7 @@ public bool Unicorn_ss() { int link_count = 0; if (m == null) { - if (Enemy.GetMonsterCount() == 0 && Duel.LifePoints[1] <= 2200 && Duel.Phase == DuelPhase.Main1) + if (Enemy.GetMonsterCount() == 0 && Enemy.LifePoints <= 2200 && Duel.Phase == DuelPhase.Main1) { IList m_list = new List(); foreach(ClientCard monster in Bot.GetMonsters()) @@ -1239,7 +1239,7 @@ public bool Snake_ss() } if (targets.Count >= 4) { - if (Duel.LifePoints[1] <= GetTotalATK(targets) && Enemy.GetMonsterCount() == 0) return false; + if (Enemy.LifePoints <= GetTotalATK(targets) && Enemy.GetMonsterCount() == 0) return false; AI.SelectMaterials(targets); AI.SelectYesNo(true); snake_four_s = true; @@ -1315,7 +1315,7 @@ public bool Borrel_ss() { bool already_link2 = false; IList material_list = new List(); - if (AI.Utils.GetProblematicEnemyMonster(2000) != null || (Enemy.GetMonsterCount() == 0 && Duel.Phase == DuelPhase.Main1 && Duel.LifePoints[1] <= 3000)) + if (AI.Utils.GetProblematicEnemyMonster(2000) != null || (Enemy.GetMonsterCount() == 0 && Duel.Phase == DuelPhase.Main1 && Enemy.LifePoints <= 3000)) { foreach(ClientCard e_m in Bot.GetMonstersInExtraZone()) { @@ -1342,7 +1342,7 @@ public bool Borrel_ss() } if ((already_link2 && material_list.Count == 3) || (!already_link2 && material_list.Count == 4)) { - if (Enemy.GetMonsterCount() == 0 && Duel.Phase == DuelPhase.Main1 && Duel.LifePoints[1] <= 3000) + if (Enemy.GetMonsterCount() == 0 && Duel.Phase == DuelPhase.Main1 && Enemy.LifePoints <= 3000) { if (GetTotalATK(material_list) >= 3000) return false; } diff --git a/Game/AI/Decks/YosenjuExecutor.cs b/Game/AI/Decks/YosenjuExecutor.cs index 5dd16ad8..0f3c8f3a 100644 --- a/Game/AI/Decks/YosenjuExecutor.cs +++ b/Game/AI/Decks/YosenjuExecutor.cs @@ -291,7 +291,7 @@ private bool CardOfDemiseEPEffect() private bool GagagaCowboySummon() { - if (Duel.LifePoints[1] <= 800 || (Bot.GetMonsterCount()>=4 && Duel.LifePoints[1] <= 1600)) + if (Enemy.LifePoints <= 800 || (Bot.GetMonsterCount()>=4 && Enemy.LifePoints <= 1600)) { AI.SelectPosition(CardPosition.FaceUpDefence); return true; diff --git a/Game/AI/Decks/ZexalWeaponsExecutor.cs b/Game/AI/Decks/ZexalWeaponsExecutor.cs index 762ad4f3..6a29a5dc 100644 --- a/Game/AI/Decks/ZexalWeaponsExecutor.cs +++ b/Game/AI/Decks/ZexalWeaponsExecutor.cs @@ -184,7 +184,7 @@ private bool ReinforcementOfTheArmy() private bool InstantFusion() { - if (Duel.LifePoints[0] <= 1000) + if (Bot.LifePoints <= 1000) return false; int count4 = 0; int count5 = 0; @@ -210,7 +210,7 @@ private bool InstantFusion() private bool XyzChangeTactics() { - return Duel.LifePoints[0] > 500; + return Bot.LifePoints > 500; } private bool NumberS39UtopiatheLightning() diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index e334dc76..0f8d5739 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -131,7 +131,7 @@ protected bool DefaultCosmicCyclone() foreach (ClientCard card in CurrentChain) if (card.Id == _CardId.CosmicCyclone) return false; - return (Duel.LifePoints[0] > 1000) && DefaultMysticalSpaceTyphoon(); + return (Bot.LifePoints > 1000) && DefaultMysticalSpaceTyphoon(); } /// @@ -255,7 +255,7 @@ protected bool DefaultSolemnJudgment() /// protected bool DefaultSolemnWarning() { - return (Duel.LifePoints[0] > 2000) && !(Duel.Player == 0 && LastChainPlayer == -1) && DefaultTrap(); + return (Bot.LifePoints > 2000) && !(Duel.Player == 0 && LastChainPlayer == -1) && DefaultTrap(); } /// @@ -263,7 +263,7 @@ protected bool DefaultSolemnWarning() /// protected bool DefaultSolemnStrike() { - return (Duel.LifePoints[0] > 1500) && !(Duel.Player == 0 && LastChainPlayer == -1) && DefaultTrap(); + return (Bot.LifePoints > 1500) && !(Duel.Player == 0 && LastChainPlayer == -1) && DefaultTrap(); } /// @@ -450,11 +450,11 @@ protected bool DefaultChickenGame() if (exec.Type == Type && exec.CardId == Card.Id) count++; } - if (count > 1 || Duel.LifePoints[0] <= 1000) + if (count > 1 || Bot.LifePoints <= 1000) return false; - if (Duel.LifePoints[0] <= Duel.LifePoints[1] && ActivateDescription == AI.Utils.GetStringId(_CardId.ChickenGame, 0)) + if (Bot.LifePoints <= Enemy.LifePoints && ActivateDescription == AI.Utils.GetStringId(_CardId.ChickenGame, 0)) return true; - if (Duel.LifePoints[0] > Duel.LifePoints[1] && ActivateDescription == AI.Utils.GetStringId(_CardId.ChickenGame, 1)) + if (Bot.LifePoints > Enemy.LifePoints && ActivateDescription == AI.Utils.GetStringId(_CardId.ChickenGame, 1)) return true; return false; } diff --git a/Game/ClientField.cs b/Game/ClientField.cs index b7f22b6e..ad28622e 100644 --- a/Game/ClientField.cs +++ b/Game/ClientField.cs @@ -13,6 +13,8 @@ public class ClientField public IList Deck { get; private set; } public IList ExtraDeck { get; private set; } + public int LifePoints; + public ClientField() { } diff --git a/Game/Duel.cs b/Game/Duel.cs index 20afa10d..e6477dad 100644 --- a/Game/Duel.cs +++ b/Game/Duel.cs @@ -8,7 +8,6 @@ public class Duel public bool IsFirst { get; set; } public bool IsNewRule { get; set; } - public int[] LifePoints { get; private set; } public ClientField[] Fields { get; private set; } public int Turn { get; set; } @@ -21,7 +20,6 @@ public class Duel public Duel() { - LifePoints = new int[2]; Fields = new ClientField[2]; Fields[0] = new ClientField(); Fields[1] = new ClientField(); diff --git a/Game/GameBehavior.cs b/Game/GameBehavior.cs index 1ca34d43..2e2d00b4 100644 --- a/Game/GameBehavior.cs +++ b/Game/GameBehavior.cs @@ -324,8 +324,8 @@ private void OnStart(BinaryReader packet) int type = packet.ReadByte(); _duel.IsFirst = (type & 0xF) == 0; _duel.Turn = 0; - _duel.LifePoints[GetLocalPlayer(0)] = packet.ReadInt32(); - _duel.LifePoints[GetLocalPlayer(1)] = packet.ReadInt32(); + _duel.Fields[GetLocalPlayer(0)].LifePoints = packet.ReadInt32(); + _duel.Fields[GetLocalPlayer(1)].LifePoints = packet.ReadInt32(); int deck = packet.ReadInt16(); int extra = packet.ReadInt16(); _duel.Fields[GetLocalPlayer(0)].Init(deck, extra); @@ -427,21 +427,21 @@ private void OnNewPhase(BinaryReader packet) private void OnDamage(BinaryReader packet) { int player = GetLocalPlayer(packet.ReadByte()); - int final = _duel.LifePoints[player] - packet.ReadInt32(); + int final = _duel.Fields[player].LifePoints - packet.ReadInt32(); if (final < 0) final = 0; - _duel.LifePoints[player] = final; + _duel.Fields[player].LifePoints = final; } private void OnRecover(BinaryReader packet) { int player = GetLocalPlayer(packet.ReadByte()); - _duel.LifePoints[player] += packet.ReadInt32(); + _duel.Fields[player].LifePoints += packet.ReadInt32(); } private void OnLpUpdate(BinaryReader packet) { int player = GetLocalPlayer(packet.ReadByte()); - _duel.LifePoints[player] = packet.ReadInt32(); + _duel.Fields[player].LifePoints = packet.ReadInt32(); } private void OnMove(BinaryReader packet) From 69eecef751452a468e32e5a9b83792e346120c9c Mon Sep 17 00:00:00 2001 From: mercury233 Date: Wed, 4 Apr 2018 15:33:56 +0800 Subject: [PATCH 08/68] add Bot.BattlingMonster --- Game/ClientField.cs | 1 + Game/GameAI.cs | 2 ++ Game/GameBehavior.cs | 8 ++++++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Game/ClientField.cs b/Game/ClientField.cs index ad28622e..88095d29 100644 --- a/Game/ClientField.cs +++ b/Game/ClientField.cs @@ -14,6 +14,7 @@ public class ClientField public IList ExtraDeck { get; private set; } public int LifePoints; + public ClientCard BattlingMonster; public ClientField() { diff --git a/Game/GameAI.cs b/Game/GameAI.cs index b52d729f..1987b5ce 100644 --- a/Game/GameAI.cs +++ b/Game/GameAI.cs @@ -91,6 +91,8 @@ public void OnNewPhase() m_yesno = -1; m_position = CardPosition.FaceUpAttack; Duel.LastSummonPlayer = -1; + Duel.Fields[0].BattlingMonster = null; + Duel.Fields[1].BattlingMonster = null; if (Duel.Player == 0 && Duel.Phase == DuelPhase.Draw) { _dialogs.SendNewTurn(); diff --git a/Game/GameBehavior.cs b/Game/GameBehavior.cs index 2e2d00b4..ca63fe89 100644 --- a/Game/GameBehavior.cs +++ b/Game/GameBehavior.cs @@ -494,12 +494,16 @@ private void OnAttack(BinaryReader packet) int la = packet.ReadByte(); int sa = packet.ReadByte(); packet.ReadByte(); // - packet.ReadByte(); // cd + int cd = packet.ReadByte(); int ld = packet.ReadByte(); - packet.ReadByte(); // sd + int sd = packet.ReadByte(); packet.ReadByte(); // ClientCard attackcard = _duel.GetCard(ca, (CardLocation)la, sa); + ClientCard defendcard = _duel.GetCard(cd, (CardLocation)ld, sd); + _duel.Fields[attackcard.Controller].BattlingMonster = attackcard; + _duel.Fields[1 - attackcard.Controller].BattlingMonster = defendcard; + if (ld == 0 && (attackcard != null) && (ca != 0)) { _ai.OnDirectAttack(attackcard); From 13bb091eadf8dfcaee4e12e79c79820f800d2add Mon Sep 17 00:00:00 2001 From: mercury233 Date: Wed, 4 Apr 2018 16:20:00 +0800 Subject: [PATCH 09/68] fix Enemy.BattlingMonster --- Game/GameBehavior.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Game/GameBehavior.cs b/Game/GameBehavior.cs index ca63fe89..93c6c26f 100644 --- a/Game/GameBehavior.cs +++ b/Game/GameBehavior.cs @@ -494,7 +494,7 @@ private void OnAttack(BinaryReader packet) int la = packet.ReadByte(); int sa = packet.ReadByte(); packet.ReadByte(); // - int cd = packet.ReadByte(); + int cd = GetLocalPlayer(packet.ReadByte()); int ld = packet.ReadByte(); int sd = packet.ReadByte(); packet.ReadByte(); // From d3fa6c303ef6f592a01ff3b19ba580f298b392c6 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Wed, 4 Apr 2018 16:22:22 +0800 Subject: [PATCH 10/68] add DefaultNumberS39UtopiaTheLightningEffect --- Game/AI/Decks/LightswornExecutor.cs | 2 +- Game/AI/Decks/RainbowExecutor.cs | 2 +- Game/AI/Decks/YosenjuExecutor.cs | 2 +- Game/AI/Decks/ZexalWeaponsExecutor.cs | 7 +------ Game/AI/Decks/ZoodiacExecutor.cs | 2 +- Game/AI/DefaultExecutor.cs | 8 ++++++++ 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Game/AI/Decks/LightswornExecutor.cs b/Game/AI/Decks/LightswornExecutor.cs index 86845edf..5d1c9949 100644 --- a/Game/AI/Decks/LightswornExecutor.cs +++ b/Game/AI/Decks/LightswornExecutor.cs @@ -79,7 +79,7 @@ public LightswornExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.ScarlightRedDragonArchfiend, DefaultScarlightRedDragonArchfiendEffect); AddExecutor(ExecutorType.SpSummon, CardId.Number39Utopia, DefaultNumberS39UtopiaTheLightningSummon); AddExecutor(ExecutorType.SpSummon, CardId.NumberS39UtopiatheLightning); - AddExecutor(ExecutorType.Activate, CardId.NumberS39UtopiatheLightning); + AddExecutor(ExecutorType.Activate, CardId.NumberS39UtopiatheLightning, DefaultNumberS39UtopiaTheLightningEffect); AddExecutor(ExecutorType.Activate, CardId.PerformageTrickClown, PerformageTrickClownEffect); AddExecutor(ExecutorType.Activate, CardId.ThousandBlades); diff --git a/Game/AI/Decks/RainbowExecutor.cs b/Game/AI/Decks/RainbowExecutor.cs index be0b01c2..93674829 100644 --- a/Game/AI/Decks/RainbowExecutor.cs +++ b/Game/AI/Decks/RainbowExecutor.cs @@ -107,7 +107,7 @@ public RainbowExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.SpSummon, CardId.Number39Utopia, DefaultNumberS39UtopiaTheLightningSummon); AddExecutor(ExecutorType.SpSummon, CardId.NumberS39UtopiatheLightning); - AddExecutor(ExecutorType.Activate, CardId.NumberS39UtopiatheLightning); + AddExecutor(ExecutorType.Activate, CardId.NumberS39UtopiatheLightning, DefaultNumberS39UtopiaTheLightningEffect); AddExecutor(ExecutorType.SpSummon, CardId.StardustDragon, DefaultStardustDragonSummon); AddExecutor(ExecutorType.Activate, CardId.StardustDragon, DefaultStardustDragonEffect); diff --git a/Game/AI/Decks/YosenjuExecutor.cs b/Game/AI/Decks/YosenjuExecutor.cs index 0f3c8f3a..6cb317ff 100644 --- a/Game/AI/Decks/YosenjuExecutor.cs +++ b/Game/AI/Decks/YosenjuExecutor.cs @@ -129,7 +129,7 @@ public YosenjuExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.SpSummon, CardId.Number39Utopia, DefaultNumberS39UtopiaTheLightningSummon); AddExecutor(ExecutorType.SpSummon, CardId.NumberS39UtopiaOne); AddExecutor(ExecutorType.SpSummon, CardId.NumberS39UtopiatheLightning); - AddExecutor(ExecutorType.Activate, CardId.NumberS39UtopiatheLightning); + AddExecutor(ExecutorType.Activate, CardId.NumberS39UtopiatheLightning, DefaultNumberS39UtopiaTheLightningEffect); AddExecutor(ExecutorType.Activate, CardId.StardustDragon, DefaultStardustDragonEffect); diff --git a/Game/AI/Decks/ZexalWeaponsExecutor.cs b/Game/AI/Decks/ZexalWeaponsExecutor.cs index 6a29a5dc..8cd8d4d5 100644 --- a/Game/AI/Decks/ZexalWeaponsExecutor.cs +++ b/Game/AI/Decks/ZexalWeaponsExecutor.cs @@ -72,7 +72,7 @@ public ZexalWeaponsExecutor(GameAI ai, Duel duel) // XYZ effects AddExecutor(ExecutorType.Activate, CardId.Number39Utopia, Number39Utopia); AddExecutor(ExecutorType.Activate, CardId.NumberS39UtopiaOne); - AddExecutor(ExecutorType.Activate, CardId.NumberS39UtopiatheLightning, NumberS39UtopiatheLightning); + AddExecutor(ExecutorType.Activate, CardId.NumberS39UtopiatheLightning, DefaultNumberS39UtopiaTheLightningEffect); AddExecutor(ExecutorType.Activate, CardId.ZwLionArms, ZwLionArms); AddExecutor(ExecutorType.Activate, CardId.AdreusKeeperOfArmageddon); AddExecutor(ExecutorType.Activate, CardId.Number61Volcasaurus); @@ -213,11 +213,6 @@ private bool XyzChangeTactics() return Bot.LifePoints > 500; } - private bool NumberS39UtopiatheLightning() - { - return Card.Attack < 5000; - } - private bool Honest() { return Duel.Phase != DuelPhase.Main1 || Duel.Turn == 1; diff --git a/Game/AI/Decks/ZoodiacExecutor.cs b/Game/AI/Decks/ZoodiacExecutor.cs index 9a5862b7..1c7ed9a4 100644 --- a/Game/AI/Decks/ZoodiacExecutor.cs +++ b/Game/AI/Decks/ZoodiacExecutor.cs @@ -73,7 +73,7 @@ public ZoodiacExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.SpSummon, CardId.Number39Utopia, DefaultNumberS39UtopiaTheLightningSummon); AddExecutor(ExecutorType.SpSummon, CardId.NumberS39UtopiatheLightning); - AddExecutor(ExecutorType.Activate, CardId.NumberS39UtopiatheLightning); + AddExecutor(ExecutorType.Activate, CardId.NumberS39UtopiatheLightning, DefaultNumberS39UtopiaTheLightningEffect); AddExecutor(ExecutorType.Activate, CardId.InvokedMechaba, DefaultTrap); diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index 0f8d5739..e193987c 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -629,6 +629,14 @@ protected bool DefaultNumberS39UtopiaTheLightningSummon() return AI.Utils.IsOneEnemyBetterThanValue(bestBotAttack, false); } + /// + /// Activate if the card is attack pos, and its attack is below 5000, when the enemy monster is attack pos or not useless faceup defense pos + /// + protected bool DefaultNumberS39UtopiaTheLightningEffect() + { + return Card.IsAttack() && Card.Attack < 5000 && (Enemy.BattlingMonster.IsAttack() || Enemy.BattlingMonster.IsFacedown() || Enemy.BattlingMonster.GetDefensePower() >= Card.Attack); + } + /// /// Summon when it can and should use effect. /// From 113f696efb658a8862fa7eff83b458e8c807a906 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Wed, 4 Apr 2018 16:38:19 +0800 Subject: [PATCH 11/68] add DefaultHonestEffect --- Game/AI/Decks/LightswornExecutor.cs | 6 +----- Game/AI/Decks/ZexalWeaponsExecutor.cs | 7 +------ Game/AI/DefaultExecutor.cs | 15 +++++++++++++++ 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Game/AI/Decks/LightswornExecutor.cs b/Game/AI/Decks/LightswornExecutor.cs index 5d1c9949..8b2a1c68 100644 --- a/Game/AI/Decks/LightswornExecutor.cs +++ b/Game/AI/Decks/LightswornExecutor.cs @@ -83,7 +83,7 @@ public LightswornExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.PerformageTrickClown, PerformageTrickClownEffect); AddExecutor(ExecutorType.Activate, CardId.ThousandBlades); - AddExecutor(ExecutorType.Activate, CardId.Honest, HonestEffect); + AddExecutor(ExecutorType.Activate, CardId.Honest, DefaultHonestEffect); AddExecutor(ExecutorType.Repos, DefaultMonsterRepos); } @@ -255,10 +255,6 @@ private bool MinervaTheExaltedEffect() return true; } } - private bool HonestEffect() - { - return Duel.Phase != DuelPhase.Main1; - } } } \ No newline at end of file diff --git a/Game/AI/Decks/ZexalWeaponsExecutor.cs b/Game/AI/Decks/ZexalWeaponsExecutor.cs index 8cd8d4d5..d6ff880d 100644 --- a/Game/AI/Decks/ZexalWeaponsExecutor.cs +++ b/Game/AI/Decks/ZexalWeaponsExecutor.cs @@ -105,7 +105,7 @@ public ZexalWeaponsExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.TinGoldfish, GoblindberghEffect); AddExecutor(ExecutorType.Activate, CardId.Kagetokage); AddExecutor(ExecutorType.Activate, CardId.SummonerMonk, SummonerMonkEffect); - AddExecutor(ExecutorType.Activate, CardId.Honest, Honest); + AddExecutor(ExecutorType.Activate, CardId.Honest, DefaultHonestEffect); // Reposition AddExecutor(ExecutorType.Repos, MonsterRepos); @@ -213,11 +213,6 @@ private bool XyzChangeTactics() return Bot.LifePoints > 500; } - private bool Honest() - { - return Duel.Phase != DuelPhase.Main1 || Duel.Turn == 1; - } - private bool GoblindberghFirst() { foreach (ClientCard card in Bot.Hand.GetMonsters()) diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index e193987c..8df41028 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -752,5 +752,20 @@ protected bool DefaultScarlightRedDragonArchfiendEffect() return (oppoCount > 0 && selfCount <= oppoCount) || oppoCount >= 3; } + /// + /// Clever enough. + /// + protected bool DefaultHonestEffect() + { + if (Card.Location == CardLocation.Hand) + { + return Bot.BattlingMonster.IsAttack() && + (((Bot.BattlingMonster.Attack < Enemy.BattlingMonster.Attack) || Bot.BattlingMonster.Attack >= Enemy.LifePoints) + || ((Bot.BattlingMonster.Attack < Enemy.BattlingMonster.Defense) && (Bot.BattlingMonster.Attack + Enemy.BattlingMonster.Attack > Enemy.BattlingMonster.Defense))); + } + else return AI.Utils.IsTurn1OrMain2(); + } + + } } From dd37ed1885983eb4d0eba2aa2e36f04815e3b170 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Wed, 4 Apr 2018 17:20:45 +0800 Subject: [PATCH 12/68] move LastChainPlayer and CurrentChain to Duel class --- Game/AI/Decks/BlueEyesExecutor.cs | 6 +++--- Game/AI/Decks/DragunityExecutor.cs | 2 +- Game/AI/Decks/HorusExecutor.cs | 2 +- Game/AI/Decks/Rank5Executor.cs | 4 ++-- Game/AI/Decks/ToadallyAwesomeExecutor.cs | 2 +- Game/AI/Decks/ZoodiacExecutor.cs | 4 ++-- Game/AI/DefaultExecutor.cs | 18 +++++++++--------- Game/AI/Executor.cs | 22 +++++++--------------- Game/Duel.cs | 5 +++++ Game/GameAI.cs | 4 ---- Game/GameBehavior.cs | 9 +++++++++ 11 files changed, 40 insertions(+), 38 deletions(-) diff --git a/Game/AI/Decks/BlueEyesExecutor.cs b/Game/AI/Decks/BlueEyesExecutor.cs index 6e72ee35..c6f0a6a8 100644 --- a/Game/AI/Decks/BlueEyesExecutor.cs +++ b/Game/AI/Decks/BlueEyesExecutor.cs @@ -302,7 +302,7 @@ private bool AlternativeWhiteDragonEffect() private bool RebornEffect() { - if (Duel.Player == 0 && CurrentChain.Count > 0) + if (Duel.Player == 0 && Duel.CurrentChain.Count > 0) { // Silver's Cry spsummon Dragon Spirit at chain 2 will miss the timing return false; @@ -446,7 +446,7 @@ private bool BlueEyesSpiritDragonEffect() { if (ActivateDescription == -1 || ActivateDescription == AI.Utils.GetStringId(CardId.BlueEyesSpiritDragon, 0)) { - return LastChainPlayer == 1; + return Duel.LastChainPlayer == 1; } else if (Duel.Player == 1 && (Duel.Phase == DuelPhase.BattleStart || Duel.Phase == DuelPhase.End)) { @@ -468,7 +468,7 @@ private bool HopeHarbingerDragonTitanicGalaxyEffect() { if (ActivateDescription == -1 || ActivateDescription == AI.Utils.GetStringId(CardId.HopeHarbingerDragonTitanicGalaxy, 0)) { - return LastChainPlayer == 1; + return Duel.LastChainPlayer == 1; } return true; } diff --git a/Game/AI/Decks/DragunityExecutor.cs b/Game/AI/Decks/DragunityExecutor.cs index 76c1c474..c06ec1aa 100644 --- a/Game/AI/Decks/DragunityExecutor.cs +++ b/Game/AI/Decks/DragunityExecutor.cs @@ -399,7 +399,7 @@ private bool CrystalWingSynchroDragonSummon() private bool CrystalWingSynchroDragonEffect() { - return LastChainPlayer != 0; + return Duel.LastChainPlayer != 0; } private bool DragunityPhalanxSummon() diff --git a/Game/AI/Decks/HorusExecutor.cs b/Game/AI/Decks/HorusExecutor.cs index 159e842e..0bc9c7d9 100644 --- a/Game/AI/Decks/HorusExecutor.cs +++ b/Game/AI/Decks/HorusExecutor.cs @@ -162,7 +162,7 @@ private bool WhiteNightDragon() private bool HorusTheBlackFlameDragonLv8() { - return LastChainPlayer == 1; + return Duel.LastChainPlayer == 1; } private bool DragonsRebirth() diff --git a/Game/AI/Decks/Rank5Executor.cs b/Game/AI/Decks/Rank5Executor.cs index 11812c97..df1b0365 100644 --- a/Game/AI/Decks/Rank5Executor.cs +++ b/Game/AI/Decks/Rank5Executor.cs @@ -262,9 +262,9 @@ private bool CyberDragonInfinitySummon() private bool CyberDragonInfinityEffect() { - if (CurrentChain.Count > 0) + if (Duel.CurrentChain.Count > 0) { - return LastChainPlayer == 1; + return Duel.LastChainPlayer == 1; } else { diff --git a/Game/AI/Decks/ToadallyAwesomeExecutor.cs b/Game/AI/Decks/ToadallyAwesomeExecutor.cs index 476652c3..f8971184 100644 --- a/Game/AI/Decks/ToadallyAwesomeExecutor.cs +++ b/Game/AI/Decks/ToadallyAwesomeExecutor.cs @@ -302,7 +302,7 @@ private bool PriorOfTheIceBarrierSummon() private bool ToadallyAwesomeEffect() { - if (CurrentChain.Count > 0) + if (Duel.CurrentChain.Count > 0) { // negate effect, select a cost for it List monsters = Bot.GetMonsters(); diff --git a/Game/AI/Decks/ZoodiacExecutor.cs b/Game/AI/Decks/ZoodiacExecutor.cs index 1c7ed9a4..f9b62222 100644 --- a/Game/AI/Decks/ZoodiacExecutor.cs +++ b/Game/AI/Decks/ZoodiacExecutor.cs @@ -486,7 +486,7 @@ private bool RatpierEffect() private bool DridentEffect() { - if (LastChainPlayer == 0) + if (Duel.LastChainPlayer == 0) return false; ClientCard target = AI.Utils.GetBestEnemyCard(true); if (target == null) @@ -571,7 +571,7 @@ private bool ZoodiacBarrageEffect() private bool ZoodiacComboEffect() { - if (CurrentChain.Count > 0) + if (Duel.CurrentChain.Count > 0) return false; if (Card.Location != CardLocation.Grave) { diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index 8df41028..1cf50fb1 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -95,7 +95,7 @@ public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender /// protected bool DefaultMysticalSpaceTyphoon() { - foreach (ClientCard card in CurrentChain) + foreach (ClientCard card in Duel.CurrentChain) if (card.Id == _CardId.MysticalSpaceTyphoon) return false; @@ -128,7 +128,7 @@ protected bool DefaultMysticalSpaceTyphoon() /// protected bool DefaultCosmicCyclone() { - foreach (ClientCard card in CurrentChain) + foreach (ClientCard card in Duel.CurrentChain) if (card.Id == _CardId.CosmicCyclone) return false; return (Bot.LifePoints > 1000) && DefaultMysticalSpaceTyphoon(); @@ -247,7 +247,7 @@ protected bool DefaultBreakthroughSkill() /// protected bool DefaultSolemnJudgment() { - return !AI.Utils.IsChainTargetOnly(Card) && !(Duel.Player == 0 && LastChainPlayer == -1) && DefaultTrap(); + return !AI.Utils.IsChainTargetOnly(Card) && !(Duel.Player == 0 && Duel.LastChainPlayer == -1) && DefaultTrap(); } /// @@ -255,7 +255,7 @@ protected bool DefaultSolemnJudgment() /// protected bool DefaultSolemnWarning() { - return (Bot.LifePoints > 2000) && !(Duel.Player == 0 && LastChainPlayer == -1) && DefaultTrap(); + return (Bot.LifePoints > 2000) && !(Duel.Player == 0 && Duel.LastChainPlayer == -1) && DefaultTrap(); } /// @@ -263,7 +263,7 @@ protected bool DefaultSolemnWarning() /// protected bool DefaultSolemnStrike() { - return (Bot.LifePoints > 1500) && !(Duel.Player == 0 && LastChainPlayer == -1) && DefaultTrap(); + return (Bot.LifePoints > 1500) && !(Duel.Player == 0 && Duel.LastChainPlayer == -1) && DefaultTrap(); } /// @@ -386,7 +386,7 @@ protected bool DefaultMonsterRepos() /// protected bool DefaultTrap() { - return (LastChainPlayer == -1 && Duel.LastSummonPlayer != 0) || LastChainPlayer == 1; + return (Duel.LastChainPlayer == -1 && Duel.LastSummonPlayer != 0) || Duel.LastChainPlayer == 1; } /// @@ -436,7 +436,7 @@ protected bool DefaultDontChainMyself() if (exec.Type == Type && exec.CardId == Card.Id) return false; } - return LastChainPlayer != 0; + return Duel.LastChainPlayer != 0; } /// @@ -510,7 +510,7 @@ protected bool DefaultDimensionalBarrier() } } ClientCard lastchaincard = GetLastChainCard(); - if (LastChainPlayer == 1 && lastchaincard != null && !lastchaincard.IsDisabled()) + if (Duel.LastChainPlayer == 1 && lastchaincard != null && !lastchaincard.IsDisabled()) { if (lastchaincard.HasType(CardType.Ritual)) { @@ -690,7 +690,7 @@ protected bool DefaultStardustDragonSummon() /// protected bool DefaultStardustDragonEffect() { - return (Card.Location == CardLocation.Grave) || LastChainPlayer == 1; + return (Card.Location == CardLocation.Grave) || Duel.LastChainPlayer == 1; } /// diff --git a/Game/AI/Executor.cs b/Game/AI/Executor.cs index f6776389..85438524 100644 --- a/Game/AI/Executor.cs +++ b/Game/AI/Executor.cs @@ -21,9 +21,6 @@ public abstract class Executor protected ClientCard Card { get; private set; } protected int ActivateDescription { get; private set; } - protected int LastChainPlayer { get; private set; } - protected IList CurrentChain { get; private set; } - protected ClientField Bot { get; private set; } protected ClientField Enemy { get; private set; } @@ -33,9 +30,6 @@ protected Executor(GameAI ai, Duel duel) AI = ai; Executors = new List(); - LastChainPlayer = -1; - CurrentChain = new List(); - Bot = Duel.Fields[0]; Enemy = Duel.Fields[1]; } @@ -109,14 +103,12 @@ public virtual bool OnPreBattleBetween(ClientCard attacker, ClientCard defender) public virtual void OnChaining(int player, ClientCard card) { - CurrentChain.Add(card); - LastChainPlayer = player; + } public virtual void OnChainEnd() { - LastChainPlayer = -1; - CurrentChain.Clear(); + } public virtual void OnNewTurn() @@ -184,7 +176,7 @@ public virtual int OnSelectOption(IList options) public bool ChainContainsCard(int id) { - foreach (ClientCard card in CurrentChain) + foreach (ClientCard card in Duel.CurrentChain) { if (card.Id == id) return true; @@ -195,7 +187,7 @@ public bool ChainContainsCard(int id) public int ChainCountPlayer(int player) { int count = 0; - foreach (ClientCard card in CurrentChain) + foreach (ClientCard card in Duel.CurrentChain) { if (card.Controller == player) count++; @@ -205,7 +197,7 @@ public int ChainCountPlayer(int player) public bool HasChainedTrap(int player) { - foreach (ClientCard card in CurrentChain) + foreach (ClientCard card in Duel.CurrentChain) { if (card.Controller == player && card.HasType(CardType.Trap)) return true; @@ -215,8 +207,8 @@ public bool HasChainedTrap(int player) public ClientCard GetLastChainCard() { - if (CurrentChain.Count > 0) - return CurrentChain[CurrentChain.Count - 1]; + if (Duel.CurrentChain.Count > 0) + return Duel.CurrentChain[Duel.CurrentChain.Count - 1]; return null; } diff --git a/Game/Duel.cs b/Game/Duel.cs index e6477dad..85c68e9b 100644 --- a/Game/Duel.cs +++ b/Game/Duel.cs @@ -15,6 +15,9 @@ public class Duel public DuelPhase Phase { get; set; } public MainPhase MainPhase { get; set; } public BattlePhase BattlePhase { get; set; } + + public int LastChainPlayer { get; set; } + public IList CurrentChain { get; set; } public IList ChainTargets { get; set; } public int LastSummonPlayer { get; set; } @@ -23,6 +26,8 @@ public Duel() Fields = new ClientField[2]; Fields[0] = new ClientField(); Fields[1] = new ClientField(); + LastChainPlayer = -1; + CurrentChain = new List(); ChainTargets = new List(); LastSummonPlayer = -1; } diff --git a/Game/GameAI.cs b/Game/GameAI.cs index 1987b5ce..c4cdc197 100644 --- a/Game/GameAI.cs +++ b/Game/GameAI.cs @@ -90,9 +90,6 @@ public void OnNewPhase() m_option = -1; m_yesno = -1; m_position = CardPosition.FaceUpAttack; - Duel.LastSummonPlayer = -1; - Duel.Fields[0].BattlingMonster = null; - Duel.Fields[1].BattlingMonster = null; if (Duel.Player == 0 && Duel.Phase == DuelPhase.Draw) { _dialogs.SendNewTurn(); @@ -114,7 +111,6 @@ public void OnDirectAttack(ClientCard card) /// Player who is currently chaining. public void OnChaining(ClientCard card, int player) { - Duel.LastSummonPlayer = -1; Executor.OnChaining(player,card); } diff --git a/Game/GameBehavior.cs b/Game/GameBehavior.cs index 93c6c26f..80bc700c 100644 --- a/Game/GameBehavior.cs +++ b/Game/GameBehavior.cs @@ -421,6 +421,9 @@ private void OnNewTurn(BinaryReader packet) private void OnNewPhase(BinaryReader packet) { _duel.Phase = (DuelPhase)packet.ReadInt16(); + _duel.LastSummonPlayer = -1; + _duel.Fields[0].BattlingMonster = null; + _duel.Fields[1].BattlingMonster = null; _ai.OnNewPhase(); } @@ -534,11 +537,17 @@ private void OnChaining(BinaryReader packet) int cc = GetLocalPlayer(packet.ReadByte()); _ai.OnChaining(card, cc); _duel.ChainTargets.Clear(); + _duel.LastSummonPlayer = -1; + _duel.CurrentChain.Add(card); + _duel.LastChainPlayer = cc; + } private void OnChainEnd(BinaryReader packet) { _ai.OnChainEnd(); + _duel.LastChainPlayer = -1; + _duel.CurrentChain.Clear(); //_duel.ChainTargets.Clear(); } From 93cc91f7f0689dc0a0180d222d2a86b33414715e Mon Sep 17 00:00:00 2001 From: mercury233 Date: Wed, 4 Apr 2018 17:27:59 +0800 Subject: [PATCH 13/68] move some functions --- Game/AI/AIFunctions.cs | 38 +++++++++++++++++++++++++++ Game/AI/Decks/ZexalWeaponsExecutor.cs | 2 +- Game/AI/DefaultExecutor.cs | 8 +++--- Game/AI/Executor.cs | 38 --------------------------- 4 files changed, 43 insertions(+), 43 deletions(-) diff --git a/Game/AI/AIFunctions.cs b/Game/AI/AIFunctions.cs index fa14c34e..f0cabf15 100644 --- a/Game/AI/AIFunctions.cs +++ b/Game/AI/AIFunctions.cs @@ -296,6 +296,44 @@ public bool IsChainTargetOnly(ClientCard card) return Duel.ChainTargets.Count == 1 && card.Equals(Duel.ChainTargets[0]); } + public bool ChainContainsCard(int id) + { + foreach (ClientCard card in Duel.CurrentChain) + { + if (card.Id == id) + return true; + } + return false; + } + + public int ChainCountPlayer(int player) + { + int count = 0; + foreach (ClientCard card in Duel.CurrentChain) + { + if (card.Controller == player) + count++; + } + return count; + } + + public bool HasChainedTrap(int player) + { + foreach (ClientCard card in Duel.CurrentChain) + { + if (card.Controller == player && card.HasType(CardType.Trap)) + return true; + } + return false; + } + + public ClientCard GetLastChainCard() + { + if (Duel.CurrentChain.Count > 0) + return Duel.CurrentChain[Duel.CurrentChain.Count - 1]; + return null; + } + /// /// Select cards listed in preferred. /// diff --git a/Game/AI/Decks/ZexalWeaponsExecutor.cs b/Game/AI/Decks/ZexalWeaponsExecutor.cs index d6ff880d..a271ebd6 100644 --- a/Game/AI/Decks/ZexalWeaponsExecutor.cs +++ b/Game/AI/Decks/ZexalWeaponsExecutor.cs @@ -150,7 +150,7 @@ public override IList OnSelectXyzMaterial(IList cards, i private bool Number39Utopia() { - if (!HasChainedTrap(0) && Duel.Player == 1 && Duel.Phase == DuelPhase.BattleStart && Card.HasXyzMaterial(2)) + if (!AI.Utils.HasChainedTrap(0) && Duel.Player == 1 && Duel.Phase == DuelPhase.BattleStart && Card.HasXyzMaterial(2)) return true; return false; } diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index 1cf50fb1..e94b4e54 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -234,7 +234,7 @@ protected bool DefaultCallOfTheHaunted() /// protected bool DefaultBreakthroughSkill() { - ClientCard LastChainCard = GetLastChainCard(); + ClientCard LastChainCard = AI.Utils.GetLastChainCard(); if (LastChainCard == null) return false; @@ -271,7 +271,7 @@ protected bool DefaultSolemnStrike() /// protected bool DefaultTorrentialTribute() { - return !HasChainedTrap(0) && AI.Utils.IsAllEnemyBetter(true); + return !AI.Utils.HasChainedTrap(0) && AI.Utils.IsAllEnemyBetter(true); } /// @@ -394,7 +394,7 @@ protected bool DefaultTrap() /// protected bool DefaultUniqueTrap() { - if (HasChainedTrap(0)) + if (AI.Utils.HasChainedTrap(0)) return false; return UniqueFaceupSpell(); @@ -509,7 +509,7 @@ protected bool DefaultDimensionalBarrier() return true; } } - ClientCard lastchaincard = GetLastChainCard(); + ClientCard lastchaincard = AI.Utils.GetLastChainCard(); if (Duel.LastChainPlayer == 1 && lastchaincard != null && !lastchaincard.IsDisabled()) { if (lastchaincard.HasType(CardType.Ritual)) diff --git a/Game/AI/Executor.cs b/Game/AI/Executor.cs index 85438524..8090c57b 100644 --- a/Game/AI/Executor.cs +++ b/Game/AI/Executor.cs @@ -174,44 +174,6 @@ public virtual int OnSelectOption(IList options) return -1; } - public bool ChainContainsCard(int id) - { - foreach (ClientCard card in Duel.CurrentChain) - { - if (card.Id == id) - return true; - } - return false; - } - - public int ChainCountPlayer(int player) - { - int count = 0; - foreach (ClientCard card in Duel.CurrentChain) - { - if (card.Controller == player) - count++; - } - return count; - } - - public bool HasChainedTrap(int player) - { - foreach (ClientCard card in Duel.CurrentChain) - { - if (card.Controller == player && card.HasType(CardType.Trap)) - return true; - } - return false; - } - - public ClientCard GetLastChainCard() - { - if (Duel.CurrentChain.Count > 0) - return Duel.CurrentChain[Duel.CurrentChain.Count - 1]; - return null; - } - public void SetMain(MainPhase main) { Main = main; From 301f85357bcc7ca9495f1b133a4a8928b36b8371 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Wed, 4 Apr 2018 19:47:12 +0800 Subject: [PATCH 14/68] fix DefaultBreakthroughSkill --- Game/AI/DefaultExecutor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index e94b4e54..0f2645d1 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -239,6 +239,7 @@ protected bool DefaultBreakthroughSkill() if (LastChainCard == null) return false; + AI.SelectCard(LastChainCard); return LastChainCard.Controller == 1 && LastChainCard.Location == CardLocation.MonsterZone && DefaultUniqueTrap(); } From 85d5c5e7ef099a87da1d31efdef76a278537fe65 Mon Sep 17 00:00:00 2001 From: handsomekiwi <36762809+handsomekiwi@users.noreply.github.com> Date: Wed, 4 Apr 2018 19:57:08 +0800 Subject: [PATCH 15/68] add LightswornShaddoldinosour deck(#21) --- Decks/AI_LightswornShaddoldinosour.ydk | 93 +++ Dialogs/kiwi.zh-CN.json | 78 ++ .../LightswornShaddoldinosourExecutor.cs | 686 ++++++++++++++++++ Game/ClientField.cs | 10 + WindBot.csproj | 1 + 5 files changed, 868 insertions(+) create mode 100644 Decks/AI_LightswornShaddoldinosour.ydk create mode 100644 Dialogs/kiwi.zh-CN.json create mode 100644 Game/AI/Decks/LightswornShaddoldinosourExecutor.cs diff --git a/Decks/AI_LightswornShaddoldinosour.ydk b/Decks/AI_LightswornShaddoldinosour.ydk new file mode 100644 index 00000000..c896c044 --- /dev/null +++ b/Decks/AI_LightswornShaddoldinosour.ydk @@ -0,0 +1,93 @@ +#created by ... +#main +18940556 +18940556 +18940556 +93332803 +93332803 +55063751 +28674152 +41782653 +41782653 +41782653 +3717252 +3717252 +80280944 +48048590 +77723643 +55623480 +30328508 +30328508 +44335251 +77558536 +77558536 +77558536 +95503687 +95503687 +4939890 +4939890 +14558127 +14558127 +59438930 +37445295 +37445295 +23434538 +23434538 +33420078 +67441435 +1475311 +1475311 +1475311 +11110587 +11110587 +11110587 +18144506 +38179121 +38179121 +38179121 +44394295 +44394295 +44394295 +67169062 +81439173 +83764718 +94886282 +94886282 +99330325 +10045474 +10045474 +74003290 +77505534 +4904633 +#extra +74822425 +20366274 +48424886 +94977269 +50954680 +80666118 +4779823 +33698022 +76547525 +42566602 +98558751 +30100551 +74997493 +50588353 +50588353 +!side +67696066 +73176465 +37742478 +15341821 +54757758 +13529466 +74586817 +6983839 +82633039 +46772449 +1861629 +1845204 +53129443 +43898403 +48130397 diff --git a/Dialogs/kiwi.zh-CN.json b/Dialogs/kiwi.zh-CN.json new file mode 100644 index 00000000..2ab014c5 --- /dev/null +++ b/Dialogs/kiwi.zh-CN.json @@ -0,0 +1,78 @@ +{ + "welcome": [ + "你找到我了!!!", + "來決鬥吧" + ], + "deckerror": [ + "阿,可能BA又把CBD修壞導致{0}消失了。" + ], + "duelstart": [ + "這只是AI,打贏不要太高興阿。", + "十分致謝233服讓我們有遊戲可以玩,別忘記去拜訪他們。", + "反主流學院請洽NOVA。", + + ], + "newturn": [ + "到我的回合了,抽牌!", + "我的回合,抽牌!", + "我抽了一張卡。" + ], + "endturn": [ + "回合结束。", + "我的回合结束了。", + "這樣算是成功的展開嗎......", + "輪到你了。你的下一句是......我要發動灰流麗對吧!" + ], + "directattack": [ + "{0},直接攻擊!", + "{0},直接攻擊對手!", + "{0},没有防守的地方,攻擊!", + "{0},攻擊對手的生命值!", + "{0},直接攻擊對手的生命值!", + "{0},通過直接攻擊打倒對手!", + "{0},使用直接攻擊打倒對手!", + "{0},直接攻擊釋放你的力量吧!", + "我的{0}將會粉碎你的生命值!", + "向對手展示你的力量吧,{0}!", + "你已經無法阻止我了。{0},攻擊!" + ], + "attack": [ + "{0},攻擊這體{1}!", + "{0},消滅這體{1}!", + "{0},打倒{1}!", + "{0},衝向那體{1}!", + "{0},把你的力量释放到{1}上吧!" + ], + "ondirectattack": [ + "可惡......", + "不過是{0}而已!", + "果然我還是太弱了......" + ], + "facedownmonstername": "怪獸", + "activate": [ + "我發動{0}。", + "我使用{0}的效果。", + "我使用{0}的力量。" + ], + "summon": [ + "真是HIGH的最高點!出來吧{0}。", + "出來吧,{0}!", + "出現吧,{0}!", + "我召喚了強大的{0}!", + "我呼喚{0}參加戰鬥!", + "我呼喚出{0}。", + "我召喚{0}。" + ], + "setmonster": [ + "我放置了一體怪獸。", + "我裡側表示放置了一體怪獸。" + ], + "chaining": [ + "看這裡!發動{0}!", + "我使用{0}的力量。", + "很不錯的戰術...但是我拒絕!{0}!", + "真不愧是納粹,竟然能識破我的蓋牌......你說你只是單純的決鬥者?{0},發動!", + "看樣子你忘了我的{0}!", + "你考慮過我有{0}嗎?" + ] +} diff --git a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs new file mode 100644 index 00000000..51366742 --- /dev/null +++ b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs @@ -0,0 +1,686 @@ +using YGOSharp.OCGWrapper.Enums; +using System.Collections.Generic; +using WindBot; +using WindBot.Game; +using WindBot.Game.AI; + +namespace WindBot.Game.AI.Decks +{ + // NOT FINISHED YET + [Deck("LightswornShaddoldinosour", "AI_LightswornShaddoldinosour", "ver0.1")] + public class LightswornShaddoldinosour : DefaultExecutor + { + public class CardId + { + //monster + public const int UltimateConductorTytanno = 18940556; + public const int DogorantheMadFlameKaiju = 93332803; + public const int GamecieltheSeaTurtleKaiju = 55063751; + public const int RadiantheMultidimensionalKaiju = 28674152; + public const int OvertexCoatls = 41782653; + public const int ShaddollBeast = 3717252; + public const int GiantRex = 80280944; + public const int ShaddollDragon = 77723643; + public const int FairyTailSnow = 55623480; + public const int KeeeperOfDragonicMagic = 48048590; + public const int ShaddollSquamata = 30328508; + public const int SouleatingOviraptor = 44335251; + public const int Raiden = 77558536; + public const int Lumina = 95503687; + public const int ShaddollHedgehog = 4939890; + public const int AshBlossom = 14558127; + public const int GhostOgre = 59438930; + public const int ShaddollFalco = 37445295; + public const int MaxxC = 23434538; + public const int PlaguespreaderZombie = 33420078; + public const int GlowUpBulb = 67441435; + + //spell + public const int AllureofDarkness = 1475311; + public const int ThatGrassLooksgreener = 11110587; + public const int HarpiesFeatherDuster = 18144506; + public const int DoubleEvolutionPill = 38179121; + public const int ShaddollFusion = 44394295; + public const int PotOfAvarice = 67169026; + public const int FoolishBurial = 81439173; + public const int MonsterReborn = 83764718; + public const int ChargeOfTheLightBrigade = 94886282; + public const int InterruptedKaijuSlumber = 99330325; + public const int ElShaddollFusion = 6417578; + + //trap + public const int infiniteTransience = 10045474; + public const int LostWind = 74003290; + public const int SinisterShadowGames = 77505534; + public const int ShaddollCore = 4904633; + + //extra + public const int ElShaddollShekhinaga = 74822425; + public const int ElShaddollConstruct = 20366274; + public const int ElShaddollGrysra = 48424886; + public const int ElShaddollWinda = 94977269; + public const int CrystalWingSynchroDragon = 50954680; + public const int ScarlightRedDragon = 80666118; + public const int Michael = 4779823; + public const int BlackRoseMoonlightDragon = 33698022; + public const int RedWyvern = 76547525; + public const int CoralDragon = 42566602; + public const int TG_WonderMagician = 98558751; + public const int MinervaTheExalte = 30100551; + public const int Sdulldeat = 74997493; + public const int CrystronNeedlefiber = 50588353; + } + + bool Pillused = false; + + public LightswornShaddoldinosour(GameAI ai, Duel duel) + : base(ai, duel) + { + //counter + + AddExecutor(ExecutorType.Activate, CardId.GhostOgre, Hand_act_eff); + AddExecutor(ExecutorType.Activate, CardId.AshBlossom, Hand_act_eff); + AddExecutor(ExecutorType.Activate, CardId.MaxxC,MaxxC); + //first do + AddExecutor(ExecutorType.Activate, CardId.HarpiesFeatherDuster, DefaultHarpiesFeatherDusterFirst); + AddExecutor(ExecutorType.Activate, CardId.infiniteTransience, infiniteTransience); + AddExecutor(ExecutorType.Activate, CardId.ThatGrassLooksgreener); + AddExecutor(ExecutorType.Summon, CardId.SouleatingOviraptor); + AddExecutor(ExecutorType.Activate, CardId.SouleatingOviraptor, SouleatingOviraptor); + AddExecutor(ExecutorType.Activate, CardId.AllureofDarkness, AllureofDarkness); + AddExecutor(ExecutorType.Activate, CardId.PotOfAvarice, PotofAvarice); + // AddExecutor(ExecutorType.Activate, CardId.HarpiesFeatherDuster); + AddExecutor(ExecutorType.Activate, CardId.ChargeOfTheLightBrigade, ChargeOfTheLightBrigadeEffect); + AddExecutor(ExecutorType.Activate, CardId.FoolishBurial, FoolishBurialEffect); + AddExecutor(ExecutorType.Activate, CardId.InterruptedKaijuSlumber, DefaultInterruptedKaijuSlumber); + AddExecutor(ExecutorType.Activate, CardId.ShaddollFusion, ShaddollFusion); + //Reborn + AddExecutor(ExecutorType.Activate, CardId.MonsterReborn, RebornEffect); + //Normal Summon + AddExecutor(ExecutorType.Summon, CardId.Raiden); + AddExecutor(ExecutorType.Activate, CardId.Raiden); + + AddExecutor(ExecutorType.Summon , CardId.KeeeperOfDragonicMagic); + AddExecutor(ExecutorType.Activate, CardId.KeeeperOfDragonicMagic, KeeeperOfDragonicMagic); + AddExecutor(ExecutorType.MonsterSet, CardId.ShaddollSquamata); + AddExecutor(ExecutorType.MonsterSet, CardId.GlowUpBulb); + AddExecutor(ExecutorType.MonsterSet, CardId.ShaddollHedgehog); + AddExecutor(ExecutorType.MonsterSet, CardId.ShaddollDragon); + AddExecutor(ExecutorType.Summon, CardId.FairyTailSnow,FairyTailSnow); + AddExecutor(ExecutorType.Activate, CardId.FairyTailSnow, FairyTailSnow); + AddExecutor(ExecutorType.Summon, CardId.Lumina); + AddExecutor(ExecutorType.Activate, CardId.Lumina); + //Sp Summon + AddExecutor(ExecutorType.SpSummon, CardId.UltimateConductorTytanno, UltimateConductorTytannosp); + AddExecutor(ExecutorType.Activate, CardId.UltimateConductorTytanno, UltimateConductorTytanno); + AddExecutor(ExecutorType.Activate, CardId.DoubleEvolutionPill, DoubleEvolutionPill); + AddExecutor(ExecutorType.SpSummon, CardId.MinervaTheExalte); + AddExecutor(ExecutorType.Activate, CardId.MinervaTheExalte, MinervaTheExaltedEffect); + + + + //activate + AddExecutor(ExecutorType.Activate , CardId.GlowUpBulb,GlowUpBulb); + + //activate chain + AddExecutor(ExecutorType.Activate, CardId.OvertexCoatls); + AddExecutor(ExecutorType.Activate, CardId.ShaddollBeast); + AddExecutor(ExecutorType.Activate, CardId.ShaddollFalco, ShaddollFalco); + AddExecutor(ExecutorType.Activate, CardId.ShaddollSquamata, ShaddollSquamata); + AddExecutor(ExecutorType.Activate, CardId.ShaddollDragon); + AddExecutor(ExecutorType.Activate, CardId.ShaddollHedgehog); + AddExecutor(ExecutorType.Activate, CardId.GiantRex); + AddExecutor(ExecutorType.Activate, CardId.ElShaddollConstruct); + AddExecutor(ExecutorType.Activate, CardId.ElShaddollGrysra); + AddExecutor(ExecutorType.Activate, CardId.ElShaddollShekhinaga); + AddExecutor(ExecutorType.Activate, CardId.ElShaddollWinda); + AddExecutor(ExecutorType.Activate, CardId.TG_WonderMagician); + //spellset + AddExecutor(ExecutorType.SpellSet, CardId.MonsterReborn, spellset); + AddExecutor(ExecutorType.SpellSet, CardId.PotOfAvarice, spellset); + AddExecutor(ExecutorType.SpellSet, CardId.ThatGrassLooksgreener, spellset); + //trap + AddExecutor(ExecutorType.SpellSet, CardId.LostWind, TrapSetWhenZoneFree); + AddExecutor(ExecutorType.SpellSet, CardId.SinisterShadowGames, TrapSetWhenZoneFree); + AddExecutor(ExecutorType.SpellSet, CardId.ShaddollCore); + AddExecutor(ExecutorType.SpellSet, CardId.infiniteTransience, SetIsFieldEmpty); + //trap activate + AddExecutor(ExecutorType.Activate, CardId.LostWind, DefaultBreakthroughSkill); + AddExecutor(ExecutorType.Activate, CardId.SinisterShadowGames, SinisterShadowGames); + AddExecutor(ExecutorType.Activate, CardId.ShaddollCore, ShaddollCoreeff); + AddExecutor(ExecutorType.Repos, MonsterRepos); + } + public int[] all_List() + { + return new[] + { + CardId.UltimateConductorTytanno, + CardId.DogorantheMadFlameKaiju, + CardId.GamecieltheSeaTurtleKaiju, + CardId.RadiantheMultidimensionalKaiju, + CardId.OvertexCoatls, + CardId.ShaddollBeast, + CardId.GiantRex, + CardId.ShaddollDragon, + CardId.FairyTailSnow, + CardId.KeeeperOfDragonicMagic, + CardId.ShaddollSquamata, + CardId.SouleatingOviraptor, + CardId.Raiden, + CardId.Lumina, + CardId.ShaddollHedgehog, + CardId.AshBlossom, + CardId.GhostOgre, + CardId.ShaddollFalco, + CardId.MaxxC, + CardId.PlaguespreaderZombie, + CardId.GlowUpBulb, + + CardId.AllureofDarkness, + CardId.ThatGrassLooksgreener, + CardId.HarpiesFeatherDuster, + CardId.DoubleEvolutionPill, + CardId.ShaddollFusion, + CardId.PotOfAvarice, + CardId.FoolishBurial, + CardId.MonsterReborn, + CardId.ChargeOfTheLightBrigade, + CardId.InterruptedKaijuSlumber, + CardId.ElShaddollFusion, + + CardId.infiniteTransience, + CardId.LostWind, + CardId.SinisterShadowGames, + CardId.ShaddollCore, + + + }; + } + public int[] Useless_List() + { + return new[] + { + CardId.GlowUpBulb, + CardId.PlaguespreaderZombie, + CardId.InterruptedKaijuSlumber, + CardId.ChargeOfTheLightBrigade, + CardId.FoolishBurial, + CardId.HarpiesFeatherDuster, + CardId.ThatGrassLooksgreener, + CardId.FairyTailSnow, + CardId.GiantRex, + CardId.Lumina, + CardId.OvertexCoatls, + + }; + } + + private bool UltimateConductorTytanno() + { + AI.SelectCard(new[] + { + CardId.OvertexCoatls, + CardId.ShaddollBeast, + CardId.ShaddollSquamata, + CardId.ShaddollHedgehog, + CardId.ShaddollDragon, + CardId.GlowUpBulb, + CardId.PlaguespreaderZombie, + CardId.FairyTailSnow, + }); + + + return true; + } + private bool UltimateConductorTytannosp() + { + Pillused = true; + foreach (ClientCard card in Bot.GetMonsters()) + { + if (card.Id == Card.Id && card.IsFaceup()) + return false; + } + return true; + + } + private bool KeeeperOfDragonicMagic() + { + AI.SelectCard(Useless_List()); + + return true; + } + private bool MonsterRepos() + { + if (Card.Id == CardId.ElShaddollConstruct && Card.IsAttack()) + return false; + return base.DefaultMonsterRepos(); + } + public override void OnNewTurn() + { + Pillused = false; + } + private bool ShaddollCoreeff() + { + if (Card.Location == CardLocation.SpellZone) + { + if(Enemy.HasAttackingMonster()) + { + AI.SelectPosition(CardPosition.FaceUpDefence); + return true; + } + + return false; + } + return true; + } + private bool FairyTailSnow() + { + + if (Card.Location == CardLocation.MonsterZone) + { + return true; + } + return false; + } + private bool SouleatingOviraptor() + { + AI.SelectCard(CardId.OvertexCoatls); + AI.SelectYesNo(false); + return true; + } + private bool GlowUpBulb() + { + AI.SelectPosition(CardPosition.FaceUpDefence); + return true; + } + private bool ShaddollFusion() + { + if (Enemy.GetMonstersExtraZoneCount() != 0) + { + IList materials0 = Bot.Deck; + IList materials1 = Bot.Deck; + IList mats = new List(); + + ClientCard mat = null; + foreach (ClientCard card in materials0) + { + if (card.HasAttribute(CardAttribute.Light)) + { + mat = card; + break; + } + } + foreach (ClientCard card in materials1) + { + AI.SelectCard(new[] + { + CardId.ShaddollBeast, + CardId.ShaddollSquamata, + CardId.ShaddollHedgehog, + CardId.ShaddollDragon, + CardId.ShaddollFalco, + + }); + } + if (mat != null) + { + mats.Add(mat); + + AI.SelectMaterials(mats); + AI.SelectCard(CardId.ElShaddollConstruct); + AI.SelectPosition(CardPosition.FaceUpAttack); + return true; + } + + + foreach (ClientCard card in materials0) + { + if (card.HasAttribute(CardAttribute.Earth)) + { + mat = card; + break; + } + } + foreach (ClientCard card in materials1) + { + AI.SelectCard(new[] + { + CardId.ShaddollBeast, + CardId.ShaddollSquamata, + CardId.ShaddollHedgehog, + CardId.ShaddollDragon, + CardId.ShaddollFalco, + + }); + } + if (mat != null) + { + mats.Add(mat); + + AI.SelectMaterials(mats); + AI.SelectCard(CardId.ElShaddollShekhinaga); + AI.SelectPosition(CardPosition.FaceUpAttack); + return true; + } + + + foreach (ClientCard card in materials0) + { + if (card.HasAttribute(CardAttribute.Fire)) + { + mat = card; + break; + } + } + foreach (ClientCard card in materials1) + { + AI.SelectCard(new[] + { + CardId.ShaddollBeast, + CardId.ShaddollSquamata, + CardId.ShaddollHedgehog, + CardId.ShaddollDragon, + CardId.ShaddollFalco, + + }); + } + if (mat != null) + { + mats.Add(mat); + + AI.SelectMaterials(mats); + AI.SelectCard(CardId.ElShaddollGrysra); + AI.SelectPosition(CardPosition.FaceUpAttack); + return true; + } + + + foreach (ClientCard card in materials0) + { + if (card.HasAttribute(CardAttribute.Dark)) + { + mat = card; + break; + } + } + foreach (ClientCard card in materials1) + { + AI.SelectCard(new[] + { + CardId.ShaddollBeast, + CardId.ShaddollSquamata, + CardId.ShaddollHedgehog, + CardId.ShaddollDragon, + CardId.ShaddollFalco, + + }); + } + if (mat != null) + { + mats.Add(mat); + + AI.SelectMaterials(mats); + AI.SelectCard(CardId.ElShaddollWinda); + AI.SelectPosition(CardPosition.FaceUpAttack); + return true; + } + } + else + { + if (!Bot.IsFieldEmpty()) + return false; + AI.SelectCard(CardId.ElShaddollConstruct); + AI.SelectPosition(CardPosition.FaceUpAttack); + } + return true; + + } + + + /* private ClientCard GetAleisterInGrave() + { + foreach (ClientCard card in Enemy.Graveyard) + { + if (card.Id == CardId.AleisterTheInvoker) + { + return card; + } + } + foreach (ClientCard card in Bot.Graveyard) + { + if (card.Id == CardId.AleisterTheInvoker) + { + return card; + } + } + return null; + }*/ + private bool DoubleEvolutionPill() + { + if (Pillused == true)return false; + Pillused = true; + if (Bot.HasInGraveyard(CardId.UltimateConductorTytanno) ) + { + AI.SelectCard(CardId.UltimateConductorTytanno); + } + + + AI.SelectThirdCard(new[] { + CardId.UltimateConductorTytanno, + + }); + + return Enemy.GetMonsterCount()>=1; + } + + + private bool ShaddollCore() + { + return Bot.HasInGraveyard(CardId.ShaddollFusion); + } + private bool AllureofDarkness() + { + IList materials = Bot.Hand; + IList check = new List(); + ClientCard mat = null; + foreach (ClientCard card in materials) + { + if (card.HasAttribute(CardAttribute.Dark)) + { + mat = card; + break; + } + } + if (mat != null) + { + return true; + } + return false; + } + private bool spellset() + { + return Bot.Hand.Count > 6; + } + private bool RebornEffect() + { + IList targets = new[] { + CardId.UltimateConductorTytanno, + CardId.ElShaddollConstruct, + CardId.DogorantheMadFlameKaiju, + CardId.GamecieltheSeaTurtleKaiju, + CardId.SouleatingOviraptor, + }; + if (!Bot.HasInGraveyard(targets)) + { + return false; + } + AI.SelectCard(targets); + return true; + } + private bool PotofAvarice() + { + return true; + } + private bool infiniteTransience() + { + return LastChainPlayer == 1; + } + private bool MaxxC() + { + return Duel.Player == 1; + } + private bool SetIsFieldEmpty() + { + return !Bot.IsFieldEmpty(); + } + private bool TrapSetWhenZoneFree() + { + return Bot.GetSpellCountWithoutField() < 4; + } + + private bool ChargeOfTheLightBrigadeEffect() + { + if (!Bot.HasInHand(CardId.Raiden)) + AI.SelectCard(CardId.Raiden); + else + AI.SelectCard(new[] + { + CardId.Lumina, + + }); + return true; + } + private bool SinisterShadowGames() + { + if (Card.Location != CardLocation.MonsterZone) + return true; + else + { + AI.SelectCard(new[] + { + CardId.ShaddollBeast, + CardId.ShaddollCore, + } + + ); + } + return true; + } + + private bool ShaddollFalco() + { + if (Card.Location != CardLocation.MonsterZone) + return true; + else + { + AI.SelectCard(new[] + { + CardId.ElShaddollConstruct, + CardId.ElShaddollShekhinaga, + CardId.ElShaddollGrysra, + CardId.ElShaddollWinda, + CardId.ShaddollSquamata, + } + ); + + } + return true; + } + private bool ShaddollSquamata() + { + AI.SelectCard(new[] + { + CardId.ShaddollBeast, + + } + ); + return true; + + } + private bool FoolishBurialEffect() + { + + AI.SelectCard(new[] + { + CardId.OvertexCoatls, + CardId.ShaddollSquamata, + CardId.ShaddollBeast, + CardId.ShaddollCore, + CardId.ShaddollHedgehog, + CardId.ShaddollFalco, + CardId.ShaddollDragon, + CardId.FairyTailSnow, + }); + return true; + } + + + private bool GoblindberghSummon() + { + foreach (ClientCard card in Bot.Hand.GetMonsters()) + { + if (!card.Equals(Card) && card.Level == 4) + return true; + } + return false; + } + + + + + private bool PerformageTrickClownEffect() + { + AI.SelectPosition(CardPosition.FaceUpDefence); + return true; + } + public bool Hand_act_eff() + { + //if (Card.Id == CardId.Urara && Bot.HasInHand(CardId.LockBird) && Bot.HasInSpellZone(CardId.Re)) return false; + if (Card.Id == CardId.GhostOgre && Card.Location == CardLocation.Hand && Bot.HasInMonstersZone(CardId.GhostOgre)) return false; + return (LastChainPlayer == 1); + } + private bool MinervaTheExaltedEffect() + { + if (Card.Location == CardLocation.MonsterZone) + { + return true; + } + else + { + IList targets = new List(); + + ClientCard target1 = AI.Utils.GetBestEnemyMonster(); + if (target1 != null) + targets.Add(target1); + ClientCard target2 = AI.Utils.GetBestEnemySpell(); + if (target2 != null) + targets.Add(target2); + + foreach (ClientCard target in Enemy.GetMonsters()) + { + if (targets.Count >= 3) + break; + if (!targets.Contains(target)) + targets.Add(target); + } + foreach (ClientCard target in Enemy.GetSpells()) + { + if (targets.Count >= 3) + break; + if (!targets.Contains(target)) + targets.Add(target); + } + if (targets.Count == 0) + return false; + + AI.SelectNextCard(targets); + return true; + } + } + private bool HonestEffect() + { + return Duel.Phase != DuelPhase.Main1; + } + + } +} \ No newline at end of file diff --git a/Game/ClientField.cs b/Game/ClientField.cs index 88095d29..2e37d01f 100644 --- a/Game/ClientField.cs +++ b/Game/ClientField.cs @@ -36,6 +36,15 @@ public void Init(int deck, int extra) ExtraDeck.Add(new ClientCard(0, CardLocation.Extra)); } + public int GetMonstersExtraZoneCount() + { + int count = 0; + if (MonsterZone[5] != null) + count++; + if (MonsterZone[6] != null) + count++; + return count; + } public int GetMonsterCount() { return GetCount(MonsterZone); @@ -71,6 +80,7 @@ public List GetMonsters() { return GetCards(MonsterZone); } + public List GetGraveyardMonsters() { diff --git a/WindBot.csproj b/WindBot.csproj index 31831e5b..1f5d4801 100644 --- a/WindBot.csproj +++ b/WindBot.csproj @@ -79,6 +79,7 @@ + From 5b8613983df6da91763913a8d8a387452deb5442 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Wed, 4 Apr 2018 19:59:06 +0800 Subject: [PATCH 16/68] fix merge --- Game/AI/Decks/LightswornShaddoldinosourExecutor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs index 51366742..07004c2d 100644 --- a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs +++ b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs @@ -523,7 +523,7 @@ private bool PotofAvarice() } private bool infiniteTransience() { - return LastChainPlayer == 1; + return Duel.LastChainPlayer == 1; } private bool MaxxC() { @@ -637,7 +637,7 @@ public bool Hand_act_eff() { //if (Card.Id == CardId.Urara && Bot.HasInHand(CardId.LockBird) && Bot.HasInSpellZone(CardId.Re)) return false; if (Card.Id == CardId.GhostOgre && Card.Location == CardLocation.Hand && Bot.HasInMonstersZone(CardId.GhostOgre)) return false; - return (LastChainPlayer == 1); + return (Duel.LastChainPlayer == 1); } private bool MinervaTheExaltedEffect() { From 042ffe189c39fada2f24285c13e5d16d762f178c Mon Sep 17 00:00:00 2001 From: mercury233 Date: Wed, 4 Apr 2018 20:00:47 +0800 Subject: [PATCH 17/68] Revert "Add AI.GetAttacker() and AI.GetDefender() (#3)" This reverts commit 258990b944be0a32a19b3cd2707023f046e5d11c. --- Game/GameAI.cs | 30 +++++------------------------- Game/GameBehavior.cs | 9 ++++----- 2 files changed, 9 insertions(+), 30 deletions(-) diff --git a/Game/GameAI.cs b/Game/GameAI.cs index 8ef45be4..b52d729f 100644 --- a/Game/GameAI.cs +++ b/Game/GameAI.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using System.Collections.Generic; using WindBot.Game.AI; using YGOSharp.OCGWrapper.Enums; @@ -90,8 +90,6 @@ public void OnNewPhase() m_option = -1; m_yesno = -1; m_position = CardPosition.FaceUpAttack; - m_attacker = null; - m_defender = null; Duel.LastSummonPlayer = -1; if (Duel.Player == 0 && Duel.Phase == DuelPhase.Draw) { @@ -169,9 +167,9 @@ public IList OnSelectCard(IList cards, int min, int max, { const int HINTMSG_FMATERIAL = 511; const int HINTMSG_SMATERIAL = 512; - const int HINTMSG_XMATERIAL = 513; - const int HINTMSG_LMATERIAL = 533; - const int HINTMSG_SPSUMMON = 509; + const int HINTMSG_XMATERIAL = 513; + const int HINTMSG_LMATERIAL = 533; + const int HINTMSG_SPSUMMON = 509; // Check for the executor. IList result = Executor.OnSelectCard(cards, min, max, hint, cancelable); @@ -628,27 +626,9 @@ public int OnAnnounceCard() private int m_number; private int m_announce; private int m_yesno; - private ClientCard m_attacker; - private ClientCard m_defender; private IList m_attributes = new List(); private IList m_races = new List(); - public void SendBattleMsg(ClientCard attackcard, ClientCard defendcard) - { - m_attacker = attackcard; - m_defender = defendcard; - } - - public ClientCard GetAttacker() - { - return m_attacker; - } - - public ClientCard GetDefender() - { - return m_defender; - } - public void SelectCard(ClientCard card) { m_selector = new CardSelector(card); @@ -914,4 +894,4 @@ private bool ShouldExecute(CardExecutor exec, ClientCard card, ExecutorType type return false; } } -} +} \ No newline at end of file diff --git a/Game/GameBehavior.cs b/Game/GameBehavior.cs index c232aae3..1ca34d43 100644 --- a/Game/GameBehavior.cs +++ b/Game/GameBehavior.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Text.RegularExpressions; @@ -494,13 +494,12 @@ private void OnAttack(BinaryReader packet) int la = packet.ReadByte(); int sa = packet.ReadByte(); packet.ReadByte(); // - int cd = GetLocalPlayer(packet.ReadByte()); // cd + packet.ReadByte(); // cd int ld = packet.ReadByte(); - int sd = packet.ReadByte(); // sd + packet.ReadByte(); // sd packet.ReadByte(); // + ClientCard attackcard = _duel.GetCard(ca, (CardLocation)la, sa); - ClientCard defendcard = _duel.GetCard(cd, (CardLocation)ld, sd); - _ai.SendBattleMsg(attackcard, defendcard); if (ld == 0 && (attackcard != null) && (ca != 0)) { _ai.OnDirectAttack(attackcard); From 3f0e0200d46e038b59806a8f6dbb454db5e96616 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Wed, 4 Apr 2018 20:30:33 +0800 Subject: [PATCH 18/68] update Trickstar deck --- Game/AI/Decks/TrickstarExecutor.cs | 524 ++++++++++++++++++++++------- 1 file changed, 397 insertions(+), 127 deletions(-) diff --git a/Game/AI/Decks/TrickstarExecutor.cs b/Game/AI/Decks/TrickstarExecutor.cs index c3477b91..92ee17fa 100644 --- a/Game/AI/Decks/TrickstarExecutor.cs +++ b/Game/AI/Decks/TrickstarExecutor.cs @@ -30,6 +30,8 @@ public class CardId public const int Sheep = 73915051; public const int Crown = 22159429; public const int Stage = 35371948; + public const int GraveCall = 24224830; + public const int DarkHole = 53129443; public const int Re = 21076084; public const int Ring = 83555666; @@ -50,6 +52,8 @@ public class CardId public const int Beelze = 34408491; public const int Abyss = 9753964; public const int Exterio = 99916754; + public const int Ultimate = 86221741; + public const int Cardian = 87460579; public const int Missus = 3987233; } @@ -57,6 +61,7 @@ public class CardId public int getLinkMarker(int id) { if (id == CardId.borrel || id == CardId.snake) return 4; + else if (id == CardId.Abyss || id == CardId.Beelze || id == CardId.Exterio || id == CardId.Ultimate) return 5; else if (id == CardId.unicorn) return 3; else if (id == CardId.Crystal || id == CardId.phoneix || id == CardId.SafeDra || id == CardId.Missus) return 2; return 1; @@ -71,6 +76,9 @@ public int getLinkMarker(int id) int red_ss_count = 0; bool white_eff_used = false; bool lockbird_useful = false; + bool lockbird_used = false; + int GraveCall_id = 0; + int GraveCall_count = 0; public TrickstarExecutor(GameAI ai, Duel duel) : base(ai, duel) @@ -82,50 +90,54 @@ public TrickstarExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.Grass, Grass_ss); AddExecutor(ExecutorType.Activate, CardId.Urara, Hand_act_eff); AddExecutor(ExecutorType.Activate, CardId.Ghost, Hand_act_eff); - AddExecutor(ExecutorType.Activate, CardId.Ring, DefaultCompulsoryEvacuationDevice); + AddExecutor(ExecutorType.Activate, CardId.Ring, Ring_act); AddExecutor(ExecutorType.Activate, CardId.Abyss, Abyss_eff); AddExecutor(ExecutorType.Activate, CardId.Exterio, Exterio_counter); + AddExecutor(ExecutorType.Activate, CardId.Cardian); + AddExecutor(ExecutorType.Activate, CardId.GraveCall, GraveCall_eff); + + AddExecutor(ExecutorType.Activate, CardId.DarkHole, DarkHole_eff); // spell clean AddExecutor(ExecutorType.Activate, CardId.Stage, Stage_Lock); AddExecutor(ExecutorType.Activate, CardId.Feather, Feather_Act); + AddExecutor(ExecutorType.Activate, CardId.Stage, Stage_act); AddExecutor(ExecutorType.Activate, CardId.Galaxy, GalaxyCyclone); AddExecutor(ExecutorType.Activate, CardId.TG, TG_eff); - // ex_monster act - AddExecutor(ExecutorType.Activate, CardId.Beelze); - AddExecutor(ExecutorType.Activate, CardId.Missus, Missus_eff); - AddExecutor(ExecutorType.Activate, CardId.Crystal, Crystal_eff); - AddExecutor(ExecutorType.Activate, CardId.SafeDra, DefaultCompulsoryEvacuationDevice); - AddExecutor(ExecutorType.Activate, CardId.Linkuri, Linkuri_eff); - AddExecutor(ExecutorType.Activate, CardId.phoneix, Phoneix_eff); - AddExecutor(ExecutorType.Activate, CardId.unicorn, Unicorn_eff); - AddExecutor(ExecutorType.Activate, CardId.snake, Snake_eff); - AddExecutor(ExecutorType.Activate, CardId.borrel, Borrel_eff); - AddExecutor(ExecutorType.Activate, CardId.Tuner,Tuner_eff); // ex ss - AddExecutor(ExecutorType.SpSummon, CardId.snake, Snake_ss); - AddExecutor(ExecutorType.SpSummon, CardId.Missus, Missus_ss); AddExecutor(ExecutorType.SpSummon, CardId.borrel, Borrel_ss); + AddExecutor(ExecutorType.SpSummon, CardId.Missus, Missus_ss); AddExecutor(ExecutorType.SpSummon, CardId.phoneix, Phoneix_ss); - AddExecutor(ExecutorType.SpSummon, CardId.unicorn, Unicorn_ss); + AddExecutor(ExecutorType.SpSummon, CardId.snake, Snake_ss); AddExecutor(ExecutorType.SpSummon, CardId.Crystal, Crystal_ss); AddExecutor(ExecutorType.SpSummon, CardId.SafeDra, Safedragon_ss); + AddExecutor(ExecutorType.Activate, CardId.Linkuri, Linkuri_eff); AddExecutor(ExecutorType.SpSummon, CardId.Linkuri, Linkuri_ss); + AddExecutor(ExecutorType.SpSummon, CardId.unicorn, Unicorn_ss); AddExecutor(ExecutorType.SpSummon, CardId.Linkspi); + // ex_monster act + AddExecutor(ExecutorType.Activate, CardId.Beelze); + AddExecutor(ExecutorType.Activate, CardId.Missus, Missus_eff); + AddExecutor(ExecutorType.Activate, CardId.Crystal, Crystal_eff); + AddExecutor(ExecutorType.Activate, CardId.SafeDra, DefaultCompulsoryEvacuationDevice); + AddExecutor(ExecutorType.Activate, CardId.phoneix, Phoneix_eff); + AddExecutor(ExecutorType.Activate, CardId.unicorn, Unicorn_eff); + AddExecutor(ExecutorType.Activate, CardId.snake, Snake_eff); + AddExecutor(ExecutorType.Activate, CardId.borrel, Borrel_eff); + // normal act AddExecutor(ExecutorType.Activate, CardId.Trans); AddExecutor(ExecutorType.SpSummon, CardId.BF, BF_pos); AddExecutor(ExecutorType.Activate, CardId.BF, BF_pos); AddExecutor(ExecutorType.Activate, CardId.Sheep, Sheep_Act); - AddExecutor(ExecutorType.Activate, CardId.Eater); + AddExecutor(ExecutorType.Activate, CardId.Eater,Eater_eff); AddExecutor(ExecutorType.Activate, CardId.LockBird, LockBird_act); // ts - AddExecutor(ExecutorType.Activate, CardId.Stage, Stage_act); AddExecutor(ExecutorType.Activate, CardId.Pink, Pink_eff); AddExecutor(ExecutorType.Activate, CardId.Re, Reincarnation); AddExecutor(ExecutorType.Activate, CardId.Red, Red_ss); @@ -235,6 +247,14 @@ public bool Abyss_eff() if (!Enemy.HasInMonstersZone(CardId.Ghost) || Enemy.GetHandCount() <= 1) { ClientCard tosolve = AI.Utils.GetProblematicEnemyCard(); + if (tosolve == null) + { + if (Duel.LastChainPlayer == 1 && AI.Utils.GetLastChainCard() != null) + { + ClientCard target = AI.Utils.GetLastChainCard(); + if (target.HasPosition(CardPosition.FaceUp) && (target.Location == CardLocation.MonsterZone || target.Location == CardLocation.SpellZone)) tosolve = target; + } + } if (tosolve != null) { AI.SelectCard(tosolve); @@ -317,7 +337,7 @@ public bool Sheep_Act() { if (Duel.Player == 0) return false; if (Duel.Phase == DuelPhase.End) return true; - if (LastChainPlayer == 1 && (AI.Utils.IsChainTarget(Card) || (GetLastChainCard().Id == CardId.Feather && !Bot.HasInSpellZone(CardId.Grass)))) return true; + if (Duel.LastChainPlayer == 1 && (AI.Utils.IsChainTarget(Card) || (AI.Utils.GetLastChainCard().Id == CardId.Feather && !Bot.HasInSpellZone(CardId.Grass)))) return true; if (Duel.Phase == DuelPhase.BattleStart) { int total_atk = 0; @@ -349,7 +369,7 @@ public bool Stage_act() stage_locked = null; return true; } - else if (Enemy.LifePoints <= 1000 && !pink_ss) + else if (Enemy.LifePoints <= 1000 && Bot.GetRemainingCount(CardId.Pink,1) > 0) { AI.SelectCard(new[] { @@ -403,19 +423,7 @@ public bool Stage_act() if (NormalSummoned) { - if (Bot.HasInMonstersZone(CardId.Yellow) && !Bot.HasInHand(CardId.Red)) - { - AI.SelectCard(new[] - { - CardId.Red, - CardId.Pink, - CardId.Yellow, - CardId.White - }); - stage_locked = null; - return true; - } - else if (Enemy.LifePoints <= 1000 && !pink_ss) + if (Enemy.LifePoints <= 1000 && !pink_ss && Bot.GetRemainingCount(CardId.Pink,1) > 0) { AI.SelectCard(new[] { @@ -427,7 +435,7 @@ public bool Stage_act() stage_locked = null; return true; } - else if (Enemy.GetMonsterCount() > 0 && AI.Utils.GetBestEnemyMonster().Attack >= AI.Utils.GetBestAttack(Bot)) + if (Enemy.GetMonsterCount() > 0 && AI.Utils.GetBestEnemyMonster().Attack >= AI.Utils.GetBestAttack(Bot) && !Bot.HasInHand(CardId.White)) { AI.SelectCard(new[] { @@ -439,18 +447,27 @@ public bool Stage_act() stage_locked = null; return true; } - else if (!Bot.HasInSpellZone(CardId.Stage)) + if (Bot.HasInMonstersZone(CardId.Yellow) && !Bot.HasInHand(CardId.Red)) { AI.SelectCard(new[] { - CardId.Yellow, - CardId.Pink, CardId.Red, + CardId.Pink, + CardId.Yellow, CardId.White }); stage_locked = null; return true; } + AI.SelectCard(new[] + { + CardId.Yellow, + CardId.Pink, + CardId.Red, + CardId.White + }); + stage_locked = null; + return true; } stage_locked = null; return false; @@ -463,14 +480,15 @@ public bool Pot_Act() public bool Hand_act_eff() { + if (GraveCall_count > 0 && GraveCall_id == Card.Id) return false; if (Card.Id == CardId.Urara && Bot.HasInHand(CardId.LockBird) && Bot.HasInSpellZone(CardId.Re)) return false; if (Card.Id == CardId.Ghost && Card.Location == CardLocation.Hand && Bot.HasInMonstersZone(CardId.Ghost)) return false; - return (LastChainPlayer == 1); + return (Duel.LastChainPlayer == 1); } public bool Exterio_counter() { - if (LastChainPlayer == 1) + if (Duel.LastChainPlayer == 1) { AI.SelectCard(Useless_List()); return true; @@ -480,7 +498,7 @@ public bool Exterio_counter() public bool G_act() { - return (Duel.Player == 1); + return (Duel.Player == 1 && !(GraveCall_count > 0 && GraveCall_id == Card.Id)); } public bool Pink_eff() @@ -526,7 +544,9 @@ public bool Pink_eff() public bool Eater_ss() { + if (AI.Utils.GetProblematicEnemyMonster() == null && Bot.ExtraDeck.Count < 5) return false; if (AI.Utils.IsTurn1OrMain2()) return false; + AI.SelectPosition(CardPosition.FaceUpAttack); IList targets = new List(); if (Bot.SpellZone[5] != null && Bot.SpellZone[5].IsFacedown()) { @@ -545,7 +565,8 @@ public bool Eater_ss() return true; } } - foreach (ClientCard s_c in Bot.SpellZone) + Logger.DebugWriteLine("*** Eater use up the extra deck."); + foreach (ClientCard s_c in Bot.GetSpells()) { targets.Add(s_c); if (targets.Count >= 5) @@ -557,14 +578,22 @@ public bool Eater_ss() return false; } + public bool Eater_eff() + { + if (Enemy.BattlingMonster.HasPosition(CardPosition.FaceDown)) return true; + if (Enemy.BattlingMonster.HasPosition(CardPosition.Attack) && (Bot.BattlingMonster.Attack - Enemy.BattlingMonster.GetDefensePower() >= Enemy.LifePoints)) return true; + return (Bot.BattlingMonster.Attack <= (Enemy.BattlingMonster.GetDefensePower() * 2)); + } + public bool Red_ss() { if (red_ss_count >= 6) return false; - if (LastChainPlayer == 0 && GetLastChainCard().Id == CardId.Red) + if ((AI.Utils.ChainContainsCard(CardId.DarkHole) || AI.Utils.ChainContainsCard(99330325) || AI.Utils.ChainContainsCard(53582587)) && AI.Utils.ChainContainsCard(CardId.Red)) return false; + if (Duel.LastChainPlayer == 0 && AI.Utils.GetLastChainCard().Id == CardId.Red) { foreach (ClientCard m in Bot.GetMonsters()) { - if (AI.Utils.IsChainTarget(m)) + if (AI.Utils.IsChainTarget(m) && IsTrickstar(m.Id)) { red_ss_count += 1; AI.SelectCard(m); @@ -572,7 +601,7 @@ public bool Red_ss() } } } - if (LastChainPlayer == 1) return true; + if (Duel.LastChainPlayer == 1) return true; if (Duel.Player == 0) { if (AI.Utils.IsTurn1OrMain2()) return false; @@ -582,9 +611,9 @@ public bool Red_ss() ClientCard tosolve_enemy = AI.Utils.GetOneEnemyBetterThanMyBest(); foreach (ClientCard c in self_m) { - if (IsTrickstar(c.Id)) + if (IsTrickstar(c.Id) && c.Id != CardId.Red) { - if (c.Attacked && c.Id != CardId.Red) + if (c.Attacked) { AI.SelectCard(c); red_ss_count += 1; @@ -592,7 +621,7 @@ public bool Red_ss() } if (tosolve_enemy != null) { - if (Bot.HasInHand(CardId.White) && c.Attack * 2 < tosolve_enemy.Attack) + if (Bot.HasInHand(CardId.White) && c.Attack + c.BaseAttack < tosolve_enemy.Attack) { if (tosolve_enemy.Attack > 3200) AI.SelectPosition(CardPosition.FaceUpDefence); AI.SelectCard(c); @@ -627,7 +656,6 @@ public bool Red_ss() } } else { - if ((ChainContainsCard(53129443) || ChainContainsCard(99330325)) && ChainContainsCard(CardId.Red)) return false; if (Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2) { if (!Bot.HasInHand(CardId.White) && AI.Utils.IsOneEnemyBetterThanValue(1600, true)) @@ -659,12 +687,43 @@ public bool Yellow_eff() CardId.White, CardId.Pink, CardId.Re, - CardId.Ring, + CardId.Crown, CardId.Yellow }); return true; } - else if (Enemy.GetMonsterCount() == 0 && !AI.Utils.IsTurn1OrMain2()) + if (Enemy.LifePoints <= 1000) + { + if (Bot.GetRemainingCount(CardId.Pink, 1) > 0 && !pink_ss) + { + AI.SelectCard(new[] + { + CardId.Pink, + CardId.Stage, + CardId.Red, + CardId.White, + CardId.Re, + CardId.Crown, + CardId.Yellow + }); + return true; + } + else if (Bot.HasInGraveyard(CardId.Pink) && Bot.GetRemainingCount(CardId.Crown, 1) > 0) + { + AI.SelectCard(new[] + { + CardId.Crown, + CardId.Pink, + CardId.Re, + CardId.Stage, + CardId.Red, + CardId.White, + CardId.Yellow + }); + return true; + } + } + if (Enemy.GetMonsterCount() == 0 && !AI.Utils.IsTurn1OrMain2()) { if (Bot.HasInGraveyard(CardId.Red) && Bot.GetRemainingCount(CardId.Pink, 1) > 0 && !pink_ss) { @@ -675,7 +734,7 @@ public bool Yellow_eff() CardId.White, CardId.Re, CardId.Stage, - CardId.Ring, + CardId.Crown, CardId.Yellow }); } @@ -683,7 +742,7 @@ public bool Yellow_eff() { AI.SelectCard(new[] { - CardId.Ring, + CardId.Crown, CardId.Red, CardId.White, CardId.Re, @@ -701,15 +760,15 @@ public bool Yellow_eff() CardId.Pink, CardId.Re, CardId.Stage, - CardId.Ring, + CardId.Crown, CardId.Yellow }); } - else if (Bot.HasInGraveyard(CardId.White) && Bot.GetRemainingCount(CardId.Ring, 1) > 0) + else if (Bot.HasInGraveyard(CardId.White) && Bot.GetRemainingCount(CardId.Crown, 1) > 0) { AI.SelectCard(new[] { - CardId.Ring, + CardId.Crown, CardId.Red, CardId.Pink, CardId.Re, @@ -725,7 +784,7 @@ public bool Yellow_eff() CardId.Red, CardId.Pink, CardId.Re, - CardId.Ring, + CardId.Crown, CardId.Stage, CardId.White, CardId.Yellow @@ -733,10 +792,10 @@ public bool Yellow_eff() } return true; } - else if (AI.Utils.GetProblematicEnemyMonster() != null) + if (AI.Utils.GetProblematicEnemyMonster() != null) { int atk = AI.Utils.GetProblematicEnemyMonster().Attack; - if (atk >= 1800 && atk <= 3600 && Bot.GetRemainingCount(CardId.White, 2) > 0) + if (atk >= 1800 && atk <= 3600 && Bot.GetRemainingCount(CardId.White, 2) > 0 && !Bot.HasInHand(CardId.White)) { AI.SelectCard(new[] { @@ -745,7 +804,7 @@ public bool Yellow_eff() CardId.Pink, CardId.Re, CardId.Stage, - CardId.Ring, + CardId.Crown, CardId.Yellow }); } @@ -756,39 +815,39 @@ public bool Yellow_eff() CardId.Red, CardId.Pink, CardId.Re, - CardId.Ring, + CardId.Crown, CardId.Stage, CardId.White, CardId.Yellow }); } return true; - } else if ((Bot.HasInHand(CardId.Red) || Bot.HasInHand(CardId.Stage)) && Bot.GetRemainingCount(CardId.Re,1) > 0 && Bot.HasInHand(CardId.LockBird)) { + } + if ((Bot.HasInHand(CardId.Red) || Bot.HasInHand(CardId.Stage) || Bot.HasInHand(CardId.Yellow)) && Bot.GetRemainingCount(CardId.Re,1) > 0) { + Logger.DebugWriteLine("to search reincarnation"); AI.SelectCard(new[] { CardId.Re, CardId.Red, CardId.White, - CardId.Ring, - CardId.Pink, - CardId.Stage, - CardId.Yellow - }); - return true; - } else - { - AI.SelectCard(new[] - { - CardId.Red, + CardId.Crown, CardId.Pink, - CardId.Re, - CardId.Ring, CardId.Stage, - CardId.White, CardId.Yellow }); return true; } + AI.SelectCard(new[] + { + CardId.Red, + CardId.Pink, + CardId.Re, + CardId.Crown, + CardId.Stage, + CardId.White, + CardId.Yellow + }); + return true; } public bool White_eff() @@ -796,6 +855,7 @@ public bool White_eff() if (Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2) { // from blackwing + /* ClientCard bestMy = Bot.GetMonsters().GetHighestAttackMonster(); ClientCard bestEnemyATK = Enemy.GetMonsters().GetHighestAttackMonster(); ClientCard bestEnemyDEF = Enemy.GetMonsters().GetHighestDefenseMonster(); @@ -811,6 +871,13 @@ public bool White_eff() white_eff_used = true; return true; } + */ + if (Bot.BattlingMonster == null || Enemy.BattlingMonster == null || !IsTrickstar(Bot.BattlingMonster.Id) || Bot.BattlingMonster.HasPosition(CardPosition.Defence)) return false; + if (Bot.BattlingMonster.Attack <= Enemy.BattlingMonster.RealPower && Bot.BattlingMonster.Attack + Bot.BattlingMonster.BaseAttack >= Enemy.BattlingMonster.RealPower) + { + white_eff_used = true; + return true; + } return false; } else { @@ -824,24 +891,32 @@ public bool White_eff() ClientCard self_card = Bot.GetMonsters().GetHighestAttackMonster(); if (tosolve == null || self_card == null || (tosolve != null && self_card != null && !IsTrickstar(self_card.Id))) { - if (Enemy.GetMonsters().GetLowestAttackMonster() == null || - Enemy.GetMonsters().GetLowestDefenseMonster() == null || - Enemy.GetMonsters().GetLowestAttackMonster().Attack < 2000 || - Enemy.GetMonsters().GetLowestDefenseMonster().Defense < 2000) + if (Enemy.GetMonsters().GetHighestAttackMonster()== null || + Enemy.GetMonsters().GetHighestDefenseMonster() == null || + Enemy.GetMonsters().GetHighestAttackMonster().GetDefensePower() < 2000 || + Enemy.GetMonsters().GetHighestDefenseMonster().GetDefensePower() < 2000) { white_eff_used = true; return true; } else return false; } - if (tosolve != null && self_card != null && IsTrickstar(self_card.Id)) + if (tosolve != null && self_card != null && IsTrickstar(self_card.Id) && !tosolve.IsMonsterHasPreventActivationEffectInBattle()) { - int attacker_atk = self_card.Attack; int defender_power = tosolve.GetDefensePower(); - if (attacker_atk <= defender_power && attacker_atk * 2 >= defender_power) + Logger.DebugWriteLine("battle check 0:" + Duel.Phase.ToString()); + Logger.DebugWriteLine("battle check 1:" + self_card.Attack.ToString()); + Logger.DebugWriteLine("battle check 2:" + (self_card.Attack+self_card.BaseAttack).ToString()); + Logger.DebugWriteLine("battle check 3:" + defender_power.ToString()); + if (self_card.Attack <= defender_power && self_card.Attack + self_card.BaseAttack >= defender_power) { return false; } + else if (defender_power <= 2000) + { + white_eff_used = true; + return true; + } } } return false; @@ -850,9 +925,14 @@ public bool White_eff() public bool LockBird_act() { - if (Duel.Player == 0) return false; + if (Duel.Player == 0 || lockbird_used) return false; lockbird_useful = true; - if (Bot.HasInSpellZone(CardId.Re)) return ChainContainsCard(CardId.Re); + if (Bot.HasInSpellZone(CardId.Re)) + { + if (AI.Utils.ChainContainsCard(CardId.Re)) lockbird_used = true; + return AI.Utils.ChainContainsCard(CardId.Re); + } + lockbird_used = true; return true; } @@ -861,7 +941,7 @@ public bool Reincarnation() if (Card.Location == CardLocation.Grave) return Ts_reborn(); if (Bot.HasInHand(CardId.LockBird)) { - if (lockbird_useful || AI.Utils.IsChainTarget(Card) || (Duel.Player == 1 && ChainContainsCard(CardId.Feather))) { + if (lockbird_useful || AI.Utils.IsChainTarget(Card) || (Duel.Player == 1 && AI.Utils.ChainContainsCard(CardId.Feather))) { lockbird_useful = false; return true; } @@ -872,8 +952,12 @@ public bool Reincarnation() public bool Crown_eff() { - if (Card.Location == CardLocation.Hand) return Ts_reborn(); - if (Bot.HasInHand(CardId.Pink)) + if (Card.Location == CardLocation.Hand) + { + if (Duel.Phase <= DuelPhase.Main1) return Ts_reborn(); + return false; + } + if (Bot.HasInHand(CardId.Pink) && GraveCall_id != CardId.Pink) { AI.SelectCard(CardId.Pink); return true; @@ -897,6 +981,11 @@ public bool Crown_eff() public bool Ts_reborn() { + if (Duel.Player == 0 && Enemy.LifePoints <= 1000) + { + AI.SelectCard(CardId.Pink); + return true; + } bool can_summon = (Duel.Player == 0 && NormalSummoned); if (can_summon) { @@ -919,6 +1008,7 @@ public bool Ts_reborn() } else { + AI.SelectCard(new[] { CardId.Red, @@ -973,8 +1063,9 @@ public bool Tuner_ns() public bool Tuner_ss() { - if (crystal_eff_used) return false; + if (crystal_eff_used || Bot.HasInMonstersZone(CardId.Crystal)) return false; if (Bot.GetMonsterCount() == 0 || !Bot.HasInExtra(CardId.Crystal)) return false; + if (Card.Id == CardId.Ghost && Bot.GetRemainingCount(CardId.Ghost, 2) <= 0) return false; int count = 0; if (Card.Id != CardId.Urara) count += 1; foreach(ClientCard hand in Bot.Hand) @@ -996,6 +1087,23 @@ public bool Tuner_eff() return true; } + public bool Ring_act() + { + if (Duel.LastChainPlayer == 0 && AI.Utils.GetLastChainCard() != null && AI.Utils.GetLastChainCard().Id == CardId.Ghost) return false; + ClientCard target = AI.Utils.GetProblematicEnemyMonster(); + if (target == null && AI.Utils.IsChainTarget(Card)) + { + target = AI.Utils.GetBestEnemyMonster(); + } + if (target != null) + { + if (Bot.LifePoints <= target.Attack) return false; + AI.SelectCard(target); + return true; + } + return false; + } + public bool Linkuri_ss() { foreach(ClientCard c in Bot.GetMonsters()) @@ -1011,7 +1119,7 @@ public bool Linkuri_ss() public bool Linkuri_eff() { - if (LastChainPlayer == 0 && GetLastChainCard().Id == CardId.Linkuri) return false; + if (Duel.LastChainPlayer == 0 && AI.Utils.GetLastChainCard().Id == CardId.Linkuri) return false; AI.SelectCard(new[] { CardId.Tuner, CardId.BF + 1 }); return true; } @@ -1027,9 +1135,14 @@ public bool Crystal_ss() }); return true; } + foreach(ClientCard extra_card in Bot.GetMonstersInExtraZone()) + { + if (getLinkMarker(extra_card.Id) >= 5) return false; + } IList targets = new List(); foreach(ClientCard t_check in Bot.GetMonsters()) { + if (t_check.IsFacedown()) continue; if (t_check.Id == CardId.BF || t_check.Id == CardId.Tuner || t_check.Id == CardId.Urara || t_check.Id == CardId.Ghost) { targets.Add(t_check); @@ -1037,8 +1150,11 @@ public bool Crystal_ss() } } if (targets.Count == 0) return false; - foreach(ClientCard e_check in Bot.GetMonsters()) + List m_list = new List(Bot.GetMonsters()); + m_list.Sort(AIFunctions.CompareCardAttack); + foreach (ClientCard e_check in m_list) { + if (e_check.IsFacedown()) continue; if (targets[0] != e_check && getLinkMarker(e_check.Id) <= 2 && e_check.Id != CardId.Eater && e_check.Id != CardId.Crystal) { targets.Add(e_check); @@ -1046,7 +1162,7 @@ public bool Crystal_ss() } } if (targets.Count <= 1) return false; - AI.SelectCard(targets); + AI.SelectMaterials(targets); return true; } @@ -1077,24 +1193,40 @@ public bool TG_eff() { if (Card.Location != CardLocation.MonsterZone) return true; ClientCard target = AI.Utils.GetProblematicEnemySpell(); - if (target != null) AI.SelectCard(target); + IList list = new List(); + if (target != null) list.Add(target); + foreach(ClientCard spells in Enemy.GetSpells()) + { + if (spells != null && !list.Contains(spells)) list.Add(spells); + } + AI.SelectCard(list); return true; } public bool Safedragon_ss() { + if (AI.Utils.IsTurn1OrMain2()) return false; ClientCard m = AI.Utils.GetProblematicEnemyMonster(); - if (m == null) + foreach(ClientCard ex_m in Bot.GetMonstersInExtraZone()) + { + if (getLinkMarker(ex_m.Id) >= 4) return false; + } + if ((m == null || m.HasPosition(CardPosition.FaceDown)) && Enemy.LifePoints <= 1100) { - if (Enemy.GetMonsterCount() == 0 && Enemy.LifePoints <= 1100 && Duel.Phase < DuelPhase.Battle) + if (Enemy.GetMonsterCount() == 0 && Duel.Phase < DuelPhase.Battle) { IList list = new List(); foreach(ClientCard monster in Bot.GetMonsters()) { if (getLinkMarker(monster.Id) <= 2) list.Add(monster); - if (list.Count >= 2) break; + if (list.Count == 2) break; + } + if (list.Count == 2 && GetTotalATK(list) <= 1100) + { + AI.SelectMaterials(list); + return true; } - return (list.Count >= 2 && GetTotalATK(list) <= 1100); + return false; } } ClientCard ex_1 = Bot.MonsterZone[5]; @@ -1107,12 +1239,13 @@ public bool Safedragon_ss() IList targets = new List(); foreach (ClientCard s_m in Bot.GetMonsters()) { + if (s_m.Id == CardId.Eater) continue; if (s_m != Bot.MonsterZone[5] && s_m != Bot.MonsterZone[6]) targets.Add(s_m); - if (targets.Count >= 2) break; + if (targets.Count == 2) break; } - if (targets.Count >= 2) + if (targets.Count == 2) { - AI.SelectCard(targets); + AI.SelectMaterials(targets); return true; } return false; @@ -1126,37 +1259,47 @@ public bool Phoneix_ss() if (Enemy.GetMonsterCount() == 0 && Enemy.LifePoints <= 1900 && Duel.Phase == DuelPhase.Main1) { IList m_list = new List(); - foreach(ClientCard monster in Bot.GetMonsters()) + List list = new List(Bot.GetMonsters()); + list.Sort(AIFunctions.CompareCardAttack); + foreach(ClientCard monster in list) { - if (getLinkMarker(monster.Id) == 1) m_list.Add(monster); + if (getLinkMarker(monster.Id) == 1 && monster.IsFaceup()) m_list.Add(monster); if (m_list.Count == 2) break; } - return (m_list.Count == 2 && GetTotalATK(m_list) <= 1900); + if (m_list.Count == 2 && GetTotalATK(m_list) <= 1900) + { + AI.SelectMaterials(m_list); + return true; + } } return false; } if (Bot.Hand.Count == 0) return false; IList targets = new List(); - ClientCard ex_zone = null; - foreach (ClientCard s_m in Bot.GetMonsters()) + List main_list = new List(Bot.GetMonstersInMainZone()); + main_list.Sort(AIFunctions.CompareCardAttack); + foreach (ClientCard s_m in main_list) { - if (s_m == Bot.MonsterZone[5] && s_m != Bot.MonsterZone[6]) + if (s_m.IsFacedown()) continue; + if ((s_m.Id != CardId.Eater || (s_m.Id == CardId.Eater && s_m.IsDisabled())) && !targets.ContainsCardWithId(s_m.Id)) { - ex_zone = s_m; - } - else + targets.Add(s_m); + }; + if (targets.Count == 2) break; + } + if (targets.Count < 2) + { + foreach (ClientCard s_m in Bot.GetMonstersInExtraZone()) { + if (s_m.IsFacedown()) continue; if (s_m.Id != CardId.Eater && !targets.ContainsCardWithId(s_m.Id)) { targets.Add(s_m); }; - }; - if (targets.Count >= 2) break; - } - if (targets.Count < 2) - { - targets.Add(ex_zone); + if (targets.Count == 2) break; + } } + if (targets.Count < 2) return false; AI.SelectMaterials(targets); return true; } @@ -1175,28 +1318,36 @@ public bool Unicorn_ss() { if (Enemy.GetMonsterCount() == 0 && Enemy.LifePoints <= 2200 && Duel.Phase == DuelPhase.Main1) { IList m_list = new List(); - foreach(ClientCard monster in Bot.GetMonsters()) + List _sort_list = new List(Bot.GetMonsters()); + _sort_list.Sort(AIFunctions.CompareCardAttack); + foreach(ClientCard monster in _sort_list) { if (getLinkMarker(monster.Id) == 2) { link_count += 2; m_list.Add(monster); - } else if (getLinkMarker(monster.Id) == 1) + } else if (getLinkMarker(monster.Id) == 1 && monster.IsFaceup()) { link_count += 1; m_list.Add(monster); } if (link_count >= 3) break; } - return (link_count >= 3 && GetTotalATK(m_list) <= 2200); + if (link_count >= 3 && GetTotalATK(m_list) <= 2200) + { + AI.SelectMaterials(m_list); + return true; + } } return false; } if (Bot.Hand.Count == 0) return false; IList targets = new List(); - foreach (ClientCard s_m in Bot.GetMonsters()) + List sort_list = Bot.GetMonsters(); + sort_list.Sort(AIFunctions.CompareCardAttack); + foreach (ClientCard s_m in sort_list) { - if (s_m.Id != CardId.Eater && getLinkMarker(s_m.Id) <= 2) + if ((s_m.Id != CardId.Eater || (s_m.Id == CardId.Eater && m.IsMonsterHasPreventActivationEffectInBattle())) && getLinkMarker(s_m.Id) <= 2 && s_m.IsFaceup()) { if (!targets.ContainsCardWithId(s_m.Id)) { @@ -1215,8 +1366,23 @@ public bool Unicorn_eff() { ClientCard m = AI.Utils.GetProblematicEnemyCard(); if (m == null) return false; + // avoid cards that cannot target. AI.SelectCard(Useless_List()); - AI.SelectNextCard(m); + IList enemy_list = new List(); + enemy_list.Add(m); + foreach(ClientCard enemy in Enemy.GetMonstersInExtraZone()) + { + if (enemy != null && !enemy_list.Contains(enemy)) enemy_list.Add(enemy); + } + foreach (ClientCard enemy in Enemy.GetMonstersInMainZone()) + { + if (enemy != null && !enemy_list.Contains(enemy)) enemy_list.Add(enemy); + } + foreach (ClientCard enemy in Enemy.GetSpells()) + { + if (enemy != null && !enemy_list.Contains(enemy)) enemy_list.Add(enemy); + } + AI.SelectNextCard(enemy_list); return true; } @@ -1226,14 +1392,16 @@ public bool Snake_ss() // exzone fo first foreach (ClientCard e_m in Bot.GetMonstersInExtraZone()) { - if (e_m.Attack < 1900 && !targets.ContainsCardWithId(e_m.Id)) + if (e_m.Attack < 1900 && !targets.ContainsCardWithId(e_m.Id) && e_m.IsFaceup()) { targets.Add(e_m); } } - foreach (ClientCard m in Bot.GetMonstersInMainZone()) + List sort_main_list = new List(Bot.GetMonstersInMainZone()); + sort_main_list.Sort(AIFunctions.CompareCardAttack); + foreach (ClientCard m in sort_main_list) { - if (m.Attack < 1900 && !targets.ContainsCardWithId(m.Id)) + if (m.Attack < 1900 && !targets.ContainsCardWithId(m.Id) && m.IsFaceup()) { targets.Add(m); } @@ -1286,9 +1454,10 @@ public bool Missus_ss() foreach(ClientCard monster in Bot.GetMonsters()) { if (monster.HasAttribute(CardAttribute.Earth) && getLinkMarker(monster.Id) == 1) material_list.Add(monster); + if (material_list.Count == 2) break; } if (material_list.Count < 2) return false; - if (Enemy.GetMonsterCount() == 0) + if (Enemy.GetMonsterCount() == 0 || AI.Utils.GetProblematicEnemyMonster(2000) == null) { AI.SelectMaterials(material_list); return true; @@ -1315,6 +1484,8 @@ public bool Borrel_ss() { bool already_link2 = false; IList material_list = new List(); + if (AI.Utils.GetProblematicEnemyMonster(2000) == null) Logger.DebugWriteLine("***borrel:null"); + else Logger.DebugWriteLine("***borrel:" + (AI.Utils.GetProblematicEnemyMonster(2000).Name ?? "unknown")); if (AI.Utils.GetProblematicEnemyMonster(2000) != null || (Enemy.GetMonsterCount() == 0 && Duel.Phase == DuelPhase.Main1 && Enemy.LifePoints <= 3000)) { foreach(ClientCard e_m in Bot.GetMonstersInExtraZone()) @@ -1325,7 +1496,10 @@ public bool Borrel_ss() material_list.Add(e_m); } } - foreach(ClientCard m in Bot.GetMonstersInMainZone()) + List sort_list = new List(Bot.GetMonstersInMainZone()); + sort_list.Sort(AIFunctions.CompareCardAttack); + + foreach(ClientCard m in sort_list) { if (getLinkMarker(m.Id) < 3) { @@ -1355,7 +1529,10 @@ public bool Borrel_ss() public bool Borrel_eff() { - if (ActivateDescription == -1) return true; + if (ActivateDescription == -1) { + Logger.DebugWriteLine("borrel's ntr effect"); + return true; + }; ClientCard BestEnemy = AI.Utils.GetBestEnemyMonster(true); ClientCard WorstBot = Bot.GetMonsters().GetLowestAttackMonster(); if (BestEnemy == null || BestEnemy.HasPosition(CardPosition.FaceDown)) return false; @@ -1368,10 +1545,51 @@ public bool Borrel_eff() return false; } + public bool GraveCall_eff() + { + if (Duel.LastChainPlayer == 1) + { + Logger.DebugWriteLine(AI.Utils.GetLastChainCard().Name.ToString()); + Logger.DebugWriteLine(AI.Utils.GetLastChainCard().IsMonster().ToString()); + Logger.DebugWriteLine(Enemy.HasInGraveyard(AI.Utils.GetLastChainCard().Id).ToString()); + if (AI.Utils.GetLastChainCard().IsMonster() && Enemy.HasInGraveyard(AI.Utils.GetLastChainCard().Id)) + { + GraveCall_id = AI.Utils.GetLastChainCard().Id; + GraveCall_count = 2; + AI.SelectCard(GraveCall_id); + return true; + } + } + return false; + } + + public bool DarkHole_eff() + { + if (Bot.GetMonsterCount() == 0) + { + + int bestPower = -1; + foreach (ClientCard hand in Bot.Hand) + { + if (hand.IsMonster() && hand.Attack > bestPower) bestPower = hand.Attack; + } + int bestenemy = -1; + foreach (ClientCard enemy in Enemy.GetMonsters()) + { + if (enemy.IsMonsterDangerous()) return true; + if (enemy.IsFaceup() && (enemy.GetDefensePower() > bestenemy)) bestenemy = enemy.GetDefensePower(); + } + return (bestPower <= bestenemy); + } + return false; + } + public bool MonsterRepos() { if (Card.Id == CardId.Eater && Card.IsAttack()) return false; + if (IsTrickstar(Card.Id) && !white_eff_used && Bot.HasInHand(CardId.White) && Card.IsAttack() && Duel.Phase == DuelPhase.Main1) return false; + if (Card.IsFaceup() && Card.IsDefense() && Card.Attack == 0) return false; bool enemyBetter = AI.Utils.IsAllEnemyBetter(true); @@ -1399,6 +1617,60 @@ public override void OnNewTurn() red_ss_count = 0; white_eff_used = false; lockbird_useful = false; + lockbird_used = false; + if (GraveCall_count > 0) + { + if (--GraveCall_count <= 0) + { + GraveCall_id = 0; + } + } + } + + public override BattlePhaseAction OnBattle(IList attackers, IList defenders) + { + if (attackers.Count == 0) + return AI.ToMainPhase2(); + if (defenders.Count == 0) + { + for (int i = attackers.Count - 1; i >= 0; --i) + { + ClientCard attacker = attackers[i]; + if (attacker.Attack > 0) + return AI.Attack(attacker, null); + } + } + else + { + for (int i = defenders.Count - 1; i >= 0; --i) + { + ClientCard defender = defenders[i]; + for (int j = 0; j < attackers.Count; ++j) + { + ClientCard attacker = attackers[j]; + attacker.RealPower = attacker.Attack; + defender.RealPower = defender.GetDefensePower(); + if (!defender.IsMonsterHasPreventActivationEffectInBattle() && !attacker.IsDisabled()) + { + if ((attacker.Id == CardId.Eater && !defender.HasType(CardType.Token) && GraveCall_id != CardId.Eater) || attacker.Id == CardId.borrel) return AI.Attack(attacker, defender); + } + if (!OnPreBattleBetween(attacker, defender)) + continue; + + if (attacker.RealPower > defender.RealPower || (attacker.RealPower >= defender.RealPower && j == attackers.Count - 1)) + return AI.Attack(attacker, defender); + } + } + for (int i = attackers.Count - 1; i >= 0; --i) + { + ClientCard attacker = attackers[i]; + if (attacker.CanDirectAttack) + return AI.Attack(attacker, null); + } + } + if (!Battle.CanMainPhaseTwo) + return AI.Attack(attackers[0], (defenders.Count == 0) ? null : defenders[0]); + return AI.ToMainPhase2(); } public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender) @@ -1407,8 +1679,6 @@ public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender { if (IsTrickstar(attacker.Id) && Bot.HasInHand(CardId.White) && !white_eff_used) attacker.RealPower = attacker.RealPower * 2; - else if (attacker.Id == CardId.Eater) - attacker.RealPower = 99999; } return base.OnPreBattleBetween(attacker, defender); } From 22b11455b7c937e67818996e0456427b489ab102 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Wed, 4 Apr 2018 20:31:10 +0800 Subject: [PATCH 19/68] update default OnPreBattleBetween MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit know VampireFräulein and InjectionFairyLily --- Game/AI/DefaultExecutor.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index 0f2645d1..7cf7ddb6 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -33,6 +33,9 @@ protected class _CardId public const int Number39Utopia = 84013237; public const int UltimayaTzolkin = 1686814; + public const int VampireFräulein = 6039967; + public const int InjectionFairyLily = 79575620; + } protected DefaultExecutor(GameAI ai, Duel duel) @@ -63,6 +66,12 @@ public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender if (defender.Id == _CardId.NumberS39UtopiaTheLightning && defender.IsAttack() && !defender.IsDisabled() && defender.HasXyzMaterial(2, _CardId.Number39Utopia)) defender.RealPower = 5000; + + if (defender.Id == _CardId.VampireFräulein && !defender.IsDisabled()) + defender.RealPower += (Duel.LifePoints[defender.Controller] > 3000) ? 3000 : (Duel.LifePoints[defender.Controller] - 100); + + if (defender.Id == _CardId.InjectionFairyLily && !defender.IsDisabled() && Duel.LifePoints[defender.Controller] > 2000) + defender.RealPower += 3000; } if (!defender.IsMonsterHasPreventActivationEffectInBattle()) From b72f663bff25b0bfc5edd053e18cb74ac29e6521 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Wed, 4 Apr 2018 20:32:06 +0800 Subject: [PATCH 20/68] fix merge --- Game/AI/DefaultExecutor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index 7cf7ddb6..3253a166 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -68,9 +68,9 @@ public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender defender.RealPower = 5000; if (defender.Id == _CardId.VampireFräulein && !defender.IsDisabled()) - defender.RealPower += (Duel.LifePoints[defender.Controller] > 3000) ? 3000 : (Duel.LifePoints[defender.Controller] - 100); + defender.RealPower += (Enemy.LifePoints > 3000) ? 3000 : (Enemy.LifePoints - 100); - if (defender.Id == _CardId.InjectionFairyLily && !defender.IsDisabled() && Duel.LifePoints[defender.Controller] > 2000) + if (defender.Id == _CardId.InjectionFairyLily && !defender.IsDisabled() && Enemy.LifePoints > 2000) defender.RealPower += 3000; } From 480c2e12ffdaabbcab9872c35f300c81d11f846f Mon Sep 17 00:00:00 2001 From: handsomekiwi <36762809+handsomekiwi@users.noreply.github.com> Date: Thu, 5 Apr 2018 20:38:36 +0800 Subject: [PATCH 21/68] kaiju improve, add DefaultAllureofDarkness, update LightswornShaddoldinosour deck (#24) --- Decks/AI_LightswornShaddoldinosour.ydk | 15 -- .../LightswornShaddoldinosourExecutor.cs | 178 +++++++++++++----- Game/AI/DefaultExecutor.cs | 51 ++++- Game/GameAI.cs | 8 +- 4 files changed, 178 insertions(+), 74 deletions(-) diff --git a/Decks/AI_LightswornShaddoldinosour.ydk b/Decks/AI_LightswornShaddoldinosour.ydk index c896c044..751bedba 100644 --- a/Decks/AI_LightswornShaddoldinosour.ydk +++ b/Decks/AI_LightswornShaddoldinosour.ydk @@ -76,18 +76,3 @@ 50588353 50588353 !side -67696066 -73176465 -37742478 -15341821 -54757758 -13529466 -74586817 -6983839 -82633039 -46772449 -1861629 -1845204 -53129443 -43898403 -48130397 diff --git a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs index 07004c2d..0b3e5dde 100644 --- a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs +++ b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs @@ -22,7 +22,7 @@ public class CardId public const int GiantRex = 80280944; public const int ShaddollDragon = 77723643; public const int FairyTailSnow = 55623480; - public const int KeeeperOfDragonicMagic = 48048590; + public const int KeeperOfDragonicMagic = 48048590; public const int ShaddollSquamata = 30328508; public const int SouleatingOviraptor = 44335251; public const int Raiden = 77558536; @@ -86,8 +86,8 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.infiniteTransience, infiniteTransience); AddExecutor(ExecutorType.Activate, CardId.ThatGrassLooksgreener); AddExecutor(ExecutorType.Summon, CardId.SouleatingOviraptor); - AddExecutor(ExecutorType.Activate, CardId.SouleatingOviraptor, SouleatingOviraptor); - AddExecutor(ExecutorType.Activate, CardId.AllureofDarkness, AllureofDarkness); + AddExecutor(ExecutorType.Activate, CardId.SouleatingOviraptor, SouleatingOviraptoreff); + AddExecutor(ExecutorType.Activate, CardId.AllureofDarkness, DefaultAllureofDarkness); AddExecutor(ExecutorType.Activate, CardId.PotOfAvarice, PotofAvarice); // AddExecutor(ExecutorType.Activate, CardId.HarpiesFeatherDuster); AddExecutor(ExecutorType.Activate, CardId.ChargeOfTheLightBrigade, ChargeOfTheLightBrigadeEffect); @@ -100,8 +100,8 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) AddExecutor(ExecutorType.Summon, CardId.Raiden); AddExecutor(ExecutorType.Activate, CardId.Raiden); - AddExecutor(ExecutorType.Summon , CardId.KeeeperOfDragonicMagic); - AddExecutor(ExecutorType.Activate, CardId.KeeeperOfDragonicMagic, KeeeperOfDragonicMagic); + AddExecutor(ExecutorType.Summon , CardId.KeeperOfDragonicMagic); + AddExecutor(ExecutorType.Activate, CardId.KeeperOfDragonicMagic, KeeperOfDragonicMagic); AddExecutor(ExecutorType.MonsterSet, CardId.ShaddollSquamata); AddExecutor(ExecutorType.MonsterSet, CardId.GlowUpBulb); AddExecutor(ExecutorType.MonsterSet, CardId.ShaddollHedgehog); @@ -112,7 +112,7 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.Lumina); //Sp Summon AddExecutor(ExecutorType.SpSummon, CardId.UltimateConductorTytanno, UltimateConductorTytannosp); - AddExecutor(ExecutorType.Activate, CardId.UltimateConductorTytanno, UltimateConductorTytanno); + AddExecutor(ExecutorType.Activate, CardId.UltimateConductorTytanno, UltimateConductorTytannoeff); AddExecutor(ExecutorType.Activate, CardId.DoubleEvolutionPill, DoubleEvolutionPill); AddExecutor(ExecutorType.SpSummon, CardId.MinervaTheExalte); AddExecutor(ExecutorType.Activate, CardId.MinervaTheExalte, MinervaTheExaltedEffect); @@ -125,9 +125,9 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) //activate chain AddExecutor(ExecutorType.Activate, CardId.OvertexCoatls); AddExecutor(ExecutorType.Activate, CardId.ShaddollBeast); - AddExecutor(ExecutorType.Activate, CardId.ShaddollFalco, ShaddollFalco); - AddExecutor(ExecutorType.Activate, CardId.ShaddollSquamata, ShaddollSquamata); - AddExecutor(ExecutorType.Activate, CardId.ShaddollDragon); + AddExecutor(ExecutorType.Activate, CardId.ShaddollFalco, ShaddollFalcoeff); + AddExecutor(ExecutorType.Activate, CardId.ShaddollSquamata, ShaddollSquamataeff); + AddExecutor(ExecutorType.Activate, CardId.ShaddollDragon, ShaddollDragoneff); AddExecutor(ExecutorType.Activate, CardId.ShaddollHedgehog); AddExecutor(ExecutorType.Activate, CardId.GiantRex); AddExecutor(ExecutorType.Activate, CardId.ElShaddollConstruct); @@ -163,7 +163,7 @@ public int[] all_List() CardId.GiantRex, CardId.ShaddollDragon, CardId.FairyTailSnow, - CardId.KeeeperOfDragonicMagic, + CardId.KeeperOfDragonicMagic, CardId.ShaddollSquamata, CardId.SouleatingOviraptor, CardId.Raiden, @@ -215,10 +215,12 @@ public int[] Useless_List() }; } - private bool UltimateConductorTytanno() + private bool UltimateConductorTytannoeff() { - AI.SelectCard(new[] + if (Duel.Phase == DuelPhase.Main1 || Duel.Phase == DuelPhase.Main2) { + AI.SelectCard(new[] + { CardId.OvertexCoatls, CardId.ShaddollBeast, CardId.ShaddollSquamata, @@ -228,8 +230,10 @@ private bool UltimateConductorTytanno() CardId.PlaguespreaderZombie, CardId.FairyTailSnow, }); - - + } + if (Duel.Phase == DuelPhase.Damage) + return true; + return true; } private bool UltimateConductorTytannosp() @@ -243,9 +247,14 @@ private bool UltimateConductorTytannosp() return true; } - private bool KeeeperOfDragonicMagic() + private bool KeeperOfDragonicMagic() { - AI.SelectCard(Useless_List()); + if (ActivateDescription == -1) + { + AI.SelectCard(Useless_List()); + return true; + } + return true; } @@ -259,6 +268,69 @@ public override void OnNewTurn() { Pillused = false; } + private bool DoubleEvolutionPill() + { + if (Pillused == true) return false; + Pillused = true; + IList targets = new[] { + CardId.GiantRex, + CardId.DogorantheMadFlameKaiju, + CardId.GamecieltheSeaTurtleKaiju, + CardId.RadiantheMultidimensionalKaiju, + CardId.OvertexCoatls, + CardId.SouleatingOviraptor, + CardId.UltimateConductorTytanno, + }; + if (Bot.HasInGraveyard(targets)) + { + AI.SelectCard(new[] { + CardId.GiantRex, + CardId.DogorantheMadFlameKaiju, + CardId.OvertexCoatls, + CardId.GamecieltheSeaTurtleKaiju, + CardId.RadiantheMultidimensionalKaiju, + CardId.SouleatingOviraptor, + CardId.UltimateConductorTytanno, + }); + } + else + { + AI.SelectCard(new[] { + CardId.GiantRex, + CardId.DogorantheMadFlameKaiju, + CardId.GamecieltheSeaTurtleKaiju, + CardId.RadiantheMultidimensionalKaiju, + CardId.OvertexCoatls, + CardId.SouleatingOviraptor, + CardId.UltimateConductorTytanno, + }); + } + AI.SelectNextCard(new[] { + CardId.ShaddollBeast, + CardId.ShaddollDragon, + CardId.KeeperOfDragonicMagic, + CardId.ShaddollSquamata, + CardId.SouleatingOviraptor, + CardId.Raiden, + CardId.Lumina, + CardId.ShaddollHedgehog, + CardId.AshBlossom, + CardId.GhostOgre, + CardId.ShaddollFalco, + CardId.MaxxC, + CardId.PlaguespreaderZombie, + CardId.GlowUpBulb, + CardId.FairyTailSnow, + }); + + AI.SelectThirdCard(new[] { + CardId.UltimateConductorTytanno, + + }); + + return Enemy.GetMonsterCount() >= 1; + } + private bool ShaddollCoreeff() { if (Card.Location == CardLocation.SpellZone) @@ -282,7 +354,7 @@ private bool FairyTailSnow() } return false; } - private bool SouleatingOviraptor() + private bool SouleatingOviraptoreff() { AI.SelectCard(CardId.OvertexCoatls); AI.SelectYesNo(false); @@ -295,12 +367,15 @@ private bool GlowUpBulb() } private bool ShaddollFusion() { + if (Enemy.GetMonstersExtraZoneCount() != 0) { IList materials0 = Bot.Deck; IList materials1 = Bot.Deck; IList mats = new List(); + AI.SelectCard(CardId.ElShaddollConstruct); + ClientCard mat = null; foreach (ClientCard card in materials0) { @@ -327,12 +402,11 @@ private bool ShaddollFusion() mats.Add(mat); AI.SelectMaterials(mats); - AI.SelectCard(CardId.ElShaddollConstruct); AI.SelectPosition(CardPosition.FaceUpAttack); return true; } - + AI.SelectCard(CardId.ElShaddollShekhinaga); foreach (ClientCard card in materials0) { if (card.HasAttribute(CardAttribute.Earth)) @@ -358,12 +432,12 @@ private bool ShaddollFusion() mats.Add(mat); AI.SelectMaterials(mats); - AI.SelectCard(CardId.ElShaddollShekhinaga); + AI.SelectPosition(CardPosition.FaceUpAttack); return true; } - + AI.SelectCard(CardId.ElShaddollGrysra); foreach (ClientCard card in materials0) { if (card.HasAttribute(CardAttribute.Fire)) @@ -389,12 +463,12 @@ private bool ShaddollFusion() mats.Add(mat); AI.SelectMaterials(mats); - AI.SelectCard(CardId.ElShaddollGrysra); + AI.SelectPosition(CardPosition.FaceUpAttack); return true; } - + AI.SelectCard(CardId.ElShaddollWinda); foreach (ClientCard card in materials0) { if (card.HasAttribute(CardAttribute.Dark)) @@ -420,7 +494,7 @@ private bool ShaddollFusion() mats.Add(mat); AI.SelectMaterials(mats); - AI.SelectCard(CardId.ElShaddollWinda); + AI.SelectPosition(CardPosition.FaceUpAttack); return true; } @@ -455,23 +529,6 @@ private bool ShaddollFusion() } return null; }*/ - private bool DoubleEvolutionPill() - { - if (Pillused == true)return false; - Pillused = true; - if (Bot.HasInGraveyard(CardId.UltimateConductorTytanno) ) - { - AI.SelectCard(CardId.UltimateConductorTytanno); - } - - - AI.SelectThirdCard(new[] { - CardId.UltimateConductorTytanno, - - }); - - return Enemy.GetMonsterCount()>=1; - } private bool ShaddollCore() @@ -503,6 +560,7 @@ private bool spellset() } private bool RebornEffect() { + IList targets = new[] { CardId.UltimateConductorTytanno, CardId.ElShaddollConstruct, @@ -559,7 +617,7 @@ private bool SinisterShadowGames() AI.SelectCard(new[] { CardId.ShaddollBeast, - CardId.ShaddollCore, + } ); @@ -567,7 +625,7 @@ private bool SinisterShadowGames() return true; } - private bool ShaddollFalco() + private bool ShaddollFalcoeff() { if (Card.Location != CardLocation.MonsterZone) return true; @@ -586,16 +644,42 @@ private bool ShaddollFalco() } return true; } - private bool ShaddollSquamata() + private bool ShaddollDragoneff() { - AI.SelectCard(new[] + if (Card.Location == CardLocation.MonsterZone) + { + ClientCard target = AI.Utils.GetBestEnemyCard(); + AI.SelectCard(target); + return true; + } + else + { + ClientCard target = AI.Utils.GetBestEnemySpell(); + AI.SelectCard(target); + return true; + } + } + private bool ShaddollSquamataeff() + { + if (Card.Location != CardLocation.MonsterZone) + { + AI.SelectCard(new[] { CardId.ShaddollBeast, + + }); + } + + else + { + ClientCard target = AI.Utils.GetBestEnemyMonster(); + AI.SelectCard(target); } - ); return true; - + + + } private bool FoolishBurialEffect() { diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index 3253a166..d655b4d7 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -12,14 +12,15 @@ public abstract class DefaultExecutor : Executor protected class _CardId { public const int JizukirutheStarDestroyingKaiju = 63941210; - public const int GadarlatheMysteryDustKaiju = 36956512; - public const int GamecieltheSeaTurtleKaiju = 55063751; - public const int RadiantheMultidimensionalKaiju = 28674152; - public const int KumongoustheStickyStringKaiju = 29726552; public const int ThunderKingtheLightningstrikeKaiju = 48770333; public const int DogorantheMadFlameKaiju = 93332803; + public const int RadiantheMultidimensionalKaiju = 28674152; + public const int GadarlatheMysteryDustKaiju = 36956512; + public const int KumongoustheStickyStringKaiju = 29726552; + public const int GamecieltheSeaTurtleKaiju = 55063751; public const int SuperAntiKaijuWarMachineMechaDogoran = 84769941; + public const int DupeFrog = 46239604; public const int MaraudingCaptain = 2460565; @@ -469,6 +470,29 @@ protected bool DefaultChickenGame() return false; } + /// + /// Draw when we have Dark monster in hand,and banish random one. Can be overrided. + /// + protected bool DefaultAllureofDarkness() + { + IList condition = Bot.Hand; + IList check = new List(); + ClientCard con = null; + foreach (ClientCard card in condition) + { + if (card.HasAttribute(CardAttribute.Dark)) + { + con = card; + break; + } + } + if (con != null) + { + return true; + } + return false; + } + /// /// Clever enough. /// @@ -557,7 +581,7 @@ protected bool DefaultDimensionalBarrier() } /// - /// Clever enough. + /// Clever enough /// protected bool DefaultInterruptedKaijuSlumber() { @@ -565,26 +589,37 @@ protected bool DefaultInterruptedKaijuSlumber() { AI.SelectCard(new[] { + _CardId.SuperAntiKaijuWarMachineMechaDogoran, _CardId.GamecieltheSeaTurtleKaiju, _CardId.KumongoustheStickyStringKaiju, + _CardId.GadarlatheMysteryDustKaiju, _CardId.RadiantheMultidimensionalKaiju, - _CardId.GadarlatheMysteryDustKaiju + _CardId.DogorantheMadFlameKaiju, + _CardId.ThunderKingtheLightningstrikeKaiju, + _CardId.JizukirutheStarDestroyingKaiju, }); return true; } AI.SelectCard(new[] { _CardId.JizukirutheStarDestroyingKaiju, + _CardId.ThunderKingtheLightningstrikeKaiju, + _CardId.DogorantheMadFlameKaiju, _CardId.RadiantheMultidimensionalKaiju, _CardId.GadarlatheMysteryDustKaiju, - _CardId.KumongoustheStickyStringKaiju + _CardId.KumongoustheStickyStringKaiju, + _CardId.GamecieltheSeaTurtleKaiju, }); AI.SelectNextCard(new[] { + _CardId.SuperAntiKaijuWarMachineMechaDogoran, _CardId.GamecieltheSeaTurtleKaiju, _CardId.KumongoustheStickyStringKaiju, _CardId.GadarlatheMysteryDustKaiju, - _CardId.RadiantheMultidimensionalKaiju + _CardId.RadiantheMultidimensionalKaiju, + _CardId.DogorantheMadFlameKaiju, + _CardId.ThunderKingtheLightningstrikeKaiju, + }); return DefaultDarkHole(); } diff --git a/Game/GameAI.cs b/Game/GameAI.cs index c4cdc197..0b624124 100644 --- a/Game/GameAI.cs +++ b/Game/GameAI.cs @@ -165,9 +165,9 @@ public IList OnSelectCard(IList cards, int min, int max, { const int HINTMSG_FMATERIAL = 511; const int HINTMSG_SMATERIAL = 512; - const int HINTMSG_XMATERIAL = 513; - const int HINTMSG_LMATERIAL = 533; - const int HINTMSG_SPSUMMON = 509; + const int HINTMSG_XMATERIAL = 513; + const int HINTMSG_LMATERIAL = 533; + const int HINTMSG_SPSUMMON = 509; // Check for the executor. IList result = Executor.OnSelectCard(cards, min, max, hint, cancelable); @@ -701,7 +701,7 @@ public void SelectThirdCard(CardLocation loc) { m_thirdSelector = new CardSelector(loc); } - + public void SelectMaterials(ClientCard card) { m_materialSelector = new CardSelector(card); From 72c9fbf8f847fe80d57afab4c42abf2f04f893d8 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Thu, 5 Apr 2018 20:57:29 +0800 Subject: [PATCH 22/68] add OnSelectUnselectCard from Gideon9212 --- Game/GameAI.cs | 8 ++-- Game/GameBehavior.cs | 74 ++++++++++++++++++++++++++++++++++ YGOSharp.OCGWrapper.Enums.dll | Bin 9728 -> 9728 bytes YGOSharp.OCGWrapper.dll | Bin 16896 -> 16896 bytes 4 files changed, 79 insertions(+), 3 deletions(-) diff --git a/Game/GameAI.cs b/Game/GameAI.cs index 0b624124..f22a68cd 100644 --- a/Game/GameAI.cs +++ b/Game/GameAI.cs @@ -220,9 +220,11 @@ public IList OnSelectCard(IList cards, int min, int max, // Always select the first available cards and choose the minimum. IList selected = new List(); - for (int i = 0; i < min; ++i) - selected.Add(cards[i]); - + if (cards.Count >= min) + { + for (int i = 0; i < min; ++i) + selected.Add(cards[i]); + } return selected; } diff --git a/Game/GameBehavior.cs b/Game/GameBehavior.cs index 80bc700c..ce072baa 100644 --- a/Game/GameBehavior.cs +++ b/Game/GameBehavior.cs @@ -108,6 +108,7 @@ private void RegisterPackets() _messages.Add(GameMessage.BecomeTarget, OnBecomeTarget); _messages.Add(GameMessage.SelectBattleCmd, OnSelectBattleCmd); _messages.Add(GameMessage.SelectCard, OnSelectCard); + _messages.Add(GameMessage.SelectUnselectCard, OnSelectUnselectCard); _messages.Add(GameMessage.SelectChain, OnSelectChain); _messages.Add(GameMessage.SelectCounter, OnSelectCounter); _messages.Add(GameMessage.SelectDisfield, OnSelectDisfield); @@ -750,11 +751,84 @@ private void InternalOnSelectCard(BinaryReader packet, Func, i Connection.Send(reply); } + private void InternalOnSelectUnselectCard(BinaryReader packet, Func, int, int, int, bool, IList> func) + { + packet.ReadByte(); // player + packet.ReadByte(); // buttonok + bool cancelable = packet.ReadByte() != 0; + int min = packet.ReadByte(); + int max = packet.ReadByte(); + + IList cards = new List(); + int count = packet.ReadByte(); + for (int i = 0; i < count; ++i) + { + int id = packet.ReadInt32(); + int player = GetLocalPlayer(packet.ReadByte()); + CardLocation loc = (CardLocation)packet.ReadByte(); + int seq = packet.ReadByte(); + packet.ReadByte(); // pos + ClientCard card; + if (((int)loc & (int)CardLocation.Overlay) != 0) + card = new ClientCard(id, CardLocation.Overlay); + else + card = _duel.GetCard(player, loc, seq); + if (card == null) continue; + if (card.Id == 0) + card.SetId(id); + cards.Add(card); + } + int count2 = packet.ReadByte(); + for (int i = 0; i < count2; ++i) + { + int id = packet.ReadInt32(); + int player = GetLocalPlayer(packet.ReadByte()); + CardLocation loc = (CardLocation)packet.ReadByte(); + int seq = packet.ReadByte(); + packet.ReadByte(); // pos + } + + IList selected = func(cards, min, max, _select_hint, cancelable); + _select_hint = 0; + + if (selected.Count == 0 && cancelable) + { + Connection.Send(CtosMessage.Response, -1); + return; + } + + byte[] result = new byte[selected.Count + 1]; + result[0] = (byte)selected.Count; + for (int i = 0; i < selected.Count; ++i) + { + int id = 0; + for (int j = 0; j < count; ++j) + { + if (cards[j] == null) continue; + if (cards[j].Equals(selected[i])) + { + id = j; + break; + } + } + result[i + 1] = (byte)id; + } + + BinaryWriter reply = GamePacketFactory.Create(CtosMessage.Response); + reply.Write(result); + Connection.Send(reply); + } + private void OnSelectCard(BinaryReader packet) { InternalOnSelectCard(packet, _ai.OnSelectCard); } + private void OnSelectUnselectCard(BinaryReader packet) + { + InternalOnSelectUnselectCard(packet, _ai.OnSelectCard); + } + private void OnSelectChain(BinaryReader packet) { packet.ReadByte(); // player diff --git a/YGOSharp.OCGWrapper.Enums.dll b/YGOSharp.OCGWrapper.Enums.dll index 09b2e77815c3624d789ed0bf440b8b0547ad4d68..21316dfd7b3236d897dba18e56124ba39f96d295 100644 GIT binary patch delta 2218 zcmX|?4NO&K7{{OYea|`f++-k<4B=|z#idgS!4e6b1m#DjC_!rCw+V`bproug7h;iN zPPj_ToSDj|HK%!-=2~LQ%r;h|nz`j@O-fsqw!TcA>v{g(+hzCn{-6Kz^>TK$8=4iG zwfz-i0%tqghpT-Zhn`j?VWm8EFx<>+4J(~wQ!0@PHwPw$OLWHM^f;nm6VX;a_xf3v zZm6rOSzS;38JA3C@fj>DrEJ!NMNcc6QOxI5j!%c*(+_$VIg01+*U?k)DPN+c_TAH= z&y3|dG{F+y(x3VgD8nUkC}_qz4!r}mgK3sHm!SzdA3DMO=yT|MEv$i4W}dYidSBby z!plsO_p8oz3wbgB@mAZB$RCZ05G6&U3rccX|Ft#z(;xLm?PW*4j?^>{aD*UUjt`b!PoqvOO(52vZR9=OD1I}#F%R{0Y&F5gP^GkCjO3%api^O>Wm3?qFf^VSm zU368$$z>h8T&2H>yF5^l=yA|z9nm>jIN7u1s7ByJQITr;e?-{d!r2GFU6$xap}(+2 zk0s$+B^(YX9eN0O5>BTh*(G2*{IB5u23_KKlJ3*Oek2-vqThx#DEb8K0&io`1=Re4 z3r&Ncc()!r1m_=Q2T(r(7j1?(O--9EoW|z$Ji4l_UKJ_ygLCF=#RLAgq}QCSdd_jJSrH zdMpmYPXSvo`UtL-$z8FR@s#^AKi!?S@LT9!(EAC;=in7b(wA7r+A{U4?36pg9-nYO zoQ1aNEO5Fd`e!8^fF6aKGtdUQ5fd6v(+qw9_Ify;bftL;7POJ*Qm`D&6<{te^V3nE zqC}=c!&nv+KpE(eWMB}d}C0pyN-hl zT}YAIxRJ`cqL*uzuInJV^rs%pyrDChw{;GaOaap}g-q8x&WtllnD-i~Pcc#-FjAjx zq&~w;WR6DHICN#BYXZ9R%u3D{m@4K}Q^PFwOg$gd%_in7^CGjvv@oACZOr**D|3bOMdC-?wDp1f MNMgn{)sgM{4-VBLZvX%Q delta 2197 zcmX|?e@xX?7{=do&i($lN^toR6D7O_BxNa@L@G`Rh*T;ZVWLzjlp#Wr#>ArUMVH8Q z1>9kca{biJQ6}EBw5Dz3A5CjP+9bBtA2n-MqN`@ftoMDmx6AJ5Jn!>9?>UF>?(Pkh zg~~d28l70!wd*Fewd=qmDkrRzr$XU2W_4KUWb1qykqY;x=ZDL6)`FBcqRbbFLcH$w zv#!|uOkLx;O~kLbR3aa*nUxh3U>y)$TDiEG*C5v)hx_$RZ-lFOeh)=g#jCuD9m`16mn zzTOhRVW;Uid4)0TZH_r+)V-7eWGVVe`1NA zPQrR6oB$^XodoWOBQqDrug26~Faf*$izj*xynsxRbiL3I2z>>s7#lqXeHCN*IBX1=J~)?)?}WFeGL2DHh#L>EaB(S$G~qu?aC zqNjj)KGEMQ;UIJpGX2n_@Yi97X6QC>A9xI$=eaUG9S5|N=nAk18!Z8Ye3+m1I*JmR zHl;Bq&~3~B%>w6wh2Uav8CV6bVctk}&`n?q=#op3M*mLj7O*<2;#K(i#Etyz>{6C) zP?6@iTa@>!&g6Pj=P>`!cQUW)*~~F5Lu4fFGxsrF^EfkLB%fj=Kgmcw-AF!Y@|jsi zrgAWK2c~i{HOJJle~+nS7MMonBD0BE?3pdR+;3W$Wo8?*+_W|w4p zuQ6-Qo6M)o2h0s-AI+eN)S+kak61Tz3iUHH={R#b4KwfJ%g>oJf4eKbC%eUL-N=lIqHJ{sY~s6~_Po diff --git a/YGOSharp.OCGWrapper.dll b/YGOSharp.OCGWrapper.dll index 4634af332a75dceb6300757d5a9caa7922b7cb06..3a16fd67bc192f6b16c73c070b4edabf28f54f3f 100644 GIT binary patch delta 68 zcmZo@VQgq&oX{b_EORW10SX>4Fez@F(ZI;aJXz7gd~yJj86(r?cBWK)0kgQ@*QCV1 TcuyANeel&zVejTYhAaXAc`Fpt delta 68 zcmZo@VQgq&oX{a4%ODcP00j>iloU43XkcVyoUCYJJ~@ENjFEA3J5#E@z^a8jc7bh1 TPTO~>y6!Kowb}f~kVOChOAZre From cfc60c2be443586aa0130a3d815f6de8f44096d0 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Thu, 5 Apr 2018 21:27:18 +0800 Subject: [PATCH 23/68] fix DefaultInterruptedKaijuSlumber --- Game/AI/DefaultExecutor.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index d655b4d7..5940b597 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -589,7 +589,6 @@ protected bool DefaultInterruptedKaijuSlumber() { AI.SelectCard(new[] { - _CardId.SuperAntiKaijuWarMachineMechaDogoran, _CardId.GamecieltheSeaTurtleKaiju, _CardId.KumongoustheStickyStringKaiju, _CardId.GadarlatheMysteryDustKaiju, From 5870c2d9836f421d9eb22037cccadfe726f68879 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Thu, 5 Apr 2018 21:27:53 +0800 Subject: [PATCH 24/68] minor format fixes --- Dialogs/{kiwi.zh-CN.json => kiwi.zh-TW.json} | 3 +- Game/AI/Decks/BlackwingExecutor.cs | 2 +- Game/AI/Decks/CyberDragonExecutor.cs | 2 +- .../LightswornShaddoldinosourExecutor.cs | 88 +++++++++---------- Game/AI/Decks/NekrozExecutor.cs | 8 +- Game/AI/Decks/QliphortExecutor.cs | 2 +- Game/GameAI.cs | 2 +- 7 files changed, 53 insertions(+), 54 deletions(-) rename Dialogs/{kiwi.zh-CN.json => kiwi.zh-TW.json} (98%) diff --git a/Dialogs/kiwi.zh-CN.json b/Dialogs/kiwi.zh-TW.json similarity index 98% rename from Dialogs/kiwi.zh-CN.json rename to Dialogs/kiwi.zh-TW.json index 2ab014c5..7c14faf6 100644 --- a/Dialogs/kiwi.zh-CN.json +++ b/Dialogs/kiwi.zh-TW.json @@ -9,8 +9,7 @@ "duelstart": [ "這只是AI,打贏不要太高興阿。", "十分致謝233服讓我們有遊戲可以玩,別忘記去拜訪他們。", - "反主流學院請洽NOVA。", - + "反主流學院請洽NOVA。" ], "newturn": [ "到我的回合了,抽牌!", diff --git a/Game/AI/Decks/BlackwingExecutor.cs b/Game/AI/Decks/BlackwingExecutor.cs index e871acc6..1f5c279c 100644 --- a/Game/AI/Decks/BlackwingExecutor.cs +++ b/Game/AI/Decks/BlackwingExecutor.cs @@ -43,7 +43,7 @@ public BlackwingExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.DarkHole, DefaultDarkHole); AddExecutor(ExecutorType.Activate, CardId.Raigeki, DefaultRaigeki); AddExecutor(ExecutorType.Activate, CardId.BlackWhirlwind, BlackWhirlwindEffect); - + AddExecutor(ExecutorType.SpSummon, CardId.KrisTheCrackOfDawn); AddExecutor(ExecutorType.SummonOrSet, CardId.KrisTheCrackOfDawn); AddExecutor(ExecutorType.Summon, CardId.SiroccoTheDawn, SiroccoTheDawnSummon); diff --git a/Game/AI/Decks/CyberDragonExecutor.cs b/Game/AI/Decks/CyberDragonExecutor.cs index 2db1a11c..2f83d93a 100644 --- a/Game/AI/Decks/CyberDragonExecutor.cs +++ b/Game/AI/Decks/CyberDragonExecutor.cs @@ -129,7 +129,7 @@ private bool EvolutionBurstEffect() if (bestMy == null || !AI.Utils.IsOneEnemyBetterThanValue(bestMy.Attack, false)) return false; else - AI.SelectCard(Enemy.MonsterZone.GetHighestAttackMonster()); + AI.SelectCard(Enemy.MonsterZone.GetHighestAttackMonster()); return true; } diff --git a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs index 0b3e5dde..b19d9f24 100644 --- a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs +++ b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs @@ -34,7 +34,7 @@ public class CardId public const int MaxxC = 23434538; public const int PlaguespreaderZombie = 33420078; public const int GlowUpBulb = 67441435; - + //spell public const int AllureofDarkness = 1475311; public const int ThatGrassLooksgreener = 11110587; @@ -53,7 +53,7 @@ public class CardId public const int LostWind = 74003290; public const int SinisterShadowGames = 77505534; public const int ShaddollCore = 4904633; - + //extra public const int ElShaddollShekhinaga = 74822425; public const int ElShaddollConstruct = 20366274; @@ -77,7 +77,7 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) : base(ai, duel) { //counter - + AddExecutor(ExecutorType.Activate, CardId.GhostOgre, Hand_act_eff); AddExecutor(ExecutorType.Activate, CardId.AshBlossom, Hand_act_eff); AddExecutor(ExecutorType.Activate, CardId.MaxxC,MaxxC); @@ -86,7 +86,7 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.infiniteTransience, infiniteTransience); AddExecutor(ExecutorType.Activate, CardId.ThatGrassLooksgreener); AddExecutor(ExecutorType.Summon, CardId.SouleatingOviraptor); - AddExecutor(ExecutorType.Activate, CardId.SouleatingOviraptor, SouleatingOviraptoreff); + AddExecutor(ExecutorType.Activate, CardId.SouleatingOviraptor, SouleatingOviraptoreff); AddExecutor(ExecutorType.Activate, CardId.AllureofDarkness, DefaultAllureofDarkness); AddExecutor(ExecutorType.Activate, CardId.PotOfAvarice, PotofAvarice); // AddExecutor(ExecutorType.Activate, CardId.HarpiesFeatherDuster); @@ -99,9 +99,9 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) //Normal Summon AddExecutor(ExecutorType.Summon, CardId.Raiden); AddExecutor(ExecutorType.Activate, CardId.Raiden); - + AddExecutor(ExecutorType.Summon , CardId.KeeperOfDragonicMagic); - AddExecutor(ExecutorType.Activate, CardId.KeeperOfDragonicMagic, KeeperOfDragonicMagic); + AddExecutor(ExecutorType.Activate, CardId.KeeperOfDragonicMagic, KeeperOfDragonicMagic); AddExecutor(ExecutorType.MonsterSet, CardId.ShaddollSquamata); AddExecutor(ExecutorType.MonsterSet, CardId.GlowUpBulb); AddExecutor(ExecutorType.MonsterSet, CardId.ShaddollHedgehog); @@ -116,12 +116,12 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.DoubleEvolutionPill, DoubleEvolutionPill); AddExecutor(ExecutorType.SpSummon, CardId.MinervaTheExalte); AddExecutor(ExecutorType.Activate, CardId.MinervaTheExalte, MinervaTheExaltedEffect); - - - + + + //activate AddExecutor(ExecutorType.Activate , CardId.GlowUpBulb,GlowUpBulb); - + //activate chain AddExecutor(ExecutorType.Activate, CardId.OvertexCoatls); AddExecutor(ExecutorType.Activate, CardId.ShaddollBeast); @@ -142,7 +142,7 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) //trap AddExecutor(ExecutorType.SpellSet, CardId.LostWind, TrapSetWhenZoneFree); AddExecutor(ExecutorType.SpellSet, CardId.SinisterShadowGames, TrapSetWhenZoneFree); - AddExecutor(ExecutorType.SpellSet, CardId.ShaddollCore); + AddExecutor(ExecutorType.SpellSet, CardId.ShaddollCore); AddExecutor(ExecutorType.SpellSet, CardId.infiniteTransience, SetIsFieldEmpty); //trap activate AddExecutor(ExecutorType.Activate, CardId.LostWind, DefaultBreakthroughSkill); @@ -206,12 +206,12 @@ public int[] Useless_List() CardId.ChargeOfTheLightBrigade, CardId.FoolishBurial, CardId.HarpiesFeatherDuster, - CardId.ThatGrassLooksgreener, + CardId.ThatGrassLooksgreener, CardId.FairyTailSnow, CardId.GiantRex, CardId.Lumina, CardId.OvertexCoatls, - + }; } @@ -233,7 +233,7 @@ private bool UltimateConductorTytannoeff() } if (Duel.Phase == DuelPhase.Damage) return true; - + return true; } private bool UltimateConductorTytannosp() @@ -254,8 +254,8 @@ private bool KeeperOfDragonicMagic() AI.SelectCard(Useless_List()); return true; } - - + + return true; } private bool MonsterRepos() @@ -273,11 +273,11 @@ private bool DoubleEvolutionPill() if (Pillused == true) return false; Pillused = true; IList targets = new[] { - CardId.GiantRex, + CardId.GiantRex, CardId.DogorantheMadFlameKaiju, CardId.GamecieltheSeaTurtleKaiju, CardId.RadiantheMultidimensionalKaiju, - CardId.OvertexCoatls, + CardId.OvertexCoatls, CardId.SouleatingOviraptor, CardId.UltimateConductorTytanno, }; @@ -288,7 +288,7 @@ private bool DoubleEvolutionPill() CardId.DogorantheMadFlameKaiju, CardId.OvertexCoatls, CardId.GamecieltheSeaTurtleKaiju, - CardId.RadiantheMultidimensionalKaiju, + CardId.RadiantheMultidimensionalKaiju, CardId.SouleatingOviraptor, CardId.UltimateConductorTytanno, }); @@ -306,7 +306,7 @@ private bool DoubleEvolutionPill() }); } AI.SelectNextCard(new[] { - CardId.ShaddollBeast, + CardId.ShaddollBeast, CardId.ShaddollDragon, CardId.KeeperOfDragonicMagic, CardId.ShaddollSquamata, @@ -320,7 +320,7 @@ private bool DoubleEvolutionPill() CardId.MaxxC, CardId.PlaguespreaderZombie, CardId.GlowUpBulb, - CardId.FairyTailSnow, + CardId.FairyTailSnow, }); AI.SelectThirdCard(new[] { @@ -340,14 +340,14 @@ private bool ShaddollCoreeff() AI.SelectPosition(CardPosition.FaceUpDefence); return true; } - + return false; } return true; } private bool FairyTailSnow() { - + if (Card.Location == CardLocation.MonsterZone) { return true; @@ -367,7 +367,7 @@ private bool GlowUpBulb() } private bool ShaddollFusion() { - + if (Enemy.GetMonstersExtraZoneCount() != 0) { IList materials0 = Bot.Deck; @@ -375,7 +375,7 @@ private bool ShaddollFusion() IList mats = new List(); AI.SelectCard(CardId.ElShaddollConstruct); - + ClientCard mat = null; foreach (ClientCard card in materials0) { @@ -432,7 +432,7 @@ private bool ShaddollFusion() mats.Add(mat); AI.SelectMaterials(mats); - + AI.SelectPosition(CardPosition.FaceUpAttack); return true; } @@ -463,7 +463,7 @@ private bool ShaddollFusion() mats.Add(mat); AI.SelectMaterials(mats); - + AI.SelectPosition(CardPosition.FaceUpAttack); return true; } @@ -494,7 +494,7 @@ private bool ShaddollFusion() mats.Add(mat); AI.SelectMaterials(mats); - + AI.SelectPosition(CardPosition.FaceUpAttack); return true; } @@ -509,7 +509,7 @@ private bool ShaddollFusion() return true; } - + /* private ClientCard GetAleisterInGrave() { @@ -529,8 +529,8 @@ private bool ShaddollFusion() } return null; }*/ - - + + private bool ShaddollCore() { return Bot.HasInGraveyard(CardId.ShaddollFusion); @@ -552,7 +552,7 @@ private bool AllureofDarkness() { return true; } - return false; + return false; } private bool spellset() { @@ -560,13 +560,13 @@ private bool spellset() } private bool RebornEffect() { - + IList targets = new[] { CardId.UltimateConductorTytanno, CardId.ElShaddollConstruct, CardId.DogorantheMadFlameKaiju, CardId.GamecieltheSeaTurtleKaiju, - CardId.SouleatingOviraptor, + CardId.SouleatingOviraptor, }; if (!Bot.HasInGraveyard(targets)) { @@ -602,9 +602,9 @@ private bool ChargeOfTheLightBrigadeEffect() AI.SelectCard(CardId.Raiden); else AI.SelectCard(new[] - { + { CardId.Lumina, - + }); return true; } @@ -617,7 +617,7 @@ private bool SinisterShadowGames() AI.SelectCard(new[] { CardId.ShaddollBeast, - + } ); @@ -640,7 +640,7 @@ private bool ShaddollFalcoeff() CardId.ShaddollSquamata, } ); - + } return true; } @@ -669,12 +669,12 @@ private bool ShaddollSquamataeff() }); } - + else { ClientCard target = AI.Utils.GetBestEnemyMonster(); AI.SelectCard(target); - + } return true; @@ -683,7 +683,7 @@ private bool ShaddollSquamataeff() } private bool FoolishBurialEffect() { - + AI.SelectCard(new[] { CardId.OvertexCoatls, @@ -697,7 +697,7 @@ private bool FoolishBurialEffect() }); return true; } - + private bool GoblindberghSummon() { @@ -709,9 +709,9 @@ private bool GoblindberghSummon() return false; } - - + + private bool PerformageTrickClownEffect() { AI.SelectPosition(CardPosition.FaceUpDefence); diff --git a/Game/AI/Decks/NekrozExecutor.cs b/Game/AI/Decks/NekrozExecutor.cs index 8e1713ae..d6486941 100644 --- a/Game/AI/Decks/NekrozExecutor.cs +++ b/Game/AI/Decks/NekrozExecutor.cs @@ -9,7 +9,7 @@ namespace WindBot.Game.AI.Decks // NOT FINISHED YET [Deck("Nekroz", "AI_Nekroz", "NotFinished")] public class NekrozExecutor : DefaultExecutor - { + { public class CardId { public const int DancePrincess = 52738610; @@ -45,7 +45,7 @@ public class CardId public NekrozExecutor(GameAI ai, Duel duel) : base(ai, duel) { - NekrozRituelCard.Add(CardId.Clausolas); + NekrozRituelCard.Add(CardId.Clausolas); NekrozRituelCard.Add(CardId.Unicore); NekrozRituelCard.Add(CardId.DecisiveArmor); NekrozRituelCard.Add(CardId.Brionac); @@ -103,7 +103,7 @@ public NekrozExecutor(GameAI ai, Duel duel) private bool ThousandHandsSummon() { - if (!Bot.HasInHand(NekrozRituelCard) || Bot.HasInHand(CardId.Shurit) || !Bot.HasInHand(NekrozSpellCard)) + if (!Bot.HasInHand(NekrozRituelCard) || Bot.HasInHand(CardId.Shurit) || !Bot.HasInHand(NekrozSpellCard)) return true; foreach (ClientCard Card in Bot.Hand) if (Card != null && Card.Id == CardId.Kaleidoscope && !Bot.HasInHand(CardId.Unicore)) @@ -175,7 +175,7 @@ private bool ValkyrusEffect() } private bool GungnirEffect() - { + { if (AI.Utils.IsOneEnemyBetter(true) && Duel.Phase == DuelPhase.Main1) { AI.SelectCard(Enemy.GetMonsters().GetHighestAttackMonster()); diff --git a/Game/AI/Decks/QliphortExecutor.cs b/Game/AI/Decks/QliphortExecutor.cs index 6fddbad9..95a56d70 100644 --- a/Game/AI/Decks/QliphortExecutor.cs +++ b/Game/AI/Decks/QliphortExecutor.cs @@ -191,7 +191,7 @@ private bool CardOfDemiseEffect() } return false; } - + private bool TrapSetUnique() { foreach (ClientCard card in Bot.GetSpells()) diff --git a/Game/GameAI.cs b/Game/GameAI.cs index f22a68cd..8ea1c596 100644 --- a/Game/GameAI.cs +++ b/Game/GameAI.cs @@ -703,7 +703,7 @@ public void SelectThirdCard(CardLocation loc) { m_thirdSelector = new CardSelector(loc); } - + public void SelectMaterials(ClientCard card) { m_materialSelector = new CardSelector(card); From 124f7da2df6495ea42675eefeb890f00db30538d Mon Sep 17 00:00:00 2001 From: Wind2009-Louse Date: Fri, 6 Apr 2018 10:21:13 +0800 Subject: [PATCH 25/68] Update TrickstarExecutor.cs Edit Eater_eff --- Game/AI/Decks/TrickstarExecutor.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Game/AI/Decks/TrickstarExecutor.cs b/Game/AI/Decks/TrickstarExecutor.cs index 92ee17fa..9648035f 100644 --- a/Game/AI/Decks/TrickstarExecutor.cs +++ b/Game/AI/Decks/TrickstarExecutor.cs @@ -580,9 +580,8 @@ public bool Eater_ss() public bool Eater_eff() { - if (Enemy.BattlingMonster.HasPosition(CardPosition.FaceDown)) return true; - if (Enemy.BattlingMonster.HasPosition(CardPosition.Attack) && (Bot.BattlingMonster.Attack - Enemy.BattlingMonster.GetDefensePower() >= Enemy.LifePoints)) return true; - return (Bot.BattlingMonster.Attack <= (Enemy.BattlingMonster.GetDefensePower() * 2)); + if (Enemy.BattlingMonster.HasPosition(CardPosition.Attack) && (Bot.BattlingMonster.Attack - Enemy.BattlingMonster.GetDefensePower() >= Enemy.LifePoints)) return false; + return true; } public bool Red_ss() From 98f7c3e1a1a9d30a3d0598207f9b4713d6092148 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Fri, 6 Apr 2018 12:11:42 +0800 Subject: [PATCH 26/68] update OnBattle --- Game/AI/DefaultExecutor.cs | 29 ++++++++++++++++++- Game/AI/Executor.cs | 57 ++++++++++++-------------------------- Game/ClientCard.cs | 1 + Game/GameAI.cs | 46 +++++++++++++++++++++++++++++- 4 files changed, 92 insertions(+), 41 deletions(-) diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index 5940b597..7d7aa309 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -45,13 +45,40 @@ protected DefaultExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, _CardId.ChickenGame, DefaultChickenGame); } + /// + /// Decide which card should the attacker attack. + /// + /// Card that attack. + /// Cards that defend. + /// BattlePhaseAction including the target, or null (in this situation, GameAI will check the next attacker) + public override BattlePhaseAction OnSelectAttackTarget(ClientCard attacker, IList defenders) + { + for (int i = 0; i < defenders.Count; ++i) + { + ClientCard defender = defenders[i]; + + attacker.RealPower = attacker.Attack; + defender.RealPower = defender.GetDefensePower(); + if (!OnPreBattleBetween(attacker, defender)) + continue; + + if (attacker.RealPower > defender.RealPower || (attacker.RealPower >= defender.RealPower && attacker.IsLastAttacker)) + return AI.Attack(attacker, defender); + } + + if (attacker.CanDirectAttack) + return AI.Attack(attacker, null); + + return null; + } + /// /// Decide whether to declare attack between attacker and defender. /// Can be overrided to update the RealPower of attacker for cards like Honest. /// /// Card that attack. /// Card that defend. - /// false if the attack can't be done. + /// false if the attack shouldn't be done. public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender) { if (attacker.RealPower <= 0) diff --git a/Game/AI/Executor.cs b/Game/AI/Executor.cs index 8090c57b..657d11b5 100644 --- a/Game/AI/Executor.cs +++ b/Game/AI/Executor.cs @@ -52,47 +52,26 @@ public virtual bool OnSelectHand() /// A new BattlePhaseAction containing the action to do. public virtual BattlePhaseAction OnBattle(IList attackers, IList defenders) { - if (attackers.Count == 0) - return AI.ToMainPhase2(); - - if (defenders.Count == 0) - { - for (int i = attackers.Count - 1; i >= 0; --i) - { - ClientCard attacker = attackers[i]; - if (attacker.Attack > 0) - return AI.Attack(attacker, null); - } - } - else - { - for (int i = defenders.Count - 1; i >= 0; --i) - { - ClientCard defender = defenders[i]; - for (int j = 0; j < attackers.Count; ++j) - { - ClientCard attacker = attackers[j]; - attacker.RealPower = attacker.Attack; - defender.RealPower = defender.GetDefensePower(); - if (!OnPreBattleBetween(attacker, defender)) - continue; - if (attacker.RealPower > defender.RealPower || (attacker.RealPower >= defender.RealPower && j == attackers.Count - 1)) - return AI.Attack(attacker, defender); - } - } - - for (int i = attackers.Count - 1; i >= 0; --i) - { - ClientCard attacker = attackers[i]; - if (attacker.CanDirectAttack) - return AI.Attack(attacker, null); - } - } + // For overriding + return null; + } - if (!Battle.CanMainPhaseTwo) - return AI.Attack(attackers[0], (defenders.Count == 0) ? null : defenders[0]); + /// + /// Called when the AI has to decide which card to attack first + /// + /// List of monsters that can attcack. + /// List of monsters of enemy. + /// The card to attack first. + public virtual ClientCard OnSelectAttacker(IList attackers, IList defenders) + { + // For overriding + return null; + } - return AI.ToMainPhase2(); + public virtual BattlePhaseAction OnSelectAttackTarget(ClientCard attacker, IList defenders) + { + // Overrided in DefalultExecutor + return null; } public virtual bool OnPreBattleBetween(ClientCard attacker, ClientCard defender) diff --git a/Game/ClientCard.cs b/Game/ClientCard.cs index b80d6a4e..9f8c8062 100644 --- a/Game/ClientCard.cs +++ b/Game/ClientCard.cs @@ -36,6 +36,7 @@ public class ClientCard public bool CanDirectAttack { get; set; } public bool ShouldDirectAttack { get; set; } public bool Attacked { get; set; } + public bool IsLastAttacker { get; set; } public int[] ActionIndex { get; set; } public IDictionary ActionActivateIndex { get; private set; } diff --git a/Game/GameAI.cs b/Game/GameAI.cs index 8ea1c596..4f1778b4 100644 --- a/Game/GameAI.cs +++ b/Game/GameAI.cs @@ -143,13 +143,57 @@ public BattlePhaseAction OnSelectBattleCmd(BattlePhase battle) } } + // Sort the attackers and defenders, make monster with higher attack go first. List attackers = new List(battle.AttackableCards); attackers.Sort(AIFunctions.CompareCardAttack); + attackers.Reverse(); List defenders = new List(Duel.Fields[1].GetMonsters()); defenders.Sort(AIFunctions.CompareDefensePower); + defenders.Reverse(); - return Executor.OnBattle(attackers, defenders); + // Let executor decide which card should attack first. + ClientCard selected = Executor.OnSelectAttacker(attackers, defenders); + if (selected != null && attackers.Contains(selected)) + { + attackers.Remove(selected); + attackers.Insert(0, selected); + } + + // Check for the executor. + BattlePhaseAction result = Executor.OnBattle(attackers, defenders); + if (result != null) + return result; + + if (attackers.Count == 0) + return ToMainPhase2(); + + if (defenders.Count == 0) + { + // Attack with the monster with the lowest attack first + for (int i = attackers.Count - 1; i >= 0; --i) + { + ClientCard attacker = attackers[i]; + if (attacker.Attack > 0) + return Attack(attacker, null); + } + } + else + { + for (int k = 0; k < attackers.Count; ++k) + { + ClientCard attacker = attackers[k]; + attacker.IsLastAttacker = (k == attackers.Count - 1); + result = Executor.OnSelectAttackTarget(attacker, defenders); + if (result != null) + return result; + } + } + + if (!battle.CanMainPhaseTwo) + return Attack(attackers[0], (defenders.Count == 0) ? null : defenders[0]); + + return ToMainPhase2(); } /// From d2925f39ba60ef565dbc8fc0f4c276a0944a8912 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Fri, 6 Apr 2018 13:31:27 +0800 Subject: [PATCH 27/68] add OnSelectBattleReplay --- Game/AI/DefaultExecutor.cs | 15 +++++++++++++++ Game/AI/Executor.cs | 6 ++++++ Game/GameAI.cs | 9 +++++++++ Game/GameBehavior.cs | 7 ++++++- 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index 7d7aa309..001a7511 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -127,6 +127,21 @@ public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender return true; } + public override bool OnSelectBattleReplay() + { + if (Bot.BattlingMonster == null) + return false; + List defenders = new List(Duel.Fields[1].GetMonsters()); + defenders.Sort(AIFunctions.CompareDefensePower); + defenders.Reverse(); + BattlePhaseAction result = OnSelectAttackTarget(Bot.BattlingMonster, defenders); + if (result != null && result.Action == BattlePhaseAction.BattleAction.Attack) + { + return true; + } + return false; + } + /// /// Destroy face-down cards first, in our turn. /// diff --git a/Game/AI/Executor.cs b/Game/AI/Executor.cs index 657d11b5..ecc7a8b7 100644 --- a/Game/AI/Executor.cs +++ b/Game/AI/Executor.cs @@ -153,6 +153,12 @@ public virtual int OnSelectOption(IList options) return -1; } + public virtual bool OnSelectBattleReplay() + { + // Overrided in DefalultExecutor + return false; + } + public void SetMain(MainPhase main) { Main = main; diff --git a/Game/GameAI.cs b/Game/GameAI.cs index 4f1778b4..96a573b5 100644 --- a/Game/GameAI.cs +++ b/Game/GameAI.cs @@ -647,6 +647,15 @@ public bool OnSelectYesNo(int desc) return Executor.OnSelectYesNo(desc); } + /// + /// Called when the AI has to select if to continue attacking when replay. + /// + /// True for yes, false for no. + public bool OnSelectBattleReplay() + { + return Executor.OnSelectBattleReplay(); + } + /// /// Called when the AI has to declare a card. /// diff --git a/Game/GameBehavior.cs b/Game/GameBehavior.cs index ce072baa..132320ea 100644 --- a/Game/GameBehavior.cs +++ b/Game/GameBehavior.cs @@ -1180,7 +1180,12 @@ private void OnSelectTribute(BinaryReader packet) private void OnSelectYesNo(BinaryReader packet) { packet.ReadByte(); // player - int reply = _ai.OnSelectYesNo(packet.ReadInt32()) ? (1) : (0); + int desc = packet.ReadInt32(); + int reply; + if (desc == 30) + reply = _ai.OnSelectBattleReplay() ? 1 : 0; + else + reply = _ai.OnSelectYesNo(desc) ? 1 : 0; Connection.Send(CtosMessage.Response, reply); } From 904b4c576bc592817e3baa7d06364d001c455810 Mon Sep 17 00:00:00 2001 From: handsomekiwi <36762809+handsomekiwi@users.noreply.github.com> Date: Fri, 6 Apr 2018 14:11:07 +0800 Subject: [PATCH 28/68] update LightswornShaddoldinosour and misc (#28) --- Dialogs/BA.zh-TW.json | 78 ++++ Dialogs/kiwi.zh-TW.json | 1 - .../LightswornShaddoldinosourExecutor.cs | 413 ++++++++++-------- Game/AI/Enums/DangerousMonster.cs | 5 +- Game/ClientField.cs | 13 + 5 files changed, 322 insertions(+), 188 deletions(-) create mode 100644 Dialogs/BA.zh-TW.json diff --git a/Dialogs/BA.zh-TW.json b/Dialogs/BA.zh-TW.json new file mode 100644 index 00000000..6acf44e1 --- /dev/null +++ b/Dialogs/BA.zh-TW.json @@ -0,0 +1,78 @@ +{ + "welcome": [ + "真難得有人發現這個。", + "真沒想到你能跟我對戰呢!決鬥者。不過也就到此為止了,接下來由我V.F.D(非常友善的決鬥者)來做你的對手。" + ], + "deckerror": [ + "阿,可能BA又把CBD修壞導致{0}消失了。" + ], + "duelstart": [ + "這只是AI,打贏不要太高興阿。", + "十分致謝233服讓我們有遊戲可以玩,別忘記去拜訪他們。", + "反主流學院請洽NOVA。", + "Wryyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy." + ], + "newturn": [ + "到我的回合了,抽牌!", + "我的回合,抽牌!", + "我抽了一張卡。" + ], + "endturn": [ + "回合结束。", + "我的回合结束了。", + "這樣算是成功的展開嗎......", + "輪到你了。你的下一句是......我要發動灰流麗對吧!" + ], + "directattack": [ + "{0},直接攻擊!", + "{0},直接攻擊對手!", + "{0},没有防守的地方,攻擊!", + "{0},攻擊對手的生命值!", + "{0},直接攻擊對手的生命值!", + "{0},通過直接攻擊打倒對手!", + "{0},使用直接攻擊打倒對手!", + "{0},直接攻擊釋放你的力量吧!", + "我的{0}將會粉碎你的生命值!", + "向對手展示你的力量吧,{0}!", + "你已經無法阻止我了。{0},攻擊!" + ], + "attack": [ + "{0},攻擊這體{1}!", + "{0},消滅這體{1}!", + "{0},打倒{1}!", + "{0},衝向那體{1}!", + "{0},把你的力量释放到{1}上吧!" + ], + "ondirectattack": [ + "可惡......", + "不過是{0}而已!", + "果然我還是太弱了......" + ], + "facedownmonstername": "怪獸", + "activate": [ + "我發動{0}。", + "我使用{0}的效果。", + "我使用{0}的力量。" + ], + "summon": [ + "真是HIGH的最高點!出來吧{0}。", + "出來吧,{0}!", + "出現吧,{0}!", + "我召喚了強大的{0}!", + "我呼喚{0}參加戰鬥!", + "我呼喚出{0}。", + "我召喚{0}。" + ], + "setmonster": [ + "我放置了一體怪獸。", + "我裡側表示放置了一體怪獸。" + ], + "chaining": [ + "看這裡!發動{0}!", + "我使用{0}的力量。", + "很不錯的戰術...但是我拒絕!{0}!", + "真不愧是納粹,竟然能識破我的蓋牌......你說你只是單純的決鬥者?{0},發動!", + "看樣子你忘了我的{0}!", + "你考慮過我有{0}嗎?" + ] +} diff --git a/Dialogs/kiwi.zh-TW.json b/Dialogs/kiwi.zh-TW.json index 7c14faf6..8999310f 100644 --- a/Dialogs/kiwi.zh-TW.json +++ b/Dialogs/kiwi.zh-TW.json @@ -70,7 +70,6 @@ "看這裡!發動{0}!", "我使用{0}的力量。", "很不錯的戰術...但是我拒絕!{0}!", - "真不愧是納粹,竟然能識破我的蓋牌......你說你只是單純的決鬥者?{0},發動!", "看樣子你忘了我的{0}!", "你考慮過我有{0}嗎?" ] diff --git a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs index b19d9f24..e5f68fe4 100644 --- a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs +++ b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs @@ -72,18 +72,20 @@ public class CardId } bool Pillused = false; + bool CrystalWingSynchroDragoneff_used = false; + bool OvertexCoatlseff_used = false; public LightswornShaddoldinosour(GameAI ai, Duel duel) : base(ai, duel) { //counter - + AddExecutor(ExecutorType.SpSummon, CardId.CrystalWingSynchroDragon, CrystalWingSynchroDragonesp); AddExecutor(ExecutorType.Activate, CardId.GhostOgre, Hand_act_eff); AddExecutor(ExecutorType.Activate, CardId.AshBlossom, Hand_act_eff); AddExecutor(ExecutorType.Activate, CardId.MaxxC,MaxxC); //first do AddExecutor(ExecutorType.Activate, CardId.HarpiesFeatherDuster, DefaultHarpiesFeatherDusterFirst); - AddExecutor(ExecutorType.Activate, CardId.infiniteTransience, infiniteTransience); + AddExecutor(ExecutorType.Activate, CardId.infiniteTransience, DefaultBreakthroughSkill); AddExecutor(ExecutorType.Activate, CardId.ThatGrassLooksgreener); AddExecutor(ExecutorType.Summon, CardId.SouleatingOviraptor); AddExecutor(ExecutorType.Activate, CardId.SouleatingOviraptor, SouleatingOviraptoreff); @@ -93,7 +95,7 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.ChargeOfTheLightBrigade, ChargeOfTheLightBrigadeEffect); AddExecutor(ExecutorType.Activate, CardId.FoolishBurial, FoolishBurialEffect); AddExecutor(ExecutorType.Activate, CardId.InterruptedKaijuSlumber, DefaultInterruptedKaijuSlumber); - AddExecutor(ExecutorType.Activate, CardId.ShaddollFusion, ShaddollFusion); + AddExecutor(ExecutorType.Activate, CardId.ShaddollFusion, ShaddollFusioneff); //Reborn AddExecutor(ExecutorType.Activate, CardId.MonsterReborn, RebornEffect); //Normal Summon @@ -113,27 +115,29 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) //Sp Summon AddExecutor(ExecutorType.SpSummon, CardId.UltimateConductorTytanno, UltimateConductorTytannosp); AddExecutor(ExecutorType.Activate, CardId.UltimateConductorTytanno, UltimateConductorTytannoeff); - AddExecutor(ExecutorType.Activate, CardId.DoubleEvolutionPill, DoubleEvolutionPill); + AddExecutor(ExecutorType.Activate, CardId.DoubleEvolutionPill, DoubleEvolutionPilleff); AddExecutor(ExecutorType.SpSummon, CardId.MinervaTheExalte); AddExecutor(ExecutorType.Activate, CardId.MinervaTheExalte, MinervaTheExaltedEffect); + AddExecutor(ExecutorType.SpSummon, CardId.GamecieltheSeaTurtleKaiju, DefaultKaijuSpsummon); //activate - AddExecutor(ExecutorType.Activate , CardId.GlowUpBulb,GlowUpBulb); + AddExecutor(ExecutorType.SpSummon , CardId.GlowUpBulb,GlowUpBulbeff); //activate chain - AddExecutor(ExecutorType.Activate, CardId.OvertexCoatls); + AddExecutor(ExecutorType.Activate, CardId.OvertexCoatls, OvertexCoatlseff); AddExecutor(ExecutorType.Activate, CardId.ShaddollBeast); AddExecutor(ExecutorType.Activate, CardId.ShaddollFalco, ShaddollFalcoeff); AddExecutor(ExecutorType.Activate, CardId.ShaddollSquamata, ShaddollSquamataeff); AddExecutor(ExecutorType.Activate, CardId.ShaddollDragon, ShaddollDragoneff); - AddExecutor(ExecutorType.Activate, CardId.ShaddollHedgehog); + AddExecutor(ExecutorType.Activate, CardId.ShaddollHedgehog, ShaddollHedgehogeff); AddExecutor(ExecutorType.Activate, CardId.GiantRex); AddExecutor(ExecutorType.Activate, CardId.ElShaddollConstruct); AddExecutor(ExecutorType.Activate, CardId.ElShaddollGrysra); - AddExecutor(ExecutorType.Activate, CardId.ElShaddollShekhinaga); + AddExecutor(ExecutorType.Activate, CardId.ElShaddollShekhinaga, ElShaddollShekhinagaeff); AddExecutor(ExecutorType.Activate, CardId.ElShaddollWinda); + AddExecutor(ExecutorType.Activate, CardId.CrystalWingSynchroDragon, CrystalWingSynchroDragoneff); AddExecutor(ExecutorType.Activate, CardId.TG_WonderMagician); //spellset AddExecutor(ExecutorType.SpellSet, CardId.MonsterReborn, spellset); @@ -215,12 +219,66 @@ public int[] Useless_List() }; } - private bool UltimateConductorTytannoeff() + public override void OnNewTurn() { - if (Duel.Phase == DuelPhase.Main1 || Duel.Phase == DuelPhase.Main2) + Pillused = false; + OvertexCoatlseff_used = false; + CrystalWingSynchroDragoneff_used = false; + } + + public bool CrystalWingSynchroDragonesp() + { + if (CrystalWingSynchroDragoneff_used) return false; + if (Bot.HasInMonstersZone(CardId.FairyTailSnow) || + Bot.HasInMonstersZone(CardId.Lumina) || + Bot.HasInMonstersZone(CardId.KeeperOfDragonicMagic)|| + Bot.HasInMonstersZone(CardId.SouleatingOviraptor) + ) { AI.SelectCard(new[] + { + CardId.KeeperOfDragonicMagic, + CardId.Lumina, + CardId.FairyTailSnow, + CardId.SouleatingOviraptor, + }); + return true; + } + return false; + } + + public bool CrystalWingSynchroDragoneff() + { + if (Duel.Player == 0) + { + + CrystalWingSynchroDragoneff_used = true; + AI.SelectCard(new[] { CardId.GhostOgre, CardId.GlowUpBulb, CardId.PlaguespreaderZombie, CardId.ShaddollFalco }); + return true; + } + else if (AI.Utils.IsChainTarget(Card) || AI.Utils.GetProblematicEnemySpell() != null) return true; + else if (Duel.Player == 1 && Duel.Phase == DuelPhase.BattleStart && AI.Utils.IsOneEnemyBetterThanValue(1500, true)) + { + if (AI.Utils.IsOneEnemyBetterThanValue(1900, true)) + { + AI.SelectPosition(CardPosition.FaceUpDefence); + } + else { + AI.SelectPosition(CardPosition.FaceUpAttack); + } + return true; + } + return false; + } + + private bool UltimateConductorTytannoeff() + { + + + if (Duel.Phase == DuelPhase.Main1 || Duel.Phase == DuelPhase.Main2) + { + IList targets = new[] { CardId.OvertexCoatls, CardId.ShaddollBeast, CardId.ShaddollSquamata, @@ -229,13 +287,35 @@ private bool UltimateConductorTytannoeff() CardId.GlowUpBulb, CardId.PlaguespreaderZombie, CardId.FairyTailSnow, - }); + CardId.KeeperOfDragonicMagic, + CardId.Raiden, + CardId.Lumina, + CardId.DogorantheMadFlameKaiju, + CardId.GamecieltheSeaTurtleKaiju, + CardId.RadiantheMultidimensionalKaiju, + CardId.GiantRex, + CardId.ShaddollSquamata, + CardId.SouleatingOviraptor, + CardId.Raiden, + CardId.Lumina, + CardId.AshBlossom, + CardId.GhostOgre, + CardId.MaxxC, + }; + if (!Bot.HasInHand(targets)) + { + if (!Bot.HasInMonstersZone(targets)) + { + return false; + } + } + AI.SelectCard(targets); } if (Duel.Phase == DuelPhase.Damage) - return true; - + AI.SelectYesNo(true); return true; } + private bool UltimateConductorTytannosp() { Pillused = true; @@ -247,6 +327,7 @@ private bool UltimateConductorTytannosp() return true; } + private bool KeeperOfDragonicMagic() { if (ActivateDescription == -1) @@ -258,17 +339,22 @@ private bool KeeperOfDragonicMagic() return true; } + private bool MonsterRepos() { if (Card.Id == CardId.ElShaddollConstruct && Card.IsAttack()) return false; return base.DefaultMonsterRepos(); } - public override void OnNewTurn() + + private bool OvertexCoatlseff() { - Pillused = false; + if (OvertexCoatlseff_used == true) + return false; + return true; } - private bool DoubleEvolutionPill() + + private bool DoubleEvolutionPilleff() { if (Pillused == true) return false; Pillused = true; @@ -305,7 +391,37 @@ private bool DoubleEvolutionPill() CardId.UltimateConductorTytanno, }); } - AI.SelectNextCard(new[] { + IList targets2 = new[] { + CardId.GiantRex, + CardId.DogorantheMadFlameKaiju, + CardId.GamecieltheSeaTurtleKaiju, + CardId.RadiantheMultidimensionalKaiju, + CardId.OvertexCoatls, + CardId.SouleatingOviraptor, + CardId.UltimateConductorTytanno, + }; + if (Bot.HasInGraveyard(targets)) + { + AI.SelectNextCard(new[] { + CardId.ShaddollBeast, + CardId.ShaddollDragon, + CardId.KeeperOfDragonicMagic, + CardId.ShaddollSquamata, + CardId.SouleatingOviraptor, + CardId.Raiden, + CardId.Lumina, + CardId.ShaddollHedgehog, + CardId.AshBlossom, + CardId.GhostOgre, + CardId.ShaddollFalco, + CardId.MaxxC, + CardId.PlaguespreaderZombie, + CardId.GlowUpBulb, + CardId.FairyTailSnow, + }); + } + else + AI.SelectNextCard(new[] { CardId.ShaddollBeast, CardId.ShaddollDragon, CardId.KeeperOfDragonicMagic, @@ -345,6 +461,7 @@ private bool ShaddollCoreeff() } return true; } + private bool FairyTailSnow() { @@ -354,132 +471,48 @@ private bool FairyTailSnow() } return false; } + private bool SouleatingOviraptoreff() { - AI.SelectCard(CardId.OvertexCoatls); - AI.SelectYesNo(false); + if (!OvertexCoatlseff_used) + { + AI.SelectCard(CardId.OvertexCoatls); + AI.SelectYesNo(false); + } + else + { + AI.SelectCard(CardId.UltimateConductorTytanno); + AI.SelectYesNo(true); + } return true; } - private bool GlowUpBulb() + + private bool GlowUpBulbeff() { + if(Bot.HasInMonstersZone(CardId.Lumina)|| + Bot.HasInMonstersZone(CardId.FairyTailSnow)|| + Bot.HasInMonstersZone(CardId.KeeperOfDragonicMagic)|| + Bot.HasInMonstersZone(CardId.SouleatingOviraptor) + ) AI.SelectPosition(CardPosition.FaceUpDefence); return true; } - private bool ShaddollFusion() + + private bool ShaddollFusioneff() { if (Enemy.GetMonstersExtraZoneCount() != 0) { - IList materials0 = Bot.Deck; - IList materials1 = Bot.Deck; - IList mats = new List(); - - AI.SelectCard(CardId.ElShaddollConstruct); - - ClientCard mat = null; - foreach (ClientCard card in materials0) - { - if (card.HasAttribute(CardAttribute.Light)) - { - mat = card; - break; - } - } - foreach (ClientCard card in materials1) - { - AI.SelectCard(new[] - { - CardId.ShaddollBeast, - CardId.ShaddollSquamata, - CardId.ShaddollHedgehog, - CardId.ShaddollDragon, - CardId.ShaddollFalco, - }); - } - if (mat != null) - { - mats.Add(mat); - - AI.SelectMaterials(mats); - AI.SelectPosition(CardPosition.FaceUpAttack); - return true; - } - AI.SelectCard(CardId.ElShaddollShekhinaga); - foreach (ClientCard card in materials0) - { - if (card.HasAttribute(CardAttribute.Earth)) - { - mat = card; - break; - } - } - foreach (ClientCard card in materials1) - { - AI.SelectCard(new[] - { - CardId.ShaddollBeast, - CardId.ShaddollSquamata, - CardId.ShaddollHedgehog, - CardId.ShaddollDragon, - CardId.ShaddollFalco, - - }); - } - if (mat != null) - { - mats.Add(mat); - - AI.SelectMaterials(mats); - - AI.SelectPosition(CardPosition.FaceUpAttack); - return true; - } - - AI.SelectCard(CardId.ElShaddollGrysra); - foreach (ClientCard card in materials0) - { - if (card.HasAttribute(CardAttribute.Fire)) - { - mat = card; - break; - } - } - foreach (ClientCard card in materials1) + AI.SelectCard(new[] { - AI.SelectCard(new[] - { - CardId.ShaddollBeast, - CardId.ShaddollSquamata, - CardId.ShaddollHedgehog, - CardId.ShaddollDragon, - CardId.ShaddollFalco, - + CardId.ElShaddollConstruct, + CardId.ElShaddollShekhinaga, + CardId.ElShaddollGrysra, + CardId.ElShaddollWinda }); - } - if (mat != null) - { - mats.Add(mat); - - AI.SelectMaterials(mats); - - AI.SelectPosition(CardPosition.FaceUpAttack); - return true; - } - - AI.SelectCard(CardId.ElShaddollWinda); - foreach (ClientCard card in materials0) - { - if (card.HasAttribute(CardAttribute.Dark)) - { - mat = card; - break; - } - } - foreach (ClientCard card in materials1) - { - AI.SelectCard(new[] + AI.SelectNextCard(new[] { CardId.ShaddollBeast, CardId.ShaddollSquamata, @@ -488,16 +521,8 @@ private bool ShaddollFusion() CardId.ShaddollFalco, }); - } - if (mat != null) - { - mats.Add(mat); - - AI.SelectMaterials(mats); - - AI.SelectPosition(CardPosition.FaceUpAttack); - return true; - } + AI.SelectPosition(CardPosition.FaceUpAttack); + return true; } else { @@ -510,27 +535,6 @@ private bool ShaddollFusion() } - - /* private ClientCard GetAleisterInGrave() - { - foreach (ClientCard card in Enemy.Graveyard) - { - if (card.Id == CardId.AleisterTheInvoker) - { - return card; - } - } - foreach (ClientCard card in Bot.Graveyard) - { - if (card.Id == CardId.AleisterTheInvoker) - { - return card; - } - } - return null; - }*/ - - private bool ShaddollCore() { return Bot.HasInGraveyard(CardId.ShaddollFusion); @@ -577,12 +581,10 @@ private bool RebornEffect() } private bool PotofAvarice() { + return true; } - private bool infiniteTransience() - { - return Duel.LastChainPlayer == 1; - } + private bool MaxxC() { return Duel.Player == 1; @@ -610,17 +612,35 @@ private bool ChargeOfTheLightBrigadeEffect() } private bool SinisterShadowGames() { - if (Card.Location != CardLocation.MonsterZone) - return true; - else - { - AI.SelectCard(new[] + + AI.SelectCard(new[] { CardId.ShaddollBeast, - } + }); + + return true; + } + + private bool ElShaddollShekhinagaeff() + { + if (Card.Location != CardLocation.MonsterZone) + return true; + else + { + if(Duel.LastChainPlayer==1) + { + AI.SelectCard(new[] + { + CardId.ElShaddollConstruct, + CardId.ElShaddollShekhinaga, + CardId.ElShaddollGrysra, + CardId.ElShaddollWinda, + CardId.ShaddollSquamata, + } ); + } } return true; } @@ -644,6 +664,21 @@ private bool ShaddollFalcoeff() } return true; } + private bool ShaddollHedgehogeff() + { + if (Card.Location != CardLocation.MonsterZone) + { + AI.SelectCard(new[] + { + CardId.ShaddollSquamata, + }); + } + else + { + AI.SelectCard(new[] { CardId.ShaddollFusion, CardId.SinisterShadowGames }); + } + return true; + } private bool ShaddollDragoneff() { if (Card.Location == CardLocation.MonsterZone) @@ -664,12 +699,10 @@ private bool ShaddollSquamataeff() if (Card.Location != CardLocation.MonsterZone) { AI.SelectCard(new[] - { + { CardId.ShaddollBeast, - - }); + }); } - else { ClientCard target = AI.Utils.GetBestEnemyMonster(); @@ -677,28 +710,38 @@ private bool ShaddollSquamataeff() } return true; - - - } private bool FoolishBurialEffect() { + if (Bot.GetRemainingCount(CardId.DoubleEvolutionPill, 3) > 0) + { + if (!OvertexCoatlseff_used) + { + AI.SelectCard(new[] + { + CardId.OvertexCoatls, + }); + } + else return false; + } + else + { AI.SelectCard(new[] - { - CardId.OvertexCoatls, - CardId.ShaddollSquamata, - CardId.ShaddollBeast, - CardId.ShaddollCore, - CardId.ShaddollHedgehog, - CardId.ShaddollFalco, - CardId.ShaddollDragon, - CardId.FairyTailSnow, - }); + { + CardId.OvertexCoatls, + CardId.ShaddollSquamata, + CardId.FairyTailSnow, + }); + + } + return true; } + + private bool GoblindberghSummon() { foreach (ClientCard card in Bot.Hand.GetMonsters()) diff --git a/Game/AI/Enums/DangerousMonster.cs b/Game/AI/Enums/DangerousMonster.cs index 4ca9fe40..c4cea308 100644 --- a/Game/AI/Enums/DangerousMonster.cs +++ b/Game/AI/Enums/DangerousMonster.cs @@ -14,6 +14,7 @@ public enum DangerousMonster MetaionTheTimelord = 74530899, KamionTheTimelord = 91712985, LazionTheTimelord = 92435533, - EaterOfMillions = 63845230 - } + EaterOfMillions = 63845230, + ElShaddollConstruct = 20366274, +} } diff --git a/Game/ClientField.cs b/Game/ClientField.cs index 2e37d01f..f7e9b62b 100644 --- a/Game/ClientField.cs +++ b/Game/ClientField.cs @@ -70,6 +70,19 @@ public int GetSpellCountWithoutField() } return count; } + + + public int GetFieldCount() + { + return GetSpellCount() + GetMonsterCount(); + } + + + public int GetFieldHandCount() + { + return GetSpellCount() + GetMonsterCount() + GetHandCount(); + } + public bool IsFieldEmpty() { From e85abe26ff9ce0d66e028093a59d530b9a50bd88 Mon Sep 17 00:00:00 2001 From: Wind2009-Louse Date: Fri, 6 Apr 2018 10:21:13 +0800 Subject: [PATCH 29/68] Update TrickstarExecutor.cs Edit Eater_eff --- Game/AI/Decks/TrickstarExecutor.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Game/AI/Decks/TrickstarExecutor.cs b/Game/AI/Decks/TrickstarExecutor.cs index 92ee17fa..9648035f 100644 --- a/Game/AI/Decks/TrickstarExecutor.cs +++ b/Game/AI/Decks/TrickstarExecutor.cs @@ -580,9 +580,8 @@ public bool Eater_ss() public bool Eater_eff() { - if (Enemy.BattlingMonster.HasPosition(CardPosition.FaceDown)) return true; - if (Enemy.BattlingMonster.HasPosition(CardPosition.Attack) && (Bot.BattlingMonster.Attack - Enemy.BattlingMonster.GetDefensePower() >= Enemy.LifePoints)) return true; - return (Bot.BattlingMonster.Attack <= (Enemy.BattlingMonster.GetDefensePower() * 2)); + if (Enemy.BattlingMonster.HasPosition(CardPosition.Attack) && (Bot.BattlingMonster.Attack - Enemy.BattlingMonster.GetDefensePower() >= Enemy.LifePoints)) return false; + return true; } public bool Red_ss() From df8ac9d0599c416348bcfef6f8daf1efa01beec5 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Fri, 6 Apr 2018 15:27:01 +0800 Subject: [PATCH 30/68] fix CRLF --- Game/AI/Decks/DoEveryThingExecutor.cs | 94 +++++++++++++-------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/Game/AI/Decks/DoEveryThingExecutor.cs b/Game/AI/Decks/DoEveryThingExecutor.cs index 13e2f222..b96bcadd 100644 --- a/Game/AI/Decks/DoEveryThingExecutor.cs +++ b/Game/AI/Decks/DoEveryThingExecutor.cs @@ -1,48 +1,48 @@ -using YGOSharp.OCGWrapper.Enums; -using System.Collections.Generic; -using WindBot; -using WindBot.Game; -using WindBot.Game.AI; - -namespace WindBot.Game.AI.Decks -{ - [Deck("Test", "AI_Test", "Test")] - public class DoEverythingExecutor : DefaultExecutor - { - public class CardId - { - public const int LeoWizard = 4392470; - public const int Bunilla = 69380702; - } - - public DoEverythingExecutor(GameAI ai, Duel duel) - : base(ai, duel) - { - AddExecutor(ExecutorType.SpSummon); - AddExecutor(ExecutorType.Activate, DefaultDontChainMyself); - AddExecutor(ExecutorType.SummonOrSet); - AddExecutor(ExecutorType.Repos, DefaultMonsterRepos); - AddExecutor(ExecutorType.SpellSet); - } - - public override IList OnSelectCard(IList cards, int min, int max, int hint, bool cancelable) - { - if (Duel.Phase == DuelPhase.BattleStart) - return null; - - IList selected = new List(); - - // select the last cards - for (int i = 1; i <= max; ++i) - selected.Add(cards[cards.Count-i]); - - return selected; - } - - public override int OnSelectOption(IList options) - { - return Program.Rand.Next(options.Count); - } - - } +using YGOSharp.OCGWrapper.Enums; +using System.Collections.Generic; +using WindBot; +using WindBot.Game; +using WindBot.Game.AI; + +namespace WindBot.Game.AI.Decks +{ + [Deck("Test", "AI_Test", "Test")] + public class DoEverythingExecutor : DefaultExecutor + { + public class CardId + { + public const int LeoWizard = 4392470; + public const int Bunilla = 69380702; + } + + public DoEverythingExecutor(GameAI ai, Duel duel) + : base(ai, duel) + { + AddExecutor(ExecutorType.SpSummon); + AddExecutor(ExecutorType.Activate, DefaultDontChainMyself); + AddExecutor(ExecutorType.SummonOrSet); + AddExecutor(ExecutorType.Repos, DefaultMonsterRepos); + AddExecutor(ExecutorType.SpellSet); + } + + public override IList OnSelectCard(IList cards, int min, int max, int hint, bool cancelable) + { + if (Duel.Phase == DuelPhase.BattleStart) + return null; + + IList selected = new List(); + + // select the last cards + for (int i = 1; i <= max; ++i) + selected.Add(cards[cards.Count-i]); + + return selected; + } + + public override int OnSelectOption(IList options) + { + return Program.Rand.Next(options.Count); + } + + } } \ No newline at end of file From 763d0f9fc8246529715d9ecd851dc6202d462cba Mon Sep 17 00:00:00 2001 From: mercury233 Date: Fri, 6 Apr 2018 15:41:24 +0800 Subject: [PATCH 31/68] fix attack defense monster --- Game/AI/DefaultExecutor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index 001a7511..d9c379b1 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -62,7 +62,7 @@ public override BattlePhaseAction OnSelectAttackTarget(ClientCard attacker, ILis if (!OnPreBattleBetween(attacker, defender)) continue; - if (attacker.RealPower > defender.RealPower || (attacker.RealPower >= defender.RealPower && attacker.IsLastAttacker)) + if (attacker.RealPower > defender.RealPower || (attacker.RealPower >= defender.RealPower && attacker.IsLastAttacker && defender.IsAttack())) return AI.Attack(attacker, defender); } From 42a2cc6b738312ac1fa6324575d91a38a207cb5e Mon Sep 17 00:00:00 2001 From: Wind2009-Louse Date: Fri, 6 Apr 2018 19:17:08 +0800 Subject: [PATCH 32/68] Update 4.1 OCG forbidden list --- Decks/AI_Trickstar.ydk | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Decks/AI_Trickstar.ydk b/Decks/AI_Trickstar.ydk index 1b07d6d5..34c4293d 100644 --- a/Decks/AI_Trickstar.ydk +++ b/Decks/AI_Trickstar.ydk @@ -2,7 +2,6 @@ #main 98169343 98169343 -9929398 61283655 61283655 61283655 @@ -11,20 +10,21 @@ 35199656 14558127 14558127 -14558127 -59438930 59438930 98700941 23434538 23434538 23434538 -67441435 +94145021 63845230 63845230 63845230 18144506 35261759 35261759 +53129443 +53129443 +53129443 73628505 73915051 73915051 @@ -42,18 +42,18 @@ 84749824 #extra 41999284 -3987233 41999284 +3987233 +2857636 50588353 98558751 -74997493 -2857636 -38342335 -99111753 +86221741 31833038 3987233 +99111753 +38342335 50588353 -41999284 9753964 +41999284 34408491 !side From 2d1896c057c06fd1510b4cf8c5191a38f480c43f Mon Sep 17 00:00:00 2001 From: handsomekiwi <36762809+handsomekiwi@users.noreply.github.com> Date: Sat, 7 Apr 2018 21:43:34 +0800 Subject: [PATCH 33/68] add chainburn deck (#31) --- Decks/AI_ChainBurn.ydk | 68 +++ Game/AI/AIFunctions.cs | 3 +- Game/AI/Decks/ChainBurnExecutor.cs | 509 ++++++++++++++++++ .../LightswornShaddoldinosourExecutor.cs | 77 +-- Game/AI/Executor.cs | 5 +- WindBot.csproj | 1 + 6 files changed, 630 insertions(+), 33 deletions(-) create mode 100644 Decks/AI_ChainBurn.ydk create mode 100644 Game/AI/Decks/ChainBurnExecutor.cs diff --git a/Decks/AI_ChainBurn.ydk b/Decks/AI_ChainBurn.ydk new file mode 100644 index 00000000..e5c36081 --- /dev/null +++ b/Decks/AI_ChainBurn.ydk @@ -0,0 +1,68 @@ +#created by ... +#main +41386308 +3549275 +45812361 +45812361 +45812361 +19665973 +19665973 +19665973 +60990740 +60990740 +60990740 +35261759 +35261759 +59750328 +59750328 +98645731 +98645731 +98645731 +91623717 +91623717 +12607053 +12607053 +18252559 +18252559 +18252559 +24068492 +24068492 +24068492 +27053506 +27053506 +27053506 +29843091 +29843091 +29843091 +36361633 +36361633 +36361633 +36468556 +37576645 +37576645 +37576645 +62279055 +62279055 +62279055 +67443336 +67443336 +67443336 +75249652 +75249652 +75249652 +83555666 +98444741 +98444741 +#extra +41999284 +41999284 +41999284 +!side +33508719 +67095270 +67095270 +67095270 +98444741 +100227025 +100227025 +100227025 \ No newline at end of file diff --git a/Game/AI/AIFunctions.cs b/Game/AI/AIFunctions.cs index f0cabf15..54ebb118 100644 --- a/Game/AI/AIFunctions.cs +++ b/Game/AI/AIFunctions.cs @@ -247,7 +247,8 @@ public ClientCard GetBestEnemySpell(bool onlyFaceup = false) foreach (ClientCard ecard in spells) { - if (ecard.IsFaceup() && ecard.HasType(CardType.Continuous)) + if (ecard.IsFaceup() && ecard.HasType(CardType.Continuous)|| + ecard.IsFaceup() && ecard.HasType(CardType.Field)) return ecard; } diff --git a/Game/AI/Decks/ChainBurnExecutor.cs b/Game/AI/Decks/ChainBurnExecutor.cs new file mode 100644 index 00000000..6d7b6236 --- /dev/null +++ b/Game/AI/Decks/ChainBurnExecutor.cs @@ -0,0 +1,509 @@ +using YGOSharp.OCGWrapper.Enums; +using System.Collections.Generic; +using WindBot; +using WindBot.Game; +using WindBot.Game.AI; + +namespace WindBot.Game.AI.Decks +{ + [Deck("ChainBurn", "AI_ChainBurn", "Normal")] + public class ChainBurnExecutor : DefaultExecutor + { + public class CardId + { + public const int SandaionTheTimloard = 100227025; + public const int Mathematician = 41386308; + public const int DiceJar = 3549275; + public const int CardcarD = 45812361; + public const int BattleFader = 19665973; + public const int AbouluteKingBackJack = 60990740; + + public const int PotOfDesires = 35261759; + public const int CardOfDemise = 59750328; + public const int PotOfDuality = 98645731; + public const int ChainStrike = 91623717; + + public const int Waboku = 12607053; + public const int SecretBlast = 18252559; + public const int JustDesserts = 24068492; + public const int SectetBarrel = 27053506; + public const int OjamaTrio = 29843091; + public const int ThreateningRoar = 36361633; + public const int Ceasefire = 36468556; + public const int RecklessGreed = 37576645; + public const int MagicCylinder = 62279055; + public const int BalanceOfJudgment = 67443336; + public const int BlazingMirrorForce = 75249652; + public const int RingOfDestruction = 83555666; + public const int AccuulatedFortune = 98444741; + + public const int Linkuriboh = 41999284; + public const int HarpiesFeatherDuster = 18144506; + } + + public ChainBurnExecutor(GameAI ai, Duel duel) + : base(ai, duel) + { + //first add + AddExecutor(ExecutorType.Activate, CardId.PotOfDesires); + AddExecutor(ExecutorType.Activate, CardId.PotOfDuality, PotOfDualityeff); + //normal summon + AddExecutor(ExecutorType.Summon, CardId.Mathematician); + AddExecutor(ExecutorType.Activate, CardId.Mathematician, Mathematicianeff); + AddExecutor(ExecutorType.MonsterSet, CardId.DiceJar); + AddExecutor(ExecutorType.Activate, CardId.DiceJar); + AddExecutor(ExecutorType.Summon, CardId.AbouluteKingBackJack, AbouluteKingBackJacksummon); + AddExecutor(ExecutorType.MonsterSet, CardId.AbouluteKingBackJack); + AddExecutor(ExecutorType.Activate, CardId.AbouluteKingBackJack, AbouluteKingBackJackeff); + AddExecutor(ExecutorType.Summon, CardId.CardcarD); + AddExecutor(ExecutorType.Summon, CardId.SandaionTheTimloard, SandaionTheTimloard_summon); + AddExecutor(ExecutorType.Activate, CardId.SandaionTheTimloard, SandaionTheTimloardeff); + // Set traps + AddExecutor(ExecutorType.SpellSet, CardId.Waboku); + AddExecutor(ExecutorType.SpellSet, CardId.ThreateningRoar); + AddExecutor(ExecutorType.SpellSet, CardId.BlazingMirrorForce); + AddExecutor(ExecutorType.SpellSet, BrunSpellSet); + //afer set + AddExecutor(ExecutorType.Activate, CardId.CardcarD); + AddExecutor(ExecutorType.Activate, CardId.CardOfDemise, CardOfDemiseeff); + //activate trap + AddExecutor(ExecutorType.Activate, CardId.BalanceOfJudgment, BalanceOfJudgmenteff); + AddExecutor(ExecutorType.Activate, CardId.AccuulatedFortune); + AddExecutor(ExecutorType.Activate, CardId.ChainStrike, ChainStrikeeff); + //battle + + AddExecutor(ExecutorType.Activate, CardId.ThreateningRoar, ThreateningRoareff); + AddExecutor(ExecutorType.Activate, CardId.Waboku, Wabokueff); + AddExecutor(ExecutorType.Activate, CardId.BattleFader, BattleFadereff); + AddExecutor(ExecutorType.Activate, CardId.MagicCylinder, MagicCylindereff); + AddExecutor(ExecutorType.Activate, CardId.BlazingMirrorForce, BlazingMirrorForceeff); + AddExecutor(ExecutorType.Activate, CardId.RingOfDestruction, Ring_act); + //chain + AddExecutor(ExecutorType.Activate, CardId.JustDesserts, JustDessertseff); + AddExecutor(ExecutorType.Activate, CardId.OjamaTrio, OjamaTrioeff); + AddExecutor(ExecutorType.Activate, CardId.Ceasefire, Ceasefireeff); + AddExecutor(ExecutorType.Activate, CardId.SecretBlast, SecretBlasteff); + AddExecutor(ExecutorType.Activate, CardId.SectetBarrel, SectetBarreleff); + AddExecutor(ExecutorType.Activate, CardId.RecklessGreed, RecklessGreedeff); + + //sp + AddExecutor(ExecutorType.SpSummon, CardId.Linkuriboh); + AddExecutor(ExecutorType.Activate, CardId.Linkuriboh, Linkuriboheff); + + } + public int[] all_List() + { + return new[] + { + CardId.SandaionTheTimloard, + CardId.Mathematician, + CardId.DiceJar, + CardId.CardcarD, + CardId.BattleFader, + CardId.AbouluteKingBackJack, + + CardId.PotOfDesires, + CardId.CardOfDemise, + CardId.PotOfDuality, + CardId.ChainStrike, + + CardId.Waboku, + CardId.SecretBlast, + CardId.JustDesserts, + CardId.OjamaTrio, + CardId.SectetBarrel, + CardId.ThreateningRoar, + CardId.Ceasefire, + CardId.RecklessGreed, + CardId.MagicCylinder, + CardId.BalanceOfJudgment, + CardId.BlazingMirrorForce, + CardId.RingOfDestruction, + CardId.AccuulatedFortune, + }; + } + public int[] AbouluteKingBackJack_List_1() + { + return new[] { + CardId.BlazingMirrorForce, + CardId.Waboku, + CardId.ThreateningRoar, + CardId.MagicCylinder, + CardId.RingOfDestruction, + CardId.RecklessGreed, + CardId.SecretBlast, + CardId.JustDesserts, + CardId.OjamaTrio, + CardId.SectetBarrel, + CardId.Ceasefire, + CardId.BalanceOfJudgment, + CardId.AccuulatedFortune, + }; + } + public int[] AbouluteKingBackJack_List_2() + { + return new[] { + CardId.SandaionTheTimloard, + CardId.PotOfDesires, + CardId.Mathematician, + CardId.DiceJar, + CardId.CardcarD, + CardId.BattleFader, + CardId.BlazingMirrorForce, + CardId.Waboku, + CardId.ThreateningRoar, + CardId.MagicCylinder, + CardId.RingOfDestruction, + CardId.RecklessGreed, + CardId.SecretBlast, + CardId.JustDesserts, + CardId.OjamaTrio, + CardId.SectetBarrel, + CardId.Ceasefire, + CardId.BalanceOfJudgment, + CardId.AccuulatedFortune, + }; + } + public int[] now_List() + { + return new[] + { + + CardId.Waboku, + CardId.SecretBlast, + CardId.JustDesserts, + CardId.SectetBarrel, + CardId.ThreateningRoar, + CardId.Ceasefire, + CardId.RecklessGreed, + CardId.RingOfDestruction, + + + }; + } + public int[] prevent_list() + { + return new[] + { + CardId.SandaionTheTimloard, + CardId.BattleFader, + + CardId.Waboku, + CardId.ThreateningRoar, + CardId.MagicCylinder, + CardId.BlazingMirrorForce, + CardId.RingOfDestruction, + }; + } + public int GetTotalATK(IList list) + { + int atk = 0; + foreach (ClientCard c in list) + { + if (c == null) continue; + atk += c.Attack; + } + return atk; + } + public bool Has_prevent_list(int id) + { + return (id == CardId.SandaionTheTimloard || + id == CardId.BattleFader || + id == CardId.Waboku || + id == CardId.ThreateningRoar|| + id == CardId.MagicCylinder|| + id == CardId.BlazingMirrorForce|| + id == CardId.RingOfDestruction + ); + } + bool pot_used = false; + int expected_blood = 0; + bool prevent_used = false; + int preventcount = 0; + bool battleprevent = false; + bool OjamaTrioused = false; + bool HasAccuulatedFortune = false; + public override bool OnSelectHand() + { + return true; + } + + public override void OnNewTurn() + { + pot_used = false; + prevent_used = false; + battleprevent = false; + OjamaTrioused = false; + } + public override void OnNewPhase() + { + preventcount = 0; + battleprevent = false; + HasAccuulatedFortune = false; + IList trap = Bot.SpellZone; + IList monster = Bot.MonsterZone; + foreach(ClientCard card in trap) + { + if (card.Id == CardId.AccuulatedFortune) HasAccuulatedFortune = true; + } + foreach (ClientCard card in trap) + { + if (Has_prevent_list(card.Id)) + { + preventcount++; + battleprevent = true; + } + + } + foreach (ClientCard card in monster) + { + if (Has_prevent_list(card.Id)) + { + preventcount++; + battleprevent = true; + } + + } + } + + + private bool must_chain() + { + if (AI.Utils.IsChainTarget(Card)) return true; + foreach (ClientCard card in Enemy.GetSpells()) + { + if (card.Id == CardId.HarpiesFeatherDuster&&card.IsFaceup()) + { + return true; + } + } + return false; + } + private bool BrunSpellSet() + { + return (Card.IsTrap() || Card.HasType(CardType.QuickPlay)) && Bot.GetSpellCountWithoutField() < 5; + } + private bool SandaionTheTimloard_summon() + { + if (!battleprevent) + return true; + return false; + } + private bool AbouluteKingBackJacksummon() + { + return !pot_used; + } + private bool AbouluteKingBackJackeff() + { + if (ActivateDescription == -1) + { + + AI.SelectCard(AbouluteKingBackJack_List_1()); + AI.SelectNextCard(AbouluteKingBackJack_List_2()); + } + + return true; + + } + private bool PotOfDualityeff() + { + pot_used = true; + AI.SelectCard(prevent_list()); + return true; + } + private bool BlazingMirrorForceeff() + { + if (prevent_used) return false; + IList list = new List(); + foreach (ClientCard monster in Enemy.GetMonsters()) + { + list.Add(monster); + } + if (GetTotalATK(list) <= 3000) return false; + return Enemy.HasAttackingMonster() && DefaultUniqueTrap(); + } + private bool ThreateningRoareff() + { + + if (must_chain()) return true; + if (prevent_used||Duel.Phase==DuelPhase.End||Duel.Phase==DuelPhase.Main2) return false; + prevent_used = true; + return DefaultUniqueTrap(); + } + private bool SandaionTheTimloardeff() + { + prevent_used = true; + return true; + } + private bool Wabokueff() + { + if (must_chain()) return true; + if (prevent_used||Duel.Player == 0||Duel.Phase!=DuelPhase.BattleStart) return false; + prevent_used = true; + return DefaultUniqueTrap(); + } + private bool BattleFadereff() + { + if (prevent_used || Duel.Player == 0) return false; + AI.SelectPosition(CardPosition.FaceUpDefence); + prevent_used = true; + return true; + } + private bool MagicCylindereff() + { + if (prevent_used) return false; + if (Bot.LifePoints <= Enemy.BattlingMonster.Attack) return DefaultUniqueTrap(); + if(Enemy.BattlingMonster.Attack>1800) return DefaultUniqueTrap(); + return false; + } + public bool Ring_act() + { + if (Duel.LastChainPlayer == 0 && AI.Utils.GetLastChainCard() != null ) return false; + ClientCard target = AI.Utils.GetProblematicEnemyMonster(); + if (target == null && AI.Utils.IsChainTarget(Card)) + { + target = AI.Utils.GetBestEnemyMonster(); + } + if (target != null) + { + if (Bot.LifePoints <= target.Attack) return false; + AI.SelectCard(target); + return true; + } + return false; + } + private bool RecklessGreedeff() + { + if (Bot.LifePoints <= 2000) return true; + if (Bot.GetHandCount() <1 && Duel.Player==0 && Duel.Phase!=DuelPhase.Standby) return true; + return false; + } + private bool SectetBarreleff() + { + if (must_chain()) return true; + int count = Enemy.GetFieldHandCount(); + if (Enemy.LifePoints < count * 200) return true; + if (count >= 8) return true; + return false; + } + private bool SecretBlasteff() + { + if (must_chain()) return true; + int count = Enemy.GetFieldCount(); + if (Enemy.LifePoints < count * 300) return true; + if (count >= 5) return true; + return false; + + } + private bool OjamaTrioeff() + { + return OjamaTrioused; + } + private bool JustDessertseff() + { + if (must_chain()) return true; + int count = Enemy.GetMonsterCount(); + if (Enemy.LifePoints <= count * 500) return true; + if (Bot.HasInSpellZone(CardId.OjamaTrio) && count <= 2 && count >= 1) + { + OjamaTrioused = true; + return true; + } + if (count >= 4) return true; + return false; + } + private bool ChainStrikeeff() + { + if (must_chain()) return true; + int chain = Duel.CurrentChain.Count; + if (Enemy.LifePoints <= (chain + 1) * 400) return true; + if (Duel.CurrentChain.Count == 4) return true; + return false; + } + private bool Ceasefireeff() + { + if (must_chain()) return true; + int count = Bot.GetMonsterCount() + Enemy.GetMonsterCount(); + if (Enemy.LifePoints <= count * 500) return true; + if (count >= 3) return true; + return false; + } + + private bool BalanceOfJudgmenteff() + { + if (must_chain()) return true; + int count = (Enemy.GetFieldCount() - Bot.GetFieldHandCount()); + if ( count>= 2)return true; + return false; + } + private bool CardOfDemiseeff() + { + if (Bot.GetHandCount() == 1 && Bot.GetSpellCountWithoutField() <= 3) + return true; + return false; + } + private bool Mathematicianeff() + { + if (Card.Location == CardLocation.MonsterZone) + { + AI.SelectCard(CardId.AbouluteKingBackJack); + return true; + } + return true; + + } + private bool DiceJarfacedown() + { + + IList check = Bot.MonsterZone; + foreach (ClientCard card in check) + { + if (card.Id == CardId.DiceJar && card.IsFacedown()) + return true; + } + return false; + } + private bool Ceasefire() + { + if (Bot.GetMonsterCount() >= 3) return true; + if (DiceJarfacedown()) return false; + if ((Bot.GetMonsterCount() + Enemy.GetMonsterCount()) >= 4) return true; + return false; + } + private bool Linkuriboheff() + { + return true; + } + /*private bool SwordsOfRevealingLight() + { + int count = Bot.SpellZone.GetCardCount(CardId.SwordsOfRevealingLight); + return count == 0; + }*/ + + /* + private bool SetInvincibleMonster() + { + foreach (ClientCard card in Bot.GetMonsters()) + { + if (card.Id == CardId.Marshmallon || card.Id == CardId.SpiritReaper) + { + return false; + } + } + return true; + }*/ + + + /* + private bool ReposEverything() + { + if (Card.Id == CardId.ReflectBounder) + return Card.IsDefense(); + if (Card.Id == CardId.FencingFireFerret) + return DefaultMonsterRepos(); + if (Card.IsAttack()) + return true; + return false; + }*/ + } +} \ No newline at end of file diff --git a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs index e5f68fe4..87c33d2f 100644 --- a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs +++ b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs @@ -103,7 +103,7 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.Raiden); AddExecutor(ExecutorType.Summon , CardId.KeeperOfDragonicMagic); - AddExecutor(ExecutorType.Activate, CardId.KeeperOfDragonicMagic, KeeperOfDragonicMagic); + AddExecutor(ExecutorType.Activate, CardId.KeeperOfDragonicMagic, KeeperOfDragonicMagiceff); AddExecutor(ExecutorType.MonsterSet, CardId.ShaddollSquamata); AddExecutor(ExecutorType.MonsterSet, CardId.GlowUpBulb); AddExecutor(ExecutorType.MonsterSet, CardId.ShaddollHedgehog); @@ -123,7 +123,7 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) //activate - AddExecutor(ExecutorType.SpSummon , CardId.GlowUpBulb,GlowUpBulbeff); + AddExecutor(ExecutorType.Activate , CardId.GlowUpBulb,GlowUpBulbeff); //activate chain AddExecutor(ExecutorType.Activate, CardId.OvertexCoatls, OvertexCoatlseff); @@ -218,7 +218,33 @@ public int[] Useless_List() }; } + public override BattlePhaseAction OnSelectAttackTarget(ClientCard attacker, IList defenders) + { + for (int i = 0; i < defenders.Count; ++i) + { + ClientCard defender = defenders[i]; + + attacker.RealPower = attacker.Attack; + defender.RealPower = defender.GetDefensePower(); + if (!OnPreBattleBetween(attacker, defender)) + continue; + + if (attacker.RealPower > defender.RealPower || + (attacker.RealPower >= defender.RealPower && attacker.IsLastAttacker)|| + attacker.Id==CardId.UltimateConductorTytanno + ) + return AI.Attack(attacker, defender); + } + if (attacker.CanDirectAttack) + return AI.Attack(attacker, null); + + return null; + } + public override bool OnSelectHand() + { + return true; + } public override void OnNewTurn() { Pillused = false; @@ -242,9 +268,9 @@ public bool CrystalWingSynchroDragonesp() CardId.FairyTailSnow, CardId.SouleatingOviraptor, }); - return true; + AI.SelectNextCard(CardId.GlowUpBulb); } - return false; + return true; } public bool CrystalWingSynchroDragoneff() @@ -276,7 +302,7 @@ private bool UltimateConductorTytannoeff() { - if (Duel.Phase == DuelPhase.Main1 || Duel.Phase == DuelPhase.Main2) + if (Duel.Phase == DuelPhase.Main1) { IList targets = new[] { CardId.OvertexCoatls, @@ -321,14 +347,14 @@ private bool UltimateConductorTytannosp() Pillused = true; foreach (ClientCard card in Bot.GetMonsters()) { - if (card.Id == Card.Id && card.IsFaceup()) + if (card.Id == CardId.UltimateConductorTytanno && card.IsFaceup()) return false; } return true; } - private bool KeeperOfDragonicMagic() + private bool KeeperOfDragonicMagiceff() { if (ActivateDescription == -1) { @@ -489,22 +515,20 @@ private bool SouleatingOviraptoreff() private bool GlowUpBulbeff() { - if(Bot.HasInMonstersZone(CardId.Lumina)|| + /*if(Bot.HasInMonstersZone(CardId.Lumina)|| Bot.HasInMonstersZone(CardId.FairyTailSnow)|| Bot.HasInMonstersZone(CardId.KeeperOfDragonicMagic)|| Bot.HasInMonstersZone(CardId.SouleatingOviraptor) - ) + )*/ AI.SelectPosition(CardPosition.FaceUpDefence); return true; } private bool ShaddollFusioneff() { - - if (Enemy.GetMonstersExtraZoneCount() != 0) + + if(Enemy.GetMonstersExtraZoneCount()>0) { - - AI.SelectCard(new[] { CardId.ElShaddollConstruct, @@ -629,7 +653,7 @@ private bool ElShaddollShekhinagaeff() return true; else { - if(Duel.LastChainPlayer==1) + if (DefaultBreakthroughSkill()) { AI.SelectCard(new[] { @@ -641,6 +665,8 @@ private bool ElShaddollShekhinagaeff() } ); } + else + return false; } return true; } @@ -707,6 +733,8 @@ private bool ShaddollSquamataeff() { ClientCard target = AI.Utils.GetBestEnemyMonster(); AI.SelectCard(target); + if (Enemy.GetMonsterCount() == 0) + return false; } return true; @@ -738,10 +766,7 @@ private bool FoolishBurialEffect() return true; } - - - - + private bool GoblindberghSummon() { foreach (ClientCard card in Bot.Hand.GetMonsters()) @@ -751,15 +776,8 @@ private bool GoblindberghSummon() } return false; } - - - - - private bool PerformageTrickClownEffect() - { - AI.SelectPosition(CardPosition.FaceUpDefence); - return true; - } + + public bool Hand_act_eff() { //if (Card.Id == CardId.Urara && Bot.HasInHand(CardId.LockBird) && Bot.HasInSpellZone(CardId.Re)) return false; @@ -804,10 +822,7 @@ private bool MinervaTheExaltedEffect() return true; } } - private bool HonestEffect() - { - return Duel.Phase != DuelPhase.Main1; - } + } } \ No newline at end of file diff --git a/Game/AI/Executor.cs b/Game/AI/Executor.cs index ecc7a8b7..152257b7 100644 --- a/Game/AI/Executor.cs +++ b/Game/AI/Executor.cs @@ -89,7 +89,10 @@ public virtual void OnChainEnd() { } - + public virtual void OnNewPhase() + { + // Some AI need do something on new phase + } public virtual void OnNewTurn() { // Some AI need do something on new turn diff --git a/WindBot.csproj b/WindBot.csproj index 1f5d4801..5393904b 100644 --- a/WindBot.csproj +++ b/WindBot.csproj @@ -76,6 +76,7 @@ + From b997cc31a8d0aec13dae0e05438c6ee1ab56d21f Mon Sep 17 00:00:00 2001 From: mercury233 Date: Sat, 7 Apr 2018 21:46:08 +0800 Subject: [PATCH 34/68] update Trickstar deck lflist --- Decks/AI_Trickstar.ydk | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Decks/AI_Trickstar.ydk b/Decks/AI_Trickstar.ydk index 1b07d6d5..34c4293d 100644 --- a/Decks/AI_Trickstar.ydk +++ b/Decks/AI_Trickstar.ydk @@ -2,7 +2,6 @@ #main 98169343 98169343 -9929398 61283655 61283655 61283655 @@ -11,20 +10,21 @@ 35199656 14558127 14558127 -14558127 -59438930 59438930 98700941 23434538 23434538 23434538 -67441435 +94145021 63845230 63845230 63845230 18144506 35261759 35261759 +53129443 +53129443 +53129443 73628505 73915051 73915051 @@ -42,18 +42,18 @@ 84749824 #extra 41999284 -3987233 41999284 +3987233 +2857636 50588353 98558751 -74997493 -2857636 -38342335 -99111753 +86221741 31833038 3987233 +99111753 +38342335 50588353 -41999284 9753964 +41999284 34408491 !side From 7a7394ec9a174c9a53a7eb8cdb87d1f04491bed5 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Sat, 7 Apr 2018 22:13:10 +0800 Subject: [PATCH 35/68] update bot list --- bots.json | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/bots.json b/bots.json index 24bb2242..88d4365f 100644 --- a/bots.json +++ b/bots.json @@ -94,6 +94,26 @@ "name": "永远之魂", "deck": "Horus", "dialog": "soul.zh-CN" + }, + { + "name": "奇異果", + "deck": "LightswornShaddoldinosour", + "dialog": "kiwi.zh-TW" + }, + { + "name": "奇異果", + "deck": "LightswornShaddoldinosour", + "dialog": "kiwi.zh-TW" + }, + { + "name": "燃血鬥士", + "deck": "ChainBurn", + "dialog": "kiwi.zh-TW" + }, + { + "name": "燃血鬥士", + "deck": "ChainBurn", + "dialog": "kiwi.zh-TW" } ] } \ No newline at end of file From 318cb4b243f592923fca31476d1a1d7482382df5 Mon Sep 17 00:00:00 2001 From: Wind2009-Louse Date: Sun, 8 Apr 2018 17:17:39 +0800 Subject: [PATCH 36/68] Update TrickstarExecutor.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix Candina's search. トリックスター・マジカローラ won't activate on the first turn. Eater of Millions and Borreload Dragon will attack first, and won't activate when damage is enough. Fix attack order. --- Game/AI/Decks/TrickstarExecutor.cs | 111 ++++++++++++----------------- 1 file changed, 47 insertions(+), 64 deletions(-) diff --git a/Game/AI/Decks/TrickstarExecutor.cs b/Game/AI/Decks/TrickstarExecutor.cs index 9648035f..eb19784d 100644 --- a/Game/AI/Decks/TrickstarExecutor.cs +++ b/Game/AI/Decks/TrickstarExecutor.cs @@ -338,7 +338,7 @@ public bool Sheep_Act() if (Duel.Player == 0) return false; if (Duel.Phase == DuelPhase.End) return true; if (Duel.LastChainPlayer == 1 && (AI.Utils.IsChainTarget(Card) || (AI.Utils.GetLastChainCard().Id == CardId.Feather && !Bot.HasInSpellZone(CardId.Grass)))) return true; - if (Duel.Phase == DuelPhase.BattleStart) + if (Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2) { int total_atk = 0; List enemy_monster = Enemy.GetMonsters(); @@ -618,6 +618,7 @@ public bool Red_ss() red_ss_count += 1; return true; } + if (c.Id == CardId.Pink) return false; if (tosolve_enemy != null) { if (Bot.HasInHand(CardId.White) && c.Attack + c.BaseAttack < tosolve_enemy.Attack) @@ -793,8 +794,8 @@ public bool Yellow_eff() } if (AI.Utils.GetProblematicEnemyMonster() != null) { - int atk = AI.Utils.GetProblematicEnemyMonster().Attack; - if (atk >= 1800 && atk <= 3600 && Bot.GetRemainingCount(CardId.White, 2) > 0 && !Bot.HasInHand(CardId.White)) + int power = AI.Utils.GetProblematicEnemyMonster().GetDefensePower(); + if (power >= 1800 && power <= 3600 && Bot.GetRemainingCount(CardId.White, 2) > 0 && !Bot.HasInHand(CardId.White)) { AI.SelectCard(new[] { @@ -823,7 +824,6 @@ public bool Yellow_eff() return true; } if ((Bot.HasInHand(CardId.Red) || Bot.HasInHand(CardId.Stage) || Bot.HasInHand(CardId.Yellow)) && Bot.GetRemainingCount(CardId.Re,1) > 0) { - Logger.DebugWriteLine("to search reincarnation"); AI.SelectCard(new[] { CardId.Re, @@ -851,26 +851,9 @@ public bool Yellow_eff() public bool White_eff() { + if (Duel.Phase >= DuelPhase.Main2) return false; if (Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2) { - // from blackwing - /* - ClientCard bestMy = Bot.GetMonsters().GetHighestAttackMonster(); - ClientCard bestEnemyATK = Enemy.GetMonsters().GetHighestAttackMonster(); - ClientCard bestEnemyDEF = Enemy.GetMonsters().GetHighestDefenseMonster(); - if (bestMy == null || (bestEnemyATK == null && bestEnemyDEF == null)) - return false; - if (bestEnemyATK != null && bestMy.Attack <= bestEnemyATK.Attack && bestMy.Attack * 2 >= bestEnemyATK.Attack) - { - white_eff_used = true; - return true; - } - if (bestEnemyDEF != null && bestMy.Attack <= bestEnemyDEF.Defense && bestMy.Attack * 2 >= bestEnemyDEF.Defense) - { - white_eff_used = true; - return true; - } - */ if (Bot.BattlingMonster == null || Enemy.BattlingMonster == null || !IsTrickstar(Bot.BattlingMonster.Id) || Bot.BattlingMonster.HasPosition(CardPosition.Defence)) return false; if (Bot.BattlingMonster.Attack <= Enemy.BattlingMonster.RealPower && Bot.BattlingMonster.Attack + Bot.BattlingMonster.BaseAttack >= Enemy.BattlingMonster.RealPower) { @@ -980,6 +963,7 @@ public bool Crown_eff() public bool Ts_reborn() { + if (AI.Utils.IsTurn1OrMain2()) return false; if (Duel.Player == 0 && Enemy.LifePoints <= 1000) { AI.SelectCard(CardId.Pink); @@ -1529,8 +1513,12 @@ public bool Borrel_ss() public bool Borrel_eff() { if (ActivateDescription == -1) { - Logger.DebugWriteLine("borrel's ntr effect"); - return true; + ClientCard enemy_monster = Enemy.BattlingMonster; + if (enemy_monster != null && enemy_monster.HasPosition(CardPosition.Attack)) + { + return (Card.Attack - enemy_monster.Attack < Enemy.LifePoints); + } + else return false; }; ClientCard BestEnemy = AI.Utils.GetBestEnemyMonster(true); ClientCard WorstBot = Bot.GetMonsters().GetLowestAttackMonster(); @@ -1548,9 +1536,6 @@ public bool GraveCall_eff() { if (Duel.LastChainPlayer == 1) { - Logger.DebugWriteLine(AI.Utils.GetLastChainCard().Name.ToString()); - Logger.DebugWriteLine(AI.Utils.GetLastChainCard().IsMonster().ToString()); - Logger.DebugWriteLine(Enemy.HasInGraveyard(AI.Utils.GetLastChainCard().Id).ToString()); if (AI.Utils.GetLastChainCard().IsMonster() && Enemy.HasInGraveyard(AI.Utils.GetLastChainCard().Id)) { GraveCall_id = AI.Utils.GetLastChainCard().Id; @@ -1626,50 +1611,48 @@ public override void OnNewTurn() } } - public override BattlePhaseAction OnBattle(IList attackers, IList defenders) + public override BattlePhaseAction OnSelectAttackTarget(ClientCard attacker, IList defenders) { - if (attackers.Count == 0) - return AI.ToMainPhase2(); - if (defenders.Count == 0) + ClientCard lowestattack = null; + for (int i = defenders.Count - 1; i >= 0; --i) { - for (int i = attackers.Count - 1; i >= 0; --i) - { - ClientCard attacker = attackers[i]; - if (attacker.Attack > 0) - return AI.Attack(attacker, null); - } + ClientCard defender = defenders[i]; + if (defender.HasPosition(CardPosition.Attack) && !defender.IsMonsterDangerous() && (lowestattack == null || defender.Attack < lowestattack.Attack)) lowestattack = defender; } - else + if (lowestattack != null && attacker.Attack - lowestattack.Attack >= Enemy.LifePoints) return AI.Attack(attacker, lowestattack); + for (int i = 0; i < defenders.Count; ++i) { - for (int i = defenders.Count - 1; i >= 0; --i) - { - ClientCard defender = defenders[i]; - for (int j = 0; j < attackers.Count; ++j) - { - ClientCard attacker = attackers[j]; - attacker.RealPower = attacker.Attack; - defender.RealPower = defender.GetDefensePower(); - if (!defender.IsMonsterHasPreventActivationEffectInBattle() && !attacker.IsDisabled()) - { - if ((attacker.Id == CardId.Eater && !defender.HasType(CardType.Token) && GraveCall_id != CardId.Eater) || attacker.Id == CardId.borrel) return AI.Attack(attacker, defender); - } - if (!OnPreBattleBetween(attacker, defender)) - continue; + ClientCard defender = defenders[i]; - if (attacker.RealPower > defender.RealPower || (attacker.RealPower >= defender.RealPower && j == attackers.Count - 1)) - return AI.Attack(attacker, defender); - } - } - for (int i = attackers.Count - 1; i >= 0; --i) + attacker.RealPower = attacker.Attack; + defender.RealPower = defender.GetDefensePower(); + + if (!defender.IsMonsterHasPreventActivationEffectInBattle() && !attacker.IsDisabled()) { - ClientCard attacker = attackers[i]; - if (attacker.CanDirectAttack) - return AI.Attack(attacker, null); + if ((attacker.Id == CardId.Eater && !defender.HasType(CardType.Token) && GraveCall_id != CardId.Eater) || attacker.Id == CardId.borrel) return AI.Attack(attacker, defender); } + + if (!OnPreBattleBetween(attacker, defender)) + continue; + + if (attacker.RealPower > defender.RealPower || (attacker.RealPower >= defender.RealPower && attacker.IsLastAttacker && defender.IsAttack())) + return AI.Attack(attacker, defender); + } + + if (attacker.CanDirectAttack) + return AI.Attack(attacker, null); + + return null; + } + + public override ClientCard OnSelectAttacker(IList attackers, IList defenders) + { + for (int i = 0; i < attackers.Count; ++i) + { + ClientCard attacker = attackers[i]; + if (attacker.Id == CardId.borrel || attacker.Id == CardId.Eater) return attacker; } - if (!Battle.CanMainPhaseTwo) - return AI.Attack(attackers[0], (defenders.Count == 0) ? null : defenders[0]); - return AI.ToMainPhase2(); + return null; } public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender) @@ -1677,7 +1660,7 @@ public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender if (!defender.IsMonsterHasPreventActivationEffectInBattle()) { if (IsTrickstar(attacker.Id) && Bot.HasInHand(CardId.White) && !white_eff_used) - attacker.RealPower = attacker.RealPower * 2; + attacker.RealPower = attacker.RealPower + attacker.Attack; } return base.OnPreBattleBetween(attacker, defender); } From a16c0fbfeb0c8ebbe42a6dd7a1c349e565930498 Mon Sep 17 00:00:00 2001 From: Wind2009-Louse Date: Sun, 8 Apr 2018 21:59:17 +0800 Subject: [PATCH 37/68] Update TrickstarExecutor.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Scapegoat won't be set when another was set. Fix やぶ蛇(Maybe). Trickstar Light Stage will choose card randomly (not from left to right). Eater of Millions won't ss when no place can be use. Trickstar Lycoris's special position. --- Game/AI/Decks/TrickstarExecutor.cs | 116 +++++++++++++++++++++++++---- 1 file changed, 100 insertions(+), 16 deletions(-) diff --git a/Game/AI/Decks/TrickstarExecutor.cs b/Game/AI/Decks/TrickstarExecutor.cs index eb19784d..9433f500 100644 --- a/Game/AI/Decks/TrickstarExecutor.cs +++ b/Game/AI/Decks/TrickstarExecutor.cs @@ -61,7 +61,7 @@ public class CardId public int getLinkMarker(int id) { if (id == CardId.borrel || id == CardId.snake) return 4; - else if (id == CardId.Abyss || id == CardId.Beelze || id == CardId.Exterio || id == CardId.Ultimate) return 5; + else if (id == CardId.Abyss || id == CardId.Beelze || id == CardId.Exterio || id == CardId.Ultimate || id == CardId.Cardian) return 5; else if (id == CardId.unicorn) return 3; else if (id == CardId.Crystal || id == CardId.phoneix || id == CardId.SafeDra || id == CardId.Missus) return 2; return 1; @@ -114,6 +114,7 @@ public TrickstarExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.SpSummon, CardId.snake, Snake_ss); AddExecutor(ExecutorType.SpSummon, CardId.Crystal, Crystal_ss); AddExecutor(ExecutorType.SpSummon, CardId.SafeDra, Safedragon_ss); + AddExecutor(ExecutorType.Activate, CardId.SafeDra, DefaultCompulsoryEvacuationDevice); AddExecutor(ExecutorType.Activate, CardId.Linkuri, Linkuri_eff); AddExecutor(ExecutorType.SpSummon, CardId.Linkuri, Linkuri_ss); AddExecutor(ExecutorType.SpSummon, CardId.unicorn, Unicorn_ss); @@ -123,7 +124,6 @@ public TrickstarExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.Beelze); AddExecutor(ExecutorType.Activate, CardId.Missus, Missus_eff); AddExecutor(ExecutorType.Activate, CardId.Crystal, Crystal_eff); - AddExecutor(ExecutorType.Activate, CardId.SafeDra, DefaultCompulsoryEvacuationDevice); AddExecutor(ExecutorType.Activate, CardId.phoneix, Phoneix_eff); AddExecutor(ExecutorType.Activate, CardId.unicorn, Unicorn_eff); AddExecutor(ExecutorType.Activate, CardId.snake, Snake_eff); @@ -157,7 +157,13 @@ public TrickstarExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Repos, MonsterRepos); AddExecutor(ExecutorType.SummonOrSet, CardId.Red); AddExecutor(ExecutorType.SummonOrSet, CardId.Pink); - AddExecutor(ExecutorType.SpellSet, DefaultSpellSet); + AddExecutor(ExecutorType.SpellSet, SpellSet); + } + + public bool SpellSet() + { + if (Card.Id == CardId.Sheep && Bot.HasInSpellZone(CardId.Sheep)) return false; + return DefaultSpellSet(); } public bool Has_down_arrow(int id) @@ -212,19 +218,50 @@ public int GetTotalATK(IList list) public bool Grass_ss() { - if (Bot.ExtraDeck.Count > 0) + // judge whether can ss from exdeck + bool judge = (Bot.ExtraDeck.Count > 0); + if (Enemy.GetMonstersExtraZoneCount() > 1) judge = false; // exlink + if (Bot.GetMonstersExtraZoneCount() >= 1) { + foreach(ClientCard card in Bot.GetMonstersInExtraZone()) + { + if (getLinkMarker(card.Id) == 5) judge = false; + } + } + // can ss from exdeck + if (judge) + { + bool fornextss = AI.Utils.ChainContainsCard(CardId.Grass); IList ex = Bot.ExtraDeck; ClientCard ex_best = null; foreach (ClientCard ex_card in ex) { - if (ex_best == null || ex_card.Attack > ex_best.Attack) ex_best = ex_card; + if (!fornextss) { + if (ex_best == null || ex_card.Attack > ex_best.Attack) ex_best = ex_card; + } else + { + if (getLinkMarker(ex_card.Id) != 5 && (ex_best == null || ex_card.Attack > ex_best.Attack)) ex_best = ex_card; + } } if (ex_best != null) { AI.SelectCard(ex_best); + return true; } + } + // cannot ss from exdeck + if (Bot.GetRemainingCount(CardId.Ghost,2) > 0) + { + AI.SelectCard(CardId.Ghost); + AI.SelectPosition(CardPosition.FaceUpDefence); return true; } + AI.SelectCard(new[] + { + CardId.White, + CardId.Red, + CardId.Yellow, + CardId.Pink + }); return true; } @@ -264,10 +301,23 @@ public bool Abyss_eff() return false; } + public void RandomSort(List list) { + + int n = list.Count; + while(n-- > 1) + { + int index = Program.Rand.Next(n + 1); + ClientCard temp = list[index]; + list[index] = list[n]; + list[n] = temp; + } + } + public bool Stage_Lock() { if (Card.Location != CardLocation.SpellZone) return false; List spells = Enemy.GetSpells(); + RandomSort(spells); if (spells.Count == 0) return false; foreach (ClientCard card in spells) { @@ -545,6 +595,7 @@ public bool Pink_eff() public bool Eater_ss() { if (AI.Utils.GetProblematicEnemyMonster() == null && Bot.ExtraDeck.Count < 5) return false; + if (Bot.GetMonstersInMainZone().Count >= 5) return false; if (AI.Utils.IsTurn1OrMain2()) return false; AI.SelectPosition(CardPosition.FaceUpAttack); IList targets = new List(); @@ -584,6 +635,32 @@ public bool Eater_eff() return true; } + public void Red_SelectPos(ClientCard return_card = null) + { + int self_power = (Bot.HasInHand(CardId.White) && !white_eff_used) ? 3200 : 1600; + if (Duel.Player == 0) + { + List monster_list = Bot.GetMonsters(); + monster_list.Sort(AIFunctions.CompareCardAttack); + monster_list.Reverse(); + ClientCard self_best = null; + foreach(ClientCard card in monster_list) + { + if (IsTrickstar(card.Id) && card != return_card && card.HasPosition(CardPosition.Attack)) + { + self_best = card; + break; + } + } + if (self_best != null) self_power = (Bot.HasInHand(CardId.White)) ? (self_best.Attack + self_best.RealPower) : self_best.Attack; + + } + ClientCard bestenemy = AI.Utils.GetOneEnemyBetterThanValue(self_power, true); + if (bestenemy != null) AI.SelectPosition(CardPosition.FaceUpDefence); + else AI.SelectPosition(CardPosition.FaceUpAttack); + return; + } + public bool Red_ss() { if (red_ss_count >= 6) return false; @@ -596,6 +673,7 @@ public bool Red_ss() { red_ss_count += 1; AI.SelectCard(m); + Red_SelectPos(); return true; } } @@ -615,6 +693,7 @@ public bool Red_ss() if (c.Attacked) { AI.SelectCard(c); + Red_SelectPos(c); red_ss_count += 1; return true; } @@ -625,12 +704,14 @@ public bool Red_ss() { if (tosolve_enemy.Attack > 3200) AI.SelectPosition(CardPosition.FaceUpDefence); AI.SelectCard(c); + Red_SelectPos(c); red_ss_count += 1; return true; } if (!Bot.HasInHand(CardId.White) && tosolve_enemy.Attack <= 3200 && c.Id == CardId.White) { AI.SelectCard(c); + Red_SelectPos(c); red_ss_count += 1; return true; } @@ -647,6 +728,7 @@ public bool Red_ss() } if (tosolve_enemy.Attack > 1600) AI.SelectPosition(CardPosition.FaceUpDefence); AI.SelectCard(c); + Red_SelectPos(c); red_ss_count += 1; return true; } @@ -658,18 +740,20 @@ public bool Red_ss() { if (Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2) { - if (!Bot.HasInHand(CardId.White) && AI.Utils.IsOneEnemyBetterThanValue(1600, true)) - { - AI.SelectPosition(CardPosition.FaceUpDefence); - } - else if (Bot.HasInHand(CardId.White) && AI.Utils.IsOneEnemyBetterThanValue(3200, true)) - { - AI.SelectPosition(CardPosition.FaceUpDefence); - } if (AI.Utils.GetOneEnemyBetterThanMyBest() != null) { - red_ss_count += 1; - return true; + List self_monster = Bot.GetMonsters(); + self_monster.Sort(AIFunctions.CompareDefensePower); + foreach(ClientCard card in self_monster) + { + if (IsTrickstar(card.Id) && card.Id != CardId.Red) + { + AI.SelectCard(card); + Red_SelectPos(card); + red_ss_count += 1; + return true; + } + } } } } @@ -1570,7 +1654,7 @@ public bool DarkHole_eff() public bool MonsterRepos() { - if (Card.Id == CardId.Eater && Card.IsAttack()) return false; + if (Card.Id == CardId.Eater && Card.HasPosition(CardPosition.Attack)) return false; if (IsTrickstar(Card.Id) && !white_eff_used && Bot.HasInHand(CardId.White) && Card.IsAttack() && Duel.Phase == DuelPhase.Main1) return false; From 896ed57e7bae4ab0eb357f66035de7fc37535148 Mon Sep 17 00:00:00 2001 From: Wind2009-Louse Date: Sun, 8 Apr 2018 17:17:39 +0800 Subject: [PATCH 38/68] Update TrickstarExecutor.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix Candina's search. トリックスター・マジカローラ won't activate on the first turn. Eater of Millions and Borreload Dragon will attack first, and won't activate when damage is enough. Fix attack order. Scapegoat won't be set when another was set. Fix やぶ蛇(Maybe). Trickstar Light Stage will choose card randomly (not from left to right). Eater of Millions won't ss when no place can be use. Trickstar Lycoris's special position. --- Game/AI/Decks/TrickstarExecutor.cs | 227 +++++++++++++++++++---------- 1 file changed, 147 insertions(+), 80 deletions(-) diff --git a/Game/AI/Decks/TrickstarExecutor.cs b/Game/AI/Decks/TrickstarExecutor.cs index 9648035f..9433f500 100644 --- a/Game/AI/Decks/TrickstarExecutor.cs +++ b/Game/AI/Decks/TrickstarExecutor.cs @@ -61,7 +61,7 @@ public class CardId public int getLinkMarker(int id) { if (id == CardId.borrel || id == CardId.snake) return 4; - else if (id == CardId.Abyss || id == CardId.Beelze || id == CardId.Exterio || id == CardId.Ultimate) return 5; + else if (id == CardId.Abyss || id == CardId.Beelze || id == CardId.Exterio || id == CardId.Ultimate || id == CardId.Cardian) return 5; else if (id == CardId.unicorn) return 3; else if (id == CardId.Crystal || id == CardId.phoneix || id == CardId.SafeDra || id == CardId.Missus) return 2; return 1; @@ -114,6 +114,7 @@ public TrickstarExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.SpSummon, CardId.snake, Snake_ss); AddExecutor(ExecutorType.SpSummon, CardId.Crystal, Crystal_ss); AddExecutor(ExecutorType.SpSummon, CardId.SafeDra, Safedragon_ss); + AddExecutor(ExecutorType.Activate, CardId.SafeDra, DefaultCompulsoryEvacuationDevice); AddExecutor(ExecutorType.Activate, CardId.Linkuri, Linkuri_eff); AddExecutor(ExecutorType.SpSummon, CardId.Linkuri, Linkuri_ss); AddExecutor(ExecutorType.SpSummon, CardId.unicorn, Unicorn_ss); @@ -123,7 +124,6 @@ public TrickstarExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.Beelze); AddExecutor(ExecutorType.Activate, CardId.Missus, Missus_eff); AddExecutor(ExecutorType.Activate, CardId.Crystal, Crystal_eff); - AddExecutor(ExecutorType.Activate, CardId.SafeDra, DefaultCompulsoryEvacuationDevice); AddExecutor(ExecutorType.Activate, CardId.phoneix, Phoneix_eff); AddExecutor(ExecutorType.Activate, CardId.unicorn, Unicorn_eff); AddExecutor(ExecutorType.Activate, CardId.snake, Snake_eff); @@ -157,7 +157,13 @@ public TrickstarExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Repos, MonsterRepos); AddExecutor(ExecutorType.SummonOrSet, CardId.Red); AddExecutor(ExecutorType.SummonOrSet, CardId.Pink); - AddExecutor(ExecutorType.SpellSet, DefaultSpellSet); + AddExecutor(ExecutorType.SpellSet, SpellSet); + } + + public bool SpellSet() + { + if (Card.Id == CardId.Sheep && Bot.HasInSpellZone(CardId.Sheep)) return false; + return DefaultSpellSet(); } public bool Has_down_arrow(int id) @@ -212,19 +218,50 @@ public int GetTotalATK(IList list) public bool Grass_ss() { - if (Bot.ExtraDeck.Count > 0) + // judge whether can ss from exdeck + bool judge = (Bot.ExtraDeck.Count > 0); + if (Enemy.GetMonstersExtraZoneCount() > 1) judge = false; // exlink + if (Bot.GetMonstersExtraZoneCount() >= 1) { + foreach(ClientCard card in Bot.GetMonstersInExtraZone()) + { + if (getLinkMarker(card.Id) == 5) judge = false; + } + } + // can ss from exdeck + if (judge) + { + bool fornextss = AI.Utils.ChainContainsCard(CardId.Grass); IList ex = Bot.ExtraDeck; ClientCard ex_best = null; foreach (ClientCard ex_card in ex) { - if (ex_best == null || ex_card.Attack > ex_best.Attack) ex_best = ex_card; + if (!fornextss) { + if (ex_best == null || ex_card.Attack > ex_best.Attack) ex_best = ex_card; + } else + { + if (getLinkMarker(ex_card.Id) != 5 && (ex_best == null || ex_card.Attack > ex_best.Attack)) ex_best = ex_card; + } } if (ex_best != null) { AI.SelectCard(ex_best); + return true; } + } + // cannot ss from exdeck + if (Bot.GetRemainingCount(CardId.Ghost,2) > 0) + { + AI.SelectCard(CardId.Ghost); + AI.SelectPosition(CardPosition.FaceUpDefence); return true; } + AI.SelectCard(new[] + { + CardId.White, + CardId.Red, + CardId.Yellow, + CardId.Pink + }); return true; } @@ -264,10 +301,23 @@ public bool Abyss_eff() return false; } + public void RandomSort(List list) { + + int n = list.Count; + while(n-- > 1) + { + int index = Program.Rand.Next(n + 1); + ClientCard temp = list[index]; + list[index] = list[n]; + list[n] = temp; + } + } + public bool Stage_Lock() { if (Card.Location != CardLocation.SpellZone) return false; List spells = Enemy.GetSpells(); + RandomSort(spells); if (spells.Count == 0) return false; foreach (ClientCard card in spells) { @@ -338,7 +388,7 @@ public bool Sheep_Act() if (Duel.Player == 0) return false; if (Duel.Phase == DuelPhase.End) return true; if (Duel.LastChainPlayer == 1 && (AI.Utils.IsChainTarget(Card) || (AI.Utils.GetLastChainCard().Id == CardId.Feather && !Bot.HasInSpellZone(CardId.Grass)))) return true; - if (Duel.Phase == DuelPhase.BattleStart) + if (Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2) { int total_atk = 0; List enemy_monster = Enemy.GetMonsters(); @@ -545,6 +595,7 @@ public bool Pink_eff() public bool Eater_ss() { if (AI.Utils.GetProblematicEnemyMonster() == null && Bot.ExtraDeck.Count < 5) return false; + if (Bot.GetMonstersInMainZone().Count >= 5) return false; if (AI.Utils.IsTurn1OrMain2()) return false; AI.SelectPosition(CardPosition.FaceUpAttack); IList targets = new List(); @@ -584,6 +635,32 @@ public bool Eater_eff() return true; } + public void Red_SelectPos(ClientCard return_card = null) + { + int self_power = (Bot.HasInHand(CardId.White) && !white_eff_used) ? 3200 : 1600; + if (Duel.Player == 0) + { + List monster_list = Bot.GetMonsters(); + monster_list.Sort(AIFunctions.CompareCardAttack); + monster_list.Reverse(); + ClientCard self_best = null; + foreach(ClientCard card in monster_list) + { + if (IsTrickstar(card.Id) && card != return_card && card.HasPosition(CardPosition.Attack)) + { + self_best = card; + break; + } + } + if (self_best != null) self_power = (Bot.HasInHand(CardId.White)) ? (self_best.Attack + self_best.RealPower) : self_best.Attack; + + } + ClientCard bestenemy = AI.Utils.GetOneEnemyBetterThanValue(self_power, true); + if (bestenemy != null) AI.SelectPosition(CardPosition.FaceUpDefence); + else AI.SelectPosition(CardPosition.FaceUpAttack); + return; + } + public bool Red_ss() { if (red_ss_count >= 6) return false; @@ -596,6 +673,7 @@ public bool Red_ss() { red_ss_count += 1; AI.SelectCard(m); + Red_SelectPos(); return true; } } @@ -615,21 +693,25 @@ public bool Red_ss() if (c.Attacked) { AI.SelectCard(c); + Red_SelectPos(c); red_ss_count += 1; return true; } + if (c.Id == CardId.Pink) return false; if (tosolve_enemy != null) { if (Bot.HasInHand(CardId.White) && c.Attack + c.BaseAttack < tosolve_enemy.Attack) { if (tosolve_enemy.Attack > 3200) AI.SelectPosition(CardPosition.FaceUpDefence); AI.SelectCard(c); + Red_SelectPos(c); red_ss_count += 1; return true; } if (!Bot.HasInHand(CardId.White) && tosolve_enemy.Attack <= 3200 && c.Id == CardId.White) { AI.SelectCard(c); + Red_SelectPos(c); red_ss_count += 1; return true; } @@ -646,6 +728,7 @@ public bool Red_ss() } if (tosolve_enemy.Attack > 1600) AI.SelectPosition(CardPosition.FaceUpDefence); AI.SelectCard(c); + Red_SelectPos(c); red_ss_count += 1; return true; } @@ -657,18 +740,20 @@ public bool Red_ss() { if (Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2) { - if (!Bot.HasInHand(CardId.White) && AI.Utils.IsOneEnemyBetterThanValue(1600, true)) - { - AI.SelectPosition(CardPosition.FaceUpDefence); - } - else if (Bot.HasInHand(CardId.White) && AI.Utils.IsOneEnemyBetterThanValue(3200, true)) - { - AI.SelectPosition(CardPosition.FaceUpDefence); - } if (AI.Utils.GetOneEnemyBetterThanMyBest() != null) { - red_ss_count += 1; - return true; + List self_monster = Bot.GetMonsters(); + self_monster.Sort(AIFunctions.CompareDefensePower); + foreach(ClientCard card in self_monster) + { + if (IsTrickstar(card.Id) && card.Id != CardId.Red) + { + AI.SelectCard(card); + Red_SelectPos(card); + red_ss_count += 1; + return true; + } + } } } } @@ -793,8 +878,8 @@ public bool Yellow_eff() } if (AI.Utils.GetProblematicEnemyMonster() != null) { - int atk = AI.Utils.GetProblematicEnemyMonster().Attack; - if (atk >= 1800 && atk <= 3600 && Bot.GetRemainingCount(CardId.White, 2) > 0 && !Bot.HasInHand(CardId.White)) + int power = AI.Utils.GetProblematicEnemyMonster().GetDefensePower(); + if (power >= 1800 && power <= 3600 && Bot.GetRemainingCount(CardId.White, 2) > 0 && !Bot.HasInHand(CardId.White)) { AI.SelectCard(new[] { @@ -823,7 +908,6 @@ public bool Yellow_eff() return true; } if ((Bot.HasInHand(CardId.Red) || Bot.HasInHand(CardId.Stage) || Bot.HasInHand(CardId.Yellow)) && Bot.GetRemainingCount(CardId.Re,1) > 0) { - Logger.DebugWriteLine("to search reincarnation"); AI.SelectCard(new[] { CardId.Re, @@ -851,26 +935,9 @@ public bool Yellow_eff() public bool White_eff() { + if (Duel.Phase >= DuelPhase.Main2) return false; if (Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2) { - // from blackwing - /* - ClientCard bestMy = Bot.GetMonsters().GetHighestAttackMonster(); - ClientCard bestEnemyATK = Enemy.GetMonsters().GetHighestAttackMonster(); - ClientCard bestEnemyDEF = Enemy.GetMonsters().GetHighestDefenseMonster(); - if (bestMy == null || (bestEnemyATK == null && bestEnemyDEF == null)) - return false; - if (bestEnemyATK != null && bestMy.Attack <= bestEnemyATK.Attack && bestMy.Attack * 2 >= bestEnemyATK.Attack) - { - white_eff_used = true; - return true; - } - if (bestEnemyDEF != null && bestMy.Attack <= bestEnemyDEF.Defense && bestMy.Attack * 2 >= bestEnemyDEF.Defense) - { - white_eff_used = true; - return true; - } - */ if (Bot.BattlingMonster == null || Enemy.BattlingMonster == null || !IsTrickstar(Bot.BattlingMonster.Id) || Bot.BattlingMonster.HasPosition(CardPosition.Defence)) return false; if (Bot.BattlingMonster.Attack <= Enemy.BattlingMonster.RealPower && Bot.BattlingMonster.Attack + Bot.BattlingMonster.BaseAttack >= Enemy.BattlingMonster.RealPower) { @@ -980,6 +1047,7 @@ public bool Crown_eff() public bool Ts_reborn() { + if (AI.Utils.IsTurn1OrMain2()) return false; if (Duel.Player == 0 && Enemy.LifePoints <= 1000) { AI.SelectCard(CardId.Pink); @@ -1529,8 +1597,12 @@ public bool Borrel_ss() public bool Borrel_eff() { if (ActivateDescription == -1) { - Logger.DebugWriteLine("borrel's ntr effect"); - return true; + ClientCard enemy_monster = Enemy.BattlingMonster; + if (enemy_monster != null && enemy_monster.HasPosition(CardPosition.Attack)) + { + return (Card.Attack - enemy_monster.Attack < Enemy.LifePoints); + } + else return false; }; ClientCard BestEnemy = AI.Utils.GetBestEnemyMonster(true); ClientCard WorstBot = Bot.GetMonsters().GetLowestAttackMonster(); @@ -1548,9 +1620,6 @@ public bool GraveCall_eff() { if (Duel.LastChainPlayer == 1) { - Logger.DebugWriteLine(AI.Utils.GetLastChainCard().Name.ToString()); - Logger.DebugWriteLine(AI.Utils.GetLastChainCard().IsMonster().ToString()); - Logger.DebugWriteLine(Enemy.HasInGraveyard(AI.Utils.GetLastChainCard().Id).ToString()); if (AI.Utils.GetLastChainCard().IsMonster() && Enemy.HasInGraveyard(AI.Utils.GetLastChainCard().Id)) { GraveCall_id = AI.Utils.GetLastChainCard().Id; @@ -1585,7 +1654,7 @@ public bool DarkHole_eff() public bool MonsterRepos() { - if (Card.Id == CardId.Eater && Card.IsAttack()) return false; + if (Card.Id == CardId.Eater && Card.HasPosition(CardPosition.Attack)) return false; if (IsTrickstar(Card.Id) && !white_eff_used && Bot.HasInHand(CardId.White) && Card.IsAttack() && Duel.Phase == DuelPhase.Main1) return false; @@ -1626,50 +1695,48 @@ public override void OnNewTurn() } } - public override BattlePhaseAction OnBattle(IList attackers, IList defenders) + public override BattlePhaseAction OnSelectAttackTarget(ClientCard attacker, IList defenders) { - if (attackers.Count == 0) - return AI.ToMainPhase2(); - if (defenders.Count == 0) + ClientCard lowestattack = null; + for (int i = defenders.Count - 1; i >= 0; --i) { - for (int i = attackers.Count - 1; i >= 0; --i) - { - ClientCard attacker = attackers[i]; - if (attacker.Attack > 0) - return AI.Attack(attacker, null); - } + ClientCard defender = defenders[i]; + if (defender.HasPosition(CardPosition.Attack) && !defender.IsMonsterDangerous() && (lowestattack == null || defender.Attack < lowestattack.Attack)) lowestattack = defender; } - else + if (lowestattack != null && attacker.Attack - lowestattack.Attack >= Enemy.LifePoints) return AI.Attack(attacker, lowestattack); + for (int i = 0; i < defenders.Count; ++i) { - for (int i = defenders.Count - 1; i >= 0; --i) - { - ClientCard defender = defenders[i]; - for (int j = 0; j < attackers.Count; ++j) - { - ClientCard attacker = attackers[j]; - attacker.RealPower = attacker.Attack; - defender.RealPower = defender.GetDefensePower(); - if (!defender.IsMonsterHasPreventActivationEffectInBattle() && !attacker.IsDisabled()) - { - if ((attacker.Id == CardId.Eater && !defender.HasType(CardType.Token) && GraveCall_id != CardId.Eater) || attacker.Id == CardId.borrel) return AI.Attack(attacker, defender); - } - if (!OnPreBattleBetween(attacker, defender)) - continue; + ClientCard defender = defenders[i]; - if (attacker.RealPower > defender.RealPower || (attacker.RealPower >= defender.RealPower && j == attackers.Count - 1)) - return AI.Attack(attacker, defender); - } - } - for (int i = attackers.Count - 1; i >= 0; --i) + attacker.RealPower = attacker.Attack; + defender.RealPower = defender.GetDefensePower(); + + if (!defender.IsMonsterHasPreventActivationEffectInBattle() && !attacker.IsDisabled()) { - ClientCard attacker = attackers[i]; - if (attacker.CanDirectAttack) - return AI.Attack(attacker, null); + if ((attacker.Id == CardId.Eater && !defender.HasType(CardType.Token) && GraveCall_id != CardId.Eater) || attacker.Id == CardId.borrel) return AI.Attack(attacker, defender); } + + if (!OnPreBattleBetween(attacker, defender)) + continue; + + if (attacker.RealPower > defender.RealPower || (attacker.RealPower >= defender.RealPower && attacker.IsLastAttacker && defender.IsAttack())) + return AI.Attack(attacker, defender); + } + + if (attacker.CanDirectAttack) + return AI.Attack(attacker, null); + + return null; + } + + public override ClientCard OnSelectAttacker(IList attackers, IList defenders) + { + for (int i = 0; i < attackers.Count; ++i) + { + ClientCard attacker = attackers[i]; + if (attacker.Id == CardId.borrel || attacker.Id == CardId.Eater) return attacker; } - if (!Battle.CanMainPhaseTwo) - return AI.Attack(attackers[0], (defenders.Count == 0) ? null : defenders[0]); - return AI.ToMainPhase2(); + return null; } public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender) @@ -1677,7 +1744,7 @@ public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender if (!defender.IsMonsterHasPreventActivationEffectInBattle()) { if (IsTrickstar(attacker.Id) && Bot.HasInHand(CardId.White) && !white_eff_used) - attacker.RealPower = attacker.RealPower * 2; + attacker.RealPower = attacker.RealPower + attacker.Attack; } return base.OnPreBattleBetween(attacker, defender); } From 987c7ae390da71f35b186756c5f90c4191223138 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Sun, 8 Apr 2018 23:04:15 +0800 Subject: [PATCH 39/68] =?UTF-8?q?fix=20=E3=82=84=E3=81=B6=E8=9B=87=20of=20?= =?UTF-8?q?trickstar=20deck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Game/AI/Decks/TrickstarExecutor.cs | 36 +++++++++++++++++++----------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/Game/AI/Decks/TrickstarExecutor.cs b/Game/AI/Decks/TrickstarExecutor.cs index 9433f500..11867fba 100644 --- a/Game/AI/Decks/TrickstarExecutor.cs +++ b/Game/AI/Decks/TrickstarExecutor.cs @@ -245,23 +245,33 @@ public bool Grass_ss() } if (ex_best != null) { AI.SelectCard(ex_best); - return true; } } - // cannot ss from exdeck - if (Bot.GetRemainingCount(CardId.Ghost,2) > 0) + if (!judge || Duel.CurrentChain.GetCardCount(CardId.Grass) > 1) { - AI.SelectCard(CardId.Ghost); - AI.SelectPosition(CardPosition.FaceUpDefence); - return true; + // cannot ss from exdeck + int[] secondselect = new[] + { + CardId.Ultimate, + CardId.Abyss, + CardId.Cardian, + CardId.Ghost, + CardId.White, + CardId.Red, + CardId.Yellow, + CardId.Pink + }; + if (!judge && Duel.CurrentChain.GetCardCount(CardId.Grass) == 1 && Bot.GetRemainingCount(CardId.Ghost, 2) > 0) + { + AI.SelectCard(CardId.Ghost); + AI.SelectPosition(CardPosition.FaceUpDefence); + } + else + { + AI.SelectNextCard(secondselect); + AI.SelectThirdCard(secondselect); + } } - AI.SelectCard(new[] - { - CardId.White, - CardId.Red, - CardId.Yellow, - CardId.Pink - }); return true; } From 8438970f320c05410ce2a3d28030c7e3e37ccc65 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Sun, 8 Apr 2018 23:21:02 +0800 Subject: [PATCH 40/68] =?UTF-8?q?fix=20=E3=82=84=E3=81=B6=E8=9B=87=20of=20?= =?UTF-8?q?trickstar=20deck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Game/AI/Decks/TrickstarExecutor.cs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Game/AI/Decks/TrickstarExecutor.cs b/Game/AI/Decks/TrickstarExecutor.cs index 11867fba..902388e5 100644 --- a/Game/AI/Decks/TrickstarExecutor.cs +++ b/Game/AI/Decks/TrickstarExecutor.cs @@ -247,11 +247,12 @@ public bool Grass_ss() AI.SelectCard(ex_best); } } - if (!judge || Duel.CurrentChain.GetCardCount(CardId.Grass) > 1) + if (!judge || AI.Utils.ChainContainsCard(CardId.Grass)) { - // cannot ss from exdeck + // cannot ss from exdeck or have more than 1 grass in chain int[] secondselect = new[] { + CardId.borrel, CardId.Ultimate, CardId.Abyss, CardId.Cardian, @@ -261,13 +262,20 @@ public bool Grass_ss() CardId.Yellow, CardId.Pink }; - if (!judge && Duel.CurrentChain.GetCardCount(CardId.Grass) == 1 && Bot.GetRemainingCount(CardId.Ghost, 2) > 0) + if (!AI.Utils.ChainContainsCard(CardId.Grass)) { - AI.SelectCard(CardId.Ghost); - AI.SelectPosition(CardPosition.FaceUpDefence); + if (!judge && Bot.GetRemainingCount(CardId.Ghost, 2) > 0) + { + AI.SelectCard(CardId.Ghost); + AI.SelectPosition(CardPosition.FaceUpDefence); + } + else + AI.SelectCard(secondselect); } else { + if (!judge) + AI.SelectCard(secondselect); AI.SelectNextCard(secondselect); AI.SelectThirdCard(secondselect); } From 77dd48f2e1c4489a5f495373cf3897d9e0e8f4fa Mon Sep 17 00:00:00 2001 From: mercury233 Date: Sun, 8 Apr 2018 23:24:06 +0800 Subject: [PATCH 41/68] update ChainBurn deck by handsomekiwi --- Game/AI/Decks/ChainBurnExecutor.cs | 68 ++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/Game/AI/Decks/ChainBurnExecutor.cs b/Game/AI/Decks/ChainBurnExecutor.cs index 6d7b6236..93615775 100644 --- a/Game/AI/Decks/ChainBurnExecutor.cs +++ b/Game/AI/Decks/ChainBurnExecutor.cs @@ -217,12 +217,16 @@ public bool Has_prevent_list(int id) ); } bool pot_used = false; + bool one_turn_kill = false; int expected_blood = 0; bool prevent_used = false; int preventcount = 0; bool battleprevent = false; bool OjamaTrioused = false; bool HasAccuulatedFortune = false; + int blast_count = 0; + int barrel_count = 0; + int just_count = 0; public override bool OnSelectHand() { return true; @@ -230,10 +234,13 @@ public override bool OnSelectHand() public override void OnNewTurn() { + + pot_used = false; prevent_used = false; battleprevent = false; OjamaTrioused = false; + } public override void OnNewPhase() { @@ -264,6 +271,33 @@ public override void OnNewPhase() } } + expected_blood = 0; + one_turn_kill = false; + blast_count = 0; + barrel_count = 0; + just_count = 0; + IList check = Bot.SpellZone; + foreach (ClientCard card in check) + { + if (card.Id == CardId.SecretBlast) + blast_count++; + break; + } + foreach (ClientCard card in check) + { + if (card.Id == CardId.SectetBarrel) + barrel_count++; + break; + } + foreach (ClientCard card in check) + { + if (card.Id == CardId.JustDesserts) + just_count++; + break; + } + expected_blood = (Enemy.GetMonsterCount() * 500 * just_count + Enemy.GetFieldHandCount() * 200 * barrel_count + Enemy.GetFieldCount() * 300 * blast_count); + if (Enemy.LifePoints <= expected_blood) + one_turn_kill = true; } @@ -319,7 +353,8 @@ private bool BlazingMirrorForceeff() { list.Add(monster); } - if (GetTotalATK(list) <= 3000) return false; + //if (GetTotalATK(list) / 2 >= Bot.LifePoints) return false; + if (GetTotalATK(list) < 3000) return false; return Enemy.HasAttackingMonster() && DefaultUniqueTrap(); } private bool ThreateningRoareff() @@ -374,12 +409,22 @@ public bool Ring_act() } private bool RecklessGreedeff() { + int count = 0; + IList check = Bot.SpellZone; + foreach (ClientCard card in check) + { + if (card.Id == CardId.RecklessGreed) + count++; + break; + } + if (count > 1) return true; if (Bot.LifePoints <= 2000) return true; if (Bot.GetHandCount() <1 && Duel.Player==0 && Duel.Phase!=DuelPhase.Standby) return true; return false; } private bool SectetBarreleff() { + if (one_turn_kill) return true; if (must_chain()) return true; int count = Enemy.GetFieldHandCount(); if (Enemy.LifePoints < count * 200) return true; @@ -388,6 +433,7 @@ private bool SectetBarreleff() } private bool SecretBlasteff() { + if (one_turn_kill) return true; if (must_chain()) return true; int count = Enemy.GetFieldCount(); if (Enemy.LifePoints < count * 300) return true; @@ -401,6 +447,7 @@ private bool OjamaTrioeff() } private bool JustDessertseff() { + if (one_turn_kill) return true; if (must_chain()) return true; int count = Enemy.GetMonsterCount(); if (Enemy.LifePoints <= count * 500) return true; @@ -417,15 +464,7 @@ private bool ChainStrikeeff() if (must_chain()) return true; int chain = Duel.CurrentChain.Count; if (Enemy.LifePoints <= (chain + 1) * 400) return true; - if (Duel.CurrentChain.Count == 4) return true; - return false; - } - private bool Ceasefireeff() - { - if (must_chain()) return true; - int count = Bot.GetMonsterCount() + Enemy.GetMonsterCount(); - if (Enemy.LifePoints <= count * 500) return true; - if (count >= 3) return true; + if (Duel.CurrentChain.Count >= 3) return true; return false; } @@ -460,19 +499,20 @@ private bool DiceJarfacedown() { if (card.Id == CardId.DiceJar && card.IsFacedown()) return true; + break; } return false; } - private bool Ceasefire() + private bool Ceasefireeff() { - if (Bot.GetMonsterCount() >= 3) return true; + if (Enemy.GetMonsterCount() >= 3) return true; if (DiceJarfacedown()) return false; if ((Bot.GetMonsterCount() + Enemy.GetMonsterCount()) >= 4) return true; return false; } private bool Linkuriboheff() - { - return true; + { + return DefaultDontChainMyself(); } /*private bool SwordsOfRevealingLight() { From 0f152da04d8a58d99049e4431853c9a336133559 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Sun, 8 Apr 2018 23:24:24 +0800 Subject: [PATCH 42/68] update LightswornShaddoldinosour deck by handsomekiwi --- .../LightswornShaddoldinosourExecutor.cs | 246 ++++++++++++------ 1 file changed, 162 insertions(+), 84 deletions(-) diff --git a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs index 87c33d2f..1fd80ada 100644 --- a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs +++ b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs @@ -41,7 +41,7 @@ public class CardId public const int HarpiesFeatherDuster = 18144506; public const int DoubleEvolutionPill = 38179121; public const int ShaddollFusion = 44394295; - public const int PotOfAvarice = 67169026; + public const int PotOfAvarice = 67169062; public const int FoolishBurial = 81439173; public const int MonsterReborn = 83764718; public const int ChargeOfTheLightBrigade = 94886282; @@ -71,15 +71,13 @@ public class CardId public const int CrystronNeedlefiber = 50588353; } - bool Pillused = false; - bool CrystalWingSynchroDragoneff_used = false; - bool OvertexCoatlseff_used = false; + public LightswornShaddoldinosour(GameAI ai, Duel duel) : base(ai, duel) { //counter - AddExecutor(ExecutorType.SpSummon, CardId.CrystalWingSynchroDragon, CrystalWingSynchroDragonesp); + AddExecutor(ExecutorType.Activate, CardId.GhostOgre, Hand_act_eff); AddExecutor(ExecutorType.Activate, CardId.AshBlossom, Hand_act_eff); AddExecutor(ExecutorType.Activate, CardId.MaxxC,MaxxC); @@ -90,8 +88,7 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) AddExecutor(ExecutorType.Summon, CardId.SouleatingOviraptor); AddExecutor(ExecutorType.Activate, CardId.SouleatingOviraptor, SouleatingOviraptoreff); AddExecutor(ExecutorType.Activate, CardId.AllureofDarkness, DefaultAllureofDarkness); - AddExecutor(ExecutorType.Activate, CardId.PotOfAvarice, PotofAvarice); - // AddExecutor(ExecutorType.Activate, CardId.HarpiesFeatherDuster); + AddExecutor(ExecutorType.Activate, CardId.PotOfAvarice, PotofAvariceeff); AddExecutor(ExecutorType.Activate, CardId.ChargeOfTheLightBrigade, ChargeOfTheLightBrigadeEffect); AddExecutor(ExecutorType.Activate, CardId.FoolishBurial, FoolishBurialEffect); AddExecutor(ExecutorType.Activate, CardId.InterruptedKaijuSlumber, DefaultInterruptedKaijuSlumber); @@ -101,29 +98,26 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) //Normal Summon AddExecutor(ExecutorType.Summon, CardId.Raiden); AddExecutor(ExecutorType.Activate, CardId.Raiden); - AddExecutor(ExecutorType.Summon , CardId.KeeperOfDragonicMagic); AddExecutor(ExecutorType.Activate, CardId.KeeperOfDragonicMagic, KeeperOfDragonicMagiceff); AddExecutor(ExecutorType.MonsterSet, CardId.ShaddollSquamata); AddExecutor(ExecutorType.MonsterSet, CardId.GlowUpBulb); AddExecutor(ExecutorType.MonsterSet, CardId.ShaddollHedgehog); AddExecutor(ExecutorType.MonsterSet, CardId.ShaddollDragon); - AddExecutor(ExecutorType.Summon, CardId.FairyTailSnow,FairyTailSnow); - AddExecutor(ExecutorType.Activate, CardId.FairyTailSnow, FairyTailSnow); + AddExecutor(ExecutorType.Summon, CardId.FairyTailSnow,FairyTailSnowsummon); + AddExecutor(ExecutorType.Activate, CardId.FairyTailSnow, FairyTailSnoweff); AddExecutor(ExecutorType.Summon, CardId.Lumina); AddExecutor(ExecutorType.Activate, CardId.Lumina); + //activate + AddExecutor(ExecutorType.Activate, CardId.GlowUpBulb, GlowUpBulbeff); //Sp Summon + AddExecutor(ExecutorType.SpSummon, CardId.CrystalWingSynchroDragon, CrystalWingSynchroDragonesp); AddExecutor(ExecutorType.SpSummon, CardId.UltimateConductorTytanno, UltimateConductorTytannosp); AddExecutor(ExecutorType.Activate, CardId.UltimateConductorTytanno, UltimateConductorTytannoeff); AddExecutor(ExecutorType.Activate, CardId.DoubleEvolutionPill, DoubleEvolutionPilleff); AddExecutor(ExecutorType.SpSummon, CardId.MinervaTheExalte); AddExecutor(ExecutorType.Activate, CardId.MinervaTheExalte, MinervaTheExaltedEffect); - AddExecutor(ExecutorType.SpSummon, CardId.GamecieltheSeaTurtleKaiju, DefaultKaijuSpsummon); - - - - //activate - AddExecutor(ExecutorType.Activate , CardId.GlowUpBulb,GlowUpBulbeff); + AddExecutor(ExecutorType.SpSummon, CardId.GamecieltheSeaTurtleKaiju, DefaultKaijuSpsummon); //activate chain AddExecutor(ExecutorType.Activate, CardId.OvertexCoatls, OvertexCoatlseff); @@ -133,7 +127,7 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.ShaddollDragon, ShaddollDragoneff); AddExecutor(ExecutorType.Activate, CardId.ShaddollHedgehog, ShaddollHedgehogeff); AddExecutor(ExecutorType.Activate, CardId.GiantRex); - AddExecutor(ExecutorType.Activate, CardId.ElShaddollConstruct); + AddExecutor(ExecutorType.Activate, CardId.ElShaddollConstruct, ElShaddollConstructeff); AddExecutor(ExecutorType.Activate, CardId.ElShaddollGrysra); AddExecutor(ExecutorType.Activate, CardId.ElShaddollShekhinaga, ElShaddollShekhinagaeff); AddExecutor(ExecutorType.Activate, CardId.ElShaddollWinda); @@ -218,33 +212,11 @@ public int[] Useless_List() }; } - public override BattlePhaseAction OnSelectAttackTarget(ClientCard attacker, IList defenders) - { - for (int i = 0; i < defenders.Count; ++i) - { - ClientCard defender = defenders[i]; - - attacker.RealPower = attacker.Attack; - defender.RealPower = defender.GetDefensePower(); - if (!OnPreBattleBetween(attacker, defender)) - continue; - - if (attacker.RealPower > defender.RealPower || - (attacker.RealPower >= defender.RealPower && attacker.IsLastAttacker)|| - attacker.Id==CardId.UltimateConductorTytanno - ) - return AI.Attack(attacker, defender); - } - - if (attacker.CanDirectAttack) - return AI.Attack(attacker, null); + int Ultimate_ss = 0; + bool Pillused = false; + bool CrystalWingSynchroDragoneff_used = false; + bool OvertexCoatlseff_used = false; - return null; - } - public override bool OnSelectHand() - { - return true; - } public override void OnNewTurn() { Pillused = false; @@ -258,7 +230,8 @@ public bool CrystalWingSynchroDragonesp() if (Bot.HasInMonstersZone(CardId.FairyTailSnow) || Bot.HasInMonstersZone(CardId.Lumina) || Bot.HasInMonstersZone(CardId.KeeperOfDragonicMagic)|| - Bot.HasInMonstersZone(CardId.SouleatingOviraptor) + Bot.HasInMonstersZone(CardId.SouleatingOviraptor)|| + Bot.HasInMonstersZone(CardId.Raiden) ) { AI.SelectCard(new[] @@ -267,6 +240,8 @@ public bool CrystalWingSynchroDragonesp() CardId.Lumina, CardId.FairyTailSnow, CardId.SouleatingOviraptor, + CardId.Raiden, + CardId.GiantRex, }); AI.SelectNextCard(CardId.GlowUpBulb); } @@ -310,6 +285,7 @@ private bool UltimateConductorTytannoeff() CardId.ShaddollSquamata, CardId.ShaddollHedgehog, CardId.ShaddollDragon, + CardId.ShaddollFalco, CardId.GlowUpBulb, CardId.PlaguespreaderZombie, CardId.FairyTailSnow, @@ -319,8 +295,7 @@ private bool UltimateConductorTytannoeff() CardId.DogorantheMadFlameKaiju, CardId.GamecieltheSeaTurtleKaiju, CardId.RadiantheMultidimensionalKaiju, - CardId.GiantRex, - CardId.ShaddollSquamata, + CardId.GiantRex, CardId.SouleatingOviraptor, CardId.Raiden, CardId.Lumina, @@ -328,22 +303,25 @@ private bool UltimateConductorTytannoeff() CardId.GhostOgre, CardId.MaxxC, }; - if (!Bot.HasInHand(targets)) + if (Bot.HasInHand(targets)|| Bot.HasInMonstersZone(targets)) { - if (!Bot.HasInMonstersZone(targets)) - { - return false; - } + AI.SelectCard(targets); + return true; } - AI.SelectCard(targets); + } - if (Duel.Phase == DuelPhase.Damage) + if (Duel.Phase == DuelPhase.BattleStart) + { AI.SelectYesNo(true); - return true; + return true; + } + return false; + } private bool UltimateConductorTytannosp() { + Ultimate_ss++; Pillused = true; foreach (ClientCard card in Bot.GetMonsters()) { @@ -375,13 +353,17 @@ private bool MonsterRepos() private bool OvertexCoatlseff() { - if (OvertexCoatlseff_used == true) - return false; + if (Card.Location == CardLocation.MonsterZone) return false; return true; } private bool DoubleEvolutionPilleff() - { + { + foreach (ClientCard card in Bot.GetMonsters()) + { + if (card.Id == CardId.UltimateConductorTytanno && card.IsFaceup()) + return false; + } if (Pillused == true) return false; Pillused = true; IList targets = new[] { @@ -477,7 +459,7 @@ private bool ShaddollCoreeff() { if (Card.Location == CardLocation.SpellZone) { - if(Enemy.HasAttackingMonster()) + if(Enemy.HasAttackingMonster() && Duel.Player==1 && Duel.Phase==DuelPhase.BattleStart) { AI.SelectPosition(CardPosition.FaceUpDefence); return true; @@ -487,8 +469,13 @@ private bool ShaddollCoreeff() } return true; } + private bool FairyTailSnowsummon() + { - private bool FairyTailSnow() + + return Enemy.GetMonsterCount()>=2; + } + private bool FairyTailSnoweff() { if (Card.Location == CardLocation.MonsterZone) @@ -515,19 +502,31 @@ private bool SouleatingOviraptoreff() private bool GlowUpBulbeff() { - /*if(Bot.HasInMonstersZone(CardId.Lumina)|| - Bot.HasInMonstersZone(CardId.FairyTailSnow)|| - Bot.HasInMonstersZone(CardId.KeeperOfDragonicMagic)|| - Bot.HasInMonstersZone(CardId.SouleatingOviraptor) - )*/ - AI.SelectPosition(CardPosition.FaceUpDefence); - return true; + if (Bot.HasInMonstersZone(CardId.Lumina) || + Bot.HasInMonstersZone(CardId.FairyTailSnow) || + Bot.HasInMonstersZone(CardId.KeeperOfDragonicMagic) || + Bot.HasInMonstersZone(CardId.SouleatingOviraptor) || + Bot.HasInMonstersZone(CardId.GiantRex) || + Bot.HasInMonstersZone(CardId.Raiden) + ) + { + AI.SelectPosition(CardPosition.FaceUpDefence); + return true; + } + return false; } private bool ShaddollFusioneff() { - - if(Enemy.GetMonstersExtraZoneCount()>0) + bool deck_check = false; + List monsters = Enemy.GetMonsters(); + foreach (ClientCard monster in monsters) + { + if (monster.HasType(CardType.Synchro)||monster.HasType(CardType.Fusion)||monster.HasType(CardType.Xyz)) + deck_check = true; + } + + if (deck_check) { AI.SelectCard(new[] { @@ -548,14 +547,31 @@ private bool ShaddollFusioneff() AI.SelectPosition(CardPosition.FaceUpAttack); return true; } - else + if (!Bot.IsFieldEmpty()) return false; + + + foreach (ClientCard monster in Bot.Hand) { - if (!Bot.IsFieldEmpty()) - return false; - AI.SelectCard(CardId.ElShaddollConstruct); - AI.SelectPosition(CardPosition.FaceUpAttack); + if (monster.HasAttribute(CardAttribute.Light)) + { + AI.SelectCard(CardId.ElShaddollConstruct); + AI.SelectPosition(CardPosition.FaceUpAttack); + return true; + } + } - return true; + List material_1 = Bot.GetMonsters(); + foreach (ClientCard monster in material_1) + { + if (monster.HasAttribute(CardAttribute.Light)) + { + AI.SelectCard(CardId.ElShaddollConstruct); + AI.SelectPosition(CardPosition.FaceUpAttack); + return true; + } + + } + return false; } @@ -588,9 +604,12 @@ private bool spellset() } private bool RebornEffect() { - - IList targets = new[] { - CardId.UltimateConductorTytanno, + if(Bot.HasInGraveyard(CardId.UltimateConductorTytanno)&&Ultimate_ss>0) + { + AI.SelectCard(CardId.UltimateConductorTytanno); + return true; + } + IList targets = new[] { CardId.ElShaddollConstruct, CardId.DogorantheMadFlameKaiju, CardId.GamecieltheSeaTurtleKaiju, @@ -603,9 +622,8 @@ private bool RebornEffect() AI.SelectCard(targets); return true; } - private bool PotofAvarice() + private bool PotofAvariceeff() { - return true; } @@ -646,7 +664,14 @@ private bool SinisterShadowGames() return true; } - + private bool ElShaddollConstructeff() + { + if(ActivateDescription==-1) + { + AI.SelectCard(CardId.ShaddollSquamata); + } + return true; + } private bool ElShaddollShekhinagaeff() { if (Card.Location != CardLocation.MonsterZone) @@ -749,15 +774,15 @@ private bool FoolishBurialEffect() { CardId.OvertexCoatls, }); + return true; } - else return false; + return false; } else { AI.SelectCard(new[] - { - CardId.OvertexCoatls, + { CardId.ShaddollSquamata, CardId.FairyTailSnow, }); @@ -822,7 +847,60 @@ private bool MinervaTheExaltedEffect() return true; } } - + + public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender) + { + if (attacker.RealPower <= 0) + return false; + if (attacker.Id == CardId.UltimateConductorTytanno) return true; + if (!attacker.IsMonsterHasPreventActivationEffectInBattle()) + { + if (defender.IsMonsterDangerous() || (defender.IsMonsterInvincible() && defender.IsDefense())) + return false; + + if (defender.Id == _CardId.CrystalWingSynchroDragon && defender.IsAttack() && !defender.IsDisabled() && attacker.Level >= 5) + return false; + + if (defender.Id == _CardId.NumberS39UtopiaTheLightning && defender.IsAttack() && !defender.IsDisabled() && defender.HasXyzMaterial(2, _CardId.Number39Utopia)) + defender.RealPower = 5000; + + if (defender.Id == _CardId.VampireFräulein && !defender.IsDisabled()) + defender.RealPower += (Enemy.LifePoints > 3000) ? 3000 : (Enemy.LifePoints - 100); + + if (defender.Id == _CardId.InjectionFairyLily && !defender.IsDisabled() && Enemy.LifePoints > 2000) + defender.RealPower += 3000; + } + + if (!defender.IsMonsterHasPreventActivationEffectInBattle()) + { + if (attacker.Id == _CardId.NumberS39UtopiaTheLightning && !attacker.IsDisabled() && attacker.HasXyzMaterial(2, _CardId.Number39Utopia)) + attacker.RealPower = 5000; + } + + if (Enemy.HasInMonstersZone(_CardId.DupeFrog, true) && defender.Id != _CardId.DupeFrog) + return false; + + if (Enemy.HasInMonstersZone(_CardId.MaraudingCaptain, true) && defender.Id != _CardId.MaraudingCaptain && defender.Race == (int)CardRace.Warrior) + return false; + + if (defender.Id == _CardId.UltimayaTzolkin && !defender.IsDisabled()) + { + List monsters = Enemy.GetMonsters(); + foreach (ClientCard monster in monsters) + { + if (monster.HasType(CardType.Synchro)) + return false; + } + } + + return true; + } + + public override bool OnSelectHand() + { + return true; + } + } } \ No newline at end of file From dd752335bfa2c20b0e85fa257050dffe74e0a802 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Sun, 8 Apr 2018 23:37:34 +0800 Subject: [PATCH 43/68] fix LightswornShaddoldinosour deck --- .../LightswornShaddoldinosourExecutor.cs | 79 +++++-------------- 1 file changed, 19 insertions(+), 60 deletions(-) diff --git a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs index 1fd80ada..0656c344 100644 --- a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs +++ b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs @@ -111,7 +111,7 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) //activate AddExecutor(ExecutorType.Activate, CardId.GlowUpBulb, GlowUpBulbeff); //Sp Summon - AddExecutor(ExecutorType.SpSummon, CardId.CrystalWingSynchroDragon, CrystalWingSynchroDragonesp); + AddExecutor(ExecutorType.SpSummon, CardId.CrystronNeedlefiber, CrystronNeedlefiberesp); AddExecutor(ExecutorType.SpSummon, CardId.UltimateConductorTytanno, UltimateConductorTytannosp); AddExecutor(ExecutorType.Activate, CardId.UltimateConductorTytanno, UltimateConductorTytannoeff); AddExecutor(ExecutorType.Activate, CardId.DoubleEvolutionPill, DoubleEvolutionPilleff); @@ -131,7 +131,7 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.ElShaddollGrysra); AddExecutor(ExecutorType.Activate, CardId.ElShaddollShekhinaga, ElShaddollShekhinagaeff); AddExecutor(ExecutorType.Activate, CardId.ElShaddollWinda); - AddExecutor(ExecutorType.Activate, CardId.CrystalWingSynchroDragon, CrystalWingSynchroDragoneff); + AddExecutor(ExecutorType.Activate, CardId.CrystronNeedlefiber, CrystronNeedlefibereff); AddExecutor(ExecutorType.Activate, CardId.TG_WonderMagician); //spellset AddExecutor(ExecutorType.SpellSet, CardId.MonsterReborn, spellset); @@ -214,27 +214,20 @@ public int[] Useless_List() } int Ultimate_ss = 0; bool Pillused = false; - bool CrystalWingSynchroDragoneff_used = false; + bool CrystronNeedlefibereff_used = false; bool OvertexCoatlseff_used = false; public override void OnNewTurn() { Pillused = false; OvertexCoatlseff_used = false; - CrystalWingSynchroDragoneff_used = false; + CrystronNeedlefibereff_used = false; } - public bool CrystalWingSynchroDragonesp() + public bool CrystronNeedlefiberesp() { - if (CrystalWingSynchroDragoneff_used) return false; - if (Bot.HasInMonstersZone(CardId.FairyTailSnow) || - Bot.HasInMonstersZone(CardId.Lumina) || - Bot.HasInMonstersZone(CardId.KeeperOfDragonicMagic)|| - Bot.HasInMonstersZone(CardId.SouleatingOviraptor)|| - Bot.HasInMonstersZone(CardId.Raiden) - ) - { - AI.SelectCard(new[] + if (CrystronNeedlefibereff_used) return false; + int[] materials = new[] { CardId.KeeperOfDragonicMagic, CardId.Lumina, @@ -242,18 +235,22 @@ public bool CrystalWingSynchroDragonesp() CardId.SouleatingOviraptor, CardId.Raiden, CardId.GiantRex, - }); - AI.SelectNextCard(CardId.GlowUpBulb); + }; + if (Bot.HasInMonstersZone(materials)) + { + AI.SelectCard(materials); + AI.SelectNextCard(CardId.GlowUpBulb); + return true; } - return true; + return false; } - public bool CrystalWingSynchroDragoneff() + public bool CrystronNeedlefibereff() { if (Duel.Player == 0) { - CrystalWingSynchroDragoneff_used = true; + CrystronNeedlefibereff_used = true; AI.SelectCard(new[] { CardId.GhostOgre, CardId.GlowUpBulb, CardId.PlaguespreaderZombie, CardId.ShaddollFalco }); return true; } @@ -850,50 +847,12 @@ private bool MinervaTheExaltedEffect() public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender) { - if (attacker.RealPower <= 0) - return false; - if (attacker.Id == CardId.UltimateConductorTytanno) return true; - if (!attacker.IsMonsterHasPreventActivationEffectInBattle()) - { - if (defender.IsMonsterDangerous() || (defender.IsMonsterInvincible() && defender.IsDefense())) - return false; - - if (defender.Id == _CardId.CrystalWingSynchroDragon && defender.IsAttack() && !defender.IsDisabled() && attacker.Level >= 5) - return false; - - if (defender.Id == _CardId.NumberS39UtopiaTheLightning && defender.IsAttack() && !defender.IsDisabled() && defender.HasXyzMaterial(2, _CardId.Number39Utopia)) - defender.RealPower = 5000; - - if (defender.Id == _CardId.VampireFräulein && !defender.IsDisabled()) - defender.RealPower += (Enemy.LifePoints > 3000) ? 3000 : (Enemy.LifePoints - 100); - - if (defender.Id == _CardId.InjectionFairyLily && !defender.IsDisabled() && Enemy.LifePoints > 2000) - defender.RealPower += 3000; - } - if (!defender.IsMonsterHasPreventActivationEffectInBattle()) { - if (attacker.Id == _CardId.NumberS39UtopiaTheLightning && !attacker.IsDisabled() && attacker.HasXyzMaterial(2, _CardId.Number39Utopia)) - attacker.RealPower = 5000; - } - - if (Enemy.HasInMonstersZone(_CardId.DupeFrog, true) && defender.Id != _CardId.DupeFrog) - return false; - - if (Enemy.HasInMonstersZone(_CardId.MaraudingCaptain, true) && defender.Id != _CardId.MaraudingCaptain && defender.Race == (int)CardRace.Warrior) - return false; - - if (defender.Id == _CardId.UltimayaTzolkin && !defender.IsDisabled()) - { - List monsters = Enemy.GetMonsters(); - foreach (ClientCard monster in monsters) - { - if (monster.HasType(CardType.Synchro)) - return false; - } + if (attacker.Id == CardId.UltimateConductorTytanno && !attacker.IsDisabled() && defender.IsDefense()) + attacker.RealPower = 9999; } - - return true; + return base.OnPreBattleBetween(attacker, defender); } public override bool OnSelectHand() From 5cf720d187650402bc0345bc2273fce1cda00917 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Mon, 9 Apr 2018 00:22:06 +0800 Subject: [PATCH 44/68] add Executor.OnSelectPosition, make 0 atk monster go defense at default --- Game/AI/DefaultExecutor.cs | 14 ++++++++++++++ Game/AI/Executor.cs | 6 ++++++ Game/GameAI.cs | 16 ++++++++++------ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index d9c379b1..841de111 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -127,6 +127,20 @@ public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender return true; } + /// + /// Called when the AI has to select a card position. + /// + /// Id of the card to position on the field. + /// List of available positions. + /// Selected position, or 0 if no position is set for this card. + public override CardPosition OnSelectPosition(int cardId, IList positions) + { + YGOSharp.OCGWrapper.NamedCard cardData = YGOSharp.OCGWrapper.NamedCard.Get(cardId); + if (cardData.Attack == 0) + return CardPosition.FaceUpDefence; + return base.OnSelectPosition(cardId, positions); + } + public override bool OnSelectBattleReplay() { if (Bot.BattlingMonster == null) diff --git a/Game/AI/Executor.cs b/Game/AI/Executor.cs index 152257b7..5ab66f85 100644 --- a/Game/AI/Executor.cs +++ b/Game/AI/Executor.cs @@ -156,6 +156,12 @@ public virtual int OnSelectOption(IList options) return -1; } + public virtual CardPosition OnSelectPosition(int cardId, IList positions) + { + // Overrided in DefalultExecutor + return 0; + } + public virtual bool OnSelectBattleReplay() { // Overrided in DefalultExecutor diff --git a/Game/GameAI.cs b/Game/GameAI.cs index 96a573b5..78b2a50a 100644 --- a/Game/GameAI.cs +++ b/Game/GameAI.cs @@ -443,13 +443,17 @@ public int OnSelectOption(IList options) /// Selected position. public CardPosition OnSelectPosition(int cardId, IList positions) { + CardPosition selector_selected = m_position; + m_position = CardPosition.FaceUpAttack; + + CardPosition executor_selected = Executor.OnSelectPosition(cardId, positions); + // Selects the selected position if available, the first available otherwise. - if (positions.Contains(m_position)) - { - CardPosition old = m_position; - m_position = CardPosition.FaceUpAttack; - return old; - } + if (positions.Contains(executor_selected)) + return executor_selected; + if (positions.Contains(selector_selected)) + return selector_selected; + return positions[0]; } From b86c5b0e00bb6918b66552115f6405c04cea11a5 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Mon, 9 Apr 2018 00:24:36 +0800 Subject: [PATCH 45/68] minor fix --- Game/AI/DefaultExecutor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index 841de111..360e1202 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -138,7 +138,7 @@ public override CardPosition OnSelectPosition(int cardId, IList po YGOSharp.OCGWrapper.NamedCard cardData = YGOSharp.OCGWrapper.NamedCard.Get(cardId); if (cardData.Attack == 0) return CardPosition.FaceUpDefence; - return base.OnSelectPosition(cardId, positions); + return 0; } public override bool OnSelectBattleReplay() From 84c20c5c88a36fdacc10fcc3860de6b7235530f6 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Mon, 9 Apr 2018 00:38:42 +0800 Subject: [PATCH 46/68] fix OnSelectPosition for unknown card --- Game/AI/DefaultExecutor.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index 360e1202..06ee7893 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -136,8 +136,11 @@ public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender public override CardPosition OnSelectPosition(int cardId, IList positions) { YGOSharp.OCGWrapper.NamedCard cardData = YGOSharp.OCGWrapper.NamedCard.Get(cardId); - if (cardData.Attack == 0) - return CardPosition.FaceUpDefence; + if (cardData != null) + { + if (cardData.Attack == 0) + return CardPosition.FaceUpDefence; + } return 0; } From c55b7a6a80503247a6d002cfae9ddeedee0d07cb Mon Sep 17 00:00:00 2001 From: mercury233 Date: Mon, 9 Apr 2018 11:31:27 +0800 Subject: [PATCH 47/68] update LightswornShaddoldinosour deck by handsomekiwi --- .../LightswornShaddoldinosourExecutor.cs | 465 ++++++++++++------ 1 file changed, 308 insertions(+), 157 deletions(-) diff --git a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs index 0656c344..fb08498d 100644 --- a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs +++ b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs @@ -110,8 +110,17 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.Lumina); //activate AddExecutor(ExecutorType.Activate, CardId.GlowUpBulb, GlowUpBulbeff); + AddExecutor(ExecutorType.Activate, CardId.CrystronNeedlefiber, CrystronNeedlefibereff); + AddExecutor(ExecutorType.Activate, CardId.TG_WonderMagician); + AddExecutor(ExecutorType.Activate, CardId.CoralDragon, CoralDragoneff); + AddExecutor(ExecutorType.Activate, CardId.RedWyvern, RedWyverneff); + AddExecutor(ExecutorType.Activate, CardId.CrystalWingSynchroDragon, CrystalWingSynchroDragoneff); + AddExecutor(ExecutorType.Activate, CardId.BlackRoseMoonlightDragon, BlackRoseMoonlightDragoneff); + AddExecutor(ExecutorType.Activate, CardId.Sdulldeat, Sdulldeateff); + AddExecutor(ExecutorType.Activate, CardId.Michael, Michaeleff); + AddExecutor(ExecutorType.Activate, CardId.ScarlightRedDragon, ScarlightRedDragoneff); //Sp Summon - AddExecutor(ExecutorType.SpSummon, CardId.CrystronNeedlefiber, CrystronNeedlefiberesp); + //AddExecutor(ExecutorType.SpSummon, CardId.CrystronNeedlefiber, CrystronNeedlefibersp); AddExecutor(ExecutorType.SpSummon, CardId.UltimateConductorTytanno, UltimateConductorTytannosp); AddExecutor(ExecutorType.Activate, CardId.UltimateConductorTytanno, UltimateConductorTytannoeff); AddExecutor(ExecutorType.Activate, CardId.DoubleEvolutionPill, DoubleEvolutionPilleff); @@ -128,11 +137,9 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.ShaddollHedgehog, ShaddollHedgehogeff); AddExecutor(ExecutorType.Activate, CardId.GiantRex); AddExecutor(ExecutorType.Activate, CardId.ElShaddollConstruct, ElShaddollConstructeff); - AddExecutor(ExecutorType.Activate, CardId.ElShaddollGrysra); + AddExecutor(ExecutorType.Activate, CardId.ElShaddollGrysra, ElShaddollGrysraeff); AddExecutor(ExecutorType.Activate, CardId.ElShaddollShekhinaga, ElShaddollShekhinagaeff); - AddExecutor(ExecutorType.Activate, CardId.ElShaddollWinda); - AddExecutor(ExecutorType.Activate, CardId.CrystronNeedlefiber, CrystronNeedlefibereff); - AddExecutor(ExecutorType.Activate, CardId.TG_WonderMagician); + AddExecutor(ExecutorType.Activate, CardId.ElShaddollWinda); //spellset AddExecutor(ExecutorType.SpellSet, CardId.MonsterReborn, spellset); AddExecutor(ExecutorType.SpellSet, CardId.PotOfAvarice, spellset); @@ -144,7 +151,7 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) AddExecutor(ExecutorType.SpellSet, CardId.infiniteTransience, SetIsFieldEmpty); //trap activate AddExecutor(ExecutorType.Activate, CardId.LostWind, DefaultBreakthroughSkill); - AddExecutor(ExecutorType.Activate, CardId.SinisterShadowGames, SinisterShadowGames); + AddExecutor(ExecutorType.Activate, CardId.SinisterShadowGames, SinisterShadowGameseff); AddExecutor(ExecutorType.Activate, CardId.ShaddollCore, ShaddollCoreeff); AddExecutor(ExecutorType.Repos, MonsterRepos); } @@ -224,52 +231,7 @@ public override void OnNewTurn() CrystronNeedlefibereff_used = false; } - public bool CrystronNeedlefiberesp() - { - if (CrystronNeedlefibereff_used) return false; - int[] materials = new[] - { - CardId.KeeperOfDragonicMagic, - CardId.Lumina, - CardId.FairyTailSnow, - CardId.SouleatingOviraptor, - CardId.Raiden, - CardId.GiantRex, - }; - if (Bot.HasInMonstersZone(materials)) - { - AI.SelectCard(materials); - AI.SelectNextCard(CardId.GlowUpBulb); - return true; - } - return false; - } - - public bool CrystronNeedlefibereff() - { - if (Duel.Player == 0) - { - - CrystronNeedlefibereff_used = true; - AI.SelectCard(new[] { CardId.GhostOgre, CardId.GlowUpBulb, CardId.PlaguespreaderZombie, CardId.ShaddollFalco }); - return true; - } - else if (AI.Utils.IsChainTarget(Card) || AI.Utils.GetProblematicEnemySpell() != null) return true; - else if (Duel.Player == 1 && Duel.Phase == DuelPhase.BattleStart && AI.Utils.IsOneEnemyBetterThanValue(1500, true)) - { - if (AI.Utils.IsOneEnemyBetterThanValue(1900, true)) - { - AI.SelectPosition(CardPosition.FaceUpDefence); - } - else - { - AI.SelectPosition(CardPosition.FaceUpAttack); - } - return true; - } - return false; - } - + private bool UltimateConductorTytannoeff() { @@ -452,26 +414,15 @@ private bool DoubleEvolutionPilleff() return Enemy.GetMonsterCount() >= 1; } - private bool ShaddollCoreeff() - { - if (Card.Location == CardLocation.SpellZone) - { - if(Enemy.HasAttackingMonster() && Duel.Player==1 && Duel.Phase==DuelPhase.BattleStart) - { - AI.SelectPosition(CardPosition.FaceUpDefence); - return true; - } - - return false; - } - return true; - } + private bool FairyTailSnowsummon() { return Enemy.GetMonsterCount()>=2; } + + private bool FairyTailSnoweff() { @@ -482,6 +433,7 @@ private bool FairyTailSnoweff() return false; } + private bool SouleatingOviraptoreff() { if (!OvertexCoatlseff_used) @@ -511,75 +463,13 @@ private bool GlowUpBulbeff() return true; } return false; - } - - private bool ShaddollFusioneff() - { - bool deck_check = false; - List monsters = Enemy.GetMonsters(); - foreach (ClientCard monster in monsters) - { - if (monster.HasType(CardType.Synchro)||monster.HasType(CardType.Fusion)||monster.HasType(CardType.Xyz)) - deck_check = true; - } - - if (deck_check) - { - AI.SelectCard(new[] - { - CardId.ElShaddollConstruct, - CardId.ElShaddollShekhinaga, - CardId.ElShaddollGrysra, - CardId.ElShaddollWinda - }); - AI.SelectNextCard(new[] - { - CardId.ShaddollBeast, - CardId.ShaddollSquamata, - CardId.ShaddollHedgehog, - CardId.ShaddollDragon, - CardId.ShaddollFalco, - - }); - AI.SelectPosition(CardPosition.FaceUpAttack); - return true; - } - if (!Bot.IsFieldEmpty()) return false; - - - foreach (ClientCard monster in Bot.Hand) - { - if (monster.HasAttribute(CardAttribute.Light)) - { - AI.SelectCard(CardId.ElShaddollConstruct); - AI.SelectPosition(CardPosition.FaceUpAttack); - return true; - } - - } - List material_1 = Bot.GetMonsters(); - foreach (ClientCard monster in material_1) - { - if (monster.HasAttribute(CardAttribute.Light)) - { - AI.SelectCard(CardId.ElShaddollConstruct); - AI.SelectPosition(CardPosition.FaceUpAttack); - return true; - } - - } - return false; - - } - - private bool ShaddollCore() - { - return Bot.HasInGraveyard(CardId.ShaddollFusion); - } + } + + private bool AllureofDarkness() { IList materials = Bot.Hand; - IList check = new List(); + // IList check = new List(); ClientCard mat = null; foreach (ClientCard card in materials) { @@ -649,20 +539,14 @@ private bool ChargeOfTheLightBrigadeEffect() }); return true; } - private bool SinisterShadowGames() - { - AI.SelectCard(new[] - { - CardId.ShaddollBeast, - - }); - - return true; - } + // all Shaddoll private bool ElShaddollConstructeff() { + /* if (Duel.Phase == DuelPhase.Battle) + if (Enemy.BattlingMonster.Attack < 2800) + return false;*/ if(ActivateDescription==-1) { AI.SelectCard(CardId.ShaddollSquamata); @@ -679,11 +563,11 @@ private bool ElShaddollShekhinagaeff() { AI.SelectCard(new[] { - CardId.ElShaddollConstruct, - CardId.ElShaddollShekhinaga, - CardId.ElShaddollGrysra, - CardId.ElShaddollWinda, + CardId.ShaddollBeast, CardId.ShaddollSquamata, + CardId.ShaddollHedgehog, + CardId.ShaddollDragon, + CardId.ShaddollFalco, } ); } @@ -692,6 +576,100 @@ private bool ElShaddollShekhinagaeff() } return true; } + private bool ElShaddollGrysraeff() + { + if (Card.Location != CardLocation.MonsterZone) + return true; + return true; + } + + private bool ShaddollFusioneff() + { + bool deck_check = false; + List monsters = Enemy.GetMonsters(); + foreach (ClientCard monster in monsters) + { + if (monster.HasType(CardType.Synchro) || monster.HasType(CardType.Fusion) || monster.HasType(CardType.Xyz)) + deck_check = true; + } + + if (deck_check) + { + AI.SelectCard(new[] + { + CardId.ElShaddollConstruct, + CardId.ElShaddollShekhinaga, + CardId.ElShaddollGrysra, + CardId.ElShaddollWinda + }); + AI.SelectNextCard(new[] + { + CardId.ShaddollBeast, + CardId.ShaddollSquamata, + CardId.ShaddollHedgehog, + CardId.ShaddollDragon, + CardId.ShaddollFalco, + + }); + AI.SelectPosition(CardPosition.FaceUpAttack); + return true; + } + if (!Bot.IsFieldEmpty()) return false; + + + foreach (ClientCard monster in Bot.Hand) + { + if (monster.HasAttribute(CardAttribute.Light)) + { + AI.SelectCard(CardId.ElShaddollConstruct); + AI.SelectPosition(CardPosition.FaceUpAttack); + return true; + } + + } + List material_1 = Bot.GetMonsters(); + foreach (ClientCard monster in material_1) + { + if (monster.HasAttribute(CardAttribute.Light)) + { + AI.SelectCard(CardId.ElShaddollConstruct); + AI.SelectPosition(CardPosition.FaceUpAttack); + return true; + } + + } + return false; + + } + + private bool SinisterShadowGameseff() + { + + AI.SelectCard(new[] + { + CardId.ShaddollBeast, + + }); + + + return true; + } + + private bool ShaddollCoreeff() + { + if (Card.Location == CardLocation.SpellZone) + { + if (Enemy.HasAttackingMonster() && Duel.Player == 1 && Duel.Phase == DuelPhase.BattleStart) + { + AI.SelectPosition(CardPosition.FaceUpDefence); + return true; + } + + return false; + } + return true; + } + private bool ShaddollFalcoeff() { @@ -789,16 +767,7 @@ private bool FoolishBurialEffect() return true; } - private bool GoblindberghSummon() - { - foreach (ClientCard card in Bot.Hand.GetMonsters()) - { - if (!card.Equals(Card) && card.Level == 4) - return true; - } - return false; - } - + public bool Hand_act_eff() { @@ -806,6 +775,16 @@ public bool Hand_act_eff() if (Card.Id == CardId.GhostOgre && Card.Location == CardLocation.Hand && Bot.HasInMonstersZone(CardId.GhostOgre)) return false; return (Duel.LastChainPlayer == 1); } + //other extra + + private bool Michaeleff() + { + if (Card.Location == CardLocation.Grave) + return true; + if (Bot.LifePoints <= 1000) return false; + return true; + } + private bool MinervaTheExaltedEffect() { if (Card.Location == CardLocation.MonsterZone) @@ -844,14 +823,176 @@ private bool MinervaTheExaltedEffect() return true; } } + public bool CrystronNeedlefibersp() + { + if (Bot.HasInMonstersZone(CardId.ElShaddollConstruct) || + Bot.HasInMonstersZone(CardId.ElShaddollGrysra) || + Bot.HasInMonstersZone(CardId.ElShaddollShekhinaga) || + Bot.HasInMonstersZone(CardId.ElShaddollWinda)) + return false; + + if (CrystronNeedlefibereff_used) return false; + if (Bot.HasInMonstersZone(CardId.CrystronNeedlefiber)) return false; + if (Bot.HasInMonstersZone(CardId.FairyTailSnow) || + Bot.HasInMonstersZone(CardId.Lumina) || + Bot.HasInMonstersZone(CardId.KeeperOfDragonicMagic) || + Bot.HasInMonstersZone(CardId.SouleatingOviraptor) || + Bot.HasInMonstersZone(CardId.Raiden) + ) + { + AI.SelectCard(new[] + { + CardId.KeeperOfDragonicMagic, + CardId.Lumina, + CardId.FairyTailSnow, + CardId.SouleatingOviraptor, + CardId.Raiden, + CardId.GiantRex, + }); + AI.SelectNextCard(CardId.GlowUpBulb); + } + return true; + } + + public bool CrystronNeedlefibereff() + { + if (Duel.Player == 0) + { + + CrystronNeedlefibereff_used = true; + AI.SelectCard(new[] { CardId.GhostOgre, CardId.GlowUpBulb, CardId.PlaguespreaderZombie, CardId.ShaddollFalco }); + return true; + } + else if (AI.Utils.IsChainTarget(Card) || AI.Utils.GetProblematicEnemySpell() != null) return true; + else if (Duel.Player == 1 && Duel.Phase == DuelPhase.BattleStart && AI.Utils.IsOneEnemyBetterThanValue(1500, true)) + { + if (AI.Utils.IsOneEnemyBetterThanValue(1900, true)) + { + AI.SelectPosition(CardPosition.FaceUpDefence); + } + else + { + AI.SelectPosition(CardPosition.FaceUpAttack); + } + return true; + } + return false; + } + + private bool ScarlightRedDragoneff() + { + IList targets = new List(); + ClientCard target1 = AI.Utils.GetBestEnemyMonster(); + if (target1 != null) + { + targets.Add(target1); + AI.SelectCard(targets); + return true; + } + return false; + } + private bool CrystalWingSynchroDragoneff() + { + return Duel.LastChainPlayer != 0; + } + + private bool Sdulldeateff() + { + /* if (snake_four_s) + { + snake_four_s = false; + AI.SelectCard(Useless_List()); + return true; + } + //if (ActivateDescription == AI.Utils.GetStringId(CardId.snake, 2)) return true; + if (ActivateDescription == AI.Utils.GetStringId(CardId.snake, 1)) + { + foreach (ClientCard hand in Bot.Hand) + { + if (hand.Id == CardId.Red || hand.Id == CardId.Pink) + { + AI.SelectCard(hand); + return true; + } + if (hand.Id == CardId.Urara || hand.Id == CardId.Ghost) + { + if (Tuner_ss()) + { + AI.SelectCard(hand); + return true; + } + } + } + }*/ + return false; + } + + + private bool BlackRoseMoonlightDragoneff() + { + IList targets = new List(); + ClientCard target1 = AI.Utils.GetBestEnemyMonster(); + if (target1 != null) + { + targets.Add(target1); + AI.SelectCard(targets); + return true; + } + return false; + + } + private bool RedWyverneff() + { + IList check = Enemy.MonsterZone; + ClientCard best = null; + foreach (ClientCard monster in check) + { + if (monster.Attack >= 2400) best = monster; + } + if (best != null) + { + AI.SelectCard(best); + return true; + } + return false; + } + + + + private bool CoralDragoneff() + { + if (Card.Location != CardLocation.MonsterZone) + return true; + IList targets = new List(); + + ClientCard target1 = AI.Utils.GetBestEnemyMonster(); + if (target1 != null) + targets.Add(target1); + ClientCard target2 = AI.Utils.GetBestEnemySpell(); + if (target2 != null) + targets.Add(target2); + else if (AI.Utils.IsChainTarget(Card) || AI.Utils.GetProblematicEnemySpell() != null) + { + AI.SelectCard(targets); + return true; + } + else if (Duel.Player == 1 && Duel.Phase == DuelPhase.BattleStart && AI.Utils.IsOneEnemyBetterThanValue(2400, true)) + { + AI.SelectCard(targets); + return true; + } + return false; + } public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender) { if (!defender.IsMonsterHasPreventActivationEffectInBattle()) { + if (attacker.Id == CardId.ElShaddollConstruct && !attacker.IsDisabled()) // TODO: && defender.IsSpecialSummoned + attacker.RealPower = 9999; if (attacker.Id == CardId.UltimateConductorTytanno && !attacker.IsDisabled() && defender.IsDefense()) attacker.RealPower = 9999; - } + } return base.OnPreBattleBetween(attacker, defender); } @@ -859,6 +1000,16 @@ public override bool OnSelectHand() { return true; } + /* + private bool GoblindberghSummon() + { + foreach (ClientCard card in Bot.Hand.GetMonsters()) + { + if (!card.Equals(Card) && card.Level == 4) + return true; + } + return false; + }*/ } From 48052612aaf6a4fd7504ecf316ad6230228c19b2 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Mon, 9 Apr 2018 11:31:39 +0800 Subject: [PATCH 48/68] update ChainBurn deck by handsomekiwi --- Game/AI/Decks/ChainBurnExecutor.cs | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Game/AI/Decks/ChainBurnExecutor.cs b/Game/AI/Decks/ChainBurnExecutor.cs index 93615775..b544a924 100644 --- a/Game/AI/Decks/ChainBurnExecutor.cs +++ b/Game/AI/Decks/ChainBurnExecutor.cs @@ -62,6 +62,7 @@ public ChainBurnExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.SpellSet, CardId.Waboku); AddExecutor(ExecutorType.SpellSet, CardId.ThreateningRoar); AddExecutor(ExecutorType.SpellSet, CardId.BlazingMirrorForce); + AddExecutor(ExecutorType.SpellSet, CardId.OjamaTrio, OjamaTrioset); AddExecutor(ExecutorType.SpellSet, BrunSpellSet); //afer set AddExecutor(ExecutorType.Activate, CardId.CardcarD); @@ -361,7 +362,7 @@ private bool ThreateningRoareff() { if (must_chain()) return true; - if (prevent_used||Duel.Phase==DuelPhase.End||Duel.Phase==DuelPhase.Main2) return false; + if (prevent_used||Duel.Phase!=DuelPhase.Main1) return false; prevent_used = true; return DefaultUniqueTrap(); } @@ -409,9 +410,8 @@ public bool Ring_act() } private bool RecklessGreedeff() { - int count = 0; - IList check = Bot.SpellZone; - foreach (ClientCard card in check) + int count = 0; + foreach (ClientCard card in Bot.GetSpells()) { if (card.Id == CardId.RecklessGreed) count++; @@ -441,6 +441,11 @@ private bool SecretBlasteff() return false; } + private bool OjamaTrioset() + { + if (Bot.HasInSpellZone(CardId.OjamaTrio)) return false; + return true; + } private bool OjamaTrioeff() { return OjamaTrioused; @@ -493,9 +498,9 @@ private bool Mathematicianeff() } private bool DiceJarfacedown() { - - IList check = Bot.MonsterZone; - foreach (ClientCard card in check) + + foreach (ClientCard card in Bot.GetMonsters()) + { if (card.Id == CardId.DiceJar && card.IsFacedown()) return true; @@ -511,8 +516,11 @@ private bool Ceasefireeff() return false; } private bool Linkuriboheff() - { - return DefaultDontChainMyself(); + { + ClientCard lastchaincard = AI.Utils.GetLastChainCard(); + if (lastchaincard == null) return true; + if (lastchaincard.Id == CardId.Linkuriboh) return false; + return true; } /*private bool SwordsOfRevealingLight() { From ead0ae2e494d0f4f7977d52140dd434464fc2ec6 Mon Sep 17 00:00:00 2001 From: Wind2009-Louse Date: Mon, 9 Apr 2018 13:19:17 +0800 Subject: [PATCH 49/68] Update TrickstarExecutor.cs Fix borreload dragon's effect. Fix Eater of Millions' repos. --- Game/AI/Decks/TrickstarExecutor.cs | 89 ++++++++++++++++++------------ 1 file changed, 53 insertions(+), 36 deletions(-) diff --git a/Game/AI/Decks/TrickstarExecutor.cs b/Game/AI/Decks/TrickstarExecutor.cs index 902388e5..facc5bbe 100644 --- a/Game/AI/Decks/TrickstarExecutor.cs +++ b/Game/AI/Decks/TrickstarExecutor.cs @@ -43,10 +43,10 @@ public class CardId public const int Linkspi = 98978921; public const int SafeDra = 99111753; public const int Crystal = 50588353; - public const int phoneix = 2857636; - public const int unicorn = 38342335; - public const int snake = 74997493; - public const int borrel = 31833038; + public const int Phoneix = 2857636; + public const int Unicorn = 38342335; + public const int Snake = 74997493; + public const int Borrel = 31833038; public const int TG = 98558751; public const int Beelze = 34408491; @@ -60,10 +60,10 @@ public class CardId public int getLinkMarker(int id) { - if (id == CardId.borrel || id == CardId.snake) return 4; + if (id == CardId.Borrel || id == CardId.Snake) return 4; else if (id == CardId.Abyss || id == CardId.Beelze || id == CardId.Exterio || id == CardId.Ultimate || id == CardId.Cardian) return 5; - else if (id == CardId.unicorn) return 3; - else if (id == CardId.Crystal || id == CardId.phoneix || id == CardId.SafeDra || id == CardId.Missus) return 2; + else if (id == CardId.Unicorn) return 3; + else if (id == CardId.Crystal || id == CardId.Phoneix || id == CardId.SafeDra || id == CardId.Missus) return 2; return 1; } @@ -108,26 +108,26 @@ public TrickstarExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.Tuner,Tuner_eff); // ex ss - AddExecutor(ExecutorType.SpSummon, CardId.borrel, Borrel_ss); + AddExecutor(ExecutorType.SpSummon, CardId.Borrel, Borrel_ss); AddExecutor(ExecutorType.SpSummon, CardId.Missus, Missus_ss); - AddExecutor(ExecutorType.SpSummon, CardId.phoneix, Phoneix_ss); - AddExecutor(ExecutorType.SpSummon, CardId.snake, Snake_ss); + AddExecutor(ExecutorType.SpSummon, CardId.Phoneix, Phoneix_ss); + AddExecutor(ExecutorType.SpSummon, CardId.Snake, Snake_ss); AddExecutor(ExecutorType.SpSummon, CardId.Crystal, Crystal_ss); AddExecutor(ExecutorType.SpSummon, CardId.SafeDra, Safedragon_ss); AddExecutor(ExecutorType.Activate, CardId.SafeDra, DefaultCompulsoryEvacuationDevice); AddExecutor(ExecutorType.Activate, CardId.Linkuri, Linkuri_eff); AddExecutor(ExecutorType.SpSummon, CardId.Linkuri, Linkuri_ss); - AddExecutor(ExecutorType.SpSummon, CardId.unicorn, Unicorn_ss); + AddExecutor(ExecutorType.SpSummon, CardId.Unicorn, Unicorn_ss); AddExecutor(ExecutorType.SpSummon, CardId.Linkspi); // ex_monster act AddExecutor(ExecutorType.Activate, CardId.Beelze); AddExecutor(ExecutorType.Activate, CardId.Missus, Missus_eff); AddExecutor(ExecutorType.Activate, CardId.Crystal, Crystal_eff); - AddExecutor(ExecutorType.Activate, CardId.phoneix, Phoneix_eff); - AddExecutor(ExecutorType.Activate, CardId.unicorn, Unicorn_eff); - AddExecutor(ExecutorType.Activate, CardId.snake, Snake_eff); - AddExecutor(ExecutorType.Activate, CardId.borrel, Borrel_eff); + AddExecutor(ExecutorType.Activate, CardId.Phoneix, Phoneix_eff); + AddExecutor(ExecutorType.Activate, CardId.Unicorn, Unicorn_eff); + AddExecutor(ExecutorType.Activate, CardId.Snake, Snake_eff); + AddExecutor(ExecutorType.Activate, CardId.Borrel, Borrel_eff); // normal act AddExecutor(ExecutorType.Activate, CardId.Trans); @@ -168,7 +168,7 @@ public bool SpellSet() public bool Has_down_arrow(int id) { - return (id == CardId.Linkuri || id == CardId.Linkspi || id == CardId.unicorn); + return (id == CardId.Linkuri || id == CardId.Linkspi || id == CardId.Unicorn); } public bool IsTrickstar(int id) @@ -223,7 +223,7 @@ public bool Grass_ss() if (Enemy.GetMonstersExtraZoneCount() > 1) judge = false; // exlink if (Bot.GetMonstersExtraZoneCount() >= 1) { - foreach(ClientCard card in Bot.GetMonstersInExtraZone()) + foreach (ClientCard card in Bot.GetMonstersInExtraZone()) { if (getLinkMarker(card.Id) == 5) judge = false; } @@ -236,14 +236,17 @@ public bool Grass_ss() ClientCard ex_best = null; foreach (ClientCard ex_card in ex) { - if (!fornextss) { + if (!fornextss) + { if (ex_best == null || ex_card.Attack > ex_best.Attack) ex_best = ex_card; - } else + } + else { if (getLinkMarker(ex_card.Id) != 5 && (ex_best == null || ex_card.Attack > ex_best.Attack)) ex_best = ex_card; } } - if (ex_best != null) { + if (ex_best != null) + { AI.SelectCard(ex_best); } } @@ -252,10 +255,11 @@ public bool Grass_ss() // cannot ss from exdeck or have more than 1 grass in chain int[] secondselect = new[] { - CardId.borrel, + CardId.Borrel, CardId.Ultimate, CardId.Abyss, CardId.Cardian, + CardId.Exterio, CardId.Ghost, CardId.White, CardId.Red, @@ -661,17 +665,14 @@ public void Red_SelectPos(ClientCard return_card = null) List monster_list = Bot.GetMonsters(); monster_list.Sort(AIFunctions.CompareCardAttack); monster_list.Reverse(); - ClientCard self_best = null; foreach(ClientCard card in monster_list) { if (IsTrickstar(card.Id) && card != return_card && card.HasPosition(CardPosition.Attack)) { - self_best = card; - break; - } + int this_power = (Bot.HasInHand(CardId.White) && !white_eff_used) ? (card.RealPower + card.Attack) : card.RealPower; + if (this_power >= self_power) self_power = this_power; + } else if (card.RealPower >= self_power) self_power = card.RealPower; } - if (self_best != null) self_power = (Bot.HasInHand(CardId.White)) ? (self_best.Attack + self_best.RealPower) : self_best.Attack; - } ClientCard bestenemy = AI.Utils.GetOneEnemyBetterThanValue(self_power, true); if (bestenemy != null) AI.SelectPosition(CardPosition.FaceUpDefence); @@ -1510,8 +1511,8 @@ public bool Snake_eff() AI.SelectCard(Useless_List()); return true; } - //if (ActivateDescription == AI.Utils.GetStringId(CardId.snake, 2)) return true; - if (ActivateDescription == AI.Utils.GetStringId(CardId.snake, 1)) + //if (ActivateDescription == AI.Utils.GetStringId(CardId.Snake, 2)) return true; + if (ActivateDescription == AI.Utils.GetStringId(CardId.Snake, 1)) { foreach(ClientCard hand in Bot.Hand) { @@ -1546,7 +1547,7 @@ public bool Missus_ss() { AI.SelectMaterials(material_list); return true; - } else if (AI.Utils.GetProblematicEnemyMonster(2000) != null && Bot.HasInExtra(CardId.borrel) && !Bot.HasInMonstersZone(CardId.Missus)) + } else if (AI.Utils.GetProblematicEnemyMonster(2000) != null && Bot.HasInExtra(CardId.Borrel) && !Bot.HasInMonstersZone(CardId.Missus)) { AI.SelectMaterials(material_list); return true; @@ -1560,7 +1561,7 @@ public bool Missus_eff() { CardId.MG, CardId.Missus, - CardId.snake + CardId.Snake }); return true; } @@ -1620,7 +1621,7 @@ public bool Borrel_eff() { return (Card.Attack - enemy_monster.Attack < Enemy.LifePoints); } - else return false; + return true; }; ClientCard BestEnemy = AI.Utils.GetBestEnemyMonster(true); ClientCard WorstBot = Bot.GetMonsters().GetLowestAttackMonster(); @@ -1670,15 +1671,30 @@ public bool DarkHole_eff() return false; } + public bool IsAllEnemyBetter() + { + int bestPower = -1; + for (int i = 0; i < 7; ++i) + { + ClientCard card = Bot.MonsterZone[i]; + if (card == null || card.Data == null) continue; + int newPower = card.Attack; + if (IsTrickstar(card.Id) && Bot.HasInHand(CardId.White) && !white_eff_used) newPower += card.RealPower; + if (newPower > bestPower) + bestPower = newPower; + } + return AI.Utils.IsAllEnemyBetterThanValue(bestPower,true); + } + public bool MonsterRepos() { - if (Card.Id == CardId.Eater && Card.HasPosition(CardPosition.Attack)) return false; + if (Card.Id == CardId.Eater) return (!Card.HasPosition(CardPosition.Attack)); if (IsTrickstar(Card.Id) && !white_eff_used && Bot.HasInHand(CardId.White) && Card.IsAttack() && Duel.Phase == DuelPhase.Main1) return false; if (Card.IsFaceup() && Card.IsDefense() && Card.Attack == 0) return false; - bool enemyBetter = AI.Utils.IsAllEnemyBetter(true); + bool enemyBetter = IsAllEnemyBetter(); if (Card.IsAttack() && enemyBetter) return true; @@ -1731,7 +1747,8 @@ public override BattlePhaseAction OnSelectAttackTarget(ClientCard attacker, ILis if (!defender.IsMonsterHasPreventActivationEffectInBattle() && !attacker.IsDisabled()) { - if ((attacker.Id == CardId.Eater && !defender.HasType(CardType.Token) && GraveCall_id != CardId.Eater) || attacker.Id == CardId.borrel) return AI.Attack(attacker, defender); + if ((attacker.Id == CardId.Eater && !defender.HasType(CardType.Token)) || attacker.Id == CardId.Borrel) return AI.Attack(attacker, defender); + if ((attacker.Id == CardId.Ultimate || attacker.Id == CardId.Cardian) && attacker.RealPower > defender.RealPower) return AI.Attack(attacker, defender); } if (!OnPreBattleBetween(attacker, defender)) @@ -1752,7 +1769,7 @@ public override ClientCard OnSelectAttacker(IList attackers, IList Date: Mon, 9 Apr 2018 13:53:10 +0800 Subject: [PATCH 50/68] Update GameBehavior.cs Add log --- Game/GameBehavior.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Game/GameBehavior.cs b/Game/GameBehavior.cs index 132320ea..7fd69c46 100644 --- a/Game/GameBehavior.cs +++ b/Game/GameBehavior.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Text.RegularExpressions; @@ -264,6 +264,7 @@ private void OnReplay(BinaryReader packet) private void OnDuelEnd(BinaryReader packet) { Connection.Close(); + Logger.DebugWriteLine("********************* Duel end *********************"); } private void OnChat(BinaryReader packet) @@ -351,6 +352,7 @@ private void OnDraw(BinaryReader packet) { int player = GetLocalPlayer(packet.ReadByte()); int count = packet.ReadByte(); + Logger.DebugWriteLine("(" + player.ToString() + "抽了" + count.ToString() + "张卡)"); for (int i = 0; i < count; ++i) { @@ -422,6 +424,7 @@ private void OnNewTurn(BinaryReader packet) private void OnNewPhase(BinaryReader packet) { _duel.Phase = (DuelPhase)packet.ReadInt16(); + Logger.DebugWriteLine("(进入" + (_duel.Phase.ToString()) + ")"); _duel.LastSummonPlayer = -1; _duel.Fields[0].BattlingMonster = null; _duel.Fields[1].BattlingMonster = null; @@ -433,6 +436,7 @@ private void OnDamage(BinaryReader packet) int player = GetLocalPlayer(packet.ReadByte()); int final = _duel.Fields[player].LifePoints - packet.ReadInt32(); if (final < 0) final = 0; + Logger.DebugWriteLine("(" + player.ToString() + "受到了伤害,当前为" + final.ToString() + ")"); _duel.Fields[player].LifePoints = final; } @@ -462,6 +466,7 @@ private void OnMove(BinaryReader packet) packet.ReadInt32(); // reason ClientCard card = _duel.GetCard(pc, (CardLocation)pl, ps); + if (card != null) Logger.DebugWriteLine("(" + pc.ToString() + "的" + (card.Name ?? "未知卡片") + "从" + (CardLocation)pl + "移动到了" + (CardLocation)cl + ")"); if ((pl & (int)CardLocation.Overlay) != 0) { @@ -505,6 +510,8 @@ private void OnAttack(BinaryReader packet) ClientCard attackcard = _duel.GetCard(ca, (CardLocation)la, sa); ClientCard defendcard = _duel.GetCard(cd, (CardLocation)ld, sd); + if (defendcard == null) Logger.DebugWriteLine("(" + (attackcard.Name ?? "未知卡片") + "直接攻击)"); + else Logger.DebugWriteLine("(" + ca.ToString() + "的" + (attackcard.Name ?? "未知卡片") + "攻击了" + cd.ToString() + "的" + (defendcard.Name ?? "未知卡片") + ")"); _duel.Fields[attackcard.Controller].BattlingMonster = attackcard; _duel.Fields[1 - attackcard.Controller].BattlingMonster = defendcard; @@ -524,7 +531,10 @@ private void OnPosChange(BinaryReader packet) int cp = packet.ReadSByte(); ClientCard card = _duel.GetCard(pc, (CardLocation)pl, ps); if (card != null) + { card.Position = cp; + Logger.DebugWriteLine("(" + (card.Name ?? "未知卡片") + "改变了表示形式为" + (CardPosition)cp + ")"); + } } private void OnChaining(BinaryReader packet) @@ -536,12 +546,12 @@ private void OnChaining(BinaryReader packet) int subs = packet.ReadSByte(); ClientCard card = _duel.GetCard(pcc, pcl, pcs, subs); int cc = GetLocalPlayer(packet.ReadByte()); + if (card != null) Logger.DebugWriteLine("(" + cc.ToString() + "的" + (card.Name ?? "未知卡片") + "发动了效果)"); _ai.OnChaining(card, cc); _duel.ChainTargets.Clear(); _duel.LastSummonPlayer = -1; _duel.CurrentChain.Add(card); _duel.LastChainPlayer = cc; - } private void OnChainEnd(BinaryReader packet) @@ -631,6 +641,7 @@ private void OnBecomeTarget(BinaryReader packet) /*int sseq = */packet.ReadByte(); ClientCard card = _duel.GetCard(player, (CardLocation)loc, seq); if (card == null) continue; + Logger.DebugWriteLine("(" + (CardLocation)loc + "的" + (card.Name ?? "未知卡片") + "成为了对象)"); _duel.ChainTargets.Add(card); } } From 4b080580d8eacb995bc6154ea6c35d851e326c81 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Mon, 9 Apr 2018 14:02:16 +0800 Subject: [PATCH 51/68] format --- Game/GameBehavior.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Game/GameBehavior.cs b/Game/GameBehavior.cs index 7fd69c46..9cb7b82a 100644 --- a/Game/GameBehavior.cs +++ b/Game/GameBehavior.cs @@ -264,7 +264,7 @@ private void OnReplay(BinaryReader packet) private void OnDuelEnd(BinaryReader packet) { Connection.Close(); - Logger.DebugWriteLine("********************* Duel end *********************"); + Logger.DebugWriteLine("********************* Duel end *********************"); } private void OnChat(BinaryReader packet) @@ -352,7 +352,7 @@ private void OnDraw(BinaryReader packet) { int player = GetLocalPlayer(packet.ReadByte()); int count = packet.ReadByte(); - Logger.DebugWriteLine("(" + player.ToString() + "抽了" + count.ToString() + "张卡)"); + Logger.DebugWriteLine("(" + player.ToString() + "抽了" + count.ToString() + "张卡)"); for (int i = 0; i < count; ++i) { @@ -424,7 +424,7 @@ private void OnNewTurn(BinaryReader packet) private void OnNewPhase(BinaryReader packet) { _duel.Phase = (DuelPhase)packet.ReadInt16(); - Logger.DebugWriteLine("(进入" + (_duel.Phase.ToString()) + ")"); + Logger.DebugWriteLine("(进入" + (_duel.Phase.ToString()) + ")"); _duel.LastSummonPlayer = -1; _duel.Fields[0].BattlingMonster = null; _duel.Fields[1].BattlingMonster = null; @@ -436,7 +436,7 @@ private void OnDamage(BinaryReader packet) int player = GetLocalPlayer(packet.ReadByte()); int final = _duel.Fields[player].LifePoints - packet.ReadInt32(); if (final < 0) final = 0; - Logger.DebugWriteLine("(" + player.ToString() + "受到了伤害,当前为" + final.ToString() + ")"); + Logger.DebugWriteLine("(" + player.ToString() + "受到了伤害,当前为" + final.ToString() + ")"); _duel.Fields[player].LifePoints = final; } @@ -466,7 +466,7 @@ private void OnMove(BinaryReader packet) packet.ReadInt32(); // reason ClientCard card = _duel.GetCard(pc, (CardLocation)pl, ps); - if (card != null) Logger.DebugWriteLine("(" + pc.ToString() + "的" + (card.Name ?? "未知卡片") + "从" + (CardLocation)pl + "移动到了" + (CardLocation)cl + ")"); + if (card != null) Logger.DebugWriteLine("(" + pc.ToString() + "的" + (card.Name ?? "未知卡片") + "从" + (CardLocation)pl + "移动到了" + (CardLocation)cl + ")"); if ((pl & (int)CardLocation.Overlay) != 0) { @@ -510,7 +510,7 @@ private void OnAttack(BinaryReader packet) ClientCard attackcard = _duel.GetCard(ca, (CardLocation)la, sa); ClientCard defendcard = _duel.GetCard(cd, (CardLocation)ld, sd); - if (defendcard == null) Logger.DebugWriteLine("(" + (attackcard.Name ?? "未知卡片") + "直接攻击)"); + if (defendcard == null) Logger.DebugWriteLine("(" + (attackcard.Name ?? "未知卡片") + "直接攻击)"); else Logger.DebugWriteLine("(" + ca.ToString() + "的" + (attackcard.Name ?? "未知卡片") + "攻击了" + cd.ToString() + "的" + (defendcard.Name ?? "未知卡片") + ")"); _duel.Fields[attackcard.Controller].BattlingMonster = attackcard; _duel.Fields[1 - attackcard.Controller].BattlingMonster = defendcard; @@ -546,7 +546,7 @@ private void OnChaining(BinaryReader packet) int subs = packet.ReadSByte(); ClientCard card = _duel.GetCard(pcc, pcl, pcs, subs); int cc = GetLocalPlayer(packet.ReadByte()); - if (card != null) Logger.DebugWriteLine("(" + cc.ToString() + "的" + (card.Name ?? "未知卡片") + "发动了效果)"); + if (card != null) Logger.DebugWriteLine("(" + cc.ToString() + "的" + (card.Name ?? "未知卡片") + "发动了效果)"); _ai.OnChaining(card, cc); _duel.ChainTargets.Clear(); _duel.LastSummonPlayer = -1; @@ -641,7 +641,7 @@ private void OnBecomeTarget(BinaryReader packet) /*int sseq = */packet.ReadByte(); ClientCard card = _duel.GetCard(player, (CardLocation)loc, seq); if (card == null) continue; - Logger.DebugWriteLine("(" + (CardLocation)loc + "的" + (card.Name ?? "未知卡片") + "成为了对象)"); + Logger.DebugWriteLine("(" + (CardLocation)loc + "的" + (card.Name ?? "未知卡片") + "成为了对象)"); _duel.ChainTargets.Add(card); } } From 8763f44077905c87087f21552143400df8ba7586 Mon Sep 17 00:00:00 2001 From: handsomekiwi <36762809+handsomekiwi@users.noreply.github.com> Date: Tue, 10 Apr 2018 00:00:43 +0800 Subject: [PATCH 52/68] update ChainBurn deck (#38) --- Decks/AI_ChainBurn.ydk | 6 +- Game/AI/Decks/ChainBurnExecutor.cs | 196 ++++++++++++++++++++--------- 2 files changed, 142 insertions(+), 60 deletions(-) diff --git a/Decks/AI_ChainBurn.ydk b/Decks/AI_ChainBurn.ydk index e5c36081..8df23d2e 100644 --- a/Decks/AI_ChainBurn.ydk +++ b/Decks/AI_ChainBurn.ydk @@ -37,7 +37,6 @@ 36361633 36361633 36361633 -36468556 37576645 37576645 37576645 @@ -52,7 +51,6 @@ 75249652 83555666 98444741 -98444741 #extra 41999284 41999284 @@ -65,4 +63,6 @@ 98444741 100227025 100227025 -100227025 \ No newline at end of file +100227025 +36468556 +98444741 \ No newline at end of file diff --git a/Game/AI/Decks/ChainBurnExecutor.cs b/Game/AI/Decks/ChainBurnExecutor.cs index b544a924..aba54a8a 100644 --- a/Game/AI/Decks/ChainBurnExecutor.cs +++ b/Game/AI/Decks/ChainBurnExecutor.cs @@ -70,8 +70,7 @@ public ChainBurnExecutor(GameAI ai, Duel duel) //activate trap AddExecutor(ExecutorType.Activate, CardId.BalanceOfJudgment, BalanceOfJudgmenteff); AddExecutor(ExecutorType.Activate, CardId.AccuulatedFortune); - AddExecutor(ExecutorType.Activate, CardId.ChainStrike, ChainStrikeeff); - //battle + //battle AddExecutor(ExecutorType.Activate, CardId.ThreateningRoar, ThreateningRoareff); AddExecutor(ExecutorType.Activate, CardId.Waboku, Wabokueff); @@ -86,7 +85,7 @@ public ChainBurnExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.SecretBlast, SecretBlasteff); AddExecutor(ExecutorType.Activate, CardId.SectetBarrel, SectetBarreleff); AddExecutor(ExecutorType.Activate, CardId.RecklessGreed, RecklessGreedeff); - + AddExecutor(ExecutorType.Activate, CardId.ChainStrike, ChainStrikeeff); //sp AddExecutor(ExecutorType.SpSummon, CardId.Linkuriboh); AddExecutor(ExecutorType.Activate, CardId.Linkuriboh, Linkuriboheff); @@ -130,15 +129,15 @@ public int[] AbouluteKingBackJack_List_1() CardId.Waboku, CardId.ThreateningRoar, CardId.MagicCylinder, - CardId.RingOfDestruction, + CardId.RingOfDestruction, CardId.RecklessGreed, CardId.SecretBlast, CardId.JustDesserts, - CardId.OjamaTrio, - CardId.SectetBarrel, - CardId.Ceasefire, - CardId.BalanceOfJudgment, - CardId.AccuulatedFortune, + CardId.OjamaTrio, + CardId.SectetBarrel, + CardId.Ceasefire, + CardId.BalanceOfJudgment, + CardId.AccuulatedFortune, }; } public int[] AbouluteKingBackJack_List_2() @@ -149,7 +148,7 @@ public int[] AbouluteKingBackJack_List_2() CardId.Mathematician, CardId.DiceJar, CardId.CardcarD, - CardId.BattleFader, + CardId.BattleFader, CardId.BlazingMirrorForce, CardId.Waboku, CardId.ThreateningRoar, @@ -169,7 +168,7 @@ public int[] now_List() { return new[] { - + CardId.Waboku, CardId.SecretBlast, CardId.JustDesserts, @@ -178,7 +177,7 @@ public int[] now_List() CardId.Ceasefire, CardId.RecklessGreed, CardId.RingOfDestruction, - + }; } @@ -217,17 +216,25 @@ public bool Has_prevent_list(int id) id == CardId.RingOfDestruction ); } - bool pot_used = false; + bool no_sp = false; bool one_turn_kill = false; + bool one_turn_kill_1 = false; int expected_blood = 0; - bool prevent_used = false; - int preventcount = 0; + bool prevent_used = false; + int preventcount = 0; bool battleprevent = false; bool OjamaTrioused = false; - bool HasAccuulatedFortune = false; + bool OjamaTrioused_draw = false; + bool drawfirst = false; + int Waboku_count = 0; + int Roar_count = 0; + int strike_count = 0; + int greed_count = 0; int blast_count = 0; int barrel_count = 0; int just_count = 0; + int Ojama_count = 0; + int HasAccuulatedFortune = 0; public override bool OnSelectHand() { return true; @@ -235,25 +242,22 @@ public override bool OnSelectHand() public override void OnNewTurn() { - - - pot_used = false; + + + no_sp = false; prevent_used = false; battleprevent = false; - OjamaTrioused = false; - + + } public override void OnNewPhase() { preventcount = 0; battleprevent = false; - HasAccuulatedFortune = false; + OjamaTrioused = false; IList trap = Bot.SpellZone; IList monster = Bot.MonsterZone; - foreach(ClientCard card in trap) - { - if (card.Id == CardId.AccuulatedFortune) HasAccuulatedFortune = true; - } + foreach (ClientCard card in trap) { if (Has_prevent_list(card.Id)) @@ -272,36 +276,98 @@ public override void OnNewPhase() } } + expected_blood = 0; one_turn_kill = false; + one_turn_kill_1 = false; + OjamaTrioused_draw = false; + drawfirst = false; + HasAccuulatedFortune = 0; + strike_count = 0; + greed_count = 0; blast_count = 0; barrel_count = 0; just_count = 0; + Waboku_count = 0; + Roar_count = 0; + Ojama_count = 0; + IList check = Bot.SpellZone; foreach (ClientCard card in check) + { + if (card.Id == CardId.AccuulatedFortune) + HasAccuulatedFortune++; + + } + foreach (ClientCard card in check) { if (card.Id == CardId.SecretBlast) blast_count++; - break; + } foreach (ClientCard card in check) { if (card.Id == CardId.SectetBarrel) barrel_count++; - break; + } foreach (ClientCard card in check) { if (card.Id == CardId.JustDesserts) just_count++; - break; + + } + foreach (ClientCard card in check) + { + if (card.Id == CardId.ChainStrike) + strike_count++; + + } + foreach (ClientCard card in Bot.GetSpells()) + { + if (card.Id == CardId.RecklessGreed) + greed_count++; + + } + foreach (ClientCard card in check) + { + if (card.Id == CardId.Waboku) + Waboku_count++; + } + foreach (ClientCard card in check) + { + if (card.Id == CardId.ThreateningRoar) + Roar_count++; + + } + if (Bot.HasInSpellZone(CardId.OjamaTrio) && Enemy.GetMonsterCount() <= 2 && Enemy.GetMonsterCount() >= 1) + { + if (HasAccuulatedFortune>0) OjamaTrioused_draw = true; + } + expected_blood = (Enemy.GetMonsterCount() * 500 * just_count + Enemy.GetFieldHandCount() * 200 * barrel_count + Enemy.GetFieldCount() * 300 * blast_count); - if (Enemy.LifePoints <= expected_blood) - one_turn_kill = true; + if (Enemy.LifePoints <= expected_blood) one_turn_kill = true; + if (greed_count >= 2) greed_count = 1; + if (blast_count >= 2) blast_count = 1; + if (just_count >= 2) just_count = 1; + if (barrel_count >= 2) barrel_count = 1; + if (Waboku_count >= 2) Waboku_count = 1; + if (Roar_count >= 2) Roar_count = 1; + if (strike_count >= 2) strike_count = 1; + int currentchain = 0; + if (OjamaTrioused_draw) + currentchain = Duel.CurrentChain.Count + blast_count + just_count + barrel_count + Waboku_count + Waboku_count + Roar_count + greed_count + strike_count + Ojama_count; + else + currentchain = Duel.CurrentChain.Count + blast_count + just_count + barrel_count + Waboku_count + Waboku_count + greed_count + Roar_count + strike_count; + if (currentchain >= 3) drawfirst = true; + currentchain = Duel.CurrentChain.Count+ blast_count + just_count+barrel_count; + expected_blood = (Enemy.GetMonsterCount() * 500 * just_count + Enemy.GetFieldHandCount() * 200 * barrel_count + Enemy.GetFieldCount() * 300 * blast_count+(currentchain+1)*400); + if (Enemy.LifePoints <= expected_blood) one_turn_kill_1 = true; + } - - + + private bool must_chain() { if (AI.Utils.IsChainTarget(Card)) return true; @@ -326,7 +392,7 @@ private bool SandaionTheTimloard_summon() } private bool AbouluteKingBackJacksummon() { - return !pot_used; + return !no_sp; } private bool AbouluteKingBackJackeff() { @@ -336,13 +402,13 @@ private bool AbouluteKingBackJackeff() AI.SelectCard(AbouluteKingBackJack_List_1()); AI.SelectNextCard(AbouluteKingBackJack_List_2()); } - + return true; - + } private bool PotOfDualityeff() { - pot_used = true; + no_sp = true; AI.SelectCard(prevent_list()); return true; } @@ -355,12 +421,12 @@ private bool BlazingMirrorForceeff() list.Add(monster); } //if (GetTotalATK(list) / 2 >= Bot.LifePoints) return false; - if (GetTotalATK(list) < 3000) return false; + if (GetTotalATK(list) < 3000) return false; return Enemy.HasAttackingMonster() && DefaultUniqueTrap(); } private bool ThreateningRoareff() { - + if (drawfirst) return true; if (must_chain()) return true; if (prevent_used||Duel.Phase!=DuelPhase.Main1) return false; prevent_used = true; @@ -368,12 +434,15 @@ private bool ThreateningRoareff() } private bool SandaionTheTimloardeff() { + prevent_used = true; return true; } private bool Wabokueff() { + if (drawfirst) return true; if (must_chain()) return true; + if (drawfirst) return true; if (prevent_used||Duel.Player == 0||Duel.Phase!=DuelPhase.BattleStart) return false; prevent_used = true; return DefaultUniqueTrap(); @@ -410,21 +479,18 @@ public bool Ring_act() } private bool RecklessGreedeff() { - int count = 0; - foreach (ClientCard card in Bot.GetSpells()) - { - if (card.Id == CardId.RecklessGreed) - count++; - break; - } - if (count > 1) return true; + if (drawfirst) return DefaultUniqueTrap(); + if (must_chain() && greed_count > 1) return true; + if (greed_count > 1) return true; if (Bot.LifePoints <= 2000) return true; if (Bot.GetHandCount() <1 && Duel.Player==0 && Duel.Phase!=DuelPhase.Standby) return true; return false; } private bool SectetBarreleff() { - if (one_turn_kill) return true; + if (drawfirst) return DefaultUniqueTrap(); + if (one_turn_kill_1) return DefaultUniqueTrap(); + if (one_turn_kill) return DefaultUniqueTrap(); if (must_chain()) return true; int count = Enemy.GetFieldHandCount(); if (Enemy.LifePoints < count * 200) return true; @@ -433,26 +499,31 @@ private bool SectetBarreleff() } private bool SecretBlasteff() { - if (one_turn_kill) return true; + if (drawfirst) return DefaultUniqueTrap(); + if (one_turn_kill_1) return DefaultUniqueTrap(); + if (one_turn_kill) return DefaultUniqueTrap(); if (must_chain()) return true; int count = Enemy.GetFieldCount(); if (Enemy.LifePoints < count * 300) return true; if (count >= 5) return true; return false; - + } private bool OjamaTrioset() { + if (Bot.HasInSpellZone(CardId.OjamaTrio)) return false; return true; } private bool OjamaTrioeff() { - return OjamaTrioused; + return OjamaTrioused||OjamaTrioused_draw; } private bool JustDessertseff() { - if (one_turn_kill) return true; + if (drawfirst) return DefaultUniqueTrap(); + if (one_turn_kill_1) return DefaultUniqueTrap(); + if (one_turn_kill) return DefaultUniqueTrap(); if (must_chain()) return true; int count = Enemy.GetMonsterCount(); if (Enemy.LifePoints <= count * 500) return true; @@ -466,13 +537,15 @@ private bool JustDessertseff() } private bool ChainStrikeeff() { + if (drawfirst) return true; if (must_chain()) return true; int chain = Duel.CurrentChain.Count; + if (strike_count >= 2 && chain >= 2) return true; if (Enemy.LifePoints <= (chain + 1) * 400) return true; if (Duel.CurrentChain.Count >= 3) return true; return false; } - + private bool BalanceOfJudgmenteff() { if (must_chain()) return true; @@ -483,7 +556,10 @@ private bool BalanceOfJudgmenteff() private bool CardOfDemiseeff() { if (Bot.GetHandCount() == 1 && Bot.GetSpellCountWithoutField() <= 3) + { + no_sp = true; return true; + } return false; } private bool Mathematicianeff() @@ -494,13 +570,13 @@ private bool Mathematicianeff() return true; } return true; - + } private bool DiceJarfacedown() { - - foreach (ClientCard card in Bot.GetMonsters()) - + + foreach (ClientCard card in Bot.GetMonsters()) + { if (card.Id == CardId.DiceJar && card.IsFacedown()) return true; @@ -522,6 +598,12 @@ private bool Linkuriboheff() if (lastchaincard.Id == CardId.Linkuriboh) return false; return true; } + + public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender) + { + if (attacker.Id == CardId.Linkuriboh && defender.IsFacedown()) return false; + return base.OnPreBattleBetween(attacker,defender); + } /*private bool SwordsOfRevealingLight() { int count = Bot.SpellZone.GetCardCount(CardId.SwordsOfRevealingLight); From 82d2241f8efa569ca336dc037e6f64a34e1eb6ef Mon Sep 17 00:00:00 2001 From: Wind2009-Louse Date: Mon, 9 Apr 2018 13:19:17 +0800 Subject: [PATCH 53/68] Update TrickstarExecutor.cs Fix borreload dragon's effect. Fix Eater of Millions' repos. --- Game/AI/Decks/TrickstarExecutor.cs | 89 ++++++++++++++++++------------ 1 file changed, 53 insertions(+), 36 deletions(-) diff --git a/Game/AI/Decks/TrickstarExecutor.cs b/Game/AI/Decks/TrickstarExecutor.cs index 902388e5..facc5bbe 100644 --- a/Game/AI/Decks/TrickstarExecutor.cs +++ b/Game/AI/Decks/TrickstarExecutor.cs @@ -43,10 +43,10 @@ public class CardId public const int Linkspi = 98978921; public const int SafeDra = 99111753; public const int Crystal = 50588353; - public const int phoneix = 2857636; - public const int unicorn = 38342335; - public const int snake = 74997493; - public const int borrel = 31833038; + public const int Phoneix = 2857636; + public const int Unicorn = 38342335; + public const int Snake = 74997493; + public const int Borrel = 31833038; public const int TG = 98558751; public const int Beelze = 34408491; @@ -60,10 +60,10 @@ public class CardId public int getLinkMarker(int id) { - if (id == CardId.borrel || id == CardId.snake) return 4; + if (id == CardId.Borrel || id == CardId.Snake) return 4; else if (id == CardId.Abyss || id == CardId.Beelze || id == CardId.Exterio || id == CardId.Ultimate || id == CardId.Cardian) return 5; - else if (id == CardId.unicorn) return 3; - else if (id == CardId.Crystal || id == CardId.phoneix || id == CardId.SafeDra || id == CardId.Missus) return 2; + else if (id == CardId.Unicorn) return 3; + else if (id == CardId.Crystal || id == CardId.Phoneix || id == CardId.SafeDra || id == CardId.Missus) return 2; return 1; } @@ -108,26 +108,26 @@ public TrickstarExecutor(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.Tuner,Tuner_eff); // ex ss - AddExecutor(ExecutorType.SpSummon, CardId.borrel, Borrel_ss); + AddExecutor(ExecutorType.SpSummon, CardId.Borrel, Borrel_ss); AddExecutor(ExecutorType.SpSummon, CardId.Missus, Missus_ss); - AddExecutor(ExecutorType.SpSummon, CardId.phoneix, Phoneix_ss); - AddExecutor(ExecutorType.SpSummon, CardId.snake, Snake_ss); + AddExecutor(ExecutorType.SpSummon, CardId.Phoneix, Phoneix_ss); + AddExecutor(ExecutorType.SpSummon, CardId.Snake, Snake_ss); AddExecutor(ExecutorType.SpSummon, CardId.Crystal, Crystal_ss); AddExecutor(ExecutorType.SpSummon, CardId.SafeDra, Safedragon_ss); AddExecutor(ExecutorType.Activate, CardId.SafeDra, DefaultCompulsoryEvacuationDevice); AddExecutor(ExecutorType.Activate, CardId.Linkuri, Linkuri_eff); AddExecutor(ExecutorType.SpSummon, CardId.Linkuri, Linkuri_ss); - AddExecutor(ExecutorType.SpSummon, CardId.unicorn, Unicorn_ss); + AddExecutor(ExecutorType.SpSummon, CardId.Unicorn, Unicorn_ss); AddExecutor(ExecutorType.SpSummon, CardId.Linkspi); // ex_monster act AddExecutor(ExecutorType.Activate, CardId.Beelze); AddExecutor(ExecutorType.Activate, CardId.Missus, Missus_eff); AddExecutor(ExecutorType.Activate, CardId.Crystal, Crystal_eff); - AddExecutor(ExecutorType.Activate, CardId.phoneix, Phoneix_eff); - AddExecutor(ExecutorType.Activate, CardId.unicorn, Unicorn_eff); - AddExecutor(ExecutorType.Activate, CardId.snake, Snake_eff); - AddExecutor(ExecutorType.Activate, CardId.borrel, Borrel_eff); + AddExecutor(ExecutorType.Activate, CardId.Phoneix, Phoneix_eff); + AddExecutor(ExecutorType.Activate, CardId.Unicorn, Unicorn_eff); + AddExecutor(ExecutorType.Activate, CardId.Snake, Snake_eff); + AddExecutor(ExecutorType.Activate, CardId.Borrel, Borrel_eff); // normal act AddExecutor(ExecutorType.Activate, CardId.Trans); @@ -168,7 +168,7 @@ public bool SpellSet() public bool Has_down_arrow(int id) { - return (id == CardId.Linkuri || id == CardId.Linkspi || id == CardId.unicorn); + return (id == CardId.Linkuri || id == CardId.Linkspi || id == CardId.Unicorn); } public bool IsTrickstar(int id) @@ -223,7 +223,7 @@ public bool Grass_ss() if (Enemy.GetMonstersExtraZoneCount() > 1) judge = false; // exlink if (Bot.GetMonstersExtraZoneCount() >= 1) { - foreach(ClientCard card in Bot.GetMonstersInExtraZone()) + foreach (ClientCard card in Bot.GetMonstersInExtraZone()) { if (getLinkMarker(card.Id) == 5) judge = false; } @@ -236,14 +236,17 @@ public bool Grass_ss() ClientCard ex_best = null; foreach (ClientCard ex_card in ex) { - if (!fornextss) { + if (!fornextss) + { if (ex_best == null || ex_card.Attack > ex_best.Attack) ex_best = ex_card; - } else + } + else { if (getLinkMarker(ex_card.Id) != 5 && (ex_best == null || ex_card.Attack > ex_best.Attack)) ex_best = ex_card; } } - if (ex_best != null) { + if (ex_best != null) + { AI.SelectCard(ex_best); } } @@ -252,10 +255,11 @@ public bool Grass_ss() // cannot ss from exdeck or have more than 1 grass in chain int[] secondselect = new[] { - CardId.borrel, + CardId.Borrel, CardId.Ultimate, CardId.Abyss, CardId.Cardian, + CardId.Exterio, CardId.Ghost, CardId.White, CardId.Red, @@ -661,17 +665,14 @@ public void Red_SelectPos(ClientCard return_card = null) List monster_list = Bot.GetMonsters(); monster_list.Sort(AIFunctions.CompareCardAttack); monster_list.Reverse(); - ClientCard self_best = null; foreach(ClientCard card in monster_list) { if (IsTrickstar(card.Id) && card != return_card && card.HasPosition(CardPosition.Attack)) { - self_best = card; - break; - } + int this_power = (Bot.HasInHand(CardId.White) && !white_eff_used) ? (card.RealPower + card.Attack) : card.RealPower; + if (this_power >= self_power) self_power = this_power; + } else if (card.RealPower >= self_power) self_power = card.RealPower; } - if (self_best != null) self_power = (Bot.HasInHand(CardId.White)) ? (self_best.Attack + self_best.RealPower) : self_best.Attack; - } ClientCard bestenemy = AI.Utils.GetOneEnemyBetterThanValue(self_power, true); if (bestenemy != null) AI.SelectPosition(CardPosition.FaceUpDefence); @@ -1510,8 +1511,8 @@ public bool Snake_eff() AI.SelectCard(Useless_List()); return true; } - //if (ActivateDescription == AI.Utils.GetStringId(CardId.snake, 2)) return true; - if (ActivateDescription == AI.Utils.GetStringId(CardId.snake, 1)) + //if (ActivateDescription == AI.Utils.GetStringId(CardId.Snake, 2)) return true; + if (ActivateDescription == AI.Utils.GetStringId(CardId.Snake, 1)) { foreach(ClientCard hand in Bot.Hand) { @@ -1546,7 +1547,7 @@ public bool Missus_ss() { AI.SelectMaterials(material_list); return true; - } else if (AI.Utils.GetProblematicEnemyMonster(2000) != null && Bot.HasInExtra(CardId.borrel) && !Bot.HasInMonstersZone(CardId.Missus)) + } else if (AI.Utils.GetProblematicEnemyMonster(2000) != null && Bot.HasInExtra(CardId.Borrel) && !Bot.HasInMonstersZone(CardId.Missus)) { AI.SelectMaterials(material_list); return true; @@ -1560,7 +1561,7 @@ public bool Missus_eff() { CardId.MG, CardId.Missus, - CardId.snake + CardId.Snake }); return true; } @@ -1620,7 +1621,7 @@ public bool Borrel_eff() { return (Card.Attack - enemy_monster.Attack < Enemy.LifePoints); } - else return false; + return true; }; ClientCard BestEnemy = AI.Utils.GetBestEnemyMonster(true); ClientCard WorstBot = Bot.GetMonsters().GetLowestAttackMonster(); @@ -1670,15 +1671,30 @@ public bool DarkHole_eff() return false; } + public bool IsAllEnemyBetter() + { + int bestPower = -1; + for (int i = 0; i < 7; ++i) + { + ClientCard card = Bot.MonsterZone[i]; + if (card == null || card.Data == null) continue; + int newPower = card.Attack; + if (IsTrickstar(card.Id) && Bot.HasInHand(CardId.White) && !white_eff_used) newPower += card.RealPower; + if (newPower > bestPower) + bestPower = newPower; + } + return AI.Utils.IsAllEnemyBetterThanValue(bestPower,true); + } + public bool MonsterRepos() { - if (Card.Id == CardId.Eater && Card.HasPosition(CardPosition.Attack)) return false; + if (Card.Id == CardId.Eater) return (!Card.HasPosition(CardPosition.Attack)); if (IsTrickstar(Card.Id) && !white_eff_used && Bot.HasInHand(CardId.White) && Card.IsAttack() && Duel.Phase == DuelPhase.Main1) return false; if (Card.IsFaceup() && Card.IsDefense() && Card.Attack == 0) return false; - bool enemyBetter = AI.Utils.IsAllEnemyBetter(true); + bool enemyBetter = IsAllEnemyBetter(); if (Card.IsAttack() && enemyBetter) return true; @@ -1731,7 +1747,8 @@ public override BattlePhaseAction OnSelectAttackTarget(ClientCard attacker, ILis if (!defender.IsMonsterHasPreventActivationEffectInBattle() && !attacker.IsDisabled()) { - if ((attacker.Id == CardId.Eater && !defender.HasType(CardType.Token) && GraveCall_id != CardId.Eater) || attacker.Id == CardId.borrel) return AI.Attack(attacker, defender); + if ((attacker.Id == CardId.Eater && !defender.HasType(CardType.Token)) || attacker.Id == CardId.Borrel) return AI.Attack(attacker, defender); + if ((attacker.Id == CardId.Ultimate || attacker.Id == CardId.Cardian) && attacker.RealPower > defender.RealPower) return AI.Attack(attacker, defender); } if (!OnPreBattleBetween(attacker, defender)) @@ -1752,7 +1769,7 @@ public override ClientCard OnSelectAttacker(IList attackers, IList Date: Tue, 10 Apr 2018 00:08:15 +0800 Subject: [PATCH 54/68] fix ThreateningRoareff of ChainBurn deck --- Game/AI/Decks/ChainBurnExecutor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Game/AI/Decks/ChainBurnExecutor.cs b/Game/AI/Decks/ChainBurnExecutor.cs index aba54a8a..060ed4b1 100644 --- a/Game/AI/Decks/ChainBurnExecutor.cs +++ b/Game/AI/Decks/ChainBurnExecutor.cs @@ -428,7 +428,7 @@ private bool ThreateningRoareff() { if (drawfirst) return true; if (must_chain()) return true; - if (prevent_used||Duel.Phase!=DuelPhase.Main1) return false; + if (prevent_used || Duel.Phase != DuelPhase.BattleStart) return false; prevent_used = true; return DefaultUniqueTrap(); } From 4b2ffc2790ef3734e1050d32fe5e1a09117297db Mon Sep 17 00:00:00 2001 From: handsomekiwi <36762809+handsomekiwi@users.noreply.github.com> Date: Tue, 10 Apr 2018 23:46:28 +0800 Subject: [PATCH 55/68] update ChainBurn deck, fix DefaultBreakthroughSkill (#40) --- Game/AI/Decks/ChainBurnExecutor.cs | 58 +++++++++++------ .../LightswornShaddoldinosourExecutor.cs | 62 ++++++++++++++----- Game/AI/DefaultExecutor.cs | 5 +- 3 files changed, 88 insertions(+), 37 deletions(-) diff --git a/Game/AI/Decks/ChainBurnExecutor.cs b/Game/AI/Decks/ChainBurnExecutor.cs index 060ed4b1..7e0ab571 100644 --- a/Game/AI/Decks/ChainBurnExecutor.cs +++ b/Game/AI/Decks/ChainBurnExecutor.cs @@ -181,10 +181,11 @@ public int[] now_List() }; } - public int[] prevent_list() + public int[] pot_list() { return new[] { + CardId.PotOfDesires, CardId.SandaionTheTimloard, CardId.BattleFader, @@ -205,10 +206,9 @@ public int GetTotalATK(IList list) } return atk; } - public bool Has_prevent_list(int id) + public bool Has_prevent_list_0(int id) { - return (id == CardId.SandaionTheTimloard || - id == CardId.BattleFader || + return ( id == CardId.Waboku || id == CardId.ThreateningRoar|| id == CardId.MagicCylinder|| @@ -216,6 +216,12 @@ public bool Has_prevent_list(int id) id == CardId.RingOfDestruction ); } + public bool Has_prevent_list_1(int id) + { + return (id == CardId.SandaionTheTimloard || + id == CardId.BattleFader + ); + } bool no_sp = false; bool one_turn_kill = false; bool one_turn_kill_1 = false; @@ -223,7 +229,7 @@ public bool Has_prevent_list(int id) bool prevent_used = false; int preventcount = 0; bool battleprevent = false; - bool OjamaTrioused = false; + bool OjamaTrioused = false; bool OjamaTrioused_draw = false; bool drawfirst = false; int Waboku_count = 0; @@ -243,10 +249,9 @@ public override bool OnSelectHand() public override void OnNewTurn() { - + no_sp = false; - prevent_used = false; - battleprevent = false; + prevent_used = false; } @@ -260,7 +265,7 @@ public override void OnNewPhase() foreach (ClientCard card in trap) { - if (Has_prevent_list(card.Id)) + if (Has_prevent_list_0(card.Id)) { preventcount++; battleprevent = true; @@ -269,7 +274,7 @@ public override void OnNewPhase() } foreach (ClientCard card in monster) { - if (Has_prevent_list(card.Id)) + if (Has_prevent_list_1(card.Id)) { preventcount++; battleprevent = true; @@ -380,8 +385,14 @@ private bool must_chain() } return false; } + private bool OjamaTrioset() + { + if (Bot.HasInSpellZone(CardId.OjamaTrio)) return false; + return true; + } private bool BrunSpellSet() { + if (Card.Id == CardId.OjamaTrio && Bot.HasInSpellZone(CardId.OjamaTrio))return false; return (Card.IsTrap() || Card.HasType(CardType.QuickPlay)) && Bot.GetSpellCountWithoutField() < 5; } private bool SandaionTheTimloard_summon() @@ -409,7 +420,8 @@ private bool AbouluteKingBackJackeff() private bool PotOfDualityeff() { no_sp = true; - AI.SelectCard(prevent_list()); + + AI.SelectCard(pot_list()); return true; } private bool BlazingMirrorForceeff() @@ -479,9 +491,18 @@ public bool Ring_act() } private bool RecklessGreedeff() { + int count=0; + foreach (ClientCard card in Bot.GetSpells()) + { + if (card.Id == CardId.RecklessGreed) + count++; + + } + bool Demiseused = AI.Utils.ChainContainsCard(CardId.CardOfDemise); if (drawfirst) return DefaultUniqueTrap(); - if (must_chain() && greed_count > 1) return true; - if (greed_count > 1) return true; + if (must_chain() && count > 1) return true; + if (Demiseused) return false; + if (count > 1) return true; if (Bot.LifePoints <= 2000) return true; if (Bot.GetHandCount() <1 && Duel.Player==0 && Duel.Phase!=DuelPhase.Standby) return true; return false; @@ -509,18 +530,14 @@ private bool SecretBlasteff() return false; } - private bool OjamaTrioset() - { - - if (Bot.HasInSpellZone(CardId.OjamaTrio)) return false; - return true; - } + private bool OjamaTrioeff() { return OjamaTrioused||OjamaTrioused_draw; } private bool JustDessertseff() { + if (Duel.Player == 0) return false; if (drawfirst) return DefaultUniqueTrap(); if (one_turn_kill_1) return DefaultUniqueTrap(); if (one_turn_kill) return DefaultUniqueTrap(); @@ -537,6 +554,7 @@ private bool JustDessertseff() } private bool ChainStrikeeff() { + if (drawfirst) return true; if (must_chain()) return true; int chain = Duel.CurrentChain.Count; @@ -593,7 +611,7 @@ private bool Ceasefireeff() } private bool Linkuriboheff() { - ClientCard lastchaincard = AI.Utils.GetLastChainCard(); + ClientCard lastchaincard = AI.Utils.GetLastChainCard(); if (lastchaincard == null) return true; if (lastchaincard.Id == CardId.Linkuriboh) return false; return true; diff --git a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs index fb08498d..8b83b47d 100644 --- a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs +++ b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs @@ -144,13 +144,13 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) AddExecutor(ExecutorType.SpellSet, CardId.MonsterReborn, spellset); AddExecutor(ExecutorType.SpellSet, CardId.PotOfAvarice, spellset); AddExecutor(ExecutorType.SpellSet, CardId.ThatGrassLooksgreener, spellset); - //trap + //trapset AddExecutor(ExecutorType.SpellSet, CardId.LostWind, TrapSetWhenZoneFree); AddExecutor(ExecutorType.SpellSet, CardId.SinisterShadowGames, TrapSetWhenZoneFree); AddExecutor(ExecutorType.SpellSet, CardId.ShaddollCore); AddExecutor(ExecutorType.SpellSet, CardId.infiniteTransience, SetIsFieldEmpty); //trap activate - AddExecutor(ExecutorType.Activate, CardId.LostWind, DefaultBreakthroughSkill); + AddExecutor(ExecutorType.Activate, CardId.LostWind, LostWindeff); AddExecutor(ExecutorType.Activate, CardId.SinisterShadowGames, SinisterShadowGameseff); AddExecutor(ExecutorType.Activate, CardId.ShaddollCore, ShaddollCoreeff); AddExecutor(ExecutorType.Repos, MonsterRepos); @@ -262,12 +262,12 @@ private bool UltimateConductorTytannoeff() CardId.GhostOgre, CardId.MaxxC, }; - if (Bot.HasInHand(targets)|| Bot.HasInMonstersZone(targets)) - { - AI.SelectCard(targets); - return true; + if (!Bot.HasInHand(targets) || !Bot.HasInMonstersZone(targets)) + { + return false; } - + AI.SelectCard(targets); + return true; } if (Duel.Phase == DuelPhase.BattleStart) { @@ -313,6 +313,7 @@ private bool MonsterRepos() private bool OvertexCoatlseff() { if (Card.Location == CardLocation.MonsterZone) return false; + OvertexCoatlseff_used = true; return true; } @@ -485,10 +486,14 @@ private bool AllureofDarkness() } return false; } + + private bool spellset() { return Bot.Hand.Count > 6; } + + private bool RebornEffect() { if(Bot.HasInGraveyard(CardId.UltimateConductorTytanno)&&Ultimate_ss>0) @@ -509,6 +514,8 @@ private bool RebornEffect() AI.SelectCard(targets); return true; } + + private bool PotofAvariceeff() { return true; @@ -518,10 +525,14 @@ private bool MaxxC() { return Duel.Player == 1; } + + private bool SetIsFieldEmpty() { return !Bot.IsFieldEmpty(); } + + private bool TrapSetWhenZoneFree() { return Bot.GetSpellCountWithoutField() < 4; @@ -553,6 +564,8 @@ private bool ElShaddollConstructeff() } return true; } + + private bool ElShaddollShekhinagaeff() { if (Card.Location != CardLocation.MonsterZone) @@ -576,6 +589,8 @@ private bool ElShaddollShekhinagaeff() } return true; } + + private bool ElShaddollGrysraeff() { if (Card.Location != CardLocation.MonsterZone) @@ -690,6 +705,8 @@ private bool ShaddollFalcoeff() } return true; } + + private bool ShaddollHedgehogeff() { if (Card.Location != CardLocation.MonsterZone) @@ -705,6 +722,8 @@ private bool ShaddollHedgehogeff() } return true; } + + private bool ShaddollDragoneff() { if (Card.Location == CardLocation.MonsterZone) @@ -720,6 +739,8 @@ private bool ShaddollDragoneff() return true; } } + + private bool ShaddollSquamataeff() { if (Card.Location != CardLocation.MonsterZone) @@ -739,6 +760,17 @@ private bool ShaddollSquamataeff() } return true; } + + private bool LostWindeff() + { + List check = Enemy.GetMonsters(); + foreach (ClientCard m in check) + { + if (m.Attack>=2000) return DefaultBreakthroughSkill(); + } + return false; + } + private bool FoolishBurialEffect() { if (Bot.GetRemainingCount(CardId.DoubleEvolutionPill, 3) > 0) @@ -752,7 +784,6 @@ private bool FoolishBurialEffect() return true; } return false; - } else { @@ -761,12 +792,9 @@ private bool FoolishBurialEffect() CardId.ShaddollSquamata, CardId.FairyTailSnow, }); - } - return true; - } - + } public bool Hand_act_eff() @@ -823,6 +851,8 @@ private bool MinervaTheExaltedEffect() return true; } } + + public bool CrystronNeedlefibersp() { if (Bot.HasInMonstersZone(CardId.ElShaddollConstruct) || @@ -879,6 +909,7 @@ public bool CrystronNeedlefibereff() return false; } + private bool ScarlightRedDragoneff() { IList targets = new List(); @@ -891,6 +922,8 @@ private bool ScarlightRedDragoneff() } return false; } + + private bool CrystalWingSynchroDragoneff() { return Duel.LastChainPlayer != 0; @@ -926,7 +959,6 @@ private bool Sdulldeateff() }*/ return false; } - private bool BlackRoseMoonlightDragoneff() { @@ -941,6 +973,8 @@ private bool BlackRoseMoonlightDragoneff() return false; } + + private bool RedWyverneff() { IList check = Enemy.MonsterZone; @@ -957,8 +991,6 @@ private bool RedWyverneff() return false; } - - private bool CoralDragoneff() { if (Card.Location != CardLocation.MonsterZone) diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index 06ee7893..ab156d7f 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -307,9 +307,10 @@ protected bool DefaultBreakthroughSkill() if (LastChainCard == null) return false; - + if (LastChainCard.Controller != 1 || LastChainCard.Location != CardLocation.MonsterZone || !DefaultUniqueTrap()) + return false; AI.SelectCard(LastChainCard); - return LastChainCard.Controller == 1 && LastChainCard.Location == CardLocation.MonsterZone && DefaultUniqueTrap(); + return true; } /// From 5d176811c91f2510238ed8a289646c2f0f2e45c6 Mon Sep 17 00:00:00 2001 From: handsomekiwi <36762809+handsomekiwi@users.noreply.github.com> Date: Wed, 11 Apr 2018 22:14:33 +0800 Subject: [PATCH 56/68] update ChainBurn deck (#41) --- Game/AI/Decks/ChainBurnExecutor.cs | 50 +++++++++++++------ .../LightswornShaddoldinosourExecutor.cs | 6 +++ Game/GameAI.cs | 1 + 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/Game/AI/Decks/ChainBurnExecutor.cs b/Game/AI/Decks/ChainBurnExecutor.cs index 7e0ab571..a2caf537 100644 --- a/Game/AI/Decks/ChainBurnExecutor.cs +++ b/Game/AI/Decks/ChainBurnExecutor.cs @@ -232,6 +232,7 @@ public bool Has_prevent_list_1(int id) bool OjamaTrioused = false; bool OjamaTrioused_draw = false; bool drawfirst = false; + bool Linkuribohused = true; int Waboku_count = 0; int Roar_count = 0; int strike_count = 0; @@ -251,8 +252,8 @@ public override void OnNewTurn() no_sp = false; - prevent_used = false; - + prevent_used = false; + Linkuribohused = true; } public override void OnNewPhase() @@ -260,8 +261,9 @@ public override void OnNewPhase() preventcount = 0; battleprevent = false; OjamaTrioused = false; - IList trap = Bot.SpellZone; - IList monster = Bot.MonsterZone; + + IList trap = Bot.GetSpells(); + IList monster = Bot.GetMonsters(); foreach (ClientCard card in trap) { @@ -297,7 +299,7 @@ public override void OnNewPhase() Roar_count = 0; Ojama_count = 0; - IList check = Bot.SpellZone; + IList check = Bot.GetSpells(); foreach (ClientCard card in check) { if (card.Id == CardId.AccuulatedFortune) @@ -352,7 +354,7 @@ public override void OnNewPhase() } expected_blood = (Enemy.GetMonsterCount() * 500 * just_count + Enemy.GetFieldHandCount() * 200 * barrel_count + Enemy.GetFieldCount() * 300 * blast_count); - if (Enemy.LifePoints <= expected_blood) one_turn_kill = true; + //if (Enemy.LifePoints <= expected_blood && Duel.Player == 1) one_turn_kill = true; if (greed_count >= 2) greed_count = 1; if (blast_count >= 2) blast_count = 1; if (just_count >= 2) just_count = 1; @@ -365,10 +367,10 @@ public override void OnNewPhase() currentchain = Duel.CurrentChain.Count + blast_count + just_count + barrel_count + Waboku_count + Waboku_count + Roar_count + greed_count + strike_count + Ojama_count; else currentchain = Duel.CurrentChain.Count + blast_count + just_count + barrel_count + Waboku_count + Waboku_count + greed_count + Roar_count + strike_count; - if (currentchain >= 3) drawfirst = true; + //if (currentchain >= 3 && Duel.Player == 1) drawfirst = true; currentchain = Duel.CurrentChain.Count+ blast_count + just_count+barrel_count; expected_blood = (Enemy.GetMonsterCount() * 500 * just_count + Enemy.GetFieldHandCount() * 200 * barrel_count + Enemy.GetFieldCount() * 300 * blast_count+(currentchain+1)*400); - if (Enemy.LifePoints <= expected_blood) one_turn_kill_1 = true; + //if (Enemy.LifePoints <= expected_blood && Duel.Player==1) one_turn_kill_1 = true; } @@ -439,7 +441,7 @@ private bool BlazingMirrorForceeff() private bool ThreateningRoareff() { if (drawfirst) return true; - if (must_chain()) return true; + if (must_chain()) return DefaultUniqueTrap(); if (prevent_used || Duel.Phase != DuelPhase.BattleStart) return false; prevent_used = true; return DefaultUniqueTrap(); @@ -452,11 +454,19 @@ private bool SandaionTheTimloardeff() } private bool Wabokueff() { - if (drawfirst) return true; - if (must_chain()) return true; - if (drawfirst) return true; + if (drawfirst) + { + Linkuribohused = false; + return true; + } + if (must_chain()) + { + Linkuribohused = false; + return DefaultUniqueTrap(); + } if (prevent_used||Duel.Player == 0||Duel.Phase!=DuelPhase.BattleStart) return false; prevent_used = true; + Linkuribohused = false; return DefaultUniqueTrap(); } private bool BattleFadereff() @@ -610,10 +620,18 @@ private bool Ceasefireeff() return false; } private bool Linkuriboheff() - { - ClientCard lastchaincard = AI.Utils.GetLastChainCard(); - if (lastchaincard == null) return true; - if (lastchaincard.Id == CardId.Linkuriboh) return false; + { + + IList newlist = new List(); + foreach (ClientCard newmonster in Enemy.GetMonsters()) + { + newlist.Add(newmonster); + } + if (!Linkuribohused) return false; + if (Enemy.BattlingMonster.Attack > 1800 && Bot.HasInSpellZone(CardId.MagicCylinder)) return false; + if (GetTotalATK(newlist) >= 3000 && Bot.HasInSpellZone(CardId.BlazingMirrorForce)) return false; + if (AI.Utils.GetLastChainCard() == null) return true; + if (AI.Utils.GetLastChainCard().Id == CardId.Linkuriboh)return false; return true; } diff --git a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs index 8b83b47d..e06c26f9 100644 --- a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs +++ b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs @@ -600,6 +600,12 @@ private bool ElShaddollGrysraeff() private bool ShaddollFusioneff() { + if (Bot.HasInMonstersZone(CardId.ElShaddollConstruct) || + Bot.HasInMonstersZone(CardId.ElShaddollGrysra) || + Bot.HasInMonstersZone(CardId.ElShaddollShekhinaga) || + Bot.HasInMonstersZone(CardId.ElShaddollWinda )) + return false; + bool deck_check = false; List monsters = Enemy.GetMonsters(); foreach (ClientCard monster in monsters) diff --git a/Game/GameAI.cs b/Game/GameAI.cs index 78b2a50a..71470129 100644 --- a/Game/GameAI.cs +++ b/Game/GameAI.cs @@ -94,6 +94,7 @@ public void OnNewPhase() { _dialogs.SendNewTurn(); } + Executor.OnNewPhase(); } /// From 3f231833bde257e695398036f667666dd26204e2 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Wed, 11 Apr 2018 22:55:55 +0800 Subject: [PATCH 57/68] version --- BotWrapper/bot.conf | 15 +++++++++++++++ README.md | 24 ++++++++++++++++++++---- WindBotInfo.cs | 2 +- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/BotWrapper/bot.conf b/BotWrapper/bot.conf index 2a048c31..c972efa3 100644 --- a/BotWrapper/bot.conf +++ b/BotWrapper/bot.conf @@ -49,6 +49,11 @@ Name=尼亚 Deck=Qliphort Dialog=near.zh-CN 机壳卡组。 SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE +!尼亚-淘气仙星 +Name=尼亚 Deck=Trickstar Dialog=near.zh-CN +淘气仙星卡组。 +SUPPORT_NEW_MASTER_RULE + !永远之魂-削血 Name=永远之魂 Deck=Burn Dialog=soul.zh-CN 老式削血卡组。 @@ -78,3 +83,13 @@ SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE Name=试作型机器人1732 Deck=ST1732 Dialog=zh-CN 由三盒ST17和三盒SD32组成的卡组。 SUPPORT_NEW_MASTER_RULE + +!奇異果 +Name=奇異果 Deck=LightswornShaddoldinosour Dialog=kiwi.zh-TW +光道影依恐龙卡组。 +SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE + +!燃血鬥士 +Name=燃血鬥士 Deck=ChainBurn Dialog=kiwi.zh-TW +连锁烧卡组。 +SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE diff --git a/README.md b/README.md index 16ee1eb1..61fcd157 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,8 @@ WindBot can run as a "server", provide a http interface to create bot. * Toadally Awesome (old lflist, master rule 3 only) +* Trickstar + * Yosenju * Zexal Weapons @@ -83,6 +85,8 @@ WindBot can run as a "server", provide a http interface to create bot. * Blackwing +* ChainBurn + * CyberDragon * Evilswarm @@ -93,6 +97,8 @@ WindBot can run as a "server", provide a http interface to create bot. * Lightsworn +* LightswornShaddoldinosour + * Nekroz ### Server mode @@ -107,12 +113,24 @@ The parameters are same as commandlines, but low cased. ### Known issues -* The attack won't be canceled when battle replay happens. - * If one chain includes two activation that use `AI.SelectCard`, the second one won't select correctly. ### Changelog +#### v0x1343 (2018-04-11) + + - Update YGOPro protrol to 0x1343 + - New decks: Trickstar, LightswornShaddoldinosour, ChainBurn + - Update `OnBattle`, add `Executor.OnSelectAttacker` and `Executor.OnSelectAttackTarget` + - Add `Executor.OnSelectPosition`, `Executor.OnSelectBattleReplay` + - Add `Bot.BattlingMonster` + - Add and update some default executors + - Change `Duel.LifePoints[0]` to `Bot.LifePoints` + - Change `LastChainPlayer` and `CurrentChain` to `Duel` class + - Change `ChainContainsCard` and `GetLastChainCard` etc. to `AI.Utils` class + - Fix turn count in match duel + - Fix don't turn 0 atk monster to atk pos + #### v0x1342 (2017-12-26) - Update YGOPro protrol to 0x1342 @@ -173,8 +191,6 @@ The parameters are same as commandlines, but low cased. * Get equip of card. -* Get attack target. - * Better new master rule support * Update the known card enums diff --git a/WindBotInfo.cs b/WindBotInfo.cs index 2d9500e6..4cd12371 100644 --- a/WindBotInfo.cs +++ b/WindBotInfo.cs @@ -21,7 +21,7 @@ public WindBotInfo() Host = "127.0.0.1"; Port = 7911; HostInfo = ""; - Version = 0x1342; + Version = 0x1343; Hand = 0; } } From f379e16a4768a1dbc6deec4341cbabdb4f0bdf19 Mon Sep 17 00:00:00 2001 From: handsomekiwi <36762809+handsomekiwi@users.noreply.github.com> Date: Mon, 16 Apr 2018 22:42:53 +0800 Subject: [PATCH 58/68] update LightswornShaddoldinosour and ChainBurn deck (#43) --- Game/AI/Decks/ChainBurnExecutor.cs | 41 +- .../LightswornShaddoldinosourExecutor.cs | 591 +++++++++++++----- Game/AI/DefaultExecutor.cs | 10 + Game/AI/Enums/Floodgate.cs | 10 +- Game/GameBehavior.cs | 4 +- 5 files changed, 474 insertions(+), 182 deletions(-) diff --git a/Game/AI/Decks/ChainBurnExecutor.cs b/Game/AI/Decks/ChainBurnExecutor.cs index a2caf537..0ec88a04 100644 --- a/Game/AI/Decks/ChainBurnExecutor.cs +++ b/Game/AI/Decks/ChainBurnExecutor.cs @@ -353,8 +353,13 @@ public override void OnNewPhase() if (HasAccuulatedFortune>0) OjamaTrioused_draw = true; } - expected_blood = (Enemy.GetMonsterCount() * 500 * just_count + Enemy.GetFieldHandCount() * 200 * barrel_count + Enemy.GetFieldCount() * 300 * blast_count); - //if (Enemy.LifePoints <= expected_blood && Duel.Player == 1) one_turn_kill = true; + expected_blood = (Enemy.GetMonsterCount() * 500 * just_count + Enemy.GetFieldHandCount() * 200 * barrel_count + Enemy.GetFieldCount() * 300 * blast_count); + if (Enemy.LifePoints <= expected_blood && Duel.Player == 1) + { + Logger.DebugWriteLine(" one_turn_kill"); + one_turn_kill = true; + } + expected_blood = 0; if (greed_count >= 2) greed_count = 1; if (blast_count >= 2) blast_count = 1; if (just_count >= 2) just_count = 1; @@ -370,8 +375,12 @@ public override void OnNewPhase() //if (currentchain >= 3 && Duel.Player == 1) drawfirst = true; currentchain = Duel.CurrentChain.Count+ blast_count + just_count+barrel_count; expected_blood = (Enemy.GetMonsterCount() * 500 * just_count + Enemy.GetFieldHandCount() * 200 * barrel_count + Enemy.GetFieldCount() * 300 * blast_count+(currentchain+1)*400); - //if (Enemy.LifePoints <= expected_blood && Duel.Player==1) one_turn_kill_1 = true; - + + /*if (!one_turn_kill && Enemy.LifePoints <= expected_blood && Duel.Player == 1) + { + Logger.DebugWriteLine(" one_turn_kill_1"); + one_turn_kill_1 = true; + }*/ } @@ -410,8 +419,7 @@ private bool AbouluteKingBackJacksummon() private bool AbouluteKingBackJackeff() { if (ActivateDescription == -1) - { - + { AI.SelectCard(AbouluteKingBackJack_List_1()); AI.SelectNextCard(AbouluteKingBackJack_List_2()); } @@ -441,7 +449,7 @@ private bool BlazingMirrorForceeff() private bool ThreateningRoareff() { if (drawfirst) return true; - if (must_chain()) return DefaultUniqueTrap(); + if (DefaultOnBecomeTarget()) return DefaultUniqueTrap(); if (prevent_used || Duel.Phase != DuelPhase.BattleStart) return false; prevent_used = true; return DefaultUniqueTrap(); @@ -459,7 +467,7 @@ private bool Wabokueff() Linkuribohused = false; return true; } - if (must_chain()) + if (DefaultOnBecomeTarget()) { Linkuribohused = false; return DefaultUniqueTrap(); @@ -510,7 +518,7 @@ private bool RecklessGreedeff() } bool Demiseused = AI.Utils.ChainContainsCard(CardId.CardOfDemise); if (drawfirst) return DefaultUniqueTrap(); - if (must_chain() && count > 1) return true; + if (DefaultOnBecomeTarget() && count > 1) return true; if (Demiseused) return false; if (count > 1) return true; if (Bot.LifePoints <= 2000) return true; @@ -522,7 +530,7 @@ private bool SectetBarreleff() if (drawfirst) return DefaultUniqueTrap(); if (one_turn_kill_1) return DefaultUniqueTrap(); if (one_turn_kill) return DefaultUniqueTrap(); - if (must_chain()) return true; + if (DefaultOnBecomeTarget()) return true; int count = Enemy.GetFieldHandCount(); if (Enemy.LifePoints < count * 200) return true; if (count >= 8) return true; @@ -533,7 +541,7 @@ private bool SecretBlasteff() if (drawfirst) return DefaultUniqueTrap(); if (one_turn_kill_1) return DefaultUniqueTrap(); if (one_turn_kill) return DefaultUniqueTrap(); - if (must_chain()) return true; + if (DefaultOnBecomeTarget()) return true; int count = Enemy.GetFieldCount(); if (Enemy.LifePoints < count * 300) return true; if (count >= 5) return true; @@ -551,7 +559,7 @@ private bool JustDessertseff() if (drawfirst) return DefaultUniqueTrap(); if (one_turn_kill_1) return DefaultUniqueTrap(); if (one_turn_kill) return DefaultUniqueTrap(); - if (must_chain()) return true; + if (DefaultOnBecomeTarget()) return true; int count = Enemy.GetMonsterCount(); if (Enemy.LifePoints <= count * 500) return true; if (Bot.HasInSpellZone(CardId.OjamaTrio) && count <= 2 && count >= 1) @@ -566,7 +574,7 @@ private bool ChainStrikeeff() { if (drawfirst) return true; - if (must_chain()) return true; + if (DefaultOnBecomeTarget()) return true; int chain = Duel.CurrentChain.Count; if (strike_count >= 2 && chain >= 2) return true; if (Enemy.LifePoints <= (chain + 1) * 400) return true; @@ -576,7 +584,7 @@ private bool ChainStrikeeff() private bool BalanceOfJudgmenteff() { - if (must_chain()) return true; + if (DefaultOnBecomeTarget()) return true; int count = (Enemy.GetFieldCount() - Bot.GetFieldHandCount()); if ( count>= 2)return true; return false; @@ -628,7 +636,10 @@ private bool Linkuriboheff() newlist.Add(newmonster); } if (!Linkuribohused) return false; - if (Enemy.BattlingMonster.Attack > 1800 && Bot.HasInSpellZone(CardId.MagicCylinder)) return false; + if(Enemy.BattlingMonster!=null) + { + if (Enemy.BattlingMonster.Attack > 1800 && Bot.HasInSpellZone(CardId.MagicCylinder)) return false; + } if (GetTotalATK(newlist) >= 3000 && Bot.HasInSpellZone(CardId.BlazingMirrorForce)) return false; if (AI.Utils.GetLastChainCard() == null) return true; if (AI.Utils.GetLastChainCard().Id == CardId.Linkuriboh)return false; diff --git a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs index e06c26f9..0850c541 100644 --- a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs +++ b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs @@ -7,7 +7,7 @@ namespace WindBot.Game.AI.Decks { // NOT FINISHED YET - [Deck("LightswornShaddoldinosour", "AI_LightswornShaddoldinosour", "ver0.1")] + [Deck("LightswornShaddoldinosour", "AI_LightswornShaddoldinosour", "ver0.5")] public class LightswornShaddoldinosour : DefaultExecutor { public class CardId @@ -46,7 +46,7 @@ public class CardId public const int MonsterReborn = 83764718; public const int ChargeOfTheLightBrigade = 94886282; public const int InterruptedKaijuSlumber = 99330325; - public const int ElShaddollFusion = 6417578; + //public const int ElShaddollFusion = 6417578; //trap public const int infiniteTransience = 10045474; @@ -76,8 +76,7 @@ public class CardId public LightswornShaddoldinosour(GameAI ai, Duel duel) : base(ai, duel) { - //counter - + //counter AddExecutor(ExecutorType.Activate, CardId.GhostOgre, Hand_act_eff); AddExecutor(ExecutorType.Activate, CardId.AshBlossom, Hand_act_eff); AddExecutor(ExecutorType.Activate, CardId.MaxxC,MaxxC); @@ -91,26 +90,23 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.PotOfAvarice, PotofAvariceeff); AddExecutor(ExecutorType.Activate, CardId.ChargeOfTheLightBrigade, ChargeOfTheLightBrigadeEffect); AddExecutor(ExecutorType.Activate, CardId.FoolishBurial, FoolishBurialEffect); - AddExecutor(ExecutorType.Activate, CardId.InterruptedKaijuSlumber, DefaultInterruptedKaijuSlumber); + AddExecutor(ExecutorType.Activate, CardId.InterruptedKaijuSlumber, InterruptedKaijuSlumbereff); AddExecutor(ExecutorType.Activate, CardId.ShaddollFusion, ShaddollFusioneff); - //Reborn - AddExecutor(ExecutorType.Activate, CardId.MonsterReborn, RebornEffect); - //Normal Summon + //Normal Summon AddExecutor(ExecutorType.Summon, CardId.Raiden); - AddExecutor(ExecutorType.Activate, CardId.Raiden); + AddExecutor(ExecutorType.Activate, CardId.Raiden); AddExecutor(ExecutorType.Summon , CardId.KeeperOfDragonicMagic); AddExecutor(ExecutorType.Activate, CardId.KeeperOfDragonicMagic, KeeperOfDragonicMagiceff); AddExecutor(ExecutorType.MonsterSet, CardId.ShaddollSquamata); AddExecutor(ExecutorType.MonsterSet, CardId.GlowUpBulb); + AddExecutor(ExecutorType.Summon, CardId.Lumina, Luminasummon); AddExecutor(ExecutorType.MonsterSet, CardId.ShaddollHedgehog); AddExecutor(ExecutorType.MonsterSet, CardId.ShaddollDragon); AddExecutor(ExecutorType.Summon, CardId.FairyTailSnow,FairyTailSnowsummon); - AddExecutor(ExecutorType.Activate, CardId.FairyTailSnow, FairyTailSnoweff); - AddExecutor(ExecutorType.Summon, CardId.Lumina); - AddExecutor(ExecutorType.Activate, CardId.Lumina); + AddExecutor(ExecutorType.Activate, CardId.FairyTailSnow, FairyTailSnoweff); + AddExecutor(ExecutorType.Activate, CardId.Lumina, Luminaeff); //activate - AddExecutor(ExecutorType.Activate, CardId.GlowUpBulb, GlowUpBulbeff); - AddExecutor(ExecutorType.Activate, CardId.CrystronNeedlefiber, CrystronNeedlefibereff); + AddExecutor(ExecutorType.Activate, CardId.GlowUpBulb, GlowUpBulbeff); AddExecutor(ExecutorType.Activate, CardId.TG_WonderMagician); AddExecutor(ExecutorType.Activate, CardId.CoralDragon, CoralDragoneff); AddExecutor(ExecutorType.Activate, CardId.RedWyvern, RedWyverneff); @@ -120,39 +116,54 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.Michael, Michaeleff); AddExecutor(ExecutorType.Activate, CardId.ScarlightRedDragon, ScarlightRedDragoneff); //Sp Summon - //AddExecutor(ExecutorType.SpSummon, CardId.CrystronNeedlefiber, CrystronNeedlefibersp); + + AddExecutor(ExecutorType.Activate, CardId.CrystronNeedlefiber, CrystronNeedlefibereff); AddExecutor(ExecutorType.SpSummon, CardId.UltimateConductorTytanno, UltimateConductorTytannosp); AddExecutor(ExecutorType.Activate, CardId.UltimateConductorTytanno, UltimateConductorTytannoeff); AddExecutor(ExecutorType.Activate, CardId.DoubleEvolutionPill, DoubleEvolutionPilleff); + //extra + AddExecutor(ExecutorType.SpSummon, CardId.CrystalWingSynchroDragon); + AddExecutor(ExecutorType.Activate, CardId.CrystalWingSynchroDragon, CrystalWingSynchroDragoneff); + AddExecutor(ExecutorType.SpSummon, CardId.ScarlightRedDragon, ScarlightRedDragonsp); + AddExecutor(ExecutorType.Activate, CardId.ScarlightRedDragon, ScarlightRedDragoneff); + AddExecutor(ExecutorType.SpSummon, CardId.Michael, Michaelsp); + AddExecutor(ExecutorType.Activate, CardId.Michael, Michaeleff); + AddExecutor(ExecutorType.SpSummon, CardId.RedWyvern, RedWyvernsp); + AddExecutor(ExecutorType.Activate, CardId.RedWyvern, RedWyverneff); AddExecutor(ExecutorType.SpSummon, CardId.MinervaTheExalte); AddExecutor(ExecutorType.Activate, CardId.MinervaTheExalte, MinervaTheExaltedEffect); - AddExecutor(ExecutorType.SpSummon, CardId.GamecieltheSeaTurtleKaiju, DefaultKaijuSpsummon); - + AddExecutor(ExecutorType.SpSummon, CardId.CrystronNeedlefiber, CrystronNeedlefibersp); + //Kaiju + AddExecutor(ExecutorType.SpSummon, CardId.GamecieltheSeaTurtleKaiju, DefaultKaijuSpsummon); + AddExecutor(ExecutorType.SpSummon, CardId.RadiantheMultidimensionalKaiju, RadiantheMultidimensionalKaijusp); + AddExecutor(ExecutorType.SpSummon, CardId.DogorantheMadFlameKaiju, DogorantheMadFlameKaijusp); + //Reborn + AddExecutor(ExecutorType.Activate, CardId.MonsterReborn, Reborneff); //activate chain AddExecutor(ExecutorType.Activate, CardId.OvertexCoatls, OvertexCoatlseff); - AddExecutor(ExecutorType.Activate, CardId.ShaddollBeast); - AddExecutor(ExecutorType.Activate, CardId.ShaddollFalco, ShaddollFalcoeff); - AddExecutor(ExecutorType.Activate, CardId.ShaddollSquamata, ShaddollSquamataeff); + AddExecutor(ExecutorType.Activate, CardId.ShaddollCore, ShaddollCoreeff); + AddExecutor(ExecutorType.Activate, CardId.ShaddollBeast, ShaddollBeasteff); + AddExecutor(ExecutorType.Activate, CardId.ShaddollFalco, ShaddollFalcoeff); AddExecutor(ExecutorType.Activate, CardId.ShaddollDragon, ShaddollDragoneff); AddExecutor(ExecutorType.Activate, CardId.ShaddollHedgehog, ShaddollHedgehogeff); + AddExecutor(ExecutorType.Activate, CardId.ShaddollSquamata, ShaddollSquamataeff); AddExecutor(ExecutorType.Activate, CardId.GiantRex); AddExecutor(ExecutorType.Activate, CardId.ElShaddollConstruct, ElShaddollConstructeff); AddExecutor(ExecutorType.Activate, CardId.ElShaddollGrysra, ElShaddollGrysraeff); AddExecutor(ExecutorType.Activate, CardId.ElShaddollShekhinaga, ElShaddollShekhinagaeff); AddExecutor(ExecutorType.Activate, CardId.ElShaddollWinda); - //spellset - AddExecutor(ExecutorType.SpellSet, CardId.MonsterReborn, spellset); - AddExecutor(ExecutorType.SpellSet, CardId.PotOfAvarice, spellset); - AddExecutor(ExecutorType.SpellSet, CardId.ThatGrassLooksgreener, spellset); + //spellset + AddExecutor(ExecutorType.SpellSet, CardId.ThatGrassLooksgreener, SpellSetZone); + AddExecutor(ExecutorType.SpellSet, SpellSetZone); //trapset - AddExecutor(ExecutorType.SpellSet, CardId.LostWind, TrapSetWhenZoneFree); - AddExecutor(ExecutorType.SpellSet, CardId.SinisterShadowGames, TrapSetWhenZoneFree); + AddExecutor(ExecutorType.SpellSet, CardId.LostWind); + AddExecutor(ExecutorType.SpellSet, CardId.SinisterShadowGames); AddExecutor(ExecutorType.SpellSet, CardId.ShaddollCore); AddExecutor(ExecutorType.SpellSet, CardId.infiniteTransience, SetIsFieldEmpty); //trap activate AddExecutor(ExecutorType.Activate, CardId.LostWind, LostWindeff); AddExecutor(ExecutorType.Activate, CardId.SinisterShadowGames, SinisterShadowGameseff); - AddExecutor(ExecutorType.Activate, CardId.ShaddollCore, ShaddollCoreeff); + AddExecutor(ExecutorType.Repos, MonsterRepos); } public int[] all_List() @@ -191,7 +202,7 @@ public int[] all_List() CardId.MonsterReborn, CardId.ChargeOfTheLightBrigade, CardId.InterruptedKaijuSlumber, - CardId.ElShaddollFusion, + //CardId.ElShaddollFusion, CardId.infiniteTransience, CardId.LostWind, @@ -207,38 +218,92 @@ public int[] Useless_List() { CardId.GlowUpBulb, CardId.PlaguespreaderZombie, - CardId.InterruptedKaijuSlumber, - CardId.ChargeOfTheLightBrigade, - CardId.FoolishBurial, - CardId.HarpiesFeatherDuster, + CardId.ChargeOfTheLightBrigade, CardId.ThatGrassLooksgreener, + CardId.HarpiesFeatherDuster, CardId.FairyTailSnow, CardId.GiantRex, CardId.Lumina, CardId.OvertexCoatls, - + CardId.InterruptedKaijuSlumber, + CardId.FoolishBurial, }; } int Ultimate_ss = 0; + int Enemy_atk = 0; bool Pillused = false; bool CrystronNeedlefibereff_used = false; bool OvertexCoatlseff_used = false; + bool ShaddollBeast_used = false; + bool ShaddollFalco_used = false; + bool ShaddollSquamata_used = false; + bool ShaddollDragon_used = false; + bool ShaddollHedgehog_used = false; + + public int GetTotalATK(IList list) + { + + int atk = 0; + foreach (ClientCard c in list) + { + if (c == null) continue; + atk += c.Attack; + } + return atk; + } + public override void OnNewPhase() + { + Enemy_atk = 0; + IList list = new List(); + foreach (ClientCard monster in Enemy.GetMonsters()) + { + if(monster.IsAttack()) + list.Add(monster); + } + //if (GetTotalATK(list) / 2 >= Bot.LifePoints) return false; + Enemy_atk = GetTotalATK(list); + //SLogger.DebugWriteLine("++++++++++++++++++" + Enemy_atk + "++++++++++++"); + } public override void OnNewTurn() { Pillused = false; OvertexCoatlseff_used = false; CrystronNeedlefibereff_used = false; + ShaddollBeast_used = false; + ShaddollFalco_used = false; + ShaddollSquamata_used = false; + ShaddollDragon_used = false; + ShaddollHedgehog_used = false; } - - private bool UltimateConductorTytannoeff() + private bool Luminasummon() { + if (Bot.Deck.Count >= 20) return true; + IList extra = Bot.GetMonstersInExtraZone(); + if (extra != null) + foreach (ClientCard monster in extra) + if (!monster.HasType(CardType.Link)) + return false; + if (Bot.LifePoints <= 3000) return true; + if (Bot.HasInGraveyard(CardId.Raiden)) return true; + return false; + } + private bool Luminaeff() + { + if (Bot.HasInGraveyard(CardId.Raiden)) + { + AI.SelectCard(Useless_List()); + AI.SelectNextCard(CardId.Raiden); + return true; + } + return false; + } - if (Duel.Phase == DuelPhase.Main1) - { - IList targets = new[] { + private bool UltimateConductorTytannoeff() + { + IList targets = new[] { CardId.OvertexCoatls, CardId.ShaddollBeast, CardId.ShaddollSquamata, @@ -249,12 +314,11 @@ private bool UltimateConductorTytannoeff() CardId.PlaguespreaderZombie, CardId.FairyTailSnow, CardId.KeeperOfDragonicMagic, - CardId.Raiden, - CardId.Lumina, CardId.DogorantheMadFlameKaiju, CardId.GamecieltheSeaTurtleKaiju, CardId.RadiantheMultidimensionalKaiju, - CardId.GiantRex, + CardId.GiantRex, + CardId.ShaddollCore, CardId.SouleatingOviraptor, CardId.Raiden, CardId.Lumina, @@ -262,8 +326,21 @@ private bool UltimateConductorTytannoeff() CardId.GhostOgre, CardId.MaxxC, }; - if (!Bot.HasInHand(targets) || !Bot.HasInMonstersZone(targets)) - { + + if (Duel.Phase == DuelPhase.Main1) + { + if(Duel.Player==0) + { + int count = 0; + IList check = Enemy.GetMonsters(); + foreach (ClientCard monster in check) + if (monster.Attack > 2500 || monster == Enemy.MonsterZone.GetDangerousMonster()) + count++; + if(count==0)return false; + } + if (!Bot.HasInHand(targets)) + { + if(!Bot.HasInMonstersZone(targets)) return false; } AI.SelectCard(targets); @@ -278,15 +355,39 @@ private bool UltimateConductorTytannoeff() } + + private bool RadiantheMultidimensionalKaijusp() + { + if (Enemy.HasInMonstersZone(CardId.GamecieltheSeaTurtleKaiju)) return true; + if (Bot.HasInHand(CardId.DogorantheMadFlameKaiju)) return DefaultKaijuSpsummon(); + return false; + } + + + private bool DogorantheMadFlameKaijusp() + { + if (Enemy.HasInMonstersZone(CardId.GamecieltheSeaTurtleKaiju)) return true; + if (Enemy.HasInMonstersZone(CardId.RadiantheMultidimensionalKaiju)) return true; + return false; + } + + + private bool InterruptedKaijuSlumbereff() + { + if (Enemy.GetMonsterCount() - Bot.GetMonsterCount() >= 2 ) + return DefaultInterruptedKaijuSlumber(); + return false; + } private bool UltimateConductorTytannosp() { - Ultimate_ss++; + Pillused = true; foreach (ClientCard card in Bot.GetMonsters()) { if (card.Id == CardId.UltimateConductorTytanno && card.IsFaceup()) return false; } + Ultimate_ss++; return true; } @@ -298,15 +399,14 @@ private bool KeeperOfDragonicMagiceff() AI.SelectCard(Useless_List()); return true; } - - return true; } private bool MonsterRepos() - { - if (Card.Id == CardId.ElShaddollConstruct && Card.IsAttack()) - return false; + { + if (Card.Id == CardId.ElShaddollConstruct && Card.IsAttack()) return false; + if (Card.Id == CardId.ShaddollDragon && Card.IsFacedown() && Enemy.GetMonsterCount() >= 0) return true; + if (Card.Id == CardId.ShaddollSquamata && Card.IsFacedown() && Enemy.GetMonsterCount() >= 0) return true; return base.DefaultMonsterRepos(); } @@ -418,9 +518,13 @@ private bool DoubleEvolutionPilleff() private bool FairyTailSnowsummon() { - - - return Enemy.GetMonsterCount()>=2; + IList list = Enemy.GetMonsters(); + if(list!=null) + { + if(list.GetHighestAttackMonster().IsFaceup()) + return true; + } + return false; } @@ -429,8 +533,45 @@ private bool FairyTailSnoweff() if (Card.Location == CardLocation.MonsterZone) { + AI.SelectCard(AI.Utils.GetBestEnemyMonster()); return true; } + else + { + + int spell_count = 0; + IList grave = Bot.Graveyard; + IList all = new List(); + foreach (ClientCard check in grave) + { + if(check.HasType(CardType.Spell)||check.HasType(CardType.Trap)) + { + spell_count++; + all.Add(check); + } + } + foreach (ClientCard check in grave) + { + if (check.HasType(CardType.Monster)) + { + all.Add(check); + } + } + if (AI.Utils.GetLastChainCard()!=null) + { + if (AI.Utils.GetLastChainCard().Id == CardId.FairyTailSnow) return false; + } + + + if ( Duel.Player == 1 && Duel.Phase == DuelPhase.BattleStart && Bot.BattlingMonster == null && Enemy_atk >=Bot.LifePoints || + Duel.Player == 0 && Duel.Phase==DuelPhase.BattleStart && Enemy.BattlingMonster == null && Enemy.LifePoints<=1850 + ) + { + AI.SelectCard(all); + AI.SelectNextCard(AI.Utils.GetBestEnemyMonster()); + return true; + } + } return false; } @@ -452,6 +593,9 @@ private bool SouleatingOviraptoreff() private bool GlowUpBulbeff() { + IList check = Bot.GetMonstersInExtraZone(); + foreach (ClientCard monster in check) + if (monster.HasType(CardType.Fusion)) return false; if (Bot.HasInMonstersZone(CardId.Lumina) || Bot.HasInMonstersZone(CardId.FairyTailSnow) || Bot.HasInMonstersZone(CardId.KeeperOfDragonicMagic) || @@ -486,21 +630,16 @@ private bool AllureofDarkness() } return false; } + - - private bool spellset() - { - return Bot.Hand.Count > 6; - } - - - private bool RebornEffect() + private bool Reborneff() { if(Bot.HasInGraveyard(CardId.UltimateConductorTytanno)&&Ultimate_ss>0) { AI.SelectCard(CardId.UltimateConductorTytanno); return true; } + if (!AI.Utils.IsOneEnemyBetter(true)) return false; IList targets = new[] { CardId.ElShaddollConstruct, CardId.DogorantheMadFlameKaiju, @@ -533,78 +672,57 @@ private bool SetIsFieldEmpty() } - private bool TrapSetWhenZoneFree() + private bool SpellSetZone() { - return Bot.GetSpellCountWithoutField() < 4; + return (Bot.GetHandCount()>6 && Duel.Phase==DuelPhase.Main2); } private bool ChargeOfTheLightBrigadeEffect() { - if (!Bot.HasInHand(CardId.Raiden)) - AI.SelectCard(CardId.Raiden); + if (Bot.HasInGraveyard(CardId.Raiden) || Bot.HasInHand(CardId.Raiden)) + AI.SelectCard(CardId.Lumina); else - AI.SelectCard(new[] - { - CardId.Lumina, - - }); + AI.SelectCard(CardId.Raiden); return true; } // all Shaddoll - private bool ElShaddollConstructeff() + private bool SinisterShadowGameseff() { - /* if (Duel.Phase == DuelPhase.Battle) - if (Enemy.BattlingMonster.Attack < 2800) - return false;*/ - if(ActivateDescription==-1) - { - AI.SelectCard(CardId.ShaddollSquamata); - } + if (Bot.HasInGraveyard(CardId.ShaddollFusion)) + AI.SelectCard(CardId.ShaddollCore); + else + AI.SelectCard(new[] + { + CardId.ShaddollBeast, + }); return true; } - private bool ElShaddollShekhinagaeff() + private bool ShaddollCoreeff() { - if (Card.Location != CardLocation.MonsterZone) - return true; - else + if (Card.Location == CardLocation.SpellZone) { - if (DefaultBreakthroughSkill()) + + if (Duel.Player == 1 && Bot.BattlingMonster == null && Duel.Phase==DuelPhase.BattleStart|| DefaultOnBecomeTarget()) { - AI.SelectCard(new[] - { - CardId.ShaddollBeast, - CardId.ShaddollSquamata, - CardId.ShaddollHedgehog, - CardId.ShaddollDragon, - CardId.ShaddollFalco, - } - ); + Logger.DebugWriteLine("+++++++++++ShaddollCoreeffdododoo++++++++++"); + AI.SelectPosition(CardPosition.FaceUpDefence); + return true; } - else - return false; + return false; } return true; } - private bool ElShaddollGrysraeff() - { - if (Card.Location != CardLocation.MonsterZone) - return true; - return true; - } - private bool ShaddollFusioneff() { - if (Bot.HasInMonstersZone(CardId.ElShaddollConstruct) || - Bot.HasInMonstersZone(CardId.ElShaddollGrysra) || - Bot.HasInMonstersZone(CardId.ElShaddollShekhinaga) || - Bot.HasInMonstersZone(CardId.ElShaddollWinda )) - return false; + List extra_zone_check = Bot.GetMonstersInExtraZone(); + foreach (ClientCard extra_monster in extra_zone_check) + if (extra_monster.HasType(CardType.Xyz) || extra_monster.HasType(CardType.Fusion)) return false; bool deck_check = false; List monsters = Enemy.GetMonsters(); @@ -625,8 +743,9 @@ private bool ShaddollFusioneff() }); AI.SelectNextCard(new[] { - CardId.ShaddollBeast, CardId.ShaddollSquamata, + CardId.ShaddollBeast, + CardId.ShaddollHedgehog, CardId.ShaddollDragon, CardId.ShaddollFalco, @@ -635,7 +754,45 @@ private bool ShaddollFusioneff() AI.SelectPosition(CardPosition.FaceUpAttack); return true; } - if (!Bot.IsFieldEmpty()) return false; + + if (Enemy.GetMonsterCount() == 0) + { + int dark_count = 0; + IList m0 = Bot.Hand; + IList m1 = Bot.MonsterZone; + IList all = new List(); + foreach (ClientCard monster in m0) + { + if (dark_count == 2) break; + if (monster.HasAttribute(CardAttribute.Dark)) + { + dark_count++; + all.Add(monster); + } + } + foreach (ClientCard monster in m1) + { + if (dark_count == 2) break; + if (monster != null) + { + if (monster.HasAttribute(CardAttribute.Dark)) + { + dark_count++; + all.Add(monster); + } + } + + + } + if (dark_count == 2) + { + AI.SelectCard(CardId.ElShaddollWinda); + AI.SelectMaterials(all); + AI.SelectPosition(CardPosition.FaceUpAttack); + return true; + } + } + if (!AI.Utils.IsOneEnemyBetter()) return false; foreach (ClientCard monster in Bot.Hand) @@ -651,6 +808,7 @@ private bool ShaddollFusioneff() List material_1 = Bot.GetMonsters(); foreach (ClientCard monster in material_1) { + if (monster == null) break; if (monster.HasAttribute(CardAttribute.Light)) { AI.SelectCard(CardId.ElShaddollConstruct); @@ -663,37 +821,97 @@ private bool ShaddollFusioneff() } - private bool SinisterShadowGameseff() + + private bool ElShaddollShekhinagaeff() { - - AI.SelectCard(new[] + if (Card.Location != CardLocation.MonsterZone) + return true; + else { - CardId.ShaddollBeast, + if (DefaultBreakthroughSkill()) + { + AI.SelectCard(new[] + { + CardId.ShaddollBeast, + CardId.ShaddollSquamata, + CardId.ShaddollHedgehog, + CardId.ShaddollDragon, + CardId.ShaddollFalco, + } + ); + } + else + return false; + } + return true; + } - }); + private bool ElShaddollGrysraeff() + { + if (Card.Location != CardLocation.MonsterZone) + return true; + return true; + } + + + private bool ElShaddollConstructeff() + { + + if (!ShaddollBeast_used) + AI.SelectCard(CardId.ShaddollBeast); + else + AI.SelectCard(CardId.ShaddollFalco); return true; } - private bool ShaddollCoreeff() + + private bool ShaddollSquamataeff() { - if (Card.Location == CardLocation.SpellZone) + ShaddollSquamata_used = true; + if (Card.Location != CardLocation.MonsterZone) { - if (Enemy.HasAttackingMonster() && Duel.Player == 1 && Duel.Phase == DuelPhase.BattleStart) + if(AI.Utils.ChainContainsCard(CardId.ElShaddollConstruct)) { - AI.SelectPosition(CardPosition.FaceUpDefence); - return true; + if (!Bot.HasInHand(CardId.ShaddollFusion) && Bot.HasInGraveyard(CardId.ShaddollFusion)) + AI.SelectNextCard(CardId.ShaddollCore); + if (!ShaddollBeast_used) AI.SelectNextCard(CardId.ShaddollBeast); + else if (!ShaddollFalco_used) AI.SelectNextCard(CardId.ShaddollFalco); + else if(!ShaddollHedgehog_used) AI.SelectNextCard(CardId.ShaddollHedgehog); + } + else + { + if (!Bot.HasInHand(CardId.ShaddollFusion) && Bot.HasInGraveyard(CardId.ShaddollFusion)) + AI.SelectCard(CardId.ShaddollCore); + if (!ShaddollBeast_used) AI.SelectCard(CardId.ShaddollBeast); + else if (!ShaddollFalco_used) AI.SelectCard(CardId.ShaddollFalco); + else if (!ShaddollHedgehog_used) AI.SelectCard(CardId.ShaddollHedgehog); } - return false; + } + else + { + ClientCard target = AI.Utils.GetBestEnemyMonster(); + AI.SelectCard(target); + if (Enemy.GetMonsterCount() == 0) + return false; + } return true; } + + + private bool ShaddollBeasteff() + { + ShaddollBeast_used = true; + return true; + } private bool ShaddollFalcoeff() { + ShaddollFalco_used = true; if (Card.Location != CardLocation.MonsterZone) return true; else @@ -715,12 +933,26 @@ private bool ShaddollFalcoeff() private bool ShaddollHedgehogeff() { + ShaddollHedgehog_used = true; if (Card.Location != CardLocation.MonsterZone) { - AI.SelectCard(new[] + if (AI.Utils.ChainContainsCard(CardId.ElShaddollConstruct)) { - CardId.ShaddollSquamata, - }); + AI.SelectNextCard(new[]{ + CardId.ShaddollFalco, + CardId.ShaddollSquamata, + CardId.ShaddollDragon, + }); + + } + else + { + AI.SelectCard(new[]{ + CardId.ShaddollSquamata, + CardId.ShaddollDragon, + }); + } + } else { @@ -732,6 +964,7 @@ private bool ShaddollHedgehogeff() private bool ShaddollDragoneff() { + ShaddollDragon_used = true; if (Card.Location == CardLocation.MonsterZone) { ClientCard target = AI.Utils.GetBestEnemyCard(); @@ -745,28 +978,8 @@ private bool ShaddollDragoneff() return true; } } - - - private bool ShaddollSquamataeff() - { - if (Card.Location != CardLocation.MonsterZone) - { - AI.SelectCard(new[] - { - CardId.ShaddollBeast, - }); - } - else - { - ClientCard target = AI.Utils.GetBestEnemyMonster(); - AI.SelectCard(target); - if (Enemy.GetMonsterCount() == 0) - return false; - - } - return true; - } - + + private bool LostWindeff() { List check = Enemy.GetMonsters(); @@ -811,18 +1024,38 @@ public bool Hand_act_eff() } //other extra + private bool Michaelsp() + { + IList targets = new[] { + CardId.Raiden, + CardId.Lumina + }; + if (!Bot.HasInMonstersZone(targets)) + return false; + AI.SelectCard(targets); + return true; + } private bool Michaeleff() { if (Card.Location == CardLocation.Grave) return true; if (Bot.LifePoints <= 1000) return false; - return true; + ClientCard select = AI.Utils.GetBestEnemyMonster(); + if (select == null) return false; + if(select!=null) + { + + AI.SelectCard(select); + return true; + } + return false; } private bool MinervaTheExaltedEffect() { if (Card.Location == CardLocation.MonsterZone) { + if (Bot.Deck.Count <= 10) return false; return true; } else @@ -869,29 +1102,46 @@ public bool CrystronNeedlefibersp() if (CrystronNeedlefibereff_used) return false; if (Bot.HasInMonstersZone(CardId.CrystronNeedlefiber)) return false; - if (Bot.HasInMonstersZone(CardId.FairyTailSnow) || - Bot.HasInMonstersZone(CardId.Lumina) || - Bot.HasInMonstersZone(CardId.KeeperOfDragonicMagic) || - Bot.HasInMonstersZone(CardId.SouleatingOviraptor) || - Bot.HasInMonstersZone(CardId.Raiden) - ) + IList check = new[] { - AI.SelectCard(new[] - { - CardId.KeeperOfDragonicMagic, - CardId.Lumina, - CardId.FairyTailSnow, - CardId.SouleatingOviraptor, - CardId.Raiden, - CardId.GiantRex, - }); - AI.SelectNextCard(CardId.GlowUpBulb); - } + CardId.GlowUpBulb, + CardId.FairyTailSnow, + CardId.KeeperOfDragonicMagic, + CardId.SouleatingOviraptor, + CardId.GiantRex, + CardId.Lumina, + CardId.Raiden, + + }; + int count=0; + foreach (ClientCard monster in Bot.GetMonsters()) + if (monster.Id == CardId.GlowUpBulb || + monster.Id == CardId.FairyTailSnow || + monster.Id == CardId.KeeperOfDragonicMagic || + monster.Id == CardId.SouleatingOviraptor|| + monster.Id == CardId.GiantRex|| + monster.Id == CardId.Lumina|| + monster.Id == CardId.Raiden + ) + count++; + if (!Bot.HasInMonstersZone(CardId.GlowUpBulb) || count<2) + return false; + AI.SelectCard(check); + AI.SelectNextCard(check); + return true; } public bool CrystronNeedlefibereff() { + bool DarkHole = false; + foreach (ClientCard card in Enemy.GetSpells()) + { + if (card.Id == 53129443 && card.IsFaceup()) + { + DarkHole = true; + } + } if (Duel.Player == 0) { @@ -899,9 +1149,16 @@ public bool CrystronNeedlefibereff() AI.SelectCard(new[] { CardId.GhostOgre, CardId.GlowUpBulb, CardId.PlaguespreaderZombie, CardId.ShaddollFalco }); return true; } - else if (AI.Utils.IsChainTarget(Card) || AI.Utils.GetProblematicEnemySpell() != null) return true; + + else if (DarkHole || AI.Utils.IsChainTarget(Card) || AI.Utils.GetProblematicEnemySpell() != null) + { + AI.SelectCard(CardId.TG_WonderMagician); + return true; + } + else if (Duel.Player == 1 && Duel.Phase == DuelPhase.BattleStart && AI.Utils.IsOneEnemyBetterThanValue(1500, true)) { + AI.SelectCard(CardId.TG_WonderMagician); if (AI.Utils.IsOneEnemyBetterThanValue(1900, true)) { AI.SelectPosition(CardPosition.FaceUpDefence); @@ -915,6 +1172,10 @@ public bool CrystronNeedlefibereff() return false; } + private bool ScarlightRedDragonsp() + { + return false; + } private bool ScarlightRedDragoneff() { @@ -980,6 +1241,10 @@ private bool BlackRoseMoonlightDragoneff() } + private bool RedWyvernsp() + { + return false; + } private bool RedWyverneff() { @@ -1030,7 +1295,7 @@ public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender attacker.RealPower = 9999; if (attacker.Id == CardId.UltimateConductorTytanno && !attacker.IsDisabled() && defender.IsDefense()) attacker.RealPower = 9999; - } + } return base.OnPreBattleBetween(attacker, defender); } diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index ab156d7f..2d418fca 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -24,6 +24,7 @@ protected class _CardId public const int DupeFrog = 46239604; public const int MaraudingCaptain = 2460565; + public const int HarpiesFeatherDuster = 18144506; public const int MysticalSpaceTyphoon = 5318639; public const int CosmicCyclone = 8267140; public const int ChickenGame = 67616300; @@ -452,6 +453,15 @@ protected bool DefaultMonsterRepos() return false; } + /// + /// if spell/trap is the target or enermy activate HarpiesFeatherDuster + /// + protected bool DefaultOnBecomeTarget() + { + if (AI.Utils.IsChainTarget(Card)) return true; + if (Enemy.HasInSpellZone(_CardId.HarpiesFeatherDuster, true)) return true; + return false; + } /// /// Chain enemy activation or summon. /// diff --git a/Game/AI/Enums/Floodgate.cs b/Game/AI/Enums/Floodgate.cs index cc5802d9..d1280ab5 100644 --- a/Game/AI/Enums/Floodgate.cs +++ b/Game/AI/Enums/Floodgate.cs @@ -59,13 +59,19 @@ public enum Floodgate NaturiaExterio = 99916754, TheLastWarriorfromAnotherPlanet = 86099788, ThousandEyesRestrict = 63519819, - ElShaddollWinda = 94977269, MaskedHERODarkLaw = 58481572, NaturiaBeast = 33198837, NaturiaBarkion = 2956282, EvilswarmOphion = 91279700, MermailAbyssgaios = 74371660, AbyssDweller = 21044178, - ZoodiacDrident = 48905153 + ZoodiacDrident = 48905153, + InvokedMechaba = 75286621, + ElShaddollShekhinaga = 74822425, + ElShaddollConstruct = 20366274, + ElShaddollGrysra = 48424886, + ElShaddollWinda = 94977269, + UltimateConductorTytanno = 18940556, + OvertexCoatls = 41782653 } } diff --git a/Game/GameBehavior.cs b/Game/GameBehavior.cs index 132320ea..3442e986 100644 --- a/Game/GameBehavior.cs +++ b/Game/GameBehavior.cs @@ -270,8 +270,8 @@ private void OnChat(BinaryReader packet) { int player = packet.ReadInt16(); string message = packet.ReadUnicode(256); - string myName = _room.Position == 0 ? _room.Names[0] : _room.Names[1]; - string otherName = _room.Position == 0 ? _room.Names[1] : _room.Names[0]; + string myName = (player != 0) ? _room.Names[1] : _room.Names[0]; + string otherName = (player == 0) ? _room.Names[1] : _room.Names[0]; if (player < 4) Logger.DebugWriteLine(otherName + " say to " + myName + ": " + message); } From 719d7b1b8b485b146a39a48492a1af37c52ff021 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Mon, 16 Apr 2018 23:01:04 +0800 Subject: [PATCH 59/68] fix defender.IsMonsterDangerous check --- Game/AI/DefaultExecutor.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Game/AI/DefaultExecutor.cs b/Game/AI/DefaultExecutor.cs index 2d418fca..395f840b 100644 --- a/Game/AI/DefaultExecutor.cs +++ b/Game/AI/DefaultExecutor.cs @@ -20,6 +20,7 @@ protected class _CardId public const int GamecieltheSeaTurtleKaiju = 55063751; public const int SuperAntiKaijuWarMachineMechaDogoran = 84769941; + public const int UltimateConductorTytanno = 18940556; public const int DupeFrog = 46239604; public const int MaraudingCaptain = 2460565; @@ -87,9 +88,18 @@ public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender if (!attacker.IsMonsterHasPreventActivationEffectInBattle()) { - if (defender.IsMonsterDangerous() || (defender.IsMonsterInvincible() && defender.IsDefense())) + if (defender.IsMonsterInvincible() && defender.IsDefense()) return false; + if (defender.IsMonsterDangerous()) + { + bool canignoreit = false; + if (attacker.Id == _CardId.UltimateConductorTytanno && !attacker.IsDisabled() && defender.IsDefense()) + canignoreit = true; + if (!canignoreit) + return false; + } + if (defender.Id == _CardId.CrystalWingSynchroDragon && defender.IsAttack() && !defender.IsDisabled() && attacker.Level >= 5) return false; From 28d2df35131dffac3f7bc34b8a98dea449013a7f Mon Sep 17 00:00:00 2001 From: mercury233 Date: Mon, 16 Apr 2018 23:29:39 +0800 Subject: [PATCH 60/68] fix InternalOnSelectUnselectCard --- Game/GameBehavior.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Game/GameBehavior.cs b/Game/GameBehavior.cs index 3442e986..92c3a330 100644 --- a/Game/GameBehavior.cs +++ b/Game/GameBehavior.cs @@ -754,8 +754,8 @@ private void InternalOnSelectCard(BinaryReader packet, Func, i private void InternalOnSelectUnselectCard(BinaryReader packet, Func, int, int, int, bool, IList> func) { packet.ReadByte(); // player - packet.ReadByte(); // buttonok - bool cancelable = packet.ReadByte() != 0; + bool buttonok = packet.ReadByte() != 0; + bool cancelable = packet.ReadByte() != 0 || buttonok; int min = packet.ReadByte(); int max = packet.ReadByte(); @@ -788,7 +788,7 @@ private void InternalOnSelectUnselectCard(BinaryReader packet, Func selected = func(cards, min, max, _select_hint, cancelable); + IList selected = func(cards, (cancelable && count2 > 0 ? 0 : 1), 1, _select_hint, cancelable); _select_hint = 0; if (selected.Count == 0 && cancelable) From b4fb58b963fb8e75b7f10476895b29e7026cfaef Mon Sep 17 00:00:00 2001 From: mercury233 Date: Tue, 17 Apr 2018 21:31:19 +0800 Subject: [PATCH 61/68] update --- Game/GameBehavior.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Game/GameBehavior.cs b/Game/GameBehavior.cs index 92c3a330..1f1c16f3 100644 --- a/Game/GameBehavior.cs +++ b/Game/GameBehavior.cs @@ -754,8 +754,8 @@ private void InternalOnSelectCard(BinaryReader packet, Func, i private void InternalOnSelectUnselectCard(BinaryReader packet, Func, int, int, int, bool, IList> func) { packet.ReadByte(); // player - bool buttonok = packet.ReadByte() != 0; - bool cancelable = packet.ReadByte() != 0 || buttonok; + bool finishable = packet.ReadByte() != 0; + bool cancelable = packet.ReadByte() != 0 || finishable; int min = packet.ReadByte(); int max = packet.ReadByte(); @@ -788,7 +788,7 @@ private void InternalOnSelectUnselectCard(BinaryReader packet, Func selected = func(cards, (cancelable && count2 > 0 ? 0 : 1), 1, _select_hint, cancelable); + IList selected = func(cards, (finishable ? 0 : 1), 1, _select_hint, cancelable); _select_hint = 0; if (selected.Count == 0 && cancelable) From 3e8bb14c0781fbb3d57c4b69b86fd1bcd79260f9 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Tue, 17 Apr 2018 23:14:20 +0800 Subject: [PATCH 62/68] fix --- Game/AI/Decks/LightswornShaddoldinosourExecutor.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs index 0850c541..d4bb2ab5 100644 --- a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs +++ b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs @@ -517,11 +517,10 @@ private bool DoubleEvolutionPilleff() private bool FairyTailSnowsummon() - { - IList list = Enemy.GetMonsters(); - if(list!=null) + { + ClientCard target = AI.Utils.GetBestEnemyMonster(true); + if(target != null) { - if(list.GetHighestAttackMonster().IsFaceup()) return true; } return false; @@ -533,7 +532,7 @@ private bool FairyTailSnoweff() if (Card.Location == CardLocation.MonsterZone) { - AI.SelectCard(AI.Utils.GetBestEnemyMonster()); + AI.SelectCard(AI.Utils.GetBestEnemyMonster(true)); return true; } else From d0454523b05db9975208ff65483de2b9f2eab29e Mon Sep 17 00:00:00 2001 From: mercury233 Date: Tue, 24 Apr 2018 20:58:32 +0800 Subject: [PATCH 63/68] add ClientCard.IsTuner --- Game/ClientCard.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Game/ClientCard.cs b/Game/ClientCard.cs index 9f8c8062..a667ef01 100644 --- a/Game/ClientCard.cs +++ b/Game/ClientCard.cs @@ -154,6 +154,11 @@ public bool IsMonster() return HasType(CardType.Monster); } + public bool IsTuner() + { + return HasType(CardType.Tuner); + } + public bool IsSpell() { return HasType(CardType.Spell); From 0f47b3c62f01951cb75941adf0e3f75d3e76472f Mon Sep 17 00:00:00 2001 From: mercury233 Date: Tue, 24 Apr 2018 20:58:56 +0800 Subject: [PATCH 64/68] add AI.Utils.GetBestBotMonster --- Game/AI/AIFunctions.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Game/AI/AIFunctions.cs b/Game/AI/AIFunctions.cs index 54ebb118..eac69314 100644 --- a/Game/AI/AIFunctions.cs +++ b/Game/AI/AIFunctions.cs @@ -132,6 +132,25 @@ public bool IsAllEnemyBetter(bool onlyATK = false) return IsAllEnemyBetterThanValue(bestBotPower, onlyATK); } + public ClientCard GetBestBotMonster(bool onlyATK = false) + { + int bestPower = -1; + ClientCard bestMonster = null; + for (int i = 0; i < 7; ++i) + { + ClientCard card = Bot.MonsterZone[i]; + if (card == null || card.Data == null) continue; + if (onlyATK && card.IsDefense()) continue; + int newPower = card.GetDefensePower(); + if (newPower > bestPower) + { + bestPower = newPower; + bestMonster = card; + } + } + return bestMonster; + } + public ClientCard GetOneEnemyBetterThanValue(int value, bool onlyATK = false) { ClientCard bestCard = null; From 279eb2a49332a55b681e1e8bef30676a3d3a5793 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Tue, 24 Apr 2018 22:27:53 +0800 Subject: [PATCH 65/68] add SkyStriker deck --- Decks/AI_SkyStriker.ydk | 59 +++ Game/AI/Decks/SkyStrikerExecutor.cs | 772 ++++++++++++++++++++++++++++ WindBot.csproj | 1 + 3 files changed, 832 insertions(+) create mode 100644 Decks/AI_SkyStriker.ydk create mode 100644 Game/AI/Decks/SkyStrikerExecutor.cs diff --git a/Decks/AI_SkyStriker.ydk b/Decks/AI_SkyStriker.ydk new file mode 100644 index 00000000..ff7bb3b3 --- /dev/null +++ b/Decks/AI_SkyStriker.ydk @@ -0,0 +1,59 @@ +#created by ... +#main +26077387 +26077387 +26077387 +14558127 +14558127 +59438930 +23434538 +23434538 +23434538 +9742784 +97268402 +97268402 +25955749 +32807846 +35726888 +35726888 +35726888 +63166095 +63166095 +63166095 +70368879 +70368879 +70368879 +73594093 +99550630 +43898403 +43898403 +43898403 +52340444 +52340444 +52340444 +98338152 +98338152 +98338152 +24010609 +97616504 +50005218 +41420027 +84749824 +84749824 +#extra +42110604 +5821478 +61665245 +38342335 +2857636 +50588353 +8491308 +8491308 +63288573 +63288573 +63288573 +90673288 +90673288 +90673288 +41999284 +!side diff --git a/Game/AI/Decks/SkyStrikerExecutor.cs b/Game/AI/Decks/SkyStrikerExecutor.cs new file mode 100644 index 00000000..22fe37c8 --- /dev/null +++ b/Game/AI/Decks/SkyStrikerExecutor.cs @@ -0,0 +1,772 @@ +using YGOSharp.OCGWrapper.Enums; +using System.Collections.Generic; +using WindBot; +using WindBot.Game; +using WindBot.Game.AI; + +namespace WindBot.Game.AI.Decks +{ + [Deck("SkyStriker", "AI_SkyStriker", "NotFinished")] + public class SkyStrikerExecutor : DefaultExecutor + { + public class CardId + { + public const int Rei = 26077387; + public const int Kagari = 63288573; + public const int Shizuku = 90673288; + public const int Hayate = 8491308; + public const int Token = 52340445; + + public const int Engage = 63166095; + public const int HornetBit = 52340444; + public const int WidowAnchor = 98338152; + public const int Afterburner = 99550630; + public const int JammingWave = 25955749; + public const int MultiRoll = 24010609; + public const int HerculesBase = 97616504; + public const int AreaZero = 50005218; + + public const int AshBlossom = 14558127; + public const int GhostRabbit = 59438930; + public const int MaxxC = 23434538; + public const int JetSynchron = 9742784; + public const int EffectVeiler = 97268402; + + public const int ReinforcementOfTheArmy = 32807846; + public const int FoolishBurialGoods = 35726888; + public const int UpstartGoblin = 70368879; + public const int MetalfoesFusion = 73594093; + public const int TwinTwisters = 43898403; + public const int SolemnJudgment = 41420027; + public const int SolemnWarning = 84749824; + + public const int HiSpeedroidChanbara = 42110604; + public const int TopologicBomberDragon = 5821478; + public const int TopologicTrisbaena = 72529749; + public const int SummonSorceress = 61665245; + public const int TroymareUnicorn = 38342335; + public const int TroymarePhoenix = 2857636; + public const int CrystronNeedlefiber = 50588353; + public const int Linkuriboh = 41999284; + } + + bool KagariSummoned = false; + bool ShizukuSummoned = false; + bool HayateSummoned = false; + ClientCard WidowAnchorTarget = null; + + public SkyStrikerExecutor(GameAI ai, Duel duel) + : base(ai, duel) + { + AddExecutor(ExecutorType.Activate, CardId.AshBlossom, DefaultTrap); + AddExecutor(ExecutorType.Activate, CardId.GhostRabbit, DefaultTrap); + AddExecutor(ExecutorType.Activate, CardId.EffectVeiler, DefaultBreakthroughSkill); + AddExecutor(ExecutorType.Activate, CardId.SolemnWarning, DefaultSolemnWarning); + AddExecutor(ExecutorType.Activate, CardId.SolemnJudgment, DefaultSolemnJudgment); + + AddExecutor(ExecutorType.Activate, CardId.MaxxC, MaxxCEffect); + + AddExecutor(ExecutorType.Activate, CardId.ReinforcementOfTheArmy); + AddExecutor(ExecutorType.Activate, CardId.UpstartGoblin); + AddExecutor(ExecutorType.Activate, CardId.FoolishBurialGoods, FoolishBurialGoodsEffect); + + AddExecutor(ExecutorType.Activate, CardId.TwinTwisters, TwinTwistersEffect); + + // + AddExecutor(ExecutorType.Activate, CardId.MultiRoll, MultiRollHandEffect); + + AddExecutor(ExecutorType.Activate, CardId.WidowAnchor, WidowAnchorEffectFirst); + + AddExecutor(ExecutorType.Activate, CardId.Afterburner, AfterburnerEffect); + AddExecutor(ExecutorType.Activate, CardId.JammingWave, JammingWaveEffect); + + AddExecutor(ExecutorType.Activate, CardId.Engage, EngageEffectFirst); + + AddExecutor(ExecutorType.Activate, CardId.HornetBit, HornetBitEffect); + + AddExecutor(ExecutorType.Activate, CardId.WidowAnchor, WidowAnchorEffect); + + AddExecutor(ExecutorType.Activate, CardId.HerculesBase, HerculesBaseEffect); + AddExecutor(ExecutorType.Activate, CardId.AreaZero, AreaZeroEffect); + AddExecutor(ExecutorType.Activate, CardId.MultiRoll, MultiRollEffect); + + AddExecutor(ExecutorType.Activate, CardId.Engage, EngageEffect); + + // + AddExecutor(ExecutorType.Summon, CardId.JetSynchron, TunerSummon); + AddExecutor(ExecutorType.Summon, CardId.EffectVeiler, TunerSummon); + AddExecutor(ExecutorType.Summon, CardId.GhostRabbit, TunerSummon); + AddExecutor(ExecutorType.Summon, CardId.AshBlossom, TunerSummon); + + AddExecutor(ExecutorType.Activate, CardId.Rei, ReiEffect); + AddExecutor(ExecutorType.SpSummon, CardId.Kagari, KagariSummon); + AddExecutor(ExecutorType.Activate, CardId.Kagari, KagariEffect); + + AddExecutor(ExecutorType.SpSummon, CardId.CrystronNeedlefiber, CrystronNeedlefiberSummon); + AddExecutor(ExecutorType.Activate, CardId.CrystronNeedlefiber, CrystronNeedlefiberEffect); + AddExecutor(ExecutorType.SpSummon, CardId.SummonSorceress); + AddExecutor(ExecutorType.Activate, CardId.SummonSorceress, SummonSorceressEffect); + AddExecutor(ExecutorType.Activate, CardId.JetSynchron, JetSynchronEffect); + AddExecutor(ExecutorType.SpSummon, CardId.HiSpeedroidChanbara); + + AddExecutor(ExecutorType.SpSummon, CardId.Shizuku, ShizukuSummon); + AddExecutor(ExecutorType.Activate, CardId.Shizuku, ShizukuEffect); + AddExecutor(ExecutorType.SpSummon, CardId.Hayate, HayateSummon); + AddExecutor(ExecutorType.Activate, CardId.Hayate, HayateEffect); + + AddExecutor(ExecutorType.SpSummon, CardId.TopologicBomberDragon, AI.Utils.IsTurn1OrMain2); + + AddExecutor(ExecutorType.Summon, CardId.Rei, ReiSummon); + + // + AddExecutor(ExecutorType.SpellSet, CardId.SolemnJudgment); + AddExecutor(ExecutorType.SpellSet, CardId.SolemnWarning); + AddExecutor(ExecutorType.SpellSet, CardId.WidowAnchor); + AddExecutor(ExecutorType.SpellSet, CardId.HerculesBase); + + AddExecutor(ExecutorType.SpellSet, CardId.TwinTwisters, HandFull); + AddExecutor(ExecutorType.SpellSet, CardId.HornetBit, HandFull); + + // + AddExecutor(ExecutorType.Activate, CardId.MetalfoesFusion); + AddExecutor(ExecutorType.Activate, CardId.MultiRoll, MultiRollEPEffect); + + AddExecutor(ExecutorType.Repos, DefaultMonsterRepos); + } + + public override bool OnSelectHand() + { + // go first + return true; + } + + public override void OnNewTurn() + { + KagariSummoned = false; + ShizukuSummoned = false; + HayateSummoned = false; + WidowAnchorTarget = null; + } + + public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender) + { + if (!defender.IsMonsterHasPreventActivationEffectInBattle()) + { + if (attacker.Id == CardId.HiSpeedroidChanbara && !attacker.IsDisabled()) + attacker.RealPower = attacker.RealPower + 200; + } + return base.OnPreBattleBetween(attacker, defender); + } + + public override bool OnSelectYesNo(int desc) + { + if (desc == AI.Utils.GetStringId(CardId.SummonSorceress, 2)) // summon to the field of opponent? + return false; + if (desc == AI.Utils.GetStringId(CardId.Engage, 0)) // draw card? + return true; + if (desc == AI.Utils.GetStringId(CardId.WidowAnchor, 0)) // get control? + return true; + if (desc == AI.Utils.GetStringId(CardId.JammingWave, 0)) // destroy monster? + { + ClientCard target = AI.Utils.GetBestEnemyMonster(); + if (target != null) + { + AI.SelectCard(target); + return true; + } + else + return false; + } + if (desc == AI.Utils.GetStringId(CardId.Afterburner, 0)) // destroy spell & trap? + { + ClientCard target = AI.Utils.GetBestEnemySpell(); + if (target != null) + { + AI.SelectCard(target); + return true; + } + else + return false; + } + + return base.OnSelectYesNo(desc); + } + + private bool MaxxCEffect() + { + return Duel.Player == 1; + } + + private bool TwinTwistersEffect() + { + if (AI.Utils.ChainContainsCard(CardId.TwinTwisters)) + return false; + IList targets = new List(); + foreach (ClientCard target in Enemy.GetSpells()) + { + if (target.IsFloodgate()) + targets.Add(target); + if (targets.Count >= 2) + break; + } + if (targets.Count < 2) + { + foreach (ClientCard target in Enemy.GetSpells()) + { + targets.Add(target); + if (targets.Count >= 2) + break; + } + } + if (targets.Count > 0) + { + AI.SelectCard(GetDiscardHand()); + AI.SelectNextCard(targets); + return true; + } + return false; + } + + private bool FoolishBurialGoodsEffect() + { + AI.SelectCard(new[]{ + CardId.MetalfoesFusion, + CardId.WidowAnchor, + CardId.Engage, + CardId.HornetBit + }); + return true; + } + + private bool MultiRollHandEffect() + { + return Card.Location == CardLocation.Hand; + } + + private bool MultiRollEPEffect() + { + if (Duel.Phase != DuelPhase.End) + return false; + + IList targets = new[] { + CardId.Engage, + CardId.HornetBit, + CardId.WidowAnchor + }; + AI.SelectCard(targets); + AI.SelectNextCard(targets); + AI.SelectThirdCard(targets); + return true; + } + + private bool AfterburnerEffect() + { + ClientCard target = AI.Utils.GetBestEnemyMonster(true); + if (target != null) + { + AI.SelectCard(target); + return true; + } + return false; + } + + private bool JammingWaveEffect() + { + ClientCard target = null; + foreach(ClientCard card in Enemy.GetSpells()) + { + if (card.IsFacedown()) + { + target = card; + break; + } + } + if (target != null) + { + AI.SelectCard(target); + return true; + } + return false; + } + + private bool WidowAnchorEffectFirst() + { + ClientCard target = AI.Utils.GetProblematicEnemyMonster(); + if (target != null) + { + WidowAnchorTarget = target; + AI.SelectCard(target); + return true; + } + return false; + } + + private bool EngageEffectFirst() + { + if (!HaveThreeSpellsInGrave()) + return false; + + int target = GetCardToSearch(); + if (target > 0) + AI.SelectCard(target); + else + AI.SelectCard(new[] { + CardId.MultiRoll, + CardId.AreaZero, + CardId.Afterburner, + CardId.JammingWave, + CardId.Rei + }); + + return true; + } + + + private bool EngageEffect() + { + int target = GetCardToSearch(); + if (target > 0) + AI.SelectCard(target); + else + AI.SelectCard(new[] { + CardId.MultiRoll, + CardId.AreaZero, + CardId.Afterburner, + CardId.JammingWave, + CardId.Rei + }); + + return true; + } + + private bool HornetBitEffect() + { + if (Duel.Player == 1) + { + return Duel.Phase == DuelPhase.End; + } + else + { + if (Duel.Phase != DuelPhase.Main1) + return false; + if (Duel.CurrentChain.Count > 0) + return false; + if (Bot.GetMonstersExtraZoneCount() == 0) + return true; + if (Bot.HasInMonstersZone(CardId.SummonSorceress)) + return true; + if (Bot.HasInMonstersZone(CardId.TopologicBomberDragon) && Enemy.GetMonsterCount() > 1) + return true; + if (!AI.Utils.IsTurn1OrMain2()) + { + foreach (ClientCard card in Bot.Hand) + { + if (card.IsTuner()) + return true; + } + } + } + return false; + } + + private bool WidowAnchorEffect() + { + if (DefaultBreakthroughSkill()) + { + WidowAnchorTarget = AI.Utils.GetLastChainCard(); + return true; + } + + if (!HaveThreeSpellsInGrave() || Duel.Player == 1 || Duel.Phase < DuelPhase.Main1 || Duel.Phase >= DuelPhase.Main2 || AI.Utils.ChainContainsCard(CardId.WidowAnchor)) + return false; + + ClientCard target = AI.Utils.GetBestEnemyMonster(true); + if (target != null && !target.IsDisabled() && !target.HasType(CardType.Normal)) + { + WidowAnchorTarget = target; + AI.SelectCard(target); + return true; + } + return false; + } + + private bool HerculesBaseEffect() + { + if (Card.Location == CardLocation.Grave) + { + IList targets = new List(); + foreach(ClientCard card in Bot.GetGraveyardMonsters()) + { + if (card.Id == CardId.Hayate || card.Id == CardId.Kagari || card.Id == CardId.Shizuku) + targets.Add(card); + } + if (targets.Count > 0) + { + AI.SelectCard(targets); + return true; + } + } + else + { + if (AI.Utils.IsTurn1OrMain2()) + return false; + ClientCard bestBotMonster = AI.Utils.GetBestBotMonster(true); + if (bestBotMonster != null) + { + int bestPower = bestBotMonster.Attack; + int count = 0; + bool have3 = HaveThreeSpellsInGrave(); + foreach (ClientCard target in Enemy.GetMonsters()) + { + if (target.GetDefensePower() < bestPower && !target.IsMonsterInvincible()) + { + count++; + if (count > 1 || have3) + { + AI.SelectCard(bestBotMonster); + return true; + } + } + } + } + } + return false; + } + + private bool AreaZeroEffect() + { + if (Card.Location == CardLocation.Hand || Card.Location == CardLocation.Grave) + { + return true; + } + foreach (ClientCard target in Bot.GetMonsters()) + { + if (target == WidowAnchorTarget && Duel.Phase == DuelPhase.Main2) + { + AI.SelectCard(target); + return true; + } + } + foreach (ClientCard target in Bot.GetMonsters()) + { + if (target.Id == CardId.Rei && Bot.GetMonstersExtraZoneCount() == 0) + { + AI.SelectCard(target); + return true; + } + } + foreach (ClientCard target in Bot.GetSpells()) + { + if (target.Id != CardId.AreaZero && target.Id != CardId.MultiRoll && target.Id != CardId.WidowAnchor && target.IsSpell()) + { + AI.SelectCard(target); + return true; + } + } + return false; + } + + private bool MultiRollEffect() + { + if (Card.Location == CardLocation.SpellZone) + { + foreach (ClientCard target in Bot.GetMonsters()) + { + if (target == WidowAnchorTarget && Duel.Phase == DuelPhase.Main2) + { + AI.SelectCard(target); + return true; + } + } + foreach (ClientCard target in Bot.GetMonsters()) + { + if (target.Id == CardId.Rei && Bot.GetMonstersExtraZoneCount() == 0) + { + AI.SelectCard(target); + return true; + } + } + foreach (ClientCard target in Bot.GetSpells()) + { + if (target.Id == CardId.AreaZero) + { + AI.SelectCard(target); + return true; + } + } + foreach (ClientCard target in Bot.GetSpells()) + { + if (target.Id != CardId.MultiRoll && target.Id != CardId.WidowAnchor && target.IsSpell()) + { + AI.SelectCard(target); + return true; + } + } + } + return false; + } + + private bool ReiSummon() + { + if (Bot.GetMonstersExtraZoneCount() == 0) + { + return true; + } + return false; + } + + private bool ReiEffect() + { + if (Card.Location == CardLocation.Grave) + { + return true; + } + if (Card.IsDisabled()) + { + return false; + } + if (AI.Utils.IsChainTarget(Card)) + { + ReiSelectTarget(); + return true; + } + if (Card.Attacked && Duel.Phase == DuelPhase.BattleStart) + { + ReiSelectTarget(); + return true; + } + if (Card == Bot.BattlingMonster && Duel.Player == 1) + { + ReiSelectTarget(); + return true; + } + if (Duel.Phase == DuelPhase.Main2) + { + ReiSelectTarget(); + return true; + } + return false; + } + + private void ReiSelectTarget() + { + if (!KagariSummoned && Bot.HasInGraveyard(new[] { + CardId.Engage, + CardId.HornetBit, + CardId.WidowAnchor + })) + { + AI.SelectCard(CardId.Kagari); + } + else + { + AI.SelectCard(new[] { + CardId.Shizuku, + CardId.Kagari, + CardId.Hayate + }); + } + } + + private bool KagariSummon() + { + if (Bot.HasInGraveyard(new[] { + CardId.Engage, + CardId.HornetBit, + CardId.WidowAnchor + })) + { + KagariSummoned = true; + return true; + } + return false; + } + + private bool KagariEffect() + { + if (EmptyMainMonsterZone() && AI.Utils.GetProblematicEnemyMonster() != null && Bot.HasInGraveyard(CardId.Afterburner)) + { + AI.SelectCard(CardId.Afterburner); + } + else if (EmptyMainMonsterZone() && AI.Utils.GetProblematicEnemySpell() != null && Bot.HasInGraveyard(CardId.JammingWave)) + { + AI.SelectCard(CardId.JammingWave); + } + else + AI.SelectCard(new[] { + CardId.Engage, + CardId.HornetBit, + CardId.WidowAnchor + }); + return true; + } + + private bool ShizukuSummon() + { + if (AI.Utils.IsTurn1OrMain2()) + { + ShizukuSummoned = true; + return true; + } + return false; + } + + private bool ShizukuEffect() + { + int target = GetCardToSearch(); + if (target != 0) + AI.SelectCard(target); + else + AI.SelectCard(new[] { + CardId.Engage, + CardId.HornetBit, + CardId.WidowAnchor + }); + return true; + } + + private bool HayateSummon() + { + if (AI.Utils.IsTurn1OrMain2()) + return false; + HayateSummoned = true; + return true; + } + + private bool HayateEffect() + { + if (!Bot.HasInGraveyard(CardId.Rei)) + AI.SelectCard(CardId.Rei); + else if (!Bot.HasInGraveyard(CardId.HornetBit)) + AI.SelectCard(CardId.HornetBit); + else if (!Bot.HasInGraveyard(CardId.WidowAnchor)) + AI.SelectCard(CardId.WidowAnchor); + return true; + } + + private bool TunerSummon() + { + return !Bot.HasInMonstersZone(new[] { + CardId.AshBlossom, + CardId.EffectVeiler, + CardId.GhostRabbit, + CardId.JetSynchron + }) && !AI.Utils.IsTurn1OrMain2() + && Bot.GetMonsterCount() > 0 + && Bot.HasInExtra(CardId.CrystronNeedlefiber); + } + + private bool CrystronNeedlefiberSummon() + { + return !AI.Utils.IsTurn1OrMain2(); + } + + private bool CrystronNeedlefiberEffect() + { + AI.SelectCard(CardId.JetSynchron); + return true; + } + + private bool SummonSorceressEffect() + { + if (ActivateDescription == -1) + return false; + return true; + } + + private bool JetSynchronEffect() + { + if (Bot.HasInMonstersZone(CardId.Rei) || Bot.HasInMonstersZone(CardId.CrystronNeedlefiber)) + { + AI.SelectCard(GetDiscardHand()); + AI.SelectPosition(CardPosition.FaceUpDefence); + return true; + } + return false; + } + + private bool HandFull() + { + return Bot.GetSpellCountWithoutField() < 4 && Bot.Hand.Count > 4; + } + + private int GetDiscardHand() + { + if (Bot.HasInHand(CardId.MetalfoesFusion)) + return CardId.MetalfoesFusion; + if (Bot.HasInHand(CardId.Rei) && !Bot.HasInGraveyard(CardId.Rei)) + return CardId.Rei; + if (Bot.HasInHand(CardId.JetSynchron)) + return CardId.JetSynchron; + if (Bot.HasInHand(CardId.ReinforcementOfTheArmy)) + return CardId.ReinforcementOfTheArmy; + if (Bot.HasInHand(CardId.FoolishBurialGoods)) + return CardId.FoolishBurialGoods; + return 0; + } + + private int GetCardToSearch() + { + if (!Bot.HasInHand(CardId.HornetBit) && Bot.GetRemainingCount(CardId.HornetBit, 3) > 0) + { + return CardId.HornetBit; + } + else if (AI.Utils.GetProblematicEnemyMonster() != null && Bot.GetRemainingCount(CardId.WidowAnchor, 3) > 0) + { + return CardId.WidowAnchor; + } + else if (EmptyMainMonsterZone() && AI.Utils.GetProblematicEnemyMonster() != null && Bot.GetRemainingCount(CardId.Afterburner, 1) > 0) + { + return CardId.Afterburner; + } + else if (EmptyMainMonsterZone() && AI.Utils.GetProblematicEnemySpell() != null && Bot.GetRemainingCount(CardId.JammingWave, 1) > 0) + { + return CardId.JammingWave; + } + else if (!Bot.HasInHand(CardId.Rei) && !Bot.HasInMonstersZone(CardId.Rei) && Bot.GetRemainingCount(CardId.Rei, 3) > 0) + { + return CardId.Rei; + } + else if (!Bot.HasInHand(CardId.WidowAnchor) && !Bot.HasInSpellZone(CardId.WidowAnchor) && Bot.GetRemainingCount(CardId.WidowAnchor, 3) > 0) + { + return CardId.WidowAnchor; + } + + return 0; + } + + private bool EmptyMainMonsterZone() + { + for (int i = 0; i < 5; i++) + { + if (Bot.MonsterZone[i] != null) + return false; + } + return true; + } + + private bool HaveThreeSpellsInGrave() + { + int count = 0; + foreach(ClientCard card in Bot.Graveyard) + { + if (card.IsSpell()) + { + count++; + } + } + return count >= 3; + } + + private bool DefaultNoExecutor() + { + foreach (CardExecutor exec in Executors) + { + if (exec.Type == Type && exec.CardId == Card.Id) + return false; + } + return true; + } + + } +} \ No newline at end of file diff --git a/WindBot.csproj b/WindBot.csproj index 5393904b..b8faf3ba 100644 --- a/WindBot.csproj +++ b/WindBot.csproj @@ -68,6 +68,7 @@ + From 2b5a3e573fbff36ec5ff758793be9e5fc47713cc Mon Sep 17 00:00:00 2001 From: mercury233 Date: Tue, 24 Apr 2018 22:33:09 +0800 Subject: [PATCH 66/68] update bots list --- BotWrapper/bot.conf | 5 +++ Dialogs/anothercopy.zh-CN.json | 77 ++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 Dialogs/anothercopy.zh-CN.json diff --git a/BotWrapper/bot.conf b/BotWrapper/bot.conf index c972efa3..492eb862 100644 --- a/BotWrapper/bot.conf +++ b/BotWrapper/bot.conf @@ -93,3 +93,8 @@ SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE Name=燃血鬥士 Deck=ChainBurn Dialog=kiwi.zh-TW 连锁烧卡组。 SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE + +!复制梁龙-闪刀姬 +Name=复制梁龙 Deck=SkyStriker Dialog=anothercopy.zh-CN +纯闪刀姬卡组。 +SUPPORT_NEW_MASTER_RULE diff --git a/Dialogs/anothercopy.zh-CN.json b/Dialogs/anothercopy.zh-CN.json new file mode 100644 index 00000000..54c80f61 --- /dev/null +++ b/Dialogs/anothercopy.zh-CN.json @@ -0,0 +1,77 @@ +{ + "welcome": [ + "你好,我是一个机器人。", + "AI功能正在测试中,遇到问题请及时反馈。" + ], + "deckerror": [ + "我的超主流卡组需要{0}才能玩。" + ], + "duelstart": [ + "闪刀姬卡组测试中,渣操是正常情况,请多指教。", + "超主流是游戏王的一环,不爽不要玩。", + "抄主流是游戏王的一环,不爽不要玩。", + "抄来的卡组不会用,怎么办?" + ], + "newturn": [ + "到我的回合了,抽卡!", + "我的回合,抽卡!", + "我抽了一张卡。" + ], + "endturn": [ + "回合结束。", + "我的回合结束了。", + "总觉得这波有点亏……", + "轮到你了。" + ], + "directattack": [ + "{0},直接攻击!", + "{0},直接攻击对手!", + "{0},没有防守的地方,攻击!", + "{0},攻击对手的生命值!", + "{0},直接攻击对手的生命值!", + "{0},通过直接攻击打倒对手!", + "{0},使用直接攻击打倒对手!", + "{0},直接攻击释放你的力量吧!", + "我的{0}将会粉碎你的生命值!", + "向对手展示你的力量吧,{0}!", + "你已经无法阻止我了。{0},攻击!" + ], + "attack": [ + "{0},攻击这只{1}!", + "{0},消灭这只{1}!", + "{0},打倒{1}!", + "{0},冲向那只{1}!", + "{0},把你的力量释放到{1}上吧!" + ], + "ondirectattack": [ + "可恶……", + "不过是{0}而已!", + "果然我还是太弱了……" + ], + "facedownmonstername": "怪兽", + "activate": [ + "我发动{0}。", + "我使用{0}的效果。", + "我使用{0}的力量。" + ], + "summon": [ + "我召唤{0}。", + "出来吧,{0}!", + "出现吧,{0}!", + "我召唤了美丽的{0}!", + "我呼唤{0}参加战斗!", + "我呼唤出{0}。", + "让我召唤{0}。" + ], + "setmonster": [ + "我放置了一只怪兽。", + "我里侧表示放置了一只怪兽。" + ], + "chaining": [ + "看这里!我发动{0}!", + "我使用{0}的力量。", + "准备!我使用{0}!", + "看样子你忘了我的{0}!", + "你考虑过我有{0}吗?" + ] +} From 40a5021bf46a244481d236903b598f77d0312dd2 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Tue, 24 Apr 2018 22:50:04 +0800 Subject: [PATCH 67/68] fixes by handsomekiwi --- Game/AI/Decks/ChainBurnExecutor.cs | 7 ++- .../LightswornShaddoldinosourExecutor.cs | 55 ++++++++++++------- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/Game/AI/Decks/ChainBurnExecutor.cs b/Game/AI/Decks/ChainBurnExecutor.cs index 0ec88a04..187e8f9f 100644 --- a/Game/AI/Decks/ChainBurnExecutor.cs +++ b/Game/AI/Decks/ChainBurnExecutor.cs @@ -590,7 +590,12 @@ private bool BalanceOfJudgmenteff() return false; } private bool CardOfDemiseeff() - { + { + foreach (ClientCard card in Bot.GetMonsters()) + { + if (card.Id == CardId.CardcarD && card.IsFaceup()) + return false; + } if (Bot.GetHandCount() == 1 && Bot.GetSpellCountWithoutField() <= 3) { no_sp = true; diff --git a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs index d4bb2ab5..e1620c45 100644 --- a/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs +++ b/Game/AI/Decks/LightswornShaddoldinosourExecutor.cs @@ -134,7 +134,7 @@ public LightswornShaddoldinosour(GameAI ai, Duel duel) AddExecutor(ExecutorType.Activate, CardId.MinervaTheExalte, MinervaTheExaltedEffect); AddExecutor(ExecutorType.SpSummon, CardId.CrystronNeedlefiber, CrystronNeedlefibersp); //Kaiju - AddExecutor(ExecutorType.SpSummon, CardId.GamecieltheSeaTurtleKaiju, DefaultKaijuSpsummon); + AddExecutor(ExecutorType.SpSummon, CardId.GamecieltheSeaTurtleKaiju, GamecieltheSeaTurtleKaijusp); AddExecutor(ExecutorType.SpSummon, CardId.RadiantheMultidimensionalKaiju, RadiantheMultidimensionalKaijusp); AddExecutor(ExecutorType.SpSummon, CardId.DogorantheMadFlameKaiju, DogorantheMadFlameKaijusp); //Reborn @@ -353,13 +353,19 @@ private bool UltimateConductorTytannoeff() } return false; + } + + private bool GamecieltheSeaTurtleKaijusp() + { + if (!Bot.HasInMonstersZone(CardId.UltimateConductorTytanno)) + return DefaultKaijuSpsummon(); + return false; } - private bool RadiantheMultidimensionalKaijusp() { if (Enemy.HasInMonstersZone(CardId.GamecieltheSeaTurtleKaiju)) return true; - if (Bot.HasInHand(CardId.DogorantheMadFlameKaiju)) return DefaultKaijuSpsummon(); + if (Bot.HasInHand(CardId.DogorantheMadFlameKaiju) && !Bot.HasInMonstersZone(CardId.UltimateConductorTytanno)) return DefaultKaijuSpsummon(); return false; } @@ -403,8 +409,11 @@ private bool KeeperOfDragonicMagiceff() } private bool MonsterRepos() - { + { + if (Card.Id == CardId.UltimateConductorTytanno && Card.IsFacedown()) return true; + if (Card.Id == CardId.ElShaddollConstruct && Card.IsFacedown()) return true; if (Card.Id == CardId.ElShaddollConstruct && Card.IsAttack()) return false; + if (Card.Id == CardId.GlowUpBulb && Card.IsDefense()) return false; if (Card.Id == CardId.ShaddollDragon && Card.IsFacedown() && Enemy.GetMonsterCount() >= 0) return true; if (Card.Id == CardId.ShaddollSquamata && Card.IsFacedown() && Enemy.GetMonsterCount() >= 0) return true; return base.DefaultMonsterRepos(); @@ -540,7 +549,14 @@ private bool FairyTailSnoweff() int spell_count = 0; IList grave = Bot.Graveyard; - IList all = new List(); + IList all = new List(); + foreach (ClientCard check in grave) + { + if (check.Id == CardId.GiantRex) + { + all.Add(check); + } + } foreach (ClientCard check in grave) { if(check.HasType(CardType.Spell)||check.HasType(CardType.Trap)) @@ -556,12 +572,8 @@ private bool FairyTailSnoweff() all.Add(check); } } - if (AI.Utils.GetLastChainCard()!=null) - { - if (AI.Utils.GetLastChainCard().Id == CardId.FairyTailSnow) return false; - } - - + if (AI.Utils.ChainContainsCard(CardId.FairyTailSnow)) return false; + if ( Duel.Player == 1 && Duel.Phase == DuelPhase.BattleStart && Bot.BattlingMonster == null && Enemy_atk >=Bot.LifePoints || Duel.Player == 0 && Duel.Phase==DuelPhase.BattleStart && Enemy.BattlingMonster == null && Enemy.LifePoints<=1850 ) @@ -577,10 +589,10 @@ private bool FairyTailSnoweff() private bool SouleatingOviraptoreff() { - if (!OvertexCoatlseff_used) - { - AI.SelectCard(CardId.OvertexCoatls); - AI.SelectYesNo(false); + if (!OvertexCoatlseff_used && Bot.GetRemainingCount(CardId.OvertexCoatls, 3) > 0) + { + AI.SelectCard(CardId.OvertexCoatls); + AI.SelectYesNo(false); } else { @@ -721,13 +733,13 @@ private bool ShaddollFusioneff() { List extra_zone_check = Bot.GetMonstersInExtraZone(); foreach (ClientCard extra_monster in extra_zone_check) - if (extra_monster.HasType(CardType.Xyz) || extra_monster.HasType(CardType.Fusion)) return false; + if (extra_monster.HasType(CardType.Xyz) || extra_monster.HasType(CardType.Fusion) || extra_monster.HasType(CardType.Synchro)) return false; bool deck_check = false; List monsters = Enemy.GetMonsters(); foreach (ClientCard monster in monsters) { - if (monster.HasType(CardType.Synchro) || monster.HasType(CardType.Fusion) || monster.HasType(CardType.Xyz)) + if (monster.HasType(CardType.Synchro) || monster.HasType(CardType.Fusion) || monster.HasType(CardType.Xyz) || monster.HasType(CardType.Link)) deck_check = true; } @@ -748,7 +760,7 @@ private bool ShaddollFusioneff() CardId.ShaddollHedgehog, CardId.ShaddollDragon, CardId.ShaddollFalco, - + CardId.FairyTailSnow, }); AI.SelectPosition(CardPosition.FaceUpAttack); return true; @@ -891,11 +903,9 @@ private bool ShaddollSquamataeff() } else { + if (Enemy.GetMonsterCount() == 0) return false; ClientCard target = AI.Utils.GetBestEnemyMonster(); AI.SelectCard(target); - if (Enemy.GetMonsterCount() == 0) - return false; - } return true; } @@ -972,6 +982,7 @@ private bool ShaddollDragoneff() } else { + if (Enemy.GetSpellCount() == 0) return false; ClientCard target = AI.Utils.GetBestEnemySpell(); AI.SelectCard(target); return true; @@ -981,6 +992,8 @@ private bool ShaddollDragoneff() private bool LostWindeff() { + if (Card.Location == CardLocation.Grave) + return true; List check = Enemy.GetMonsters(); foreach (ClientCard m in check) { From beed24a4c7d2b418e56f67778e9db525138f93dd Mon Sep 17 00:00:00 2001 From: mercury233 Date: Tue, 24 Apr 2018 22:54:48 +0800 Subject: [PATCH 68/68] update bots.json --- bots.json | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/bots.json b/bots.json index 88d4365f..d6eba16a 100644 --- a/bots.json +++ b/bots.json @@ -37,7 +37,7 @@ }, { "name": "复制植物", - "deck": "Zoodiac", + "deck": "Blue-Eyes", "dialog": "copy.zh-CN" }, { @@ -46,18 +46,28 @@ "dialog": "copy.zh-CN" }, { - "name": "尼亚", - "deck": "Yosenju", - "dialog": "near.zh-CN" + "name": "复制梁龙", + "deck": "SkyStriker", + "dialog": "anothercopy.zh-CN" + }, + { + "name": "复制梁龙", + "deck": "SkyStriker", + "dialog": "anothercopy.zh-CN" + }, + { + "name": "复制梁龙", + "deck": "SkyStriker", + "dialog": "anothercopy.zh-CN" }, { "name": "尼亚", - "deck": "Qliphort", + "deck": "Yosenju", "dialog": "near.zh-CN" }, { "name": "尼亚", - "deck": "Trickstar", + "deck": "Qliphort", "dialog": "near.zh-CN" }, {