Commit 18b0cc48 authored by wind2009's avatar wind2009 Committed by GitHub

Update default excutor (#178)

parent f0581a87
...@@ -21,7 +21,8 @@ namespace WindBot.Game.AI ...@@ -21,7 +21,8 @@ namespace WindBot.Game.AI
/// </summary> /// </summary>
public static bool IsMonsterDangerous(this ClientCard card) public static bool IsMonsterDangerous(this ClientCard card)
{ {
return !card.IsDisabled() && Enum.IsDefined(typeof(DangerousMonster), card.Id); return !card.IsDisabled() &&
(Enum.IsDefined(typeof(DangerousMonster), card.Id) || (card.HasSetcode(0x18d) && (card.HasType(CardType.Ritual) || card.EquipCards.Count > 0)));
} }
/// <summary> /// <summary>
......
...@@ -126,12 +126,92 @@ namespace WindBot.Game.AI ...@@ -126,12 +126,92 @@ namespace WindBot.Game.AI
public const int VaylantzWorld_KonigWissen = 75952542; public const int VaylantzWorld_KonigWissen = 75952542;
public const int DivineArsenalAAZEUS_SkyThunder = 90448279; public const int DivineArsenalAAZEUS_SkyThunder = 90448279;
public const int BelialMarquisOfDarkness = 33655493;
public const int ChirubiméPrincessOfAutumnLeaves = 87294988;
public const int PerformapalBarokuriboh = 19050066;
public const int LabrynthArchfiend = 48745395;
public const int HarpiesPetDragonFearsomeFireBlast = 4991081;
public const int DynaHeroFurHire = 25123713;
public const int Hieracosphinx = 82260502;
public const int SpeedroidPassinglider = 26420373;
public const int TyrOfTheNordicChampions = 2333365;
public const int ValkyrianKnight = 99348756;
public const int Victoria = 75162696;
public const int MadolcheChouxvalier = 75363626;
public const int LadyOfD = 67511500;
public const int MermailAbysslung = 95466842;
public const int HarpiesPetBabyDragon = 6924874;
public const int HandHoldingGenie = 94535485;
public const int GolemDragon = 9666558;
public const int TwilightRoseKnight = 2986553;
public const int PerformapalThunderhino = 70458081;
public const int MiracleFlipper = 131182;
public const int Decoyroid = 25034083;
public const int AltergeistFifinellag = 12977245;
public const int BatterymanD = 55401221;
public const int Watthopper = 61380658;
public const int EgyptianGodSlime = 42166000;
public const int DinowrestlerChimeraTWrextle = 22900219;
public const int DinowrestlerGigaSpinosavate = 58672736;
public const int ScarredWarrior = 45298492;
public const int SharkFortress = 50449881;
public const int HeroicChampionClaivesolish = 97453744;
public const int GhostrickAlucard = 75367227;
public const int DinowrestlerKingTWrextle = 77967790;
public const int PerformapalMissDirector = 92932860;
public const int AncientWarriorsMasterfulSunMou = 40140448;
public const int AncientWarriorsVirtuousLiuXuan = 40428851;
public const int CommandKnight = 10375182;
public const int HunterOwl = 51962254;
public const int RokketRecharger = 5969957;
public const int EmissaryOfTheOasis = 6103294;
public const int Zuttomozaurus = 24454387;
public const int Otoshidamashi = 14957440;
public const int NaturiaMosquito = 17285476;
public const int RescueACEHydrant = 37617348; public const int RescueACEHydrant = 37617348;
public const int MeizenTheBattleNinja = 11825276;
public const int VindikiteRGenex = 73483491;
public const int PrincessCologne = 75574498;
public const int Number48ShadowLich = 1426714;
public const int PhantomToken = 1426715;
public const int DuelLinkDragonTheDuelDragon = 60025883;
public const int DuelDragonToken = 60025884;
public const int SeleneQueenOfTheMasterMagicians = 45819647;
public const int TheWingedDragonofRaSphereMode = 10000080;
public const int RockOfTheVanquisher = 28168628;
public const int SpiralDischarge = 29477860;
public const int GaiaTheDragonChampion = 66889139;
public const int CrusadiaVanguard = 55312487;
public const int GladiatorBeastDomitianus = 33652635;
public const int PatricianOfDarkness = 19153634;
public const int DictatorOfD = 66961194;
public const int NovoxTheSilenforcerDisciple = 25801745;
public const int SilenforcingBarrier = 98477480;
} }
protected class _Setcode protected class _Setcode
{ {
public const int Watt = 0xe;
public const int Speedroid = 0x2016;
public const int EarthboundImmortal = 0x1021;
public const int Naturia = 0x2a;
public const int Nordic = 0x42;
public const int Harpie = 0x64;
public const int Madolche = 0x71;
public const int Ghostrick = 0x8d;
public const int OddEyes = 0x99;
public const int Performapal = 0x9f;
public const int BlueEyes = 0xdd;
public const int FurHire = 0x114;
public const int Altergeist = 0x103;
public const int Crusadia = 0x116;
public const int Endymion = 0x12a;
public const int AncientWarriors = 0x137;
public const int RescueACE = 0x18b; public const int RescueACE = 0x18b;
public const int VanquishSoul = 0x195;
} }
protected DefaultExecutor(GameAI ai, Duel duel) protected DefaultExecutor(GameAI ai, Duel duel)
...@@ -143,6 +223,77 @@ namespace WindBot.Game.AI ...@@ -143,6 +223,77 @@ namespace WindBot.Game.AI
AddExecutor(ExecutorType.Activate, _CardId.SantaClaws); AddExecutor(ExecutorType.Activate, _CardId.SantaClaws);
} }
/// <summary>
/// Defined:
/// if monster with code as KEY, other monsters with rules as VALUE won't be targeted for attack.
/// </summary>
protected Dictionary<int, Func<ClientCard, bool>> DefenderProtectRule = new Dictionary<int, Func<ClientCard, bool>> {
{_CardId.BelialMarquisOfDarkness, defender => defender.IsFaceup()},
{_CardId.ChirubiméPrincessOfAutumnLeaves, defender => defender.HasRace(CardRace.Plant)},
{_CardId.PerformapalBarokuriboh, defender => true},
{_CardId.LabrynthArchfiend, defender => defender.HasRace(CardRace.Fiend) && !defender.IsCode(_CardId.LabrynthArchfiend)},
{_CardId.HarpiesPetDragonFearsomeFireBlast, defender => defender.Level <= 6 && defender.HasSetcode(_Setcode.Harpie)},
{_CardId.DynaHeroFurHire, defender => defender.HasSetcode(_Setcode.FurHire)},
{_CardId.Hieracosphinx, defender => defender.IsFacedown()},
{_CardId.SpeedroidPassinglider, defender => defender.HasSetcode(_Setcode.Speedroid)},
{_CardId.TyrOfTheNordicChampions, defender => defender.HasSetcode(_Setcode.Nordic)},
{_CardId.ValkyrianKnight, defender => defender.HasRace(CardRace.Warrior) && !defender.IsCode(_CardId.ValkyrianKnight)},
{_CardId.Victoria, defender => defender.HasRace(CardRace.Fairy)},
{_CardId.MadolcheChouxvalier, defender => defender.HasSetcode(_Setcode.Madolche) && !defender.IsCode(_CardId.MadolcheChouxvalier)},
{_CardId.LadyOfD, defender => defender.HasRace(CardRace.Dragon)},
{_CardId.MermailAbysslung, defender => defender.HasAttribute(CardAttribute.Water)},
{_CardId.HarpiesPetBabyDragon, defender => defender.HasSetcode(_Setcode.Harpie) && !defender.IsCode(_CardId.HarpiesPetBabyDragon)},
{_CardId.HandHoldingGenie, defender => true},
{_CardId.GolemDragon, defender => defender.HasRace(CardRace.Dragon)},
{_CardId.MaraudingCaptain, defender => defender.HasRace(CardRace.Warrior)},
{_CardId.TwilightRoseKnight, defender => defender.HasRace(CardRace.Plant)},
{_CardId.PerformapalThunderhino, defender => defender.HasSetcode(_Setcode.Performapal)},
{_CardId.MiracleFlipper, defender => defender.IsFaceup()},
{_CardId.Decoyroid, defender => defender.IsFaceup()},
{_CardId.DupeFrog, defender => true},
{_CardId.AltergeistFifinellag, defender => defender.HasSetcode(_Setcode.Altergeist)},
{_CardId.BatterymanD, defender => defender.HasRace(CardRace.Thunder) && !defender.IsCode(_CardId.BatterymanD)},
{_CardId.Watthopper, defender => defender.HasSetcode(_Setcode.Watt) && defender.IsFaceup()},
{_CardId.EgyptianGodSlime, defender => true},
{_CardId.DinowrestlerChimeraTWrextle, defender => true},
{_CardId.DinowrestlerGigaSpinosavate, defender => true},
{_CardId.ScarredWarrior, defender => defender.HasRace(CardRace.Warrior) && defender.IsFaceup()},
{_CardId.SharkFortress, defender => true},
{_CardId.HeroicChampionClaivesolish, defender => true},
{_CardId.GhostrickAlucard, defender => defender.HasSetcode(_Setcode.Ghostrick) || defender.IsFacedown()},
{_CardId.MekkKnightCrusadiaAstram, defender => true},
{_CardId.DinowrestlerKingTWrextle, defender => true}
};
/// <summary>
/// Defined:
/// if monster with KEY on field, and meet VALUE(monster, all monster), it cannot be targeted for attack.
/// </summary>
protected Dictionary<int, Func<ClientCard, List<ClientCard>, bool>> DefenderInvisbleRule = new Dictionary<int, Func<ClientCard, List<ClientCard>, bool>> {
{_CardId.UltimayaTzolkin, (defender, list) => list.Any(monster => !monster.Equals(defender) && monster.HasType(CardType.Synchro))},
{_CardId.PerformapalMissDirector, (defender, list) => list.Any(monster => monster.HasSetcode(_Setcode.OddEyes))},
{_CardId.AncientWarriorsMasterfulSunMou, (defender, list) => list.Any(monster => !monster.Equals(defender) && monster.HasSetcode(_Setcode.AncientWarriors))},
{_CardId.AncientWarriorsVirtuousLiuXuan, (defender, list) => list.Any(monster => !monster.Equals(defender) && monster.HasSetcode(_Setcode.AncientWarriors))},
{_CardId.CommandKnight, (defender, list) => list.Any(monster => !monster.Equals(defender))},
{_CardId.HunterOwl, (defender, list) => list.Any(monster => !monster.Equals(defender) && monster.HasAttribute(CardAttribute.Wind))},
{_CardId.RokketRecharger, (defender, list) => list.Any(monster => monster.IsExtraCard() && monster.HasAttribute(CardAttribute.Dark))},
{_CardId.EmissaryOfTheOasis, (defender, list) => list.Any(monster => monster.HasType(CardType.Normal) && monster.Level <= 3)},
{_CardId.Zuttomozaurus, (defender, list) => list.Any(monster => !monster.Equals(defender) && monster.HasRace(CardRace.Dinosaur))},
{_CardId.Otoshidamashi, (defender, list) => list.Any(monster => !monster.HasType(CardType.Tuner))},
{_CardId.NaturiaMosquito, (defender, list) => list.Any(monster => !monster.Equals(defender) && monster.HasSetcode(_Setcode.Naturia))},
{_CardId.RescueACEHydrant, (defender, list) => list.Any(monster => !monster.IsCode(_CardId.RescueACEHydrant) && monster.HasSetcode(_Setcode.RescueACE))},
{_CardId.MeizenTheBattleNinja, (defender, list) => list.Any(monster => monster.IsFacedown())},
{_CardId.VindikiteRGenex, (defender, list) => true},
{_CardId.PrincessCologne, (defender, list) => list.Any(monster => !monster.Equals(defender))},
{_CardId.Number48ShadowLich, (defender, list) => list.Any(monster => monster.IsCode(_CardId.PhantomToken))},
{_CardId.DuelLinkDragonTheDuelDragon, (defender, list) => list.Any(monster => monster.IsCode(_CardId.DuelDragonToken))},
{_CardId.SeleneQueenOfTheMasterMagicians, (defender, list) => list.Any(monster => monster.HasSetcode(_Setcode.Endymion))},
{_CardId.TheWingedDragonofRaSphereMode, (defender, list) => true}
};
/// <summary> /// <summary>
/// Decide which card should the attacker attack. /// Decide which card should the attacker attack.
/// </summary> /// </summary>
...@@ -192,21 +343,16 @@ namespace WindBot.Game.AI ...@@ -192,21 +343,16 @@ namespace WindBot.Game.AI
return false; return false;
} }
foreach (ClientCard equip in defender.EquipCards) if (defender.EquipCards.Any(equip => equip.IsCode(_CardId.MoonMirrorShield) && !equip.IsDisabled()))
{ return false;
if (equip.IsCode(_CardId.MoonMirrorShield) && !equip.IsDisabled())
{
return false;
}
}
if (!defender.IsDisabled()) if (!defender.IsDisabled())
{ {
if (defender.IsCode(_CardId.MekkKnightCrusadiaAstram) && defender.IsAttack() && attacker.IsSpecialSummoned) if (defender.IsCode(_CardId.MekkKnightCrusadiaAstram) && defender.IsAttack() && attacker.IsSpecialSummoned)
return false; defender.RealPower += attacker.Attack;
if (defender.IsCode(_CardId.CrystalWingSynchroDragon) && defender.IsAttack() && attacker.Level >= 5) if (defender.IsCode(_CardId.CrystalWingSynchroDragon) && defender.IsAttack() && attacker.Level >= 5)
return false; defender.RealPower += attacker.Attack;
if (defender.IsCode(_CardId.AllyOfJusticeCatastor) && !attacker.HasAttribute(CardAttribute.Dark)) if (defender.IsCode(_CardId.AllyOfJusticeCatastor) && !attacker.HasAttribute(CardAttribute.Dark))
return false; return false;
...@@ -232,37 +378,62 @@ namespace WindBot.Game.AI ...@@ -232,37 +378,62 @@ namespace WindBot.Game.AI
if (attacker.IsMonsterInvincible()) if (attacker.IsMonsterInvincible())
attacker.RealPower = 9999; attacker.RealPower = 9999;
if (attacker.EquipCards.Any(equip => equip.IsCode(_CardId.MoonMirrorShield) && !equip.IsDisabled()))
attacker.RealPower = defender.RealPower + 100;
}
foreach (ClientCard equip in attacker.EquipCards) foreach (ClientCard protecter in Enemy.GetMonsters())
{
if (!protecter.IsDisabled() && protecter != defender)
{ {
if (equip.IsCode(_CardId.MoonMirrorShield) && !equip.IsDisabled()) Func<ClientCard, bool> defenderRule = card => false;
if (DefenderProtectRule.TryGetValue(protecter.Id, out defenderRule))
{ {
attacker.RealPower = defender.RealPower + 100; if (defenderRule(defender)) return false;
} }
} }
} }
if (Enemy.HasInMonstersZone(_CardId.MekkKnightCrusadiaAstram, true) && !(defender).IsCode(_CardId.MekkKnightCrusadiaAstram)) if (!defender.IsDisabled())
return false; {
Func<ClientCard, List<ClientCard>, bool> defenderRule = (card, monsterList) => false;
if (Enemy.HasInMonstersZone(_CardId.DupeFrog, true) && !(defender).IsCode(_CardId.DupeFrog)) if (DefenderInvisbleRule.TryGetValue(defender.Id, out defenderRule))
return false; {
if (defenderRule(defender, Enemy.GetMonsters())) return false;
}
}
if (Enemy.HasInMonstersZone(_CardId.MaraudingCaptain, true) && !defender.IsCode(_CardId.MaraudingCaptain) && defender.Race == (int)CardRace.Warrior) if (Enemy.GetMonsters().Any(monster => !monster.Equals(defender) && monster.IsCode(_CardId.HamonLordofStrikingThunder) && !monster.IsDisabled() && monster.IsDefense()))
return false; return false;
if (defender.IsCode(_CardId.UltimayaTzolkin) && !defender.IsDisabled() && Enemy.GetMonsters().Any(monster => !monster.Equals(defender) && monster.HasType(CardType.Synchro))) if (defender.OwnTargets.Any(card => card.IsCode(_CardId.PhantomKnightsFogBlade) && !card.IsDisabled()))
return false; return false;
if (Enemy.GetMonsters().Any(monster => !monster.Equals(defender) && monster.IsCode(_CardId.HamonLordofStrikingThunder) && !monster.IsDisabled() && monster.IsDefense())) if (defender.HasSetcode(_Setcode.EarthboundImmortal) && !defender.IsDisabled())
return false; return false;
bool attackHighestMonster =
Enemy.HasInMonstersZone(_CardId.RockOfTheVanquisher, true) && Enemy.GetMonsters().Any(card => card.HasSetcode(_Setcode.VanquishSoul)) ||
Enemy.HasInMonstersZone(_CardId.GladiatorBeastDomitianus, true) || Enemy.HasInMonstersZone(_CardId.PatricianOfDarkness) ||
Enemy.HasInMonstersZone(_CardId.DictatorOfD, true) && Enemy.GetMonsters().Any(card => card.HasSetcode(_Setcode.BlueEyes));
if (attackHighestMonster)
{
if (defender.HasPosition(CardPosition.FaceDown))
return false;
if (Enemy.GetMonsters().Any(card => card.IsFaceup() && card.Attack > defender.Attack))
return false;
}
if (defender.OwnTargets.Any(card => card.IsCode(_CardId.PhantomKnightsFogBlade) && !card.IsDisabled())) if (Enemy.HasInSpellZone(_CardId.SpiralDischarge, true) && Enemy.HasInMonstersZone(_CardId.GaiaTheDragonChampion) && !defender.IsCode(_CardId.GaiaTheDragonChampion))
return false; return false;
if (defender.IsCode(_CardId.RescueACEHydrant) && !defender.IsDisabled() && Enemy.GetMonsters().Any(monster => monster.HasSetcode(_Setcode.RescueACE) && !monster.IsCode(_CardId.RescueACEHydrant))) if (Enemy.HasInSpellZone(_CardId.CrusadiaVanguard, true) && Enemy.GetMonsters().Any(card => card.HasSetcode(_Setcode.Crusadia) && card.HasType(CardType.Link)) && !defender.HasType(CardType.Link))
return false; return false;
if (Enemy.HasInSpellZone(_CardId.SilenforcingBarrier, true) && Enemy.HasInMonstersZone(_CardId.NovoxTheSilenforcerDisciple, faceUp: true) && !defender.HasType(CardType.Ritual))
return false;
return true; return true;
} }
...@@ -1227,7 +1398,7 @@ namespace WindBot.Game.AI ...@@ -1227,7 +1398,7 @@ namespace WindBot.Game.AI
if (Card.Location == CardLocation.Hand) if (Card.Location == CardLocation.Hand)
{ {
return Bot.BattlingMonster.IsAttack() && return Bot.BattlingMonster.IsAttack() &&
(((Bot.BattlingMonster.Attack < Enemy.BattlingMonster.Attack) || Bot.BattlingMonster.Attack >= Enemy.LifePoints) ((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))); || ((Bot.BattlingMonster.Attack < Enemy.BattlingMonster.Defense) && (Bot.BattlingMonster.Attack + Enemy.BattlingMonster.Attack > Enemy.BattlingMonster.Defense)));
} }
...@@ -1263,13 +1434,13 @@ namespace WindBot.Game.AI ...@@ -1263,13 +1434,13 @@ namespace WindBot.Game.AI
List<ClientCard> targetList = new List<ClientCard>(); List<ClientCard> targetList = new List<ClientCard>();
List<ClientCard> floodgateCards = monsters List<ClientCard> floodgateCards = monsters
.Where(card => card?.Data != null && card.IsFloodgate() && card.IsFaceup() && !card.IsShouldNotBeTarget()) .Where(card => card?.Data != null && card.IsFloodgate() && card.IsFaceup() && !card.IsShouldNotBeTarget())
.OrderBy(card => card.Attack).ToList(); .OrderByDescending(card => card.Attack).ToList();
List<ClientCard> dangerousCards = monsters List<ClientCard> dangerousCards = monsters
.Where(card => card?.Data != null && card.IsMonsterDangerous() && card.IsFaceup() && !card.IsShouldNotBeTarget()) .Where(card => card?.Data != null && card.IsMonsterDangerous() && card.IsFaceup() && !card.IsShouldNotBeTarget())
.OrderBy(card => card.Attack).ToList(); .OrderByDescending(card => card.Attack).ToList();
List<ClientCard> attackOrderedCards = monsters List<ClientCard> attackOrderedCards = monsters
.Where(card => card?.Data != null && card.HasType(CardType.Monster) && card.IsFaceup() && card.IsShouldNotBeTarget()) .Where(card => card?.Data != null && card.HasType(CardType.Monster) && card.IsFaceup() && card.IsShouldNotBeTarget())
.OrderBy(card => card.Attack).ToList(); .OrderByDescending(card => card.Attack).ToList();
targetList.AddRange(floodgateCards); targetList.AddRange(floodgateCards);
targetList.AddRange(dangerousCards); targetList.AddRange(dangerousCards);
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
Heart_eartHDragon = 97403510, Heart_eartHDragon = 97403510,
DaigustoSphreeze = 29552709, DaigustoSphreeze = 29552709,
OhimetheManifestedMikanko = 81260679, OhimetheManifestedMikanko = 81260679,
ArahimetheManifestedMikanko = 75771170 ArahimetheManifestedMikanko = 75771170,
YubelDasEwigLiebeWächter = 47172959
} }
} }
...@@ -210,6 +210,7 @@ ...@@ -210,6 +210,7 @@
TGGlaiveBlaster = 95973569, TGGlaiveBlaster = 95973569,
StellarNemesisTPHON_DoomsdayStar = 93039339, StellarNemesisTPHON_DoomsdayStar = 93039339,
SPLittleKnight = 29301450, SPLittleKnight = 29301450,
AngelRing = 40678060 AngelRing = 40678060,
SkullGuardianTheSilenforcingProtector = 10774240
} }
} }
...@@ -109,6 +109,11 @@ ...@@ -109,6 +109,11 @@
NightmareMagician = 40221691, NightmareMagician = 40221691,
ArahimetheManifestedMikanko = 75771170, ArahimetheManifestedMikanko = 75771170,
UFOLight = 9275482, UFOLight = 9275482,
TaotheGreatChanter = 34541543 TaotheGreatChanter = 34541543,
SpiritOfYubel = 90829280,
DarkGuardian = 26746975,
EnvoyOfTheWaxState = 87462901,
Fluffyfluff = 85401123,
YubelDasEwigLiebeWächter = 47172959
} }
} }
...@@ -49,6 +49,8 @@ ...@@ -49,6 +49,8 @@
Blackwing_FullArmoredWing = 54082269, Blackwing_FullArmoredWing = 54082269,
DragunofRedEyes = 37818794, DragunofRedEyes = 37818794,
RedEyesBDragon = 74677422, // sometimes the name of DragunofRedEyes will be changed to RedEyesBDragon RedEyesBDragon = 74677422, // sometimes the name of DragunofRedEyes will be changed to RedEyesBDragon
TheArrivalCyberseIgnister = 11738489 TheArrivalCyberseIgnister = 11738489,
MajespecterPorcupineYamaarashi = 51073802,
RaidraptorRisingRebellionFalcon = 71222868
} }
} }
...@@ -95,6 +95,11 @@ namespace WindBot.Game.AI ...@@ -95,6 +95,11 @@ namespace WindBot.Game.AI
// For overriding // For overriding
} }
public virtual void OnChainSolved(int chainIndex)
{
// For overriding
}
public virtual void OnChainEnd() public virtual void OnChainEnd()
{ {
// For overriding // For overriding
......
using System.Collections.Generic; using System.Collections.Generic;
using YGOSharp.OCGWrapper.Enums; using YGOSharp.OCGWrapper.Enums;
namespace WindBot.Game namespace WindBot.Game
...@@ -26,6 +26,8 @@ namespace WindBot.Game ...@@ -26,6 +26,8 @@ namespace WindBot.Game
public int LastSummonPlayer { get; set; } public int LastSummonPlayer { get; set; }
public IList<ClientCard> SummoningCards { get; set; } public IList<ClientCard> SummoningCards { get; set; }
public IList<ClientCard> LastSummonedCards { get; set; } public IList<ClientCard> LastSummonedCards { get; set; }
public int SolvingChainIndex { get; set; }
public IList<int> NegatedChainIndexList { get; set; }
public Duel() public Duel()
{ {
...@@ -41,6 +43,8 @@ namespace WindBot.Game ...@@ -41,6 +43,8 @@ namespace WindBot.Game
LastSummonPlayer = -1; LastSummonPlayer = -1;
SummoningCards = new List<ClientCard>(); SummoningCards = new List<ClientCard>();
LastSummonedCards = new List<ClientCard>(); LastSummonedCards = new List<ClientCard>();
SolvingChainIndex = 0;
NegatedChainIndexList = new List<int>();
} }
public ClientCard GetCard(int player, CardLocation loc, int seq) public ClientCard GetCard(int player, CardLocation loc, int seq)
...@@ -169,5 +173,16 @@ namespace WindBot.Game ...@@ -169,5 +173,16 @@ namespace WindBot.Game
{ {
return IsFirst ? player : 1 - player; return IsFirst ? player : 1 - player;
} }
public ClientCard GetCurrentSolvingChainCard()
{
if (SolvingChainIndex == 0 || SolvingChainIndex > CurrentChain.Count) return null;
return CurrentChain[SolvingChainIndex - 1];
}
public bool IsCurrentSolvingChainNegated()
{
return SolvingChainIndex > 0 && NegatedChainIndexList.Contains(SolvingChainIndex);
}
} }
} }
\ No newline at end of file
...@@ -141,6 +141,11 @@ namespace WindBot.Game ...@@ -141,6 +141,11 @@ namespace WindBot.Game
{ {
Executor.OnChaining(player,card); Executor.OnChaining(player,card);
} }
public void OnChainSolved(int chainIndex)
{
Executor.OnChainSolved(chainIndex);
}
/// <summary> /// <summary>
/// Called when a chain has been solved. /// Called when a chain has been solved.
...@@ -300,6 +305,8 @@ namespace WindBot.Game ...@@ -300,6 +305,8 @@ namespace WindBot.Game
// Always select the first available cards and choose the minimum. // Always select the first available cards and choose the minimum.
IList<ClientCard> selected = new List<ClientCard>(); IList<ClientCard> selected = new List<ClientCard>();
if (hint == HintMsg.AttackTarget && cancelable) return selected;
if (cards.Count >= min) if (cards.Count >= min)
{ {
for (int i = 0; i < min; ++i) for (int i = 0; i < min; ++i)
......
...@@ -109,6 +109,10 @@ namespace WindBot.Game ...@@ -109,6 +109,10 @@ namespace WindBot.Game
_messages.Add(GameMessage.AttackDisabled, OnAttackDisabled); _messages.Add(GameMessage.AttackDisabled, OnAttackDisabled);
_messages.Add(GameMessage.PosChange, OnPosChange); _messages.Add(GameMessage.PosChange, OnPosChange);
_messages.Add(GameMessage.Chaining, OnChaining); _messages.Add(GameMessage.Chaining, OnChaining);
_messages.Add(GameMessage.ChainSolving, OnChainSolving);
_messages.Add(GameMessage.ChainNegated, OnChainNegated);
_messages.Add(GameMessage.ChainDisabled, OnChainDisabled);
_messages.Add(GameMessage.ChainSolved, OnChainSolved);
_messages.Add(GameMessage.ChainEnd, OnChainEnd); _messages.Add(GameMessage.ChainEnd, OnChainEnd);
_messages.Add(GameMessage.SortCard, OnCardSorting); _messages.Add(GameMessage.SortCard, OnCardSorting);
_messages.Add(GameMessage.SortChain, OnChainSorting); _messages.Add(GameMessage.SortChain, OnChainSorting);
...@@ -362,6 +366,19 @@ namespace WindBot.Game ...@@ -362,6 +366,19 @@ namespace WindBot.Game
extra = packet.ReadInt16(); extra = packet.ReadInt16();
_duel.Fields[GetLocalPlayer(1)].Init(deck, extra); _duel.Fields[GetLocalPlayer(1)].Init(deck, extra);
// in case of ending duel in chain's solving
_duel.LastChainPlayer = -1;
_duel.LastChainLocation = 0;
_duel.CurrentChain.Clear();
_duel.ChainTargets.Clear();
_duel.LastChainTargets.Clear();
_duel.ChainTargetOnly.Clear();
_duel.LastSummonPlayer = -1;
_duel.SummoningCards.Clear();
_duel.LastSummonedCards.Clear();
_duel.SolvingChainIndex = 0;
_duel.NegatedChainIndexList.Clear();
Logger.DebugWriteLine("Duel started: " + _room.Names[0] + " versus " + _room.Names[1]); Logger.DebugWriteLine("Duel started: " + _room.Names[0] + " versus " + _room.Names[1]);
_ai.OnStart(); _ai.OnStart();
} }
...@@ -742,6 +759,30 @@ namespace WindBot.Game ...@@ -742,6 +759,30 @@ namespace WindBot.Game
} }
private void OnChainSolving(BinaryReader packet)
{
int chainIndex = packet.ReadByte();
_duel.SolvingChainIndex = chainIndex;
}
private void OnChainNegated(BinaryReader packet)
{
int chainIndex = packet.ReadByte();
_duel.NegatedChainIndexList.Add(chainIndex);
}
private void OnChainDisabled(BinaryReader packet)
{
int chainIndex = packet.ReadByte();
_duel.NegatedChainIndexList.Add(chainIndex);
}
private void OnChainSolved(BinaryReader packet)
{
int chainIndex = packet.ReadByte();
_ai.OnChainSolved(chainIndex);
}
private void OnChainEnd(BinaryReader packet) private void OnChainEnd(BinaryReader packet)
{ {
_ai.OnChainEnd(); _ai.OnChainEnd();
...@@ -751,6 +792,8 @@ namespace WindBot.Game ...@@ -751,6 +792,8 @@ namespace WindBot.Game
_duel.ChainTargets.Clear(); _duel.ChainTargets.Clear();
_duel.LastChainTargets.Clear(); _duel.LastChainTargets.Clear();
_duel.ChainTargetOnly.Clear(); _duel.ChainTargetOnly.Clear();
_duel.SolvingChainIndex = 0;
_duel.NegatedChainIndexList.Clear();
} }
private void OnCardSorting(BinaryReader packet) private void OnCardSorting(BinaryReader packet)
...@@ -1083,7 +1126,7 @@ namespace WindBot.Game ...@@ -1083,7 +1126,7 @@ namespace WindBot.Game
int count = packet.ReadByte(); int count = packet.ReadByte();
packet.ReadByte(); // specount packet.ReadByte(); // specount
bool forced = packet.ReadByte() != 0; bool forced = packet.ReadByte() != 0;
packet.ReadInt32(); // hint1 int hint1 = packet.ReadInt32(); // hint1
int hint2 = packet.ReadInt32(); // hint2 int hint2 = packet.ReadInt32(); // hint2
IList<ClientCard> cards = new List<ClientCard>(); IList<ClientCard> cards = new List<ClientCard>();
...@@ -1124,7 +1167,7 @@ namespace WindBot.Game ...@@ -1124,7 +1167,7 @@ namespace WindBot.Game
return; return;
} }
Connection.Send(CtosMessage.Response, _ai.OnSelectChain(cards, descs, forced, hint2)); Connection.Send(CtosMessage.Response, _ai.OnSelectChain(cards, descs, forced, hint1 | hint2));
} }
private void OnSelectCounter(BinaryReader packet) private void OnSelectCounter(BinaryReader packet)
......
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