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
Name=神数不神 Deck=Tearlaments Dialog=Zefra.zh-CN
旧式地天使珠泪哀歌族卡组。
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 @@
"乎,我发动{0}!",
"不好意思拉,我有{0}",
"哈哈,发动{0}的效果!"
],
"custom": [
"呱!本体出征!",
"凸(艹皿艹 )卡手不玩拉!!!",
"嘿不慌,还有摆子场( ̄y▽ ̄)╭"
]
}
......@@ -442,5 +442,115 @@ namespace WindBot.Game.AI
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
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)
{
if (cardA == null && cardB == null)
......
......@@ -78,5 +78,21 @@ namespace WindBot.Game.AI
{
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
}
// 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);
transformDestList.AddRange(new List<int>{CardId.ExosistersMagnifica, CardId.ExosisterMikailis, CardId.ExosisterGibrine, CardId.ExosisterKaspitell, CardId.ExosisterAsophiel});
......@@ -2025,7 +2025,7 @@ namespace WindBot.Game.AI.Decks
public bool ExosisterPaxActivate()
{
if (potActivate)
if (potActivate || Bot.LifePoints <= 800)
{
return false;
}
......@@ -2198,7 +2198,7 @@ namespace WindBot.Game.AI.Decks
public bool ExosisterPaxActivateForEndSearch()
{
if (potActivate)
if (potActivate || Bot.LifePoints <= 800)
{
return false;
}
......@@ -2230,6 +2230,10 @@ namespace WindBot.Game.AI.Decks
public bool ExosisterArmentActivate()
{
if (Bot.LifePoints <= 800)
{
return false;
}
ClientCard activateTarget = null;
if (Duel.Player == 0)
......@@ -2366,6 +2370,11 @@ namespace WindBot.Game.AI.Decks
public bool ExosisterVadisActivate()
{
if (Bot.LifePoints <= 800)
{
return false;
}
List<int> checkListForSpSummon = new List<int>{
CardId.ExosisterSophia, CardId.ExosisterIrene, CardId.ExosisterStella, CardId.ExosisterMartha, CardId.ExosisterElis
};
......@@ -2435,6 +2444,11 @@ namespace WindBot.Game.AI.Decks
public bool ExosisterReturniaActivate()
{
if (Bot.LifePoints <= 800)
{
return false;
}
// banish problem card
ClientCard target = GetProblematicEnemyCard(true);
if (target != null && Duel.LastChainPlayer != 0)
......@@ -2463,7 +2477,7 @@ namespace WindBot.Game.AI.Decks
// dump banish
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 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);
......
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
[DataMember]
public string[] setmonster { get; set; }
[DataMember]
public string[] chaining { get; set; }
public string[] chaining { get; set; }
[DataMember]
public string[] custom { get; set; }
}
public class Dialogs
{
......@@ -53,7 +55,8 @@ namespace WindBot.Game.AI
private string[] _summon;
private string[] _setmonster;
private string[] _chaining;
private string[] _custom;
public Dialogs(GameClient game)
{
_game = game;
......@@ -75,6 +78,7 @@ namespace WindBot.Game.AI
_summon = data.summon;
_setmonster = data.setmonster;
_chaining = data.chaining;
_custom = data.custom;
}
}
......@@ -176,5 +180,14 @@ namespace WindBot.Game.AI
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
// For overriding
return null;
}
public virtual void OnSelectChain(IList<ClientCard> cards)
{
return;
......
......@@ -54,6 +54,14 @@ namespace WindBot.Game
_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>
/// Called when the AI do the rock-paper-scissors.
/// </summary>
......
......@@ -1804,7 +1804,7 @@ namespace WindBot.Game
int count = packet.ReadByte();
int available = packet.ReadInt32();
int filter = 0x1;
for (int i = 0; i < 23; ++i)
for (int i = 0; i < 26; ++i)
{
if ((available & filter) != 0)
races.Add((CardRace)filter);
......
......@@ -115,12 +115,15 @@
<Compile Include="Game\AI\Decks\DoEveryThingExecutor.cs" />
<Compile Include="Game\AI\Decks\OldSchoolExecutor.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\ZexalWeaponsExecutor.cs" />
<Compile Include="Game\AI\DefaultExecutor.cs" />
<Compile Include="Game\AI\Dialogs.cs" />
<Compile Include="Game\AI\Enums\DangerousMonster.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\ShouldNotBeSpellTarget.cs" />
<Compile Include="Game\AI\Enums\ShouldNotBeMonsterTarget.cs" />
......
......@@ -26,7 +26,7 @@ namespace WindBot
Host = "127.0.0.1";
Port = 7911;
HostInfo = "";
Version = 0x1354;
Version = 0x1360;
Hand = 0;
Debug = false;
Chat = true;
......
......@@ -280,6 +280,16 @@
"name": "神数不神",
"deck": "Tearlaments",
"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