Commit 62cf4fa6 authored by mercury233's avatar mercury233

Merge branch 'master' of https://github.com/IceYGO/windbot

parents 7d2a40df 0448ed76
......@@ -2,8 +2,10 @@
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Linq;
namespace BotWrapper
{
......@@ -12,6 +14,8 @@ namespace BotWrapper
[DllImport("User32.dll", CharSet = CharSet.Unicode)]
public static extern int MessageBox(IntPtr hWnd, string lpText, string lpCaption, int uType);
const int MB_ICONERROR = 0x00000010;
static void Main(string[] args)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
......@@ -24,7 +28,19 @@ namespace BotWrapper
startInfo.CreateNoWindow = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
string arg = args[0].Replace("'","\"");
string arg = args[0];
Match match = Regex.Match(arg, "Random=(.*)");
if (match.Success)
{
string randomFlag = match.Groups[1].Value;
ReadBots();
arg = GetRandomBot(randomFlag);
if (arg == "")
{
MessageBox((IntPtr)0, "Can't find random bot with this flag!\n\nA totally random bot will appear instead.", "WindBot", MB_ICONERROR);
}
}
arg = arg.Replace("'", "\"");
if (int.Parse(args[1]) == 1)
{
arg += " Hand=1";
......@@ -39,8 +55,51 @@ namespace BotWrapper
}
catch
{
MessageBox((IntPtr)0, "WindBot can't be started!", "WindBot", 0x00000010); // MB_ICONERROR
MessageBox((IntPtr)0, "WindBot can't be started!", "WindBot", MB_ICONERROR);
}
}
public class BotInfo
{
public string name;
public string command;
public string desc;
public string[] flags;
}
static public IList<BotInfo> Bots = new List<BotInfo>();
static void ReadBots()
{
using (StreamReader reader = new StreamReader("bot.conf"))
{
while (!reader.EndOfStream)
{
string line = reader.ReadLine().Trim();
if (line.Length > 0 && line[0] == '!')
{
BotInfo newBot = new BotInfo();
newBot.name = line;
newBot.command = reader.ReadLine().Trim();
newBot.desc = reader.ReadLine().Trim();
line = reader.ReadLine().Trim();
newBot.flags = line.Split(' ');
Bots.Add(newBot);
}
}
}
}
static string GetRandomBot(string flag)
{
IList<BotInfo> foundBots = Bots.Where(bot => bot.flags.Contains(flag)).ToList();
if (foundBots.Count > 0)
{
Random rand = new Random();
BotInfo bot = foundBots[rand.Next(foundBots.Count)];
return bot.command;
}
return "";
}
}
}
......@@ -4,25 +4,40 @@
# description
# flags (avail flags: SUPPORT_MASTER_RULE_3, SUPPORT_NEW_MASTER_RULE)
!随机-非常简单
Random=AI_LV1
主要是一些沙包。
SUPPORT_NEW_MASTER_RULE
!随机-简单
Random=AI_LV2
一些比较弱的卡组。
SUPPORT_NEW_MASTER_RULE
!随机-普通
Random=AI_LV3
一些环境里可以看到的卡组。
SUPPORT_NEW_MASTER_RULE
!谜之剑士LV4-龙骑星爆
Name=谜之剑士LV4 Deck=Dragunity Dialog=swordsman.zh-CN
龙骑轴星尘龙爆裂体卡组。
SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
AI_LV2 SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
!谜之剑士LV4-R5
Name=谜之剑士LV4 Deck='Rank V' Dialog=swordsman.zh-CN
5阶超量卡组。
SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
AI_LV2 SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
!谜之剑士LV4-异热同心武器
Name=谜之剑士LV4 Deck='Zexal Weapons' Dialog=swordsman.zh-CN
神装电光皇卡组。
SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
AI_LV2 SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
!琪露诺-彩虹
Name=琪露诺 Deck=Rainbow Dialog=cirno.zh-CN
全属性凡骨卡组。
SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
AI_LV2 SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
!琪露诺-饼蛙
Name=琪露诺 Deck='Toadally Awesome' Dialog=cirno.zh-CN
......@@ -32,7 +47,7 @@ SUPPORT_MASTER_RULE_3
!复制植物-青眼
Name=复制植物 Deck=Blue-Eyes Dialog=copy.zh-CN
青眼卡组。
SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
AI_LV3 SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
!复制植物-十二兽
Name=复制植物 Deck=Zoodiac Dialog=copy.zh-CN
......@@ -42,64 +57,64 @@ SUPPORT_MASTER_RULE_3
!尼亚-妖仙兽
Name=尼亚 Deck=Yosenju Dialog=near.zh-CN
妖仙兽卡组。
SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
AI_LV3 SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
!尼亚-机壳
Name=尼亚 Deck=Qliphort Dialog=near.zh-CN
机壳卡组。
SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
AI_LV3 SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
!尼亚-淘气仙星
Name=尼亚 Deck=Trickstar Dialog=near.zh-CN
淘气仙星卡组。
SUPPORT_NEW_MASTER_RULE
AI_LV3 SUPPORT_NEW_MASTER_RULE
!永远之魂-削血
Name=永远之魂 Deck=Burn Dialog=soul.zh-CN
老式削血卡组。
SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
AI_LV1 SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
!永远之魂-青蛙
Name=永远之魂 Deck=Frog Dialog=soul.zh-CN
老式青蛙卡组。
SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
AI_LV1 SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
!永远之魂-荷鲁斯
Name=永远之魂 Deck=Horus Dialog=soul.zh-CN
老式龙族卡组。
SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
AI_LV1 SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
!悠悠
Name=悠悠 Deck=MokeyMokey Dialog=mokey.zh-CN
沙包。
SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
AI_LV1 SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
!悠悠王
Name=悠悠王 Deck=MokeyMokeyKing Dialog=mokey.zh-CN
大沙包。
SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
AI_LV1 SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
!试作型机器人1732
Name=试作型机器人1732 Deck=ST1732 Dialog=zh-CN
由三盒ST17和三盒SD32组成的卡组。
SUPPORT_NEW_MASTER_RULE
AI_LV2 SUPPORT_NEW_MASTER_RULE
!奇異果
Name=奇異果 Deck=LightswornShaddoldinosour Dialog=kiwi.zh-TW
光道影依恐龙卡组。
SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
AI_LV3 SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
!奇魔果
Name=奇魔果 Deck=DarkMagician Dialog=kiwi.zh-TW
黑魔术师卡组。
SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
AI_LV3 SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
!燃血鬥士
Name=燃血鬥士 Deck=ChainBurn Dialog=kiwi.zh-TW
连锁烧卡组。
SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
AI_LV3 SUPPORT_MASTER_RULE_3 SUPPORT_NEW_MASTER_RULE
!复制梁龙-闪刀姬
Name=复制梁龙 Deck=SkyStriker Dialog=anothercopy.zh-CN
纯闪刀姬卡组。
SUPPORT_NEW_MASTER_RULE
AI_LV3 SUPPORT_NEW_MASTER_RULE
#created by ...
#main
52927340
53143898
53143898
53143898
42790071
42790071
42790071
14558127
14558127
59438930
62015408
62015408
89538537
89538537
23434538
23434538
23434538
25533642
25533642
25533642
2295440
18144506
35261759
68462976
68462976
10045474
10045474
10045474
10813327
23924608
35146019
35146019
27541563
27541563
53936268
53936268
53936268
61740673
40605147
40605147
41420027
41420027
#extra
99916754
86221741
85289965
5043010
49725936
24094258
59934749
1508649
1508649
1508649
50588353
63288573
90673288
41999284
94259633
!side
#created by ...
#main
15397015
15397015
15397015
71564252
71564252
71564252
36584821
36584821
36584821
23434538
23434538
63845230
63845230
63845230
18144506
35261759
35261759
35261759
59750328
59750328
70368879
70368879
70368879
98645731
98645731
98645731
73915051
73915051
10045474
10045474
10045474
10813327
15693423
23924608
30241314
30241314
58921041
58921041
61740673
69452756
40605147
40605147
77538567
77538567
84749824
84749824
#extra
86221741
31833038
85289965
5043010
30194529
38342335
2857636
24094258
50588353
3987233
3987233
63288573
98978921
41999284
41999284
!side
10000080
86937530
14558127
62015408
9742784
67441435
72529749
43898403
19508728
15693423
24207889
69452756
23002292
41420027
41420027
......@@ -350,7 +350,7 @@ namespace WindBot.Game.AI
public bool IsChainTargetOnly(ClientCard card)
{
return Duel.ChainTargets.Count == 1 && card.Equals(Duel.ChainTargets[0]);
return Duel.ChainTargetOnly.Count == 1 && card.Equals(Duel.ChainTargetOnly[0]);
}
public bool ChainContainsCard(int id)
......
......@@ -179,6 +179,16 @@ namespace WindBot.Game.AI
return null;
}
public static ClientCard GetShouldBeDisabledBeforeItUseEffectMonster(this IEnumerable<ClientCard> cards)
{
foreach (ClientCard card in cards)
{
if (card != null && card.IsMonsterShouldBeDisabledBeforeItUseEffect() && card.IsFaceup())
return card;
}
return null;
}
public static IEnumerable<IEnumerable<T>> GetCombinations<T>(this IEnumerable<T> elements, int k)
{
return k == 0 ? new[] { new T[0] } :
......
This source diff could not be displayed because it is too large. You can view the blob instead.
using YGOSharp.OCGWrapper.Enums;
using System.Collections.Generic;
using WindBot;
using WindBot.Game;
using WindBot.Game.AI;
namespace WindBot.Game.AI.Decks
{
[Deck("GrenMajuThunderBoarder", "AI_GrenMajuThunderBoarder", "Normal")]
public class GrenMajuThunderBoarderExecutor : DefaultExecutor
{
public class CardId
{
public const int InspectBoarder = 15397015;
public const int ThunderKingRaiOh = 71564252;
public const int GhostReaperAndWinterCherries = 62015408;
public const int GrenMajuDaEizo = 36584821;
public const int MaxxC = 23434538;
public const int EaterOfMillions = 63845230;
public const int HarpieFeatherDuster = 18144506;
public const int PotOfDesires = 35261759;
public const int CardOfDemise = 59750328;
public const int UpstartGoblin = 70368879;
public const int PotOfDuality = 98645731;
public const int Scapegoat = 73915051;
public const int MoonMirrorShield = 19508728;
public const int InfiniteImpermanence = 10045474;
public const int WakingTheDragon = 10813327;
public const int EvenlyMatched = 15693423;
public const int HeavyStormDuster = 23924608;
public const int MacroCosmos = 30241314;
public const int AntiSpellFragrance = 58921041;
public const int ImperialOrder = 61740673;
public const int UnendingNightmare= 69452756;
public const int SolemnWarning = 84749824;
public const int SolemStrike= 40605147;
public const int SolemnJudgment = 41420027;
public const int DarkBribe = 77538567;
public const int RaidraptorUltimateFalcon = 86221741;
public const int BorreloadDragon = 31833038;
public const int BirrelswordDragon = 85289965;
public const int FirewallDragon = 5043010;
public const int BingirsuTheWorldChaliceWarrior = 30194529;
public const int TopologicTrisbaena = 72529749;
public const int KnightmareUnicorn = 38342335;
public const int KnightmarePhoenix = 2857636;
public const int HeavymetalfoesElectrumite= 24094258;
public const int KnightmareCerberus = 75452921;
public const int CrystronNeedlefiber = 50588353;
public const int MissusRadiant= 3987233;
public const int BrandishMaidenKagari= 63288573;
public const int LinkSpider = 98978921;
public const int Linkuriboh = 41999284;
}
public GrenMajuThunderBoarderExecutor(GameAI ai, Duel duel)
: base(ai, duel)
{
AddExecutor(ExecutorType.Activate, CardId.EvenlyMatched, EvenlyMatchedeff);
//Sticker
AddExecutor(ExecutorType.Activate, CardId.MacroCosmos, MacroCosmoseff);
AddExecutor(ExecutorType.Activate, CardId.AntiSpellFragrance, AntiSpellFragranceeff);
//counter
AddExecutor(ExecutorType.Activate, CardId.MaxxC, MaxxCeff);
AddExecutor(ExecutorType.Activate, CardId.InfiniteImpermanence, InfiniteImpermanenceeff);
AddExecutor(ExecutorType.Activate, CardId.SolemnWarning, DefaultSolemnWarning);
AddExecutor(ExecutorType.Activate, CardId.SolemStrike, DefaultSolemnStrike);
AddExecutor(ExecutorType.Activate, CardId.HeavyStormDuster, HeavyStormDustereff);
AddExecutor(ExecutorType.Activate, CardId.UnendingNightmare, UnendingNightmareeff);
AddExecutor(ExecutorType.Activate, CardId.DarkBribe);
AddExecutor(ExecutorType.Activate, CardId.ImperialOrder, ImperialOrdereff);
AddExecutor(ExecutorType.Activate, CardId.ThunderKingRaiOh, ThunderKingRaiOheff);
AddExecutor(ExecutorType.Activate, CardId.SolemnJudgment, DefaultSolemnJudgment);
//first do
AddExecutor(ExecutorType.Activate, CardId.UpstartGoblin, UpstartGoblineff);
AddExecutor(ExecutorType.Activate, CardId.HarpieFeatherDuster, DefaultHarpiesFeatherDusterFirst);
AddExecutor(ExecutorType.Activate, CardId.PotOfDuality, PotOfDualityeff);
AddExecutor(ExecutorType.Activate, CardId.PotOfDesires, PotOfDesireseff);
AddExecutor(ExecutorType.Activate, CardId.CardOfDemise, CardOfDemiseeff);
//sp
AddExecutor(ExecutorType.SpSummon, CardId.BorreloadDragon, BorreloadDragonsp);
AddExecutor(ExecutorType.Activate, CardId.BorreloadDragon, BorreloadDragoneff);
AddExecutor(ExecutorType.Activate, CardId.EaterOfMillions, EaterOfMillionseff);
AddExecutor(ExecutorType.Activate, CardId.WakingTheDragon, WakingTheDragoneff);
AddExecutor(ExecutorType.SpSummon, CardId.MissusRadiant, MissusRadiantsp);
AddExecutor(ExecutorType.Activate, CardId.MissusRadiant, MissusRadianteff);
AddExecutor(ExecutorType.Activate, CardId.Linkuriboh, Linkuriboheff);
AddExecutor(ExecutorType.SpSummon, CardId.Linkuriboh, Linkuribohsp);
AddExecutor(ExecutorType.SpSummon, CardId.LinkSpider);
// normal summon
AddExecutor(ExecutorType.Summon, CardId.InspectBoarder, InspectBoardersummon);
AddExecutor(ExecutorType.Summon, CardId.GrenMajuDaEizo, GrenMajuDaEizosummon);
AddExecutor(ExecutorType.Summon, CardId.ThunderKingRaiOh, ThunderKingRaiOhsummon);
AddExecutor(ExecutorType.SpSummon, CardId.EaterOfMillions, EaterOfMillionssp);
//spell
AddExecutor(ExecutorType.Activate, CardId.MoonMirrorShield, MoonMirrorShieldeff);
AddExecutor(ExecutorType.Activate, CardId.Scapegoat, Scapegoateff);
AddExecutor(ExecutorType.Repos, MonsterRepos);
//set
AddExecutor(ExecutorType.SpellSet, SpellSet);
}
bool CardOfDemiseeff_used = false;
bool plan_A = false;
bool eater_eff = false;
public override void OnNewTurn()
{
eater_eff = false;
CardOfDemiseeff_used = false;
if (Bot.HasInHand(CardId.EvenlyMatched) && Duel.Turn == 2 && Enemy.GetFieldCount()>=2)
{
Logger.DebugWriteLine("***********plan_A");
plan_A = true;
//todo:Duel.Global.ToBattlePhase = true;
}
}
public override void OnNewPhase()
{
foreach (ClientCard check in Bot.GetMonsters())
{
if (check.HasType(CardType.Fusion) || check.HasType(CardType.Xyz) ||
check.HasType(CardType.Synchro) || check.HasType(CardType.Link) ||
check.HasType(CardType.Ritual))
{
eater_eff = true;
break;
}
}
foreach (ClientCard check in Enemy.GetMonsters())
{
if (check.HasType(CardType.Fusion) || check.HasType(CardType.Xyz) ||
check.HasType(CardType.Synchro) || check.HasType(CardType.Link) ||
check.HasType(CardType.Ritual))
{
eater_eff = true;
break;
}
}
base.OnNewPhase();
}
private bool SpellWillBeNegated()
{
ClientCard card = null;
foreach (ClientCard check in Bot.GetSpells())
{
if(check.Id==CardId.ImperialOrder && !check.IsDisabled())
card = check;
}
if (card!=null && card.IsFaceup())
return true;
if (Enemy.HasInSpellZone(CardId.ImperialOrder, true))
return true;
return false;
}
private bool MacroCosmoseff()
{
return (Duel.LastChainPlayer == 1 || Duel.LastSummonPlayer == 1 || Duel.Player == 0) && UniqueFaceupSpell();
}
private bool AntiSpellFragranceeff()
{
int spell_count = 0;
foreach(ClientCard check in Bot.Hand)
{
if (check.HasType(CardType.Spell))
spell_count++;
}
if (spell_count >= 2) return false;
return Duel.Player == 1 && UniqueFaceupSpell();
}
private bool MaxxCeff()
{
return Duel.Player == 1;
}
private bool EvenlyMatchedeff()
{
// todo:Duel.Global.ToBattlePhase = false;
plan_A = false;
return true;
}
private bool InfiniteImpermanenceeff()
{
if (plan_A) return false;
AI.SelectPlace(Zones.z2);
ClientCard target = Enemy.MonsterZone.GetShouldBeDisabledBeforeItUseEffectMonster();
if(target!=null)
{
AI.SelectCard(target);
return true;
}
if(Duel.LastChainPlayer==1)
{
foreach (ClientCard check in Enemy.GetMonsters())
{
if(AI.Utils.GetLastChainCard()==check)
{
target = check;
break;
}
}
if(target!=null)
{
AI.SelectCard(target);
return true;
}
}
return false;
}
private bool HeavyStormDustereff()
{
IList<ClientCard> targets = new List<ClientCard>();
foreach (ClientCard check in Enemy.GetSpells())
{
if (check.HasType(CardType.Continuous) || check.HasType(CardType.Field))
targets.Add(check);
}
foreach (ClientCard check in Enemy.GetSpells())
{
if (!check.HasType(CardType.Continuous) && !check.HasType(CardType.Field))
targets.Add(check);
}
if(DefaultOnBecomeTarget())
{
AI.SelectCard(targets);
return true;
}
if(AI.Utils.GetLastChainCard()!=null &&
(AI.Utils.GetLastChainCard().HasType(CardType.Continuous)||
AI.Utils.GetLastChainCard().HasType(CardType.Field)) &&
Duel.LastChainPlayer==1)
{
AI.SelectCard(targets);
return true;
}
return false;
}
private bool UnendingNightmareeff()
{
ClientCard card = null;
foreach(ClientCard check in Enemy.GetSpells())
{
if (check.HasType(CardType.Continuous) || check.HasType(CardType.Field))
card = check;
break;
}
if(card!=null && Bot.LifePoints>1000)
{
AI.SelectCard(card);
return true;
}
return false;
}
private bool ImperialOrdereff()
{
if (Duel.LastChainPlayer == 1)
{
foreach(ClientCard check in Enemy.SpellZone)
{
if (AI.Utils.GetLastChainCard() == check)
return true;
}
}
return false;
}
private bool UpstartGoblineff()
{
return !SpellWillBeNegated();
}
private bool PotOfDualityeff()
{
if (SpellWillBeNegated())
return false;
int count = 0;
if (Bot.GetMonsterCount() > 0)
count = 1;
foreach(ClientCard card in Bot.Hand)
{
if (card.HasType(CardType.Monster))
count++;
}
if (count == 0)
AI.SelectCard(new[]
{
CardId.PotOfDesires,
CardId.InspectBoarder,
CardId.ThunderKingRaiOh,
CardId.EaterOfMillions,
CardId.GrenMajuDaEizo,
});
else
{
AI.SelectCard(new[]
{
CardId.PotOfDesires,
CardId.CardOfDemise,
CardId.SolemnJudgment,
CardId.SolemnWarning,
CardId.SolemStrike,
CardId.InfiniteImpermanence,
});
}
return true;
}
private bool PotOfDesireseff()
{
return Bot.Deck.Count > 14 && !SpellWillBeNegated();
}
private bool CardOfDemiseeff()
{
if(Bot.Hand.Count == 1 && Bot.GetSpellCountWithoutField() <= 3 && !SpellWillBeNegated())
{
CardOfDemiseeff_used = true;
return true;
}
return false;
}
private bool MoonMirrorShieldeff()
{
if(Card.Location==CardLocation.Hand)
{
if (Bot.GetMonsterCount() == 0) return false;
return !SpellWillBeNegated();
}
if(Card.Location==CardLocation.Grave)
{
return true;
}
return false;
}
private bool Scapegoateff()
{
if (SpellWillBeNegated()) return false;
if (Duel.Player == 0) return false;
if (Duel.Phase == DuelPhase.End) return true;
if (Duel.LastChainPlayer == 1 && (AI.Utils.IsChainTarget(Card) || (DefaultOnBecomeTarget() && !Bot.HasInSpellZone(CardId.WakingTheDragon)))) return true;
if (Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2)
{
int total_atk = 0;
List<ClientCard> enemy_monster = Enemy.GetMonsters();
foreach (ClientCard m in enemy_monster)
{
if (m.IsAttack() && !m.Attacked) total_atk += m.Attack;
}
if (total_atk >= Bot.LifePoints) return true;
}
return false;
}
private bool InspectBoardersummon()
{
if (plan_A) return false;
AI.SelectPlace(Zones.z4 | Zones.z0);
return true;
}
private bool GrenMajuDaEizosummon()
{
if (Duel.Turn == 1) return false;
if (plan_A) return false;
AI.SelectPlace(Zones.z4 | Zones.z0);
return Bot.Banished.Count >= 6;
}
private bool ThunderKingRaiOhsummon()
{
if (plan_A) return false;
AI.SelectPlace(Zones.z4 | Zones.z0);
return true;
}
private bool ThunderKingRaiOheff()
{
foreach (ClientCard card in Duel.SummoningCards)
{
if (card.Attack >= 1900)
return true;
}
return false;
}
private bool BorreloadDragonsp()
{
IList<ClientCard> material_list = new List<ClientCard>();
foreach (ClientCard monster in Bot.GetMonsters())
{
if (monster.Id != CardId.EaterOfMillions)
material_list.Add(monster);
if (material_list.Count == 3) break;
}
if(material_list.Count>=3)
{
AI.SelectMaterials(material_list);
return true;
}
return false;
}
public bool BorreloadDragoneff()
{
if (ActivateDescription == -1)
{
ClientCard enemy_monster = Enemy.BattlingMonster;
if (enemy_monster != null && enemy_monster.HasPosition(CardPosition.Attack))
{
return (Card.Attack - enemy_monster.Attack < Enemy.LifePoints);
}
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;
}
private bool EaterOfMillionssp()
{
if (Bot.HasInMonstersZone(CardId.InspectBoarder) && !eater_eff) return false;
if (plan_A) return false;
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<ClientCard> targets = new List<ClientCard>();
foreach (ClientCard e_c in Bot.ExtraDeck)
{
targets.Add(e_c);
if (targets.Count >= 5)
{
AI.SelectCard(targets);
/*AI.SelectCard(new[] {
CardId.BingirsuTheWorldChaliceWarrior,
CardId.TopologicTrisbaena,
CardId.KnightmareCerberus,
CardId.KnightmarePhoenix,
CardId.KnightmareUnicorn,
CardId.BrandishMaidenKagari,
CardId.HeavymetalfoesElectrumite,
CardId.CrystronNeedlefiber,
CardId.FirewallDragon,
CardId.BirrelswordDragon,
CardId.RaidraptorUltimateFalcon,
});*/
AI.SelectPlace(Zones.z4 | Zones.z0);
return true;
}
}
Logger.DebugWriteLine("*** Eater use up the extra deck.");
foreach (ClientCard s_c in Bot.GetSpells())
{
targets.Add(s_c);
if (targets.Count >= 5)
{
AI.SelectCard(targets);
return true;
}
}
return false;
}
private bool EaterOfMillionseff()
{
//if (Enemy.BattlingMonster.HasPosition(CardPosition.Attack) && (Bot.BattlingMonster.Attack - Enemy.BattlingMonster.GetDefensePower() >= Enemy.LifePoints)) return false;
return true;
}
private bool WakingTheDragoneff()
{
AI.SelectCard(new[] { CardId.RaidraptorUltimateFalcon });
return true;
}
private bool MissusRadiantsp()
{
IList<ClientCard> material_list = new List<ClientCard>();
foreach (ClientCard monster in Bot.GetMonsters())
{
if (monster.HasAttribute(CardAttribute.Earth) && monster.Level==1 && monster.Id!=CardId.EaterOfMillions)
material_list.Add(monster);
if (material_list.Count == 2) break;
}
if (material_list.Count < 2) return false;
if (Bot.HasInMonstersZone(CardId.MissusRadiant)) return false;
AI.SelectMaterials(material_list);
AI.SelectPlace(Zones.z5 | Zones.z6);
return true;
}
private bool MissusRadianteff()
{
AI.SelectCard(new[]
{
CardId.MaxxC,
CardId.MissusRadiant,
});
return true;
}
private bool Linkuribohsp()
{
foreach (ClientCard c in Bot.GetMonsters())
{
if (c.Id != CardId.EaterOfMillions && c.Level == 1 && c.Id != CardId.Linkuriboh && c.Id != CardId.LinkSpider)
{
AI.SelectCard(c);
return true;
}
}
return false;
}
private bool Linkuriboheff()
{
if (Duel.LastChainPlayer == 0 && AI.Utils.GetLastChainCard().Id == CardId.Linkuriboh) return false;
return true;
}
private bool MonsterRepos()
{
if (Card.Id == CardId.EaterOfMillions && Card.IsAttack()) return false;
return DefaultMonsterRepos();
}
private bool SpellSet()
{
if (plan_A) return false;
int count = 0;
foreach(ClientCard check in Bot.Hand)
{
if (check.Id == CardId.CardOfDemise)
count++;
}
if (count == 2 && Bot.Hand.Count == 2 && Bot.GetSpellCountWithoutField() <= 2)
return true;
if (Card.Id == CardId.MacroCosmos && Bot.HasInSpellZone(CardId.MacroCosmos)) return false;
if (Card.Id == CardId.AntiSpellFragrance && Bot.HasInSpellZone(CardId.AntiSpellFragrance)) return false;
if (CardOfDemiseeff_used)return true;
//if (Duel.Turn > 1 && Duel.Phase != DuelPhase.Main2) return false;
if (Card.Id == CardId.EvenlyMatched && (Enemy.GetFieldCount() - Bot.GetFieldCount()) < 0) return false;
if (Card.Id == CardId.AntiSpellFragrance && Bot.HasInSpellZone(CardId.AntiSpellFragrance)) return false;
if (Card.Id == CardId.MacroCosmos && Bot.HasInSpellZone(CardId.MacroCosmos)) return false;
if (Card.Id == CardId.InfiniteImpermanence)
return Bot.GetFieldCount() > 0 && Bot.GetSpellCountWithoutField() < 4;
if (Card.Id == CardId.Scapegoat)
return true;
if (Card.HasType(CardType.Trap))
return Bot.GetSpellCountWithoutField() < 4;
if(Bot.HasInSpellZone(CardId.AntiSpellFragrance,true))
{
if (Card.Id == CardId.UpstartGoblin || Card.Id == CardId.PotOfDesires || Card.Id==CardId.PotOfDuality) return true;
if (Card.Id == CardId.CardOfDemise && Bot.HasInSpellZone(CardId.CardOfDemise)) return false;
if (Card.HasType(CardType.Spell))
return Bot.GetSpellCountWithoutField() < 4;
}
return false;
}
public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender)
{
if (attacker.Id==CardId.EaterOfMillions && (Bot.HasInMonstersZone(CardId.InspectBoarder) && eater_eff))
{
attacker.RealPower = 9999;
return true;
}
if (attacker.Id == CardId.EaterOfMillions && !Bot.HasInMonstersZone(CardId.InspectBoarder))
{
attacker.RealPower = 9999;
return true;
}
return base.OnPreBattleBetween(attacker, defender);
}
public override ClientCard OnSelectAttacker(IList<ClientCard> attackers, IList<ClientCard> defenders)
{
for (int i = 0; i < attackers.Count; ++i)
{
ClientCard attacker = attackers[i];
if (attacker.Id == CardId.BirrelswordDragon || attacker.Id == CardId.EaterOfMillions) return attacker;
}
return null;
}
public override bool OnSelectHand()
{
return true;
}
}
}
\ No newline at end of file
......@@ -37,7 +37,7 @@ namespace WindBot.Game.AI.Decks
public const int Ring = 83555666;
public const int Strike = 40605147;
public const int Warn = 84749824;
public const int Grass = 10813327;
public const int Awaken = 10813327;
public const int Linkuri = 41999284;
public const int Linkspi = 98978921;
......@@ -80,6 +80,13 @@ namespace WindBot.Game.AI.Decks
int GraveCall_id = 0;
int GraveCall_count = 0;
List<int> SkyStrike_list = new List<int> {
26077387, 8491308, 63288573, 90673288,
21623008, 25955749, 63166095, 99550630,
25733157, 51227866, 52340444,98338152,
24010609, 97616504, 50005218
};
public TrickstarExecutor(GameAI ai, Duel duel)
: base(ai, duel)
{
......@@ -87,7 +94,7 @@ namespace WindBot.Game.AI.Decks
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.Awaken, Awaken_ss);
AddExecutor(ExecutorType.Activate, CardId.Urara, Hand_act_eff);
AddExecutor(ExecutorType.Activate, CardId.Ghost, Hand_act_eff);
AddExecutor(ExecutorType.Activate, CardId.Ring, Ring_act);
......@@ -99,6 +106,7 @@ namespace WindBot.Game.AI.Decks
AddExecutor(ExecutorType.Activate, CardId.DarkHole, DarkHole_eff);
// spell clean
AddExecutor(ExecutorType.Activate, field_activate);
AddExecutor(ExecutorType.Activate, CardId.Stage, Stage_Lock);
AddExecutor(ExecutorType.Activate, CardId.Feather, Feather_Act);
AddExecutor(ExecutorType.Activate, CardId.Stage, Stage_act);
......@@ -106,6 +114,7 @@ namespace WindBot.Game.AI.Decks
AddExecutor(ExecutorType.Activate, CardId.TG, TG_eff);
AddExecutor(ExecutorType.Activate, CardId.Tuner,Tuner_eff);
AddExecutor(ExecutorType.SpellSet, Five_Rainbow);
// ex ss
AddExecutor(ExecutorType.SpSummon, CardId.Borrel, Borrel_ss);
......@@ -160,15 +169,69 @@ namespace WindBot.Game.AI.Decks
AddExecutor(ExecutorType.SpellSet, SpellSet);
}
public bool SpellSet()
public bool Five_Rainbow()
{
if (Card.Id == CardId.Sheep && Bot.HasInSpellZone(CardId.Sheep)) return false;
return DefaultSpellSet();
if (Enemy.HasInSpellZone(19619755,true) || Bot.HasInSpellZone(19619755, true))
{
if (Card.HasType(CardType.Field)) return false;
bool has_setcard = false;
for (int i = 0; i < 5; ++i)
{
ClientCard sp = Bot.SpellZone[i];
if (sp != null && sp.HasPosition(CardPosition.FaceDown))
{
has_setcard = true;
break;
}
}
if (has_setcard) return false;
AI.SelectPlace(SelectSTPlace());
return true;
}
return false;
}
public bool Has_down_arrow(int id)
public int SelectSTPlace()
{
List<int> list = new List<int>();
list.Add(0);
list.Add(1);
list.Add(2);
list.Add(3);
list.Add(4);
int n = list.Count;
while (n-- > 1)
{
return (id == CardId.Linkuri || id == CardId.Linkspi || id == CardId.Unicorn);
int index = Program.Rand.Next(n + 1);
int temp = list[index];
list[index] = list[n];
list[n] = temp;
}
foreach(int seq in list)
{
int zone = (int)System.Math.Pow(2, seq);
if (Bot.SpellZone[seq] == null) return zone;
}
return 0;
}
public bool SpellSet()
{
if (Card.Id == CardId.Sheep && Bot.HasInSpellZone(CardId.Sheep)) return false;
if (DefaultSpellSet())
{
AI.SelectPlace(SelectSTPlace());
return true;
} else if (Enemy.HasInSpellZone(58921041,true) || Bot.HasInSpellZone(58921041, true))
{
if (Card.Id == CardId.Stage) return !Bot.HasInSpellZone(CardId.Stage);
if (Card.IsSpell())
{
AI.SelectPlace(SelectSTPlace());
return true;
}
}
return false;
}
public bool IsTrickstar(int id)
......@@ -176,12 +239,43 @@ namespace WindBot.Game.AI.Decks
return (id == CardId.Yellow || id == CardId.Red || id == CardId.Pink || id == CardId.White || id == CardId.Stage || id == CardId.Re || id == CardId.Crown);
}
public bool field_activate()
{
if (Card.HasPosition(CardPosition.FaceDown) && Card.HasType(CardType.Field) && Card.Location == CardLocation.SpellZone)
{
// field spells that forbid other fields' activate
return (Card.Id != 71650854 && Card.Id != 78082039);
}
return false;
}
public bool spell_trap_activate()
{
if (Card.Location != CardLocation.SpellZone && Card.Location != CardLocation.Hand) return true;
if (Enemy.HasInMonstersZone(CardId.Exterio,true) && !Bot.HasInHandOrHasInMonstersZone(CardId.Ghost)) return false;
if (Card.IsSpell())
{
if (Enemy.HasInMonstersZone(33198837, true) && !Bot.HasInHandOrHasInMonstersZone(CardId.Ghost)) return false;
if (Enemy.HasInSpellZone(61740673, true) || Bot.HasInSpellZone(61740673,true)) return false;
if (Enemy.HasInMonstersZone(37267041, true) || Bot.HasInMonstersZone(37267041, true)) return false;
return true;
}
if (Card.IsTrap())
{
if (Enemy.HasInSpellZone(51452091, true) || Bot.HasInSpellZone(51452091, true)) return false;
if (Enemy.HasInSpellZone(51452091, true) || Bot.HasInSpellZone(51452091, true)) return false;
return true;
}
// how to get here?
return false;
}
public int[] Useless_List()
{
return new[]
{
CardId.Tuner,
CardId.Grass,
CardId.Awaken,
CardId.Crown,
CardId.Pink,
CardId.Pot,
......@@ -216,7 +310,7 @@ namespace WindBot.Game.AI.Decks
return atk;
}
public bool Grass_ss()
public bool Awaken_ss()
{
// judge whether can ss from exdeck
bool judge = (Bot.ExtraDeck.Count > 0);
......@@ -231,15 +325,60 @@ namespace WindBot.Game.AI.Decks
// can ss from exdeck
if (judge)
{
bool fornextss = AI.Utils.ChainContainsCard(CardId.Grass);
bool fornextss = AI.Utils.ChainContainsCard(CardId.Awaken);
IList<ClientCard> ex = Bot.ExtraDeck;
ClientCard ex_best = null;
foreach (ClientCard ex_card in ex)
{
if (!fornextss)
{
if (Bot.HasInExtra(CardId.Exterio))
{
bool has_skystriker = false;
foreach (ClientCard card in Enemy.Graveyard)
{
if (card != null && SkyStrike_list.Contains(card.Id))
{
has_skystriker = true;
break;
}
}
if (!has_skystriker)
{
foreach (ClientCard card in Enemy.GetSpells())
{
if (card != null && SkyStrike_list.Contains(card.Id))
{
has_skystriker = true;
break;
}
}
}
if (!has_skystriker)
{
foreach (ClientCard card in Enemy.GetSpells())
{
if (card != null && SkyStrike_list.Contains(card.Id))
{
has_skystriker = true;
break;
}
}
}
if (has_skystriker)
{
AI.SelectCard(CardId.Exterio);
return true;
} else
{
if (ex_best == null || ex_card.Attack > ex_best.Attack) ex_best = ex_card;
}
}
else
{
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;
......@@ -250,7 +389,7 @@ namespace WindBot.Game.AI.Decks
AI.SelectCard(ex_best);
}
}
if (!judge || AI.Utils.ChainContainsCard(CardId.Grass))
if (!judge || AI.Utils.ChainContainsCard(CardId.Awaken))
{
// cannot ss from exdeck or have more than 1 grass in chain
int[] secondselect = new[]
......@@ -266,7 +405,7 @@ namespace WindBot.Game.AI.Decks
CardId.Yellow,
CardId.Pink
};
if (!AI.Utils.ChainContainsCard(CardId.Grass))
if (!AI.Utils.ChainContainsCard(CardId.Awaken))
{
if (!judge && Bot.GetRemainingCount(CardId.Ghost, 2) > 0)
{
......@@ -366,6 +505,7 @@ namespace WindBot.Game.AI.Decks
}
else
{
if (!spell_trap_activate()) return false;
foreach (ClientCard card in spells)
{
if (card.IsFacedown() && card != stage_locked)
......@@ -378,6 +518,7 @@ namespace WindBot.Game.AI.Decks
if (selected == null)
return false;
AI.SelectCard(selected);
AI.SelectPlace(SelectSTPlace());
return true;
}
......@@ -389,6 +530,7 @@ namespace WindBot.Game.AI.Decks
public bool Feather_Act()
{
if (!spell_trap_activate()) return false;
if (AI.Utils.GetProblematicEnemySpell() != null)
{
List<ClientCard> grave = Bot.GetGraveyardSpells();
......@@ -397,19 +539,22 @@ namespace WindBot.Game.AI.Decks
if (self_card.Id == CardId.Galaxy)
return false;
}
AI.SelectPlace(SelectSTPlace());
return true;
}
// activate when more than 2 cards
if (Enemy.GetSpellCount() <= 1)
return false;
AI.SelectPlace(SelectSTPlace());
return true;
}
public bool Sheep_Act()
{
if (!spell_trap_activate()) return false;
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.LastChainPlayer == 1 && (AI.Utils.IsChainTarget(Card) || (AI.Utils.GetLastChainCard().Id == CardId.Feather && !Bot.HasInSpellZone(CardId.Awaken)))) return true;
if (Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2)
{
int total_atk = 0;
......@@ -425,8 +570,8 @@ namespace WindBot.Game.AI.Decks
public bool Stage_act()
{
if (Card.Location != CardLocation.Hand) return false;
if (Card.Location == CardLocation.SpellZone && Card.HasPosition(CardPosition.FaceUp)) return false;
if (!spell_trap_activate()) return false;
if (!NormalSummoned)
{
if (!Bot.HasInHand(CardId.Yellow))
......@@ -547,7 +692,13 @@ namespace WindBot.Game.AI.Decks
public bool Pot_Act()
{
return Bot.Deck.Count > 15;
if (!spell_trap_activate()) return false;
if (Bot.Deck.Count > 15)
{
AI.SelectPlace(SelectSTPlace());
return true;
}
return false;
}
public bool Hand_act_eff()
......@@ -621,7 +772,7 @@ namespace WindBot.Game.AI.Decks
if (AI.Utils.IsTurn1OrMain2()) return false;
AI.SelectPosition(CardPosition.FaceUpAttack);
IList<ClientCard> targets = new List<ClientCard>();
if (Bot.SpellZone[5] != null && Bot.SpellZone[5].IsFacedown())
if (Bot.SpellZone[5] != null && Bot.SpellZone[5].Id != CardId.Stage)
{
targets.Add(Bot.SpellZone[5]);
}
......@@ -1024,6 +1175,7 @@ namespace WindBot.Game.AI.Decks
public bool Reincarnation()
{
if (Card.Location == CardLocation.Grave) return Ts_reborn();
if (!spell_trap_activate()) return false;
if (Bot.HasInHand(CardId.LockBird))
{
if (lockbird_useful || AI.Utils.IsChainTarget(Card) || (Duel.Player == 1 && AI.Utils.ChainContainsCard(CardId.Feather))) {
......@@ -1037,9 +1189,14 @@ namespace WindBot.Game.AI.Decks
public bool Crown_eff()
{
if (Card.Location == CardLocation.Hand)
if (Card.Location == CardLocation.Hand || (Card.Location == CardLocation.SpellZone && Card.HasPosition(CardPosition.FaceDown)))
{
if (!spell_trap_activate()) return false;
if (Duel.Phase <= DuelPhase.Main1 && Ts_reborn())
{
if (Duel.Phase <= DuelPhase.Main1) return Ts_reborn();
AI.SelectPlace(SelectSTPlace());
return true;
}
return false;
}
if (Bot.HasInHand(CardId.Pink) && GraveCall_id != CardId.Pink)
......@@ -1176,6 +1333,7 @@ namespace WindBot.Game.AI.Decks
public bool Ring_act()
{
if (Duel.LastChainPlayer == 0 && AI.Utils.GetLastChainCard() != null && AI.Utils.GetLastChainCard().Id == CardId.Ghost) return false;
if (!spell_trap_activate()) return false;
ClientCard target = AI.Utils.GetProblematicEnemyMonster();
if (target == null && AI.Utils.IsChainTarget(Card))
{
......@@ -1321,7 +1479,7 @@ namespace WindBot.Game.AI.Decks
if (ex_1 != null && ex_1.Controller == 0) ex = ex_1;
if (ex_2 != null && ex_2.Controller == 0) ex = ex_2;
if (ex == null) return false;
if (!Has_down_arrow(ex.Id)) return false;
if (!ex.HasLinkMarker(2)) return false;
IList<ClientCard> targets = new List<ClientCard>();
foreach (ClientCard s_m in Bot.GetMonsters())
{
......@@ -1393,6 +1551,19 @@ namespace WindBot.Game.AI.Decks
public bool Phoneix_eff()
{
AI.SelectCard(Useless_List());
ClientCard target = AI.Utils.GetProblematicEnemySpell();
if (target != null)
{
AI.SelectNextCard(target);
} else
{
List<ClientCard> spells = Enemy.GetSpells();
RandomSort(spells);
foreach (ClientCard card in spells)
{
if ((card != stage_locked || card.HasPosition(CardPosition.FaceUp)) && !(card.IsShouldNotBeTarget() || card.IsShouldNotBeMonsterTarget())) AI.SelectNextCard(card);
}
}
return true;
}
......@@ -1455,21 +1626,27 @@ namespace WindBot.Game.AI.Decks
// avoid cards that cannot target.
AI.SelectCard(Useless_List());
IList<ClientCard> enemy_list = new List<ClientCard>();
enemy_list.Add(m);
if (!m.IsShouldNotBeMonsterTarget() && !m.IsShouldNotBeTarget()) enemy_list.Add(m);
foreach(ClientCard enemy in Enemy.GetMonstersInExtraZone())
{
if (enemy != null && !enemy_list.Contains(enemy)) enemy_list.Add(enemy);
if (enemy != null && !enemy_list.Contains(enemy) && !enemy.IsShouldNotBeMonsterTarget() && !enemy.IsShouldNotBeTarget()) enemy_list.Add(enemy);
}
foreach (ClientCard enemy in Enemy.GetMonstersInMainZone())
{
if (enemy != null && !enemy_list.Contains(enemy)) enemy_list.Add(enemy);
if (enemy != null && !enemy_list.Contains(enemy) && !enemy.IsShouldNotBeMonsterTarget() && !enemy.IsShouldNotBeTarget()) enemy_list.Add(enemy);
}
foreach (ClientCard enemy in Enemy.GetSpells())
{
if (enemy != null && !enemy_list.Contains(enemy)) enemy_list.Add(enemy);
if (enemy != null && !enemy_list.Contains(enemy) && !enemy.IsShouldNotBeMonsterTarget() && !enemy.IsShouldNotBeTarget()) enemy_list.Add(enemy);
}
if (enemy_list.Count > 0)
{
AI.SelectNextCard(enemy_list);
return true;
} else
{
return false;
}
}
public bool Snake_ss()
......@@ -1635,8 +1812,10 @@ namespace WindBot.Game.AI.Decks
return false;
}
// unfinished.
public bool GraveCall_eff()
{
if (!spell_trap_activate()) return false;
if (Duel.LastChainPlayer == 1)
{
if (AI.Utils.GetLastChainCard().IsMonster() && Enemy.HasInGraveyard(AI.Utils.GetLastChainCard().Id))
......@@ -1652,6 +1831,7 @@ namespace WindBot.Game.AI.Decks
public bool DarkHole_eff()
{
if (!spell_trap_activate()) return false;
if (Bot.GetMonsterCount() == 0)
{
......@@ -1663,10 +1843,18 @@ namespace WindBot.Game.AI.Decks
int bestenemy = -1;
foreach (ClientCard enemy in Enemy.GetMonsters())
{
if (enemy.IsMonsterDangerous()) return true;
if (enemy.IsMonsterDangerous())
{
AI.SelectPlace(SelectSTPlace());
return true;
}
if (enemy.IsFaceup() && (enemy.GetDefensePower() > bestenemy)) bestenemy = enemy.GetDefensePower();
}
return (bestPower <= bestenemy);
if (bestPower <= bestenemy)
{
AI.SelectPlace(SelectSTPlace());
return true;
}
}
return false;
}
......@@ -1694,6 +1882,15 @@ namespace WindBot.Game.AI.Decks
if (Card.IsFaceup() && Card.IsDefense() && Card.Attack == 0)
return false;
if (Card.Id == CardId.Pink)
{
if ((Bot.HasInSpellZone(CardId.Stage, true) && Enemy.LifePoints <= 1000) || (!Bot.HasInSpellZone(CardId.Stage, true) && Enemy.LifePoints <= 800))
{
return !Card.HasPosition(CardPosition.Attack);
}
}
bool enemyBetter = IsAllEnemyBetter();
if (Card.IsAttack() && enemyBetter)
......
......@@ -887,8 +887,7 @@ namespace WindBot.Game.AI
List<ClientCard> monsters = Bot.GetMonsters();
foreach (ClientCard monster in monsters)
{
// The bot don't know if the card is special summoned, so let we assume all monsters are special summoned
if (!monster.Equals(Card) && monster.HasType(CardType.Effect) && monster.Attack <= Card.Attack)
if (!monster.Equals(Card) && monster.IsSpecialSummoned && monster.HasType(CardType.Effect) && monster.Attack <= Card.Attack)
selfCount++;
}
......@@ -896,7 +895,7 @@ namespace WindBot.Game.AI
monsters = Enemy.GetMonsters();
foreach (ClientCard monster in monsters)
{
if (monster.HasType(CardType.Effect) && monster.Attack <= Card.Attack)
if (monster.IsSpecialSummoned && monster.HasType(CardType.Effect) && monster.Attack <= Card.Attack)
oppoCount++;
}
......
......@@ -74,6 +74,8 @@
UltimateConductorTytanno = 18940556,
OvertexCoatls = 41782653,
FirePrison = 269510,
LairOfDarkness = 59160188
LairOfDarkness = 59160188,
SuperboltThunderDragon = 15291624,
ThunderDragonLord = 41685633
}
}
......@@ -32,6 +32,7 @@
HazyFlamePeryton = 37803172,
HazyFlameGriffin = 74010769,
BlueEyesChaosMAXDragon = 55410871,
BlueEyesChaosDragon = 20654247,
SupremeKingZARC = 13331639,
CrimsonNovaTrinitytheDarkCubicLord = 72664875,
LunalightLeoDancer = 24550676,
......
......@@ -8,6 +8,9 @@
MonsterSet,
SpellSet,
Activate,
SummonOrSet
SummonOrSet,
GoToBattlePhase,
GoToMainPhase2,
GoToEndPhase
}
}
\ No newline at end of file
......@@ -39,6 +39,7 @@ namespace WindBot.Game
public bool ShouldDirectAttack { get; set; }
public bool Attacked { get; set; }
public bool IsLastAttacker { get; set; }
public bool IsSpecialSummoned { get; set; }
public int[] ActionIndex { get; set; }
public IDictionary<int, int> ActionActivateIndex { get; private set; }
......
......@@ -19,7 +19,10 @@ namespace WindBot.Game
public int LastChainPlayer { get; set; }
public IList<ClientCard> CurrentChain { get; set; }
public IList<ClientCard> ChainTargets { get; set; }
public IList<ClientCard> ChainTargetOnly { get; set; }
public int LastSummonPlayer { get; set; }
public IList<ClientCard> SummoningCards { get; set; }
public IList<ClientCard> LastSummonedCards { get; set; }
public Duel()
{
......@@ -29,7 +32,10 @@ namespace WindBot.Game
LastChainPlayer = -1;
CurrentChain = new List<ClientCard>();
ChainTargets = new List<ClientCard>();
ChainTargetOnly = new List<ClientCard>();
LastSummonPlayer = -1;
SummoningCards = new List<ClientCard>();
LastSummonedCards = new List<ClientCard>();
}
public ClientCard GetCard(int player, CardLocation loc, int index)
......
......@@ -91,9 +91,8 @@ namespace WindBot.Game
/// </summary>
public void OnNewPhase()
{
m_selector = null;
m_nextSelector = null;
m_thirdSelector = null;
m_selector.Clear();
m_selector_pointer = -1;
m_materialSelector = null;
m_option = -1;
m_yesno = -1;
......@@ -129,6 +128,8 @@ namespace WindBot.Game
/// </summary>
public void OnChainEnd()
{
m_selector.Clear();
m_selector_pointer = -1;
Executor.OnChainEnd();
}
......@@ -142,6 +143,14 @@ namespace WindBot.Game
Executor.SetBattle(battle);
foreach (CardExecutor exec in Executor.Executors)
{
if (exec.Type == ExecutorType.GoToMainPhase2 && battle.CanMainPhaseTwo && exec.Func()) // check if should enter main phase 2 directly
{
return ToMainPhase2();
}
if (exec.Type == ExecutorType.GoToEndPhase && battle.CanEndPhase && exec.Func()) // check if should enter end phase directly
{
return ToEndPhase();
}
for (int i = 0; i < battle.ActivableCards.Count; ++i)
{
ClientCard card = battle.ActivableCards[i];
......@@ -382,6 +391,18 @@ namespace WindBot.Game
Executor.SetMain(main);
foreach (CardExecutor exec in Executor.Executors)
{
if (exec.Type == ExecutorType.GoToEndPhase && main.CanEndPhase && exec.Func()) // check if should enter end phase directly
{
_dialogs.SendEndTurn();
return new MainPhaseAction(MainPhaseAction.MainAction.ToEndPhase);
}
if (exec.Type==ExecutorType.GoToBattlePhase && main.CanBattlePhase && exec.Func()) // check if should enter battle phase directly
{
return new MainPhaseAction(MainPhaseAction.MainAction.ToBattlePhase);
}
// NOTICE: GoToBattlePhase and GoToEndPhase has no "card" can be accessed to ShouldExecute(), so instead use exec.Func() to check ...
// enter end phase and enter battle pahse is in higher priority.
for (int i = 0; i < main.ActivableCards.Count; ++i)
{
ClientCard card = main.ActivableCards[i];
......@@ -409,7 +430,6 @@ namespace WindBot.Game
if (ShouldExecute(exec, card, ExecutorType.SpSummon))
{
_dialogs.SendSummon(card.Name);
Duel.LastSummonPlayer = 0;
return new MainPhaseAction(MainPhaseAction.MainAction.SpSummon, card.ActionIndex);
}
}
......@@ -418,7 +438,6 @@ namespace WindBot.Game
if (ShouldExecute(exec, card, ExecutorType.Summon))
{
_dialogs.SendSummon(card.Name);
Duel.LastSummonPlayer = 0;
return new MainPhaseAction(MainPhaseAction.MainAction.Summon, card.ActionIndex);
}
if (ShouldExecute(exec, card, ExecutorType.SummonOrSet))
......@@ -430,7 +449,6 @@ namespace WindBot.Game
return new MainPhaseAction(MainPhaseAction.MainAction.SetMonster, card.ActionIndex);
}
_dialogs.SendSummon(card.Name);
Duel.LastSummonPlayer = 0;
return new MainPhaseAction(MainPhaseAction.MainAction.Summon, card.ActionIndex);
}
}
......@@ -721,9 +739,7 @@ namespace WindBot.Game
// _ Others functions _
// Those functions are used by the AI behavior.
private CardSelector m_selector;
private CardSelector m_nextSelector;
private CardSelector m_thirdSelector;
private CardSelector m_materialSelector;
private CardPosition m_position = CardPosition.FaceUpAttack;
private int m_place;
......@@ -732,81 +748,138 @@ namespace WindBot.Game
private int m_announce;
private int m_yesno;
private IList<CardAttribute> m_attributes = new List<CardAttribute>();
private IList<CardSelector> m_selector = new List<CardSelector>();
private int m_selector_pointer = -1;
private IList<CardRace> m_races = new List<CardRace>();
public void SelectCard(ClientCard card)
{
m_selector = new CardSelector(card);
m_selector_pointer = m_selector.Count();
m_selector.Add(new CardSelector(card));
}
public void SelectCard(IList<ClientCard> cards)
{
m_selector = new CardSelector(cards);
m_selector_pointer = m_selector.Count();
m_selector.Add(new CardSelector(cards));
}
public void SelectCard(int cardId)
{
m_selector = new CardSelector(cardId);
m_selector_pointer = m_selector.Count();
m_selector.Add(new CardSelector(cardId));
}
public void SelectCard(IList<int> ids)
{
m_selector = new CardSelector(ids);
m_selector_pointer = m_selector.Count();
m_selector.Add(new CardSelector(ids));
}
public void SelectCard(CardLocation loc)
{
m_selector = new CardSelector(loc);
m_selector_pointer = m_selector.Count();
m_selector.Add(new CardSelector(loc));
}
public void SelectNextCard(ClientCard card)
{
m_nextSelector = new CardSelector(card);
if (m_selector_pointer == -1)
{
Logger.WriteErrorLine("Error: Call SelectNextCard() before SelectCard()");
m_selector_pointer = 0;
}
m_selector.Insert(m_selector_pointer, new CardSelector(card));
}
public void SelectNextCard(IList<ClientCard> cards)
{
m_nextSelector = new CardSelector(cards);
if (m_selector_pointer == -1)
{
Logger.WriteErrorLine("Error: Call SelectNextCard() before SelectCard()");
m_selector_pointer = 0;
}
m_selector.Insert(m_selector_pointer, new CardSelector(cards));
}
public void SelectNextCard(int cardId)
{
m_nextSelector = new CardSelector(cardId);
if (m_selector_pointer == -1)
{
Logger.WriteErrorLine("Error: Call SelectNextCard() before SelectCard()");
m_selector_pointer = 0;
}
m_selector.Insert(m_selector_pointer, new CardSelector(cardId));
}
public void SelectNextCard(IList<int> ids)
{
m_nextSelector = new CardSelector(ids);
if (m_selector_pointer == -1)
{
Logger.WriteErrorLine("Error: Call SelectNextCard() before SelectCard()");
m_selector_pointer = 0;
}
m_selector.Insert(m_selector_pointer, new CardSelector(ids));
}
public void SelectNextCard(CardLocation loc)
{
m_nextSelector = new CardSelector(loc);
if (m_selector_pointer == -1)
{
Logger.WriteErrorLine("Error: Call SelectNextCard() before SelectCard()");
m_selector_pointer = 0;
}
m_selector.Insert(m_selector_pointer, new CardSelector(loc));
}
public void SelectThirdCard(ClientCard card)
{
m_thirdSelector = new CardSelector(card);
if (m_selector_pointer == -1)
{
Logger.WriteErrorLine("Error: Call SelectThirdCard() before SelectCard()");
m_selector_pointer = 0;
}
m_selector.Insert(m_selector_pointer, new CardSelector(card));
}
public void SelectThirdCard(IList<ClientCard> cards)
{
m_thirdSelector = new CardSelector(cards);
if (m_selector_pointer == -1)
{
Logger.WriteErrorLine("Error: Call SelectThirdCard() before SelectCard()");
m_selector_pointer = 0;
}
m_selector.Insert(m_selector_pointer, new CardSelector(cards));
}
public void SelectThirdCard(int cardId)
{
m_thirdSelector = new CardSelector(cardId);
if (m_selector_pointer == -1)
{
Logger.WriteErrorLine("Error: Call SelectThirdCard() before SelectCard()");
m_selector_pointer = 0;
}
m_selector.Insert(m_selector_pointer, new CardSelector(cardId));
}
public void SelectThirdCard(IList<int> ids)
{
m_thirdSelector = new CardSelector(ids);
if (m_selector_pointer == -1)
{
Logger.WriteErrorLine("Error: Call SelectThirdCard() before SelectCard()");
m_selector_pointer = 0;
}
m_selector.Insert(m_selector_pointer, new CardSelector(ids));
}
public void SelectThirdCard(CardLocation loc)
{
m_thirdSelector = new CardSelector(loc);
if (m_selector_pointer == -1)
{
Logger.WriteErrorLine("Error: Call SelectThirdCard() before SelectCard()");
m_selector_pointer = 0;
}
m_selector.Insert(m_selector_pointer, new CardSelector(loc));
}
public void SelectMaterials(ClientCard card)
......@@ -841,17 +914,11 @@ namespace WindBot.Game
public CardSelector GetSelectedCards()
{
CardSelector selected = m_selector;
m_selector = null;
if (m_nextSelector != null)
CardSelector selected = null;
if (m_selector.Count > 0)
{
m_selector = m_nextSelector;
m_nextSelector = null;
if (m_thirdSelector != null)
{
m_nextSelector = m_thirdSelector;
m_thirdSelector = null;
}
selected = m_selector[m_selector.Count - 1];
m_selector.RemoveAt(m_selector.Count - 1);
}
return selected;
}
......
......@@ -129,8 +129,12 @@ namespace WindBot.Game
_messages.Add(GameMessage.AnnounceCardFilter, OnAnnounceCard);
_messages.Add(GameMessage.RockPaperScissors, OnRockPaperScissors);
_messages.Add(GameMessage.SpSummoning, OnSpSummon);
_messages.Add(GameMessage.SpSummoned, OnSpSummon);
_messages.Add(GameMessage.Summoning, OnSummoning);
_messages.Add(GameMessage.Summoned, OnSummoned);
_messages.Add(GameMessage.SpSummoning, OnSpSummoning);
_messages.Add(GameMessage.SpSummoned, OnSpSummoned);
_messages.Add(GameMessage.FlipSummoning, OnSummoning);
_messages.Add(GameMessage.FlipSummoned, OnSummoned);
}
private void OnJoinGame(BinaryReader packet)
......@@ -478,6 +482,8 @@ namespace WindBot.Game
if (_debug)
Logger.WriteLine("(Go to " + (_duel.Phase.ToString()) + ")");
_duel.LastSummonPlayer = -1;
_duel.SummoningCards.Clear();
_duel.LastSummonedCards.Clear();
_duel.Fields[0].BattlingMonster = null;
_duel.Fields[1].BattlingMonster = null;
_ai.OnNewPhase();
......@@ -557,6 +563,8 @@ namespace WindBot.Game
else
{
_duel.AddCard((CardLocation)currentLocation, card, currentControler, currentSequence, currentPosition, cardId);
if (card != null && previousLocation != currentLocation)
card.IsSpecialSummoned = false;
if (_debug && card != null)
Logger.WriteLine("(" + previousControler.ToString() + " 's " + (card.Name ?? "UnKnowCard")
+ " from " +
......@@ -621,7 +629,8 @@ namespace WindBot.Game
if (_debug)
if (card != null) Logger.WriteLine("(" + cc.ToString() + " 's " + (card.Name ?? "UnKnowCard") + " activate effect)");
_ai.OnChaining(card, cc);
_duel.ChainTargets.Clear();
//_duel.ChainTargets.Clear();
_duel.ChainTargetOnly.Clear();
_duel.LastSummonPlayer = -1;
_duel.CurrentChain.Add(card);
_duel.LastChainPlayer = cc;
......@@ -633,7 +642,8 @@ namespace WindBot.Game
_ai.OnChainEnd();
_duel.LastChainPlayer = -1;
_duel.CurrentChain.Clear();
//_duel.ChainTargets.Clear();
_duel.ChainTargets.Clear();
_duel.ChainTargetOnly.Clear();
}
private void OnCardSorting(BinaryReader packet)
......@@ -758,6 +768,7 @@ namespace WindBot.Game
if (_debug)
Logger.WriteLine("(" + (CardLocation)loc + " 's " + (card.Name ?? "UnKnowCard") + " become target)");
_duel.ChainTargets.Add(card);
_duel.ChainTargetOnly.Add(card);
}
}
......@@ -1397,9 +1408,50 @@ namespace WindBot.Game
Connection.Send(CtosMessage.Response, result);
}
private void OnSpSummon(BinaryReader packet)
private void OnSummoning(BinaryReader packet)
{
_duel.LastSummonedCards.Clear();
int code = packet.ReadInt32();
int currentControler = GetLocalPlayer(packet.ReadByte());
int currentLocation = packet.ReadByte();
int currentSequence = packet.ReadSByte();
int currentPosition = packet.ReadSByte();
ClientCard card = _duel.GetCard(currentControler, (CardLocation)currentLocation, currentSequence);
_duel.SummoningCards.Add(card);
_duel.LastSummonPlayer = currentControler;
}
private void OnSummoned(BinaryReader packet)
{
foreach (ClientCard card in _duel.SummoningCards)
{
_duel.LastSummonedCards.Add(card);
}
_duel.SummoningCards.Clear();
}
private void OnSpSummoning(BinaryReader packet)
{
_duel.LastSummonedCards.Clear();
_ai.CleanSelectMaterials();
int code = packet.ReadInt32();
int currentControler = GetLocalPlayer(packet.ReadByte());
int currentLocation = packet.ReadByte();
int currentSequence = packet.ReadSByte();
int currentPosition = packet.ReadSByte();
ClientCard card = _duel.GetCard(currentControler, (CardLocation)currentLocation, currentSequence);
_duel.SummoningCards.Add(card);
_duel.LastSummonPlayer = currentControler;
}
private void OnSpSummoned(BinaryReader packet)
{
foreach (ClientCard card in _duel.SummoningCards)
{
card.IsSpecialSummoned = true;
_duel.LastSummonedCards.Add(card);
}
_duel.SummoningCards.Clear();
}
}
}
......@@ -66,6 +66,7 @@
<Compile Include="Game\AI\CardSelector.cs" />
<Compile Include="Game\AI\DeckAttribute.cs" />
<Compile Include="Game\AI\DecksManager.cs" />
<Compile Include="Game\AI\Decks\AltergeistExecutor.cs" />
<Compile Include="Game\AI\Decks\BlackwingExecutor.cs" />
<Compile Include="Game\AI\Decks\CyberDragonExecutor.cs" />
<Compile Include="Game\AI\Decks\DarkMagicianExecutor.cs" />
......@@ -81,6 +82,7 @@
<Compile Include="Game\AI\Decks\ChainBurnExecutor.cs" />
<Compile Include="Game\AI\Decks\EvilswarmExecutor.cs" />
<Compile Include="Game\AI\Decks\GraydleExecutor.cs" />
<Compile Include="Game\AI\Decks\GrenMajuThunderBoarderExecutor.cs" />
<Compile Include="Game\AI\Decks\LightswornExecutor.cs" />
<Compile Include="Game\AI\Decks\LightswornShaddoldinosourExecutor.cs" />
<Compile Include="Game\AI\Decks\QliphortExecutor.cs" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment