Commit 5b2e9ed8 authored by nanahira's avatar nanahira

Merge branch 'master' of github.com:moecube/windbot

parents 5079368b 486ccf0b
...@@ -258,3 +258,8 @@ SUPPORT_MASTER_RULE_2020 ...@@ -258,3 +258,8 @@ SUPPORT_MASTER_RULE_2020
Name=神数不神 Deck=Tearlaments Dialog=Zefra.zh-CN Name=神数不神 Deck=Tearlaments Dialog=Zefra.zh-CN
旧式地天使珠泪哀歌族卡组。 旧式地天使珠泪哀歌族卡组。
AI_LV3 SUPPORT_MASTER_RULE_2020 AI_LV3 SUPPORT_MASTER_RULE_2020
!神数不神-神数
Name=神数不神 Deck=Zefra Dialog=Zefra.zh-CN
神数卡组。
AI_LV3 SUPPORT_MASTER_RULE_2020
#created by ...
#main
49036338
29432356
29432356
29432356
3611830
76794549
5560911
96227613
96227613
27354732
58990362
58990362
58990362
20773176
22617205
69610326
14785765
95401059
31314549
96223501
52159691
21495657
21495657
57777714
92559258
92559258
92559258
38814750
38814750
38814750
72291078
23434538
23434538
23434538
94693857
9742784
19580308
11609969
61488417
2295440
23581825
38943357
38943357
38943357
41620959
41620959
41620959
73628505
74580251
74580251
74580251
81439173
24224830
24224830
46372010
32354768
32354768
32354768
35561352
57831349
#extra
27548199
74586817
80696379
33158448
65536818
79606837
88581108
96157835
73347079
74997493
44097050
24094258
50588353
36429703
41999284
!side
...@@ -50,5 +50,10 @@ ...@@ -50,5 +50,10 @@
"乎,我发动{0}!", "乎,我发动{0}!",
"不好意思拉,我有{0}", "不好意思拉,我有{0}",
"哈哈,发动{0}的效果!" "哈哈,发动{0}的效果!"
],
"custom": [
"呱!本体出征!",
"凸(艹皿艹 )卡手不玩拉!!!",
"嘿不慌,还有摆子场( ̄y▽ ̄)╭"
] ]
} }
...@@ -442,5 +442,115 @@ namespace WindBot.Game.AI ...@@ -442,5 +442,115 @@ namespace WindBot.Game.AI
return selected; return selected;
} }
/// <summary>
/// Get all xyz materials lists that xyz monster required level in the 'pre_materials' list
/// </summary>
/// <param name="param_pre_materials">Original materials</param>
/// <param name="level">Xyz monster required level</param>
/// <param name="material_count">SpSummon rule:number of xyz materials</param>
/// <param name="material_count_above">More xyz materials</param>
/// <param name="material_func">Filter xyz materials func</param>
/// <returns></returns>
public List<List<ClientCard>> GetXyzMaterials(IList<ClientCard> param_pre_materials, int level, int material_count, bool material_count_above = false, Func<ClientCard, bool> material_func = null)
{
List<List<ClientCard>> result = new List<List<ClientCard>>();
List<ClientCard> pre_materials = param_pre_materials?.Where(card => card != null && !(card.IsFacedown() & card.Location == CardLocation.MonsterZone) && card.Level == level && !card.IsMonsterNotBeXyzMaterial()).ToList();
if (pre_materials?.Count() < material_count) return result;
Func<ClientCard, bool> default_func = card => true;
material_func = material_func ?? default_func;
for (int i = 1; i < Math.Pow(2, pre_materials.Count); i++)
{
List<ClientCard> temp_materials = new List<ClientCard>();
string binaryString = Convert.ToString(i, 2).PadLeft(pre_materials.Count, '0');
char[] reversedBinaryChars = binaryString.Reverse().ToArray();
for (int j = 0; j < pre_materials.Count; j++)
{
if (reversedBinaryChars[j] == '1' && material_func(pre_materials[j]))
{
temp_materials.Add(pre_materials[j]);
}
}
if (material_count_above ? temp_materials.Count >= material_count : temp_materials.Count == material_count)
{
result.Add(temp_materials);
}
}
return result;
}
/// <summary>
/// Get all synchro materials lists that synchro monster level == param 'level' in the 'pre_materials' list
/// </summary>
/// <param name="pre_materials">Original materials</param>
/// <param name="level">Synchro monster level</param>
/// <param name="tuner_count">SpSummon rule:number of tuner monsters </param>
/// <param name="n_tuner_count">SpSummon rule:number of non-tuner monsters count</param>
/// <param name="tuner_count_above">More tuner monsters</param>
/// <param name="n_tuner_count_above">More non-tuner monsters</param>
/// <param name="tuner_func">Filter tuner monsters func</param>
/// <param name="n_tuner_func">Filter non-tuner monsters func</param>
/// <returns></returns>
public List<List<ClientCard>> GetSynchroMaterials(IList<ClientCard> param_pre_materials, int level, int tuner_count, int n_tuner_count, bool tuner_count_above = false, bool n_tuner_count_above = true, Func<ClientCard, bool> tuner_func = null, Func<ClientCard, bool> n_tuner_func = null)
{
List<List<ClientCard>> t_result = new List<List<ClientCard>>();
List<ClientCard> pre_materials = param_pre_materials?.Where(card => card != null && !(card.IsFacedown() & card.Location == CardLocation.MonsterZone) && card.Level > 0 && !card.IsMonsterNotBeSynchroMaterial()).ToList();
if (pre_materials?.Count() < tuner_count + n_tuner_count) return t_result;
Func<ClientCard, bool> default_func = card => true;
tuner_func = tuner_func ?? default_func;
n_tuner_func = n_tuner_func ?? default_func;
pre_materials.Sort(CardContainer.CompareCardLevel);
Stack<object[]> materials_stack = new Stack<object[]>();
for (var i = 0; i < pre_materials.Count; i++)
{
if (pre_materials[i].Level > level) break;
materials_stack.Push(new object[] { pre_materials[i].Level, i, pre_materials[i].Level, new List<ClientCard> { pre_materials[i] } });
}
while (materials_stack.Count > 0)
{
object[] data = materials_stack.Pop();
int num = (int)data[0];
int index = (int)data[1];
int sum = (int)data[2];
List<ClientCard> temp_materials = (List<ClientCard>)data[3];
if (sum == level)
{
t_result.Add(temp_materials);
}
else if (sum < level)
{
for (var i = index + 1; i < pre_materials.Count; i++)
{
if (pre_materials[i].Level > level - sum) break;
if (i > index + 1 && pre_materials[i].Level == pre_materials[i - 1].Level) continue;
var new_temp_materials = new List<ClientCard>(temp_materials);
new_temp_materials.Add(pre_materials[i]);
materials_stack.Push(new object[] { pre_materials[i].Level, i, sum + pre_materials[i].Level, new_temp_materials });
}
}
}
List<List<ClientCard>> result = new List<List<ClientCard>>();
for (int i = 0; i < t_result.Count; i++)
{
List<ClientCard> materials = t_result[i];
List<ClientCard> tuner_materials = new List<ClientCard>();
List<ClientCard> n_tuner_materials = new List<ClientCard>();
foreach (ClientCard material in materials)
{
if (material.HasType(CardType.Tuner) && tuner_func(material))
{
tuner_materials.Add(material);
}
else if (material.Level > 0 && n_tuner_func(material))
{
n_tuner_materials.Add(material);
}
}
if ((tuner_count_above ? tuner_materials.Count >= tuner_count : tuner_materials.Count == tuner_count)
&& (n_tuner_count_above ? n_tuner_materials.Count >= n_tuner_count : n_tuner_materials.Count == n_tuner_count))
result.Add(materials);
}
return result;
}
} }
} }
\ No newline at end of file
...@@ -25,6 +25,15 @@ namespace WindBot.Game.AI ...@@ -25,6 +25,15 @@ namespace WindBot.Game.AI
return 1; return 1;
} }
public static int CompareCardLink(ClientCard cardA, ClientCard cardB)
{
if (cardA.LinkCount < cardB.LinkCount)
return -1;
if (cardA.LinkCount == cardB.LinkCount)
return 0;
return 1;
}
public static int CompareDefensePower(ClientCard cardA, ClientCard cardB) public static int CompareDefensePower(ClientCard cardA, ClientCard cardB)
{ {
if (cardA == null && cardB == null) if (cardA == null && cardB == null)
......
...@@ -78,5 +78,21 @@ namespace WindBot.Game.AI ...@@ -78,5 +78,21 @@ namespace WindBot.Game.AI
{ {
return Enum.IsDefined(typeof(FusionSpell), card.Id); return Enum.IsDefined(typeof(FusionSpell), card.Id);
} }
/// <summary>
/// Is this monster not be synchro material?
/// </summary>
public static bool IsMonsterNotBeSynchroMaterial(this ClientCard card)
{
return Enum.IsDefined(typeof(NotBeSynchroMaterialMonster), card.Id);
}
/// <summary>
/// Is this monster not be xyz material?
/// </summary>
public static bool IsMonsterNotBeXyzMaterial(this ClientCard card)
{
return Enum.IsDefined(typeof(NotBeXyzMaterialMonster), card.Id);
}
} }
} }
\ No newline at end of file
...@@ -1950,7 +1950,7 @@ namespace WindBot.Game.AI.Decks ...@@ -1950,7 +1950,7 @@ namespace WindBot.Game.AI.Decks
} }
// become target // become target
if (DefaultOnBecomeTarget() || (Duel.CurrentChain.Any(c => c == Card) && Duel.LastChainPlayer != 0)) if ((DefaultOnBecomeTarget() && !Util.ChainContainsCard(_CardId.EvenlyMatched)) || (Duel.CurrentChain.Any(c => c == Card) && Duel.LastChainPlayer != 0))
{ {
targetedMagnificaList.Add(Card); targetedMagnificaList.Add(Card);
transformDestList.AddRange(new List<int>{CardId.ExosistersMagnifica, CardId.ExosisterMikailis, CardId.ExosisterGibrine, CardId.ExosisterKaspitell, CardId.ExosisterAsophiel}); transformDestList.AddRange(new List<int>{CardId.ExosistersMagnifica, CardId.ExosisterMikailis, CardId.ExosisterGibrine, CardId.ExosisterKaspitell, CardId.ExosisterAsophiel});
...@@ -2025,7 +2025,7 @@ namespace WindBot.Game.AI.Decks ...@@ -2025,7 +2025,7 @@ namespace WindBot.Game.AI.Decks
public bool ExosisterPaxActivate() public bool ExosisterPaxActivate()
{ {
if (potActivate) if (potActivate || Bot.LifePoints <= 800)
{ {
return false; return false;
} }
...@@ -2198,7 +2198,7 @@ namespace WindBot.Game.AI.Decks ...@@ -2198,7 +2198,7 @@ namespace WindBot.Game.AI.Decks
public bool ExosisterPaxActivateForEndSearch() public bool ExosisterPaxActivateForEndSearch()
{ {
if (potActivate) if (potActivate || Bot.LifePoints <= 800)
{ {
return false; return false;
} }
...@@ -2230,6 +2230,10 @@ namespace WindBot.Game.AI.Decks ...@@ -2230,6 +2230,10 @@ namespace WindBot.Game.AI.Decks
public bool ExosisterArmentActivate() public bool ExosisterArmentActivate()
{ {
if (Bot.LifePoints <= 800)
{
return false;
}
ClientCard activateTarget = null; ClientCard activateTarget = null;
if (Duel.Player == 0) if (Duel.Player == 0)
...@@ -2366,6 +2370,11 @@ namespace WindBot.Game.AI.Decks ...@@ -2366,6 +2370,11 @@ namespace WindBot.Game.AI.Decks
public bool ExosisterVadisActivate() public bool ExosisterVadisActivate()
{ {
if (Bot.LifePoints <= 800)
{
return false;
}
List<int> checkListForSpSummon = new List<int>{ List<int> checkListForSpSummon = new List<int>{
CardId.ExosisterSophia, CardId.ExosisterIrene, CardId.ExosisterStella, CardId.ExosisterMartha, CardId.ExosisterElis CardId.ExosisterSophia, CardId.ExosisterIrene, CardId.ExosisterStella, CardId.ExosisterMartha, CardId.ExosisterElis
}; };
...@@ -2435,6 +2444,11 @@ namespace WindBot.Game.AI.Decks ...@@ -2435,6 +2444,11 @@ namespace WindBot.Game.AI.Decks
public bool ExosisterReturniaActivate() public bool ExosisterReturniaActivate()
{ {
if (Bot.LifePoints <= 800)
{
return false;
}
// banish problem card // banish problem card
ClientCard target = GetProblematicEnemyCard(true); ClientCard target = GetProblematicEnemyCard(true);
if (target != null && Duel.LastChainPlayer != 0) if (target != null && Duel.LastChainPlayer != 0)
...@@ -2463,7 +2477,7 @@ namespace WindBot.Game.AI.Decks ...@@ -2463,7 +2477,7 @@ namespace WindBot.Game.AI.Decks
// dump banish // dump banish
target = GetBestEnemyCard(false, true, true); target = GetBestEnemyCard(false, true, true);
bool check1 = DefaultOnBecomeTarget() && target.Id != _CardId.EvenlyMatched; bool check1 = DefaultOnBecomeTarget() && target != null && (target.Location != CardLocation.Onfield || target.Id != _CardId.EvenlyMatched);
bool check2 = Bot.UnderAttack; bool check2 = Bot.UnderAttack;
bool check3 = (Duel.Player == 1 && Duel.Phase == DuelPhase.End && Duel.LastChainPlayer != 0 && target != null && target.Location != CardLocation.Grave); bool check3 = (Duel.Player == 1 && Duel.Phase == DuelPhase.End && Duel.LastChainPlayer != 0 && target != null && target.Location != CardLocation.Grave);
bool check4 = (Duel.Player == 1 && Enemy.GetMonsterCount() >= 2 && Duel.LastChainPlayer != 0); bool check4 = (Duel.Player == 1 && Enemy.GetMonsterCount() >= 2 && Duel.LastChainPlayer != 0);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -34,7 +34,9 @@ namespace WindBot.Game.AI ...@@ -34,7 +34,9 @@ namespace WindBot.Game.AI
[DataMember] [DataMember]
public string[] setmonster { get; set; } public string[] setmonster { get; set; }
[DataMember] [DataMember]
public string[] chaining { get; set; } public string[] chaining { get; set; }
[DataMember]
public string[] custom { get; set; }
} }
public class Dialogs public class Dialogs
{ {
...@@ -53,7 +55,8 @@ namespace WindBot.Game.AI ...@@ -53,7 +55,8 @@ namespace WindBot.Game.AI
private string[] _summon; private string[] _summon;
private string[] _setmonster; private string[] _setmonster;
private string[] _chaining; private string[] _chaining;
private string[] _custom;
public Dialogs(GameClient game) public Dialogs(GameClient game)
{ {
_game = game; _game = game;
...@@ -75,6 +78,7 @@ namespace WindBot.Game.AI ...@@ -75,6 +78,7 @@ namespace WindBot.Game.AI
_summon = data.summon; _summon = data.summon;
_setmonster = data.setmonster; _setmonster = data.setmonster;
_chaining = data.chaining; _chaining = data.chaining;
_custom = data.custom;
} }
} }
...@@ -176,5 +180,14 @@ namespace WindBot.Game.AI ...@@ -176,5 +180,14 @@ namespace WindBot.Game.AI
Logger.WriteLine("Error: " + message); Logger.WriteLine("Error: " + message);
} }
} }
public void SendCustomChat(int index, params object[] opts)
{
if (!_game._chat || _custom == null)
return;
string message = string.Format(_custom[index], opts);
if (message != "")
_game.Chat(message);
}
} }
} }
namespace WindBot.Game.AI.Enums
{
public enum NotBeSynchroMaterialMonster
{
Ronintoadin = 1357146,
GagagaCaesar = 9583383,
VagueShadowToken = 9929399,
TourGuideFromtheUnderworld = 10802915,
PhotonToken = 17418745,
KagemuchaKnight = 19353570,
SharkStickers = 20838380,
GagagaMagician = 26082117,
RadianToken = 28674153,
Kurivolt = 40817915,
BlueMountainButterspy = 54582424,
Lightserpent = 55501446,
SaberShark = 63193879,
ConstellarKaus = 70908596,
CeremonialToken = 82340057,
HeroicChallenger_DoubleLance = 89774530,
SteelswarmScout = 90727556,
Kagetokage = 94656263,
YellowDuston = 16366810,
BlueDuston = 40217358,
Centerfrog = 47346782,
GreenDuston = 52182715,
RedDuston = 61019812,
EaterofMillions = 63845230,
PutridPuddingBodyBuddies = 85101097
}
}
\ No newline at end of file
namespace WindBot.Game.AI.Enums
{
public enum NotBeXyzMaterialMonster
{
YellowDuston = 16366810,
BlueDuston = 40217358,
Centerfrog = 47346782,
GreenDuston = 52182715,
RedDuston = 61019812,
EaterofMillions = 63845230,
PutridPuddingBodyBuddies = 85101097
}
}
\ No newline at end of file
...@@ -165,6 +165,7 @@ namespace WindBot.Game.AI ...@@ -165,6 +165,7 @@ namespace WindBot.Game.AI
// For overriding // For overriding
return null; return null;
} }
public virtual void OnSelectChain(IList<ClientCard> cards) public virtual void OnSelectChain(IList<ClientCard> cards)
{ {
return; return;
......
...@@ -54,6 +54,14 @@ namespace WindBot.Game ...@@ -54,6 +54,14 @@ namespace WindBot.Game
_dialogs.SendDuelStart(); _dialogs.SendDuelStart();
} }
/// <summary>
/// Customized called when the AI do something in a duel.
/// </summary>
public void SendCustomChat(int index, params object[] opts)
{
_dialogs.SendCustomChat(index, opts);
}
/// <summary> /// <summary>
/// Called when the AI do the rock-paper-scissors. /// Called when the AI do the rock-paper-scissors.
/// </summary> /// </summary>
......
...@@ -1804,7 +1804,7 @@ namespace WindBot.Game ...@@ -1804,7 +1804,7 @@ namespace WindBot.Game
int count = packet.ReadByte(); int count = packet.ReadByte();
int available = packet.ReadInt32(); int available = packet.ReadInt32();
int filter = 0x1; int filter = 0x1;
for (int i = 0; i < 23; ++i) for (int i = 0; i < 26; ++i)
{ {
if ((available & filter) != 0) if ((available & filter) != 0)
races.Add((CardRace)filter); races.Add((CardRace)filter);
......
...@@ -115,12 +115,15 @@ ...@@ -115,12 +115,15 @@
<Compile Include="Game\AI\Decks\DoEveryThingExecutor.cs" /> <Compile Include="Game\AI\Decks\DoEveryThingExecutor.cs" />
<Compile Include="Game\AI\Decks\OldSchoolExecutor.cs" /> <Compile Include="Game\AI\Decks\OldSchoolExecutor.cs" />
<Compile Include="Game\AI\Decks\Rank5Executor.cs" /> <Compile Include="Game\AI\Decks\Rank5Executor.cs" />
<Compile Include="Game\AI\Decks\ZefraExecutor.cs" />
<Compile Include="Game\AI\Decks\ZoodiacExecutor.cs" /> <Compile Include="Game\AI\Decks\ZoodiacExecutor.cs" />
<Compile Include="Game\AI\Decks\ZexalWeaponsExecutor.cs" /> <Compile Include="Game\AI\Decks\ZexalWeaponsExecutor.cs" />
<Compile Include="Game\AI\DefaultExecutor.cs" /> <Compile Include="Game\AI\DefaultExecutor.cs" />
<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\NotBeSynchroMaterialMonster.cs" />
<Compile Include="Game\AI\Enums\NotBeXyzMaterialMonster.cs" />
<Compile Include="Game\AI\Enums\ShouldBeDisabledBeforeItUseEffectMonster.cs" /> <Compile Include="Game\AI\Enums\ShouldBeDisabledBeforeItUseEffectMonster.cs" />
<Compile Include="Game\AI\Enums\ShouldNotBeSpellTarget.cs" /> <Compile Include="Game\AI\Enums\ShouldNotBeSpellTarget.cs" />
<Compile Include="Game\AI\Enums\ShouldNotBeMonsterTarget.cs" /> <Compile Include="Game\AI\Enums\ShouldNotBeMonsterTarget.cs" />
......
...@@ -26,7 +26,7 @@ namespace WindBot ...@@ -26,7 +26,7 @@ namespace WindBot
Host = "127.0.0.1"; Host = "127.0.0.1";
Port = 7911; Port = 7911;
HostInfo = ""; HostInfo = "";
Version = 0x1354; Version = 0x1360;
Hand = 0; Hand = 0;
Debug = false; Debug = false;
Chat = true; Chat = true;
......
...@@ -280,6 +280,16 @@ ...@@ -280,6 +280,16 @@
"name": "神数不神", "name": "神数不神",
"deck": "Tearlaments", "deck": "Tearlaments",
"dialog": "Zefra.zh-CN" "dialog": "Zefra.zh-CN"
},
{
"name": "神数不神",
"deck": "Zefra",
"dialog": "Zefra.zh-CN"
},
{
"name": "神数不神",
"deck": "Zefra",
"dialog": "Zefra.zh-CN"
} }
] ]
} }
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