Commit 415dccdb authored by mercury233's avatar mercury233

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

parents beed24a4 0f71dc96
#created by ...
#main
46986414
46986414
46986414
30603688
30603688
30603688
71007216
71007216
7084129
7084129
7084129
43722862
43722862
14558127
14558127
14824019
23434538
70117860
1784686
1784686
2314238
23314220
70368879
70368879
89739383
41735184
73616671
47222536
47222536
47222536
67775894
67775894
7922915
7922915
7922915
48680970
48680970
48680970
40605147
40605147
#extra
41721210
41721210
50954680
58074177
90036274
14577226
16691074
22110647
80117527
71384012
71384012
71384012
1482001
!side
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
80280944 80280944
48048590 48048590
77723643 77723643
77723643
55623480 55623480
30328508 30328508
30328508 30328508
......
using System.Collections.Generic; using System.Collections.Generic;
using YGOSharp.OCGWrapper.Enums; using YGOSharp.OCGWrapper.Enums;
namespace WindBot.Game.AI namespace WindBot.Game.AI
{ {
public class AIFunctions public class AIFunctions
...@@ -150,15 +149,34 @@ namespace WindBot.Game.AI ...@@ -150,15 +149,34 @@ namespace WindBot.Game.AI
} }
return bestMonster; return bestMonster;
} }
public ClientCard GetOneEnemyBetterThanValue(int value, bool onlyATK = false) public ClientCard GetWorstBotMonster(bool onlyATK = false)
{
int WorstPower = -1;
ClientCard WorstMonster = 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 < WorstPower)
{
WorstPower = newPower;
WorstMonster = card;
}
}
return WorstMonster;
}
public ClientCard GetOneEnemyBetterThanValue(int value, bool onlyATK = false, bool canBeTarget = false)
{ {
ClientCard bestCard = null; ClientCard bestCard = null;
int bestValue = value; int bestValue = value;
for (int i = 0; i < 7; ++i) for (int i = 0; i < 7; ++i)
{ {
ClientCard card = Enemy.MonsterZone[i]; ClientCard card = Enemy.MonsterZone[i];
if (card == null || card.Data == null) continue; if (card == null || card.Data == null || (canBeTarget && card.IsShouldNotBeTarget())) continue;
if (onlyATK && card.IsDefense()) continue; if (onlyATK && card.IsDefense()) continue;
int enemyValue = card.GetDefensePower(); int enemyValue = card.GetDefensePower();
if (enemyValue >= bestValue) if (enemyValue >= bestValue)
...@@ -170,52 +188,52 @@ namespace WindBot.Game.AI ...@@ -170,52 +188,52 @@ namespace WindBot.Game.AI
return bestCard; return bestCard;
} }
public ClientCard GetOneEnemyBetterThanMyBest(bool onlyATK = false) public ClientCard GetOneEnemyBetterThanMyBest(bool onlyATK = false, bool canBeTarget = false)
{ {
int bestBotPower = GetBestPower(Bot, onlyATK); int bestBotPower = GetBestPower(Bot, onlyATK);
return GetOneEnemyBetterThanValue(bestBotPower, onlyATK); return GetOneEnemyBetterThanValue(bestBotPower, onlyATK, canBeTarget);
} }
public ClientCard GetProblematicEnemyCard(int attack = 0) public ClientCard GetProblematicEnemyCard(int attack = 0, bool canBeTarget = false)
{ {
ClientCard card = Enemy.MonsterZone.GetFloodgate(); ClientCard card = Enemy.MonsterZone.GetFloodgate(canBeTarget);
if (card != null) if (card != null)
return card; return card;
card = Enemy.SpellZone.GetFloodgate(); card = Enemy.SpellZone.GetFloodgate(canBeTarget);
if (card != null) if (card != null)
return card; return card;
card = Enemy.MonsterZone.GetDangerousMonster(); card = Enemy.MonsterZone.GetDangerousMonster(canBeTarget);
if (card != null) if (card != null)
return card; return card;
card = Enemy.MonsterZone.GetInvincibleMonster(); card = Enemy.MonsterZone.GetInvincibleMonster(canBeTarget);
if (card != null) if (card != null)
return card; return card;
if (attack == 0) if (attack == 0)
attack = GetBestAttack(Bot); attack = GetBestAttack(Bot);
return GetOneEnemyBetterThanValue(attack, true); return GetOneEnemyBetterThanValue(attack, true, canBeTarget);
} }
public ClientCard GetProblematicEnemyMonster(int attack = 0) public ClientCard GetProblematicEnemyMonster(int attack = 0, bool canBeTarget = false)
{ {
ClientCard card = Enemy.MonsterZone.GetFloodgate(); ClientCard card = Enemy.MonsterZone.GetFloodgate(canBeTarget);
if (card != null) if (card != null)
return card; return card;
card = Enemy.MonsterZone.GetDangerousMonster(); card = Enemy.MonsterZone.GetDangerousMonster(canBeTarget);
if (card != null) if (card != null)
return card; return card;
card = Enemy.MonsterZone.GetInvincibleMonster(); card = Enemy.MonsterZone.GetInvincibleMonster(canBeTarget);
if (card != null) if (card != null)
return card; return card;
if (attack == 0) if (attack == 0)
attack = GetBestAttack(Bot); attack = GetBestAttack(Bot);
return GetOneEnemyBetterThanValue(attack, true); return GetOneEnemyBetterThanValue(attack, true, canBeTarget);
} }
public ClientCard GetProblematicEnemySpell() public ClientCard GetProblematicEnemySpell()
...@@ -224,9 +242,9 @@ namespace WindBot.Game.AI ...@@ -224,9 +242,9 @@ namespace WindBot.Game.AI
return card; return card;
} }
public ClientCard GetBestEnemyCard(bool onlyFaceup = false) public ClientCard GetBestEnemyCard(bool onlyFaceup = false, bool canBeTarget = false)
{ {
ClientCard card = GetBestEnemyMonster(onlyFaceup); ClientCard card = GetBestEnemyMonster(onlyFaceup, canBeTarget);
if (card != null) if (card != null)
return card; return card;
...@@ -237,25 +255,44 @@ namespace WindBot.Game.AI ...@@ -237,25 +255,44 @@ namespace WindBot.Game.AI
return null; return null;
} }
public ClientCard GetBestEnemyMonster(bool onlyFaceup = false) public ClientCard GetBestEnemyMonster(bool onlyFaceup = false, bool canBeTarget = false)
{ {
ClientCard card = GetProblematicEnemyMonster(); ClientCard card = GetProblematicEnemyMonster(0, canBeTarget);
if (card != null) if (card != null)
return card; return card;
card = Enemy.MonsterZone.GetHighestAttackMonster(); card = Enemy.MonsterZone.GetHighestAttackMonster(canBeTarget);
if (card != null) if (card != null)
return card; return card;
List<ClientCard> monsters = Enemy.GetMonsters(); List<ClientCard> monsters = Enemy.GetMonsters();
// after GetHighestAttackMonster, the left monsters must be face-down. // after GetHighestAttackMonster, the left monsters must be face-down.
if (monsters.Count > 0 && !onlyFaceup) if (monsters.Count > 0 && !onlyFaceup && (!canBeTarget || !card.IsShouldNotBeTarget()))
return monsters[0]; return monsters[0];
return null; return null;
} }
public ClientCard GetWorstEnemyMonster(bool onlyATK = false)
{
int WorstPower = -1;
ClientCard WorstMonster = null;
for (int i = 0; i < 7; ++i)
{
ClientCard card = Enemy.MonsterZone[i];
if (card == null || card.Data == null) continue;
if (onlyATK && card.IsDefense()) continue;
int newPower = card.GetDefensePower();
if (newPower < WorstPower)
{
WorstPower = newPower;
WorstMonster = card;
}
}
return WorstMonster;
}
public ClientCard GetBestEnemySpell(bool onlyFaceup = false) public ClientCard GetBestEnemySpell(bool onlyFaceup = false)
{ {
ClientCard card = GetProblematicEnemySpell(); ClientCard card = GetProblematicEnemySpell();
...@@ -337,6 +374,16 @@ namespace WindBot.Game.AI ...@@ -337,6 +374,16 @@ namespace WindBot.Game.AI
return count; return count;
} }
public bool ChainContainPlayer(int player)
{
foreach (ClientCard card in Duel.CurrentChain)
{
if (card.Controller == player)
return true;
}
return false;
}
public bool HasChainedTrap(int player) public bool HasChainedTrap(int player)
{ {
foreach (ClientCard card in Duel.CurrentChain) foreach (ClientCard card in Duel.CurrentChain)
......
...@@ -6,13 +6,13 @@ namespace WindBot.Game.AI ...@@ -6,13 +6,13 @@ namespace WindBot.Game.AI
{ {
public static class CardContainer public static class CardContainer
{ {
public static ClientCard GetHighestAttackMonster(this IEnumerable<ClientCard> cards) public static ClientCard GetHighestAttackMonster(this IEnumerable<ClientCard> cards, bool canBeTarget = false)
{ {
int highestAtk = 0; int highestAtk = 0;
ClientCard selected = null; ClientCard selected = null;
foreach (ClientCard card in cards) foreach (ClientCard card in cards)
{ {
if (card == null || card.Data == null || card.IsFacedown()) continue; if (card == null || card.Data == null || card.IsFacedown() || (canBeTarget && card.IsShouldNotBeTarget())) continue;
if (card.HasType(CardType.Monster) && card.Attack > highestAtk) if (card.HasType(CardType.Monster) && card.Attack > highestAtk)
{ {
highestAtk = card.Attack; highestAtk = card.Attack;
...@@ -22,13 +22,13 @@ namespace WindBot.Game.AI ...@@ -22,13 +22,13 @@ namespace WindBot.Game.AI
return selected; return selected;
} }
public static ClientCard GetHighestDefenseMonster(this IEnumerable<ClientCard> cards) public static ClientCard GetHighestDefenseMonster(this IEnumerable<ClientCard> cards, bool canBeTarget = false)
{ {
int highestDef = 0; int highestDef = 0;
ClientCard selected = null; ClientCard selected = null;
foreach (ClientCard card in cards) foreach (ClientCard card in cards)
{ {
if (card == null || card.Data == null || card.IsFacedown()) continue; if (card == null || card.Data == null || card.IsFacedown() || (canBeTarget && card.IsShouldNotBeTarget())) continue;
if (card.HasType(CardType.Monster) && card.Defense > highestDef) if (card.HasType(CardType.Monster) && card.Defense > highestDef)
{ {
highestDef = card.Defense; highestDef = card.Defense;
...@@ -38,13 +38,13 @@ namespace WindBot.Game.AI ...@@ -38,13 +38,13 @@ namespace WindBot.Game.AI
return selected; return selected;
} }
public static ClientCard GetLowestAttackMonster(this IEnumerable<ClientCard> cards) public static ClientCard GetLowestAttackMonster(this IEnumerable<ClientCard> cards, bool canBeTarget = false)
{ {
int lowestAtk = 0; int lowestAtk = 0;
ClientCard selected = null; ClientCard selected = null;
foreach (ClientCard card in cards) foreach (ClientCard card in cards)
{ {
if (card == null || card.Data == null || card.IsFacedown()) continue; if (card == null || card.Data == null || card.IsFacedown() || (canBeTarget && card.IsShouldNotBeTarget())) continue;
if (lowestAtk == 0 && card.HasType(CardType.Monster) || if (lowestAtk == 0 && card.HasType(CardType.Monster) ||
card.HasType(CardType.Monster) && card.Attack < lowestAtk) card.HasType(CardType.Monster) && card.Attack < lowestAtk)
{ {
...@@ -55,13 +55,13 @@ namespace WindBot.Game.AI ...@@ -55,13 +55,13 @@ namespace WindBot.Game.AI
return selected; return selected;
} }
public static ClientCard GetLowestDefenseMonster(this IEnumerable<ClientCard> cards) public static ClientCard GetLowestDefenseMonster(this IEnumerable<ClientCard> cards, bool canBeTarget = false)
{ {
int lowestDef = 0; int lowestDef = 0;
ClientCard selected = null; ClientCard selected = null;
foreach (ClientCard card in cards) foreach (ClientCard card in cards)
{ {
if (card == null || card.Data == null || card.IsFacedown()) continue; if (card == null || card.Data == null || card.IsFacedown() || (canBeTarget && card.IsShouldNotBeTarget())) continue;
if (lowestDef == 0 && card.HasType(CardType.Monster) || if (lowestDef == 0 && card.HasType(CardType.Monster) ||
card.HasType(CardType.Monster) && card.Defense < lowestDef) card.HasType(CardType.Monster) && card.Defense < lowestDef)
{ {
...@@ -149,31 +149,31 @@ namespace WindBot.Game.AI ...@@ -149,31 +149,31 @@ namespace WindBot.Game.AI
return cardlist; return cardlist;
} }
public static ClientCard GetInvincibleMonster(this IEnumerable<ClientCard> cards) public static ClientCard GetInvincibleMonster(this IEnumerable<ClientCard> cards, bool canBeTarget = false)
{ {
foreach (ClientCard card in cards) foreach (ClientCard card in cards)
{ {
if (card != null && card.IsMonsterInvincible() && card.IsFaceup()) if (card != null && card.IsMonsterInvincible() && card.IsFaceup() && (!canBeTarget || !card.IsShouldNotBeTarget()))
return card; return card;
} }
return null; return null;
} }
public static ClientCard GetDangerousMonster(this IEnumerable<ClientCard> cards) public static ClientCard GetDangerousMonster(this IEnumerable<ClientCard> cards, bool canBeTarget = false)
{ {
foreach (ClientCard card in cards) foreach (ClientCard card in cards)
{ {
if (card != null && card.IsMonsterDangerous() && card.IsFaceup()) if (card != null && card.IsMonsterDangerous() && card.IsFaceup() && (!canBeTarget || !card.IsShouldNotBeTarget()))
return card; return card;
} }
return null; return null;
} }
public static ClientCard GetFloodgate(this IEnumerable<ClientCard> cards) public static ClientCard GetFloodgate(this IEnumerable<ClientCard> cards, bool canBeTarget = false)
{ {
foreach (ClientCard card in cards) foreach (ClientCard card in cards)
{ {
if (card != null && card.IsFloodgate() && card.IsFaceup()) if (card != null && card.IsFloodgate() && card.IsFaceup() && (!canBeTarget || !card.IsShouldNotBeTarget()))
return card; return card;
} }
return null; return null;
......
...@@ -29,6 +29,38 @@ namespace WindBot.Game.AI ...@@ -29,6 +29,38 @@ namespace WindBot.Game.AI
return !card.IsDisabled() && Enum.IsDefined(typeof(PreventActivationEffectInBattle), card.Id); return !card.IsDisabled() && Enum.IsDefined(typeof(PreventActivationEffectInBattle), card.Id);
} }
/// <summary>
/// Is this card shouldn't be tried to be selected as target?
/// </summary>
public static bool IsShouldNotBeTarget(this ClientCard card)
{
return !card.IsDisabled() && Enum.IsDefined(typeof(ShouldNotBeTarget), card.Id);
}
/// <summary>
/// Is this card shouldn't be tried to be selected as target of monster?
/// </summary>
public static bool IsShouldNotBeMonsterTarget(this ClientCard card)
{
return !card.IsDisabled() && Enum.IsDefined(typeof(ShouldNotBeMonsterTarget), card.Id);
}
/// <summary>
/// Is this card shouldn't be tried to be selected as target of spell & trap?
/// </summary>
public static bool IsShouldNotBeSpellTrapTarget(this ClientCard card)
{
return !card.IsDisabled() && Enum.IsDefined(typeof(ShouldNotBeSpellTrapTarget), card.Id);
}
/// <summary>
/// Is this monster should be disabled (with Breakthrough Skill) before it use effect and release or banish itself?
/// </summary>
public static bool IsMonsterShouldBeDisabledBeforeItUseEffect(this ClientCard card)
{
return !card.IsDisabled() && Enum.IsDefined(typeof(ShouldBeDisabledBeforeItUseEffectMonster), card.Id);
}
public static bool IsFloodgate(this ClientCard card) public static bool IsFloodgate(this ClientCard card)
{ {
return Enum.IsDefined(typeof(Floodgate), card.Id); return Enum.IsDefined(typeof(Floodgate), card.Id);
......
...@@ -292,7 +292,7 @@ namespace WindBot.Game.AI.Decks ...@@ -292,7 +292,7 @@ namespace WindBot.Game.AI.Decks
} }
if (CanDealWithUsedAlternativeWhiteDragon()) if (CanDealWithUsedAlternativeWhiteDragon())
{ {
target = AI.Utils.GetBestEnemyMonster(); target = AI.Utils.GetBestEnemyMonster(false, true);
AI.SelectCard(target); AI.SelectCard(target);
UsedAlternativeWhiteDragon.Add(Card); UsedAlternativeWhiteDragon.Add(Card);
return true; return true;
......
This diff is collapsed.
This diff is collapsed.
...@@ -527,7 +527,7 @@ namespace WindBot.Game.AI.Decks ...@@ -527,7 +527,7 @@ namespace WindBot.Game.AI.Decks
private bool FairyTailSnowsummon() private bool FairyTailSnowsummon()
{ {
ClientCard target = AI.Utils.GetBestEnemyMonster(true); ClientCard target = AI.Utils.GetBestEnemyMonster(true, true);
if(target != null) if(target != null)
{ {
return true; return true;
...@@ -541,7 +541,7 @@ namespace WindBot.Game.AI.Decks ...@@ -541,7 +541,7 @@ namespace WindBot.Game.AI.Decks
if (Card.Location == CardLocation.MonsterZone) if (Card.Location == CardLocation.MonsterZone)
{ {
AI.SelectCard(AI.Utils.GetBestEnemyMonster(true)); AI.SelectCard(AI.Utils.GetBestEnemyMonster(true, true));
return true; return true;
} }
else else
...@@ -1052,7 +1052,7 @@ namespace WindBot.Game.AI.Decks ...@@ -1052,7 +1052,7 @@ namespace WindBot.Game.AI.Decks
if (Card.Location == CardLocation.Grave) if (Card.Location == CardLocation.Grave)
return true; return true;
if (Bot.LifePoints <= 1000) return false; if (Bot.LifePoints <= 1000) return false;
ClientCard select = AI.Utils.GetBestEnemyMonster(); ClientCard select = AI.Utils.GetBestEnemyCard();
if (select == null) return false; if (select == null) return false;
if(select!=null) if(select!=null)
{ {
......
This diff is collapsed.
...@@ -25,7 +25,9 @@ namespace WindBot.Game.AI ...@@ -25,7 +25,9 @@ namespace WindBot.Game.AI
public const int DupeFrog = 46239604; public const int DupeFrog = 46239604;
public const int MaraudingCaptain = 2460565; public const int MaraudingCaptain = 2460565;
public const int EvilswarmExcitonKnight = 46772449;
public const int HarpiesFeatherDuster = 18144506; public const int HarpiesFeatherDuster = 18144506;
public const int DarkMagicAttack = 2314238;
public const int MysticalSpaceTyphoon = 5318639; public const int MysticalSpaceTyphoon = 5318639;
public const int CosmicCyclone = 8267140; public const int CosmicCyclone = 8267140;
public const int ChickenGame = 67616300; public const int ChickenGame = 67616300;
...@@ -39,6 +41,7 @@ namespace WindBot.Game.AI ...@@ -39,6 +41,7 @@ namespace WindBot.Game.AI
public const int VampireFräulein = 6039967; public const int VampireFräulein = 6039967;
public const int InjectionFairyLily = 79575620; public const int InjectionFairyLily = 79575620;
public const int BlueEyesChaosMAXDragon = 55410871;
} }
protected DefaultExecutor(GameAI ai, Duel duel) protected DefaultExecutor(GameAI ai, Duel duel)
...@@ -310,15 +313,31 @@ namespace WindBot.Game.AI ...@@ -310,15 +313,31 @@ namespace WindBot.Game.AI
} }
/// <summary> /// <summary>
/// Chain the enemy monster. /// Chain the enemy monster, or disable monster like Rescue Rabbit.
/// </summary> /// </summary>
protected bool DefaultBreakthroughSkill() protected bool DefaultBreakthroughSkill()
{ {
if (!DefaultUniqueTrap())
return false;
if (Duel.Player == 1)
{
foreach (ClientCard target in Enemy.GetMonsters())
{
if (target.IsMonsterShouldBeDisabledBeforeItUseEffect())
{
AI.SelectCard(target);
return true;
}
}
}
ClientCard LastChainCard = AI.Utils.GetLastChainCard(); ClientCard LastChainCard = AI.Utils.GetLastChainCard();
if (LastChainCard == null) if (LastChainCard == null)
return false; return false;
if (LastChainCard.Controller != 1 || LastChainCard.Location != CardLocation.MonsterZone || !DefaultUniqueTrap()) if (LastChainCard.Controller != 1 || LastChainCard.Location != CardLocation.MonsterZone
|| LastChainCard.IsDisabled() || LastChainCard.IsShouldNotBeTarget() || LastChainCard.IsShouldNotBeSpellTrapTarget())
return false; return false;
AI.SelectCard(LastChainCard); AI.SelectCard(LastChainCard);
return true; return true;
...@@ -453,7 +472,13 @@ namespace WindBot.Game.AI ...@@ -453,7 +472,13 @@ namespace WindBot.Game.AI
{ {
if (Card.IsFaceup() && Card.IsDefense() && Card.Attack == 0) if (Card.IsFaceup() && Card.IsDefense() && Card.Attack == 0)
return false; return false;
if (Enemy.HasInMonstersZone(_CardId.BlueEyesChaosMAXDragon) &&
Card.IsAttack() && (4000-Card.Defense)*2>(4000 - Card.Attack))
return false;
if (Enemy.HasInMonstersZone(_CardId.BlueEyesChaosMAXDragon) &&
Card.IsDefense() && Card.IsFaceup() &&
(4000 - Card.Defense) * 2 > (4000 - Card.Attack))
return true;
bool enemyBetter = AI.Utils.IsAllEnemyBetter(true); bool enemyBetter = AI.Utils.IsAllEnemyBetter(true);
if (Card.IsAttack() && enemyBetter) if (Card.IsAttack() && enemyBetter)
...@@ -469,7 +494,9 @@ namespace WindBot.Game.AI ...@@ -469,7 +494,9 @@ namespace WindBot.Game.AI
protected bool DefaultOnBecomeTarget() protected bool DefaultOnBecomeTarget()
{ {
if (AI.Utils.IsChainTarget(Card)) return true; if (AI.Utils.IsChainTarget(Card)) return true;
if (AI.Utils.ChainContainsCard(_CardId.EvilswarmExcitonKnight)) return true;
if (Enemy.HasInSpellZone(_CardId.HarpiesFeatherDuster, true)) return true; if (Enemy.HasInSpellZone(_CardId.HarpiesFeatherDuster, true)) return true;
if (Enemy.HasInSpellZone(_CardId.DarkMagicAttack, true)) return true;
return false; return false;
} }
/// <summary> /// <summary>
......
...@@ -80,15 +80,15 @@ namespace WindBot.Game.AI ...@@ -80,15 +80,15 @@ namespace WindBot.Game.AI
public void SendSorry() public void SendSorry()
{ {
InternalSendMessage(new[] { "Sorry, an error occurs." }); InternalSendMessageForced(new[] { "Sorry, an error occurs." });
} }
public void SendDeckSorry(string card) public void SendDeckSorry(string card)
{ {
if (card == "DECK") if (card == "DECK")
InternalSendMessage(new[] { "Deck illegal. Please check the database of your YGOPro and WindBot." }); InternalSendMessageForced(new[] { "Deck illegal. Please check the database of your YGOPro and WindBot." });
else else
InternalSendMessage(_deckerror, card); InternalSendMessageForced(_deckerror, card);
} }
public void SendWelcome() public void SendWelcome()
...@@ -159,6 +159,15 @@ namespace WindBot.Game.AI ...@@ -159,6 +159,15 @@ namespace WindBot.Game.AI
} }
private void InternalSendMessage(IList<string> array, params object[] opts) private void InternalSendMessage(IList<string> array, params object[] opts)
{
if (!_game._chat)
return;
string message = string.Format(array[Program.Rand.Next(array.Count)], opts);
if (message != "")
_game.Chat(message);
}
private void InternalSendMessageForced(IList<string> array, params object[] opts)
{ {
string message = string.Format(array[Program.Rand.Next(array.Count)], opts); string message = string.Format(array[Program.Rand.Next(array.Count)], opts);
if (message != "") if (message != "")
......
...@@ -72,6 +72,7 @@ ...@@ -72,6 +72,7 @@
ElShaddollGrysra = 48424886, ElShaddollGrysra = 48424886,
ElShaddollWinda = 94977269, ElShaddollWinda = 94977269,
UltimateConductorTytanno = 18940556, UltimateConductorTytanno = 18940556,
OvertexCoatls = 41782653 OvertexCoatls = 41782653,
FirePrison = 269510
} }
} }
namespace WindBot.Game.AI.Enums
{
/// <summary>
/// Monsters that release or banish itself to use effect. So them should be disabled (with Breakthrough Skill) before it use effect.
/// </summary>
public enum ShouldBeDisabledBeforeItUseEffectMonster
{
MachinaMegaform = 51617185,
DarkSummoningBeast = 87917187,
GemKnightAlexandrite = 90019393,
RedEyesRetroDragon = 53485634,
DeepSweeper = 8649148,
BeastWarriorPuma = 16796157,
ZefrasaberSwordmasteroftheNekroz = 84388461,
CipherWing = 81974607,
MadolcheAnjelly = 34680482,
PlanetPathfinder = 97526666,
RescueCat = 14878871,
RescueHamster = 50485594,
RescueFerret = 56343672,
RescueRabbit = 85138716,
GalaxyWizard = 98555327,
Backlinker = 71172240,
Merlin = 3580032,
CrystalVanguard = 87475570,
Kuribandit = 16404809,
PhotonLizard = 38973775,
SuperheavySamuraiFlutist = 27978707,
ConstellarRasalhague = 70624184,
CardcarD = 45812361,
UnifloraMysticalBeastoftheForest = 36318200,
BusterWhelpoftheDestructionSwordsman = 49823708,
GalaxyEyesCloudragon = 9260791,
SylvanPrincessprout = 20579538,
AltergeistPixiel = 57769391,
AbyssActorExtras = 88412339,
PerformapalTrumpWitch = 91584698,
RaidraptorLastStrix = 97219708,
TimeMaiden = 27107590,
SuperQuantalFairyAlphan = 58753372,
TheBlackStoneofLegend = 66574418,
PaladinofDarkDragon = 71408082,
PaladinofPhotonDragon = 85346853,
TwinPhotonLizard = 29455728
}
}
namespace WindBot.Game.AI.Enums
{
/// <summary>
/// Cards that are can't be selected as target of monster's effect, or immuned to monster's effect.
/// So them shouldn't be tried to be selected as target of monster at most times.
/// </summary>
public enum ShouldNotBeMonsterTarget
{
TheLegendaryFishermanII = 19801646,
FirstoftheDragons = 10817524,
Tatsunoko = 55863245,
CXyzSimontheGreatMoralLeader = 41147577,
PaleozoicAnomalocaris = 61307542,
PaleozoicOpabinia = 37649320,
BorreloadDragon = 31833038
}
}
namespace WindBot.Game.AI.Enums
{
/// <summary>
/// Cards that are can't be selected as target of spell&trap's effect, or immuned to spell&trap's effect.
/// So them shouldn't be tried to be selected as target of spell&trap at most times.
/// </summary>
public enum ShouldNotBeSpellTrapTarget
{
ApoqliphortTowers = 27279764,
ApoqliphortSkybase = 40061558,
TheLegendaryFishermanIII = 44968687,
ChaosAncientGearGiant = 51788412
}
}
namespace WindBot.Game.AI.Enums
{
/// <summary>
/// Cards that are can't be selected as target, or immuned to most effect.
/// So them shouldn't be tried to be selected as target at most times.
/// </summary>
public enum ShouldNotBeTarget
{
DivineSerpentGeh = 82103466,
ObelisktheTormentor = 10000000,
TheWingedDragonofRaSphereMode = 10000080,
TheWingedDragonofRaImmortalPhoenix = 10000090,
KozmoDarkPlanet = 85991529,
ZushintheSleepingGiant = 67547370,
TheLegendaryExodiaIncarnate = 58604027,
KozmoDarkEclipser = 64063868,
KozmoDarkDestroyer = 55885348,
KozmoForerunner = 20849090,
MajespecterUnicornKirin = 31178212,
WorldLegacyWorldShield = 55787576,
KiwiMagicianGirl = 82627406,
MajespecterFoxKyubi = 94784213,
MajespecterToadOgama = 645794,
MajespecterCrowYata = 68395509,
MajespecterRaccoonBunbuku = 31991800,
MajespecterCatNekomata = 5506791,
HazyFlameHydra = 8696773,
HazyFlameMantikor = 96051150,
HazyFlameHyppogrif = 31303283,
HazyFlameCerbereus = 38525760,
HazyFlameSphynx = 1409474,
HazyFlamePeryton = 37803172,
HazyFlameGriffin = 74010769,
BlueEyesChaosMAXDragon = 55410871,
SupremeKingZARC = 13331639,
CrimsonNovaTrinitytheDarkCubicLord = 72664875,
LunalightLeoDancer = 24550676,
TimaeustheKnightofDestiny = 53315891,
DantePilgrimoftheBurningAbyss = 18386170,
AncientGearHowitzer = 87182127,
InvokedCocytus = 85908279,
LyriluscIndependentNightingale = 76815942,
FlowerCardianLightshower = 42291297,
YaziEviloftheYangZing = 43202238,
RaidraptorUltimateFalcon = 86221741,
DisdainfulBirdofParadise = 27240101,
DarkestDiabolosLordOfTheLair = 50383626
}
}
...@@ -97,6 +97,11 @@ namespace WindBot.Game.AI ...@@ -97,6 +97,11 @@ namespace WindBot.Game.AI
{ {
// Some AI need do something on new turn // Some AI need do something on new turn
} }
public virtual void OnDraw(int player)
{
// Some AI need do something on draw
}
public virtual IList<ClientCard> OnSelectCard(IList<ClientCard> cards, int min, int max, int hint, bool cancelable) public virtual IList<ClientCard> OnSelectCard(IList<ClientCard> cards, int min, int max, int hint, bool cancelable)
{ {
...@@ -146,6 +151,12 @@ namespace WindBot.Game.AI ...@@ -146,6 +151,12 @@ namespace WindBot.Game.AI
return null; return null;
} }
public virtual IList<ClientCard> OnCardSorting(IList<ClientCard> cards)
{
// For overriding
return null;
}
public virtual bool OnSelectYesNo(int desc) public virtual bool OnSelectYesNo(int desc)
{ {
return true; return true;
...@@ -156,6 +167,12 @@ namespace WindBot.Game.AI ...@@ -156,6 +167,12 @@ namespace WindBot.Game.AI
return -1; return -1;
} }
public virtual int OnSelectPlace(int cardId, int player, int location, int available)
{
// For overriding
return 0;
}
public virtual CardPosition OnSelectPosition(int cardId, IList<CardPosition> positions) public virtual CardPosition OnSelectPosition(int cardId, IList<CardPosition> positions)
{ {
// Overrided in DefalultExecutor // Overrided in DefalultExecutor
......
namespace WindBot.Game.AI
{
public static class Zones
{
public const int z0 = 0x1,
z1 = 0x2,
z2 = 0x4,
z3 = 0x8,
z4 = 0x10,
z5 = 0x20,
z6 = 0x40,
MonsterZones = 0x7f,
MainMonsterZones = 0x1f,
ExtraMonsterZones = 0x60,
SpellZones = 0x1f,
PendulumZones = 0x3,
LinkedZones = 0x10000,
NotLinkedZones = 0x20000;
}
}
\ No newline at end of file
...@@ -23,6 +23,8 @@ namespace WindBot.Game ...@@ -23,6 +23,8 @@ namespace WindBot.Game
public int Defense { get; private set; } public int Defense { get; private set; }
public int LScale { get; private set; } public int LScale { get; private set; }
public int RScale { get; private set; } public int RScale { get; private set; }
public int LinkCount { get; private set; }
public int LinkMarker { get; private set; }
public int BaseAttack { get; private set; } public int BaseAttack { get; private set; }
public int BaseDefense { get; private set; } public int BaseDefense { get; private set; }
public int RealPower { get; set; } public int RealPower { get; set; }
...@@ -132,6 +134,21 @@ namespace WindBot.Game ...@@ -132,6 +134,21 @@ namespace WindBot.Game
LScale = packet.ReadInt32(); LScale = packet.ReadInt32();
if ((flag & (int)Query.RScale) != 0) if ((flag & (int)Query.RScale) != 0)
RScale = packet.ReadInt32(); RScale = packet.ReadInt32();
if ((flag & (int)Query.Link) != 0)
{
LinkCount = packet.ReadInt32();
LinkMarker = packet.ReadInt32();
}
}
public bool HasLinkMarker(int dir)
{
return ((LinkMarker & dir) != 0);
}
public bool HasLinkMarker(LinkMarker dir)
{
return ((LinkMarker & (int)dir) != 0);
} }
public bool HasType(CardType type) public bool HasType(CardType type)
......
...@@ -70,6 +70,30 @@ namespace WindBot.Game ...@@ -70,6 +70,30 @@ namespace WindBot.Game
} }
return count; return count;
} }
/// <summary>
/// Count Column
/// </summary>
/// <param zone>range of zone 0-4</param>
public int GetColumnCount(int zone, bool IncludeExtraMonsterZone = true)
{
int count = 0;
if (SpellZone[zone] != null)
count++;
if (MonsterZone[zone] != null)
count++;
if(zone == 1 && IncludeExtraMonsterZone)
{
if (MonsterZone[5] != null)
count++;
}
if (zone == 3 && IncludeExtraMonsterZone)
{
if (MonsterZone[6] != null)
count++;
}
return count;
}
public int GetFieldCount() public int GetFieldCount()
...@@ -218,6 +242,76 @@ namespace WindBot.Game ...@@ -218,6 +242,76 @@ namespace WindBot.Game
return HasInCards(SpellZone, cardId, notDisabled); return HasInCards(SpellZone, cardId, notDisabled);
} }
public bool HasInHandOrInSpellZone(int cardId)
{
return HasInHand(cardId) || HasInSpellZone(cardId);
}
public bool HasInHandOrHasInMonstersZone(int cardId)
{
return HasInHand(cardId) || HasInMonstersZone(cardId);
}
public bool HasInHandOrInGraveyard(int cardId)
{
return HasInHand(cardId) || HasInGraveyard(cardId);
}
public bool HasInMonstersZoneOrInGraveyard(int cardId)
{
return HasInMonstersZone(cardId) || HasInGraveyard(cardId);
}
public bool HasInSpellZoneOrInGraveyard(int cardId)
{
return HasInSpellZone(cardId) || HasInGraveyard(cardId);
}
public bool HasInHandOrInMonstersZoneOrInGraveyard(int cardId)
{
return HasInHand(cardId) || HasInMonstersZone(cardId) || HasInGraveyard(cardId);
}
public bool HasInHandOrInSpellZoneOrInGraveyard(int cardId)
{
return HasInHand(cardId) || HasInSpellZone(cardId) || HasInGraveyard(cardId);
}
public bool HasInHandOrInSpellZone(IList<int> cardId)
{
return HasInHand(cardId) || HasInSpellZone(cardId);
}
public bool HasInHandOrHasInMonstersZone(IList<int> cardId)
{
return HasInHand(cardId) || HasInMonstersZone(cardId);
}
public bool HasInHandOrInGraveyard(IList<int> cardId)
{
return HasInHand(cardId) || HasInGraveyard(cardId);
}
public bool HasInMonstersZoneOrInGraveyard(IList<int> cardId)
{
return HasInMonstersZone(cardId) || HasInGraveyard(cardId);
}
public bool HasInSpellZoneOrInGraveyard(IList<int> cardId)
{
return HasInSpellZone(cardId) || HasInGraveyard(cardId);
}
public bool HasInHandOrInMonstersZoneOrInGraveyard(IList<int> cardId)
{
return HasInHand(cardId) || HasInMonstersZone(cardId) || HasInGraveyard(cardId);
}
public bool HasInHandOrInSpellZoneOrInGraveyard(IList<int> cardId)
{
return HasInHand(cardId) || HasInSpellZone(cardId) || HasInGraveyard(cardId);
}
public int GetRemainingCount(int cardId, int initialCount) public int GetRemainingCount(int cardId, int initialCount)
{ {
int remaining = initialCount; int remaining = initialCount;
......
...@@ -115,6 +115,37 @@ namespace WindBot.Game ...@@ -115,6 +115,37 @@ namespace WindBot.Game
} }
} }
public void AddCard(CardLocation loc, ClientCard card, int player, int zone, int pos, int id)
{
card.Location = loc;
card.Position = pos;
card.SetId(id);
switch (loc)
{
case CardLocation.Hand:
Fields[player].Hand.Add(card);
break;
case CardLocation.Grave:
Fields[player].Graveyard.Add(card);
break;
case CardLocation.Removed:
Fields[player].Banished.Add(card);
break;
case CardLocation.MonsterZone:
Fields[player].MonsterZone[zone] = card;
break;
case CardLocation.SpellZone:
Fields[player].SpellZone[zone] = card;
break;
case CardLocation.Deck:
Fields[player].Deck.Add(card);
break;
case CardLocation.Extra:
Fields[player].ExtraDeck.Add(card);
break;
}
}
public void RemoveCard(CardLocation loc, ClientCard card, int player, int zone) public void RemoveCard(CardLocation loc, ClientCard card, int player, int zone)
{ {
switch (loc) switch (loc)
......
...@@ -70,6 +70,14 @@ namespace WindBot.Game ...@@ -70,6 +70,14 @@ namespace WindBot.Game
return Executor.OnSelectHand(); return Executor.OnSelectHand();
} }
/// <summary>
/// Called when any player draw card.
/// </summary>
public void OnDraw(int player)
{
Executor.OnDraw(player);
}
/// <summary> /// <summary>
/// Called when it's a new turn. /// Called when it's a new turn.
/// </summary> /// </summary>
...@@ -90,6 +98,7 @@ namespace WindBot.Game ...@@ -90,6 +98,7 @@ namespace WindBot.Game
m_option = -1; m_option = -1;
m_yesno = -1; m_yesno = -1;
m_position = CardPosition.FaceUpAttack; m_position = CardPosition.FaceUpAttack;
m_place = 0;
if (Duel.Player == 0 && Duel.Phase == DuelPhase.Draw) if (Duel.Player == 0 && Duel.Phase == DuelPhase.Draw)
{ {
_dialogs.SendNewTurn(); _dialogs.SendNewTurn();
...@@ -328,6 +337,26 @@ namespace WindBot.Game ...@@ -328,6 +337,26 @@ namespace WindBot.Game
return used; return used;
} }
/// <summary>
/// Called when the AI has to sort cards.
/// </summary>
/// <param name="cards">Cards to sort.</param>
/// <returns>List of sorted cards.</returns>
public IList<ClientCard> OnCardSorting(IList<ClientCard> cards)
{
IList<ClientCard> result = Executor.OnCardSorting(cards);
if (result != null)
return result;
result = new List<ClientCard>();
// TODO: use selector
for (int i = 0; i < cards.Count; i++)
{
result.Add(cards[i]);
}
return result;
}
/// <summary> /// <summary>
/// Called when the AI has to choose to activate or not an effect. /// Called when the AI has to choose to activate or not an effect.
/// </summary> /// </summary>
...@@ -436,6 +465,23 @@ namespace WindBot.Game ...@@ -436,6 +465,23 @@ namespace WindBot.Game
return 0; // Always select the first option. return 0; // Always select the first option.
} }
public int OnSelectPlace(int cardId, int player, int location, int available)
{
int selector_selected = m_place;
m_place = 0;
int executor_selected = Executor.OnSelectPlace(cardId, player, location, available);
if ((executor_selected & available) > 0)
return executor_selected & available;
if ((selector_selected & available) > 0)
return selector_selected & available;
// TODO: LinkedZones
return 0;
}
/// <summary> /// <summary>
/// Called when the AI has to select a card position. /// Called when the AI has to select a card position.
/// </summary> /// </summary>
...@@ -680,6 +726,7 @@ namespace WindBot.Game ...@@ -680,6 +726,7 @@ namespace WindBot.Game
private CardSelector m_thirdSelector; private CardSelector m_thirdSelector;
private CardSelector m_materialSelector; private CardSelector m_materialSelector;
private CardPosition m_position = CardPosition.FaceUpAttack; private CardPosition m_position = CardPosition.FaceUpAttack;
private int m_place;
private int m_option; private int m_option;
private int m_number; private int m_number;
private int m_announce; private int m_announce;
...@@ -814,6 +861,11 @@ namespace WindBot.Game ...@@ -814,6 +861,11 @@ namespace WindBot.Game
m_position = pos; m_position = pos;
} }
public void SelectPlace(int zones)
{
m_place = zones;
}
public void SelectOption(int opt) public void SelectOption(int opt)
{ {
m_option = opt; m_option = opt;
......
This diff is collapsed.
...@@ -14,7 +14,8 @@ namespace WindBot.Game ...@@ -14,7 +14,8 @@ namespace WindBot.Game
public string Deck; public string Deck;
public string Dialog; public string Dialog;
public int Hand; public int Hand;
public bool Debug;
public bool _chat;
private string _serverHost; private string _serverHost;
private int _serverPort; private int _serverPort;
private short _proVersion; private short _proVersion;
...@@ -29,6 +30,8 @@ namespace WindBot.Game ...@@ -29,6 +30,8 @@ namespace WindBot.Game
Deck = Info.Deck; Deck = Info.Deck;
Dialog = Info.Dialog; Dialog = Info.Dialog;
Hand = Info.Hand; Hand = Info.Hand;
Debug = Info.Debug;
_chat = Info.Chat;
_serverHost = Info.Host; _serverHost = Info.Host;
_serverPort = Info.Port; _serverPort = Info.Port;
_roomInfo = Info.HostInfo; _roomInfo = Info.HostInfo;
......
...@@ -74,6 +74,8 @@ namespace WindBot ...@@ -74,6 +74,8 @@ namespace WindBot
Info.HostInfo = Config.GetString("HostInfo", Info.HostInfo); Info.HostInfo = Config.GetString("HostInfo", Info.HostInfo);
Info.Version = Config.GetInt("Version", Info.Version); Info.Version = Config.GetInt("Version", Info.Version);
Info.Hand = Config.GetInt("Hand", Info.Hand); Info.Hand = Config.GetInt("Hand", Info.Hand);
Info.Debug = Config.GetBool("Debug", Info.Debug);
Info.Chat = Config.GetBool("Chat", Info.Chat);
Run(Info); Run(Info);
} }
...@@ -114,6 +116,12 @@ namespace WindBot ...@@ -114,6 +116,12 @@ namespace WindBot
string hand = HttpUtility.ParseQueryString(RawUrl).Get("hand"); string hand = HttpUtility.ParseQueryString(RawUrl).Get("hand");
if (hand != null) if (hand != null)
Info.Hand = Int32.Parse(hand); Info.Hand = Int32.Parse(hand);
string debug = HttpUtility.ParseQueryString(RawUrl).Get("debug");
if (debug != null)
Info.Debug= bool.Parse(debug);
string chat = HttpUtility.ParseQueryString(RawUrl).Get("chat");
if (chat != null)
Info.Chat = bool.Parse(chat);
if (Info.Name == null || Info.Host == null || port == null) if (Info.Name == null || Info.Host == null || port == null)
{ {
......
...@@ -68,6 +68,7 @@ ...@@ -68,6 +68,7 @@
<Compile Include="Game\AI\DecksManager.cs" /> <Compile Include="Game\AI\DecksManager.cs" />
<Compile Include="Game\AI\Decks\BlackwingExecutor.cs" /> <Compile Include="Game\AI\Decks\BlackwingExecutor.cs" />
<Compile Include="Game\AI\Decks\CyberDragonExecutor.cs" /> <Compile Include="Game\AI\Decks\CyberDragonExecutor.cs" />
<Compile Include="Game\AI\Decks\DarkMagicianExecutor.cs" />
<Compile Include="Game\AI\Decks\SkyStrikerExecutor.cs" /> <Compile Include="Game\AI\Decks\SkyStrikerExecutor.cs" />
<Compile Include="Game\AI\Decks\MokeyMokeyKingExecutor.cs" /> <Compile Include="Game\AI\Decks\MokeyMokeyKingExecutor.cs" />
<Compile Include="Game\AI\Decks\MokeyMokeyExecutor.cs" /> <Compile Include="Game\AI\Decks\MokeyMokeyExecutor.cs" />
...@@ -98,11 +99,16 @@ ...@@ -98,11 +99,16 @@
<Compile Include="Game\AI\Dialogs.cs" /> <Compile Include="Game\AI\Dialogs.cs" />
<Compile Include="Game\AI\Enums\DangerousMonster.cs" /> <Compile Include="Game\AI\Enums\DangerousMonster.cs" />
<Compile Include="Game\AI\Enums\FusionSpell.cs" /> <Compile Include="Game\AI\Enums\FusionSpell.cs" />
<Compile Include="Game\AI\Enums\ShouldBeDisabledBeforeItUseEffectMonster.cs" />
<Compile Include="Game\AI\Enums\ShouldNotBeSpellTarget.cs" />
<Compile Include="Game\AI\Enums\ShouldNotBeMonsterTarget.cs" />
<Compile Include="Game\AI\Enums\ShouldNotBeTarget.cs" />
<Compile Include="Game\AI\Enums\PreventActivationEffectInBattle.cs" /> <Compile Include="Game\AI\Enums\PreventActivationEffectInBattle.cs" />
<Compile Include="Game\AI\Enums\OneForXyz.cs" /> <Compile Include="Game\AI\Enums\OneForXyz.cs" />
<Compile Include="Game\AI\Enums\InvincibleMonster.cs" /> <Compile Include="Game\AI\Enums\InvincibleMonster.cs" />
<Compile Include="Game\AI\Enums\Floodgate.cs" /> <Compile Include="Game\AI\Enums\Floodgate.cs" />
<Compile Include="Game\AI\Executor.cs" /> <Compile Include="Game\AI\Executor.cs" />
<Compile Include="Game\AI\Zones.cs" />
<Compile Include="Game\AI\ExecutorType.cs" /> <Compile Include="Game\AI\ExecutorType.cs" />
<Compile Include="Game\BattlePhase.cs" /> <Compile Include="Game\BattlePhase.cs" />
<Compile Include="Game\BattlePhaseAction.cs" /> <Compile Include="Game\BattlePhaseAction.cs" />
......
...@@ -12,7 +12,8 @@ namespace WindBot ...@@ -12,7 +12,8 @@ namespace WindBot
public string HostInfo { get; set; } public string HostInfo { get; set; }
public int Version { get; set; } public int Version { get; set; }
public int Hand { get; set; } public int Hand { get; set; }
public bool Debug { get; set; }
public bool Chat { get; set; }
public WindBotInfo() public WindBotInfo()
{ {
Name = "WindBot"; Name = "WindBot";
...@@ -23,6 +24,8 @@ namespace WindBot ...@@ -23,6 +24,8 @@ namespace WindBot
HostInfo = ""; HostInfo = "";
Version = 0x1343; Version = 0x1343;
Hand = 0; Hand = 0;
Debug = false;
Chat = true;
} }
} }
} }
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