Commit f6eae0a7 authored by mercury233's avatar mercury233

fully implement announce card

parent 59231c54
...@@ -438,32 +438,6 @@ namespace WindBot.Game.AI.Decks ...@@ -438,32 +438,6 @@ namespace WindBot.Game.AI.Decks
return base.OnSelectPosition(cardId, positions); return base.OnSelectPosition(cardId, positions);
} }
/// <summary>
/// Override for CrossoutDesignator
/// </summary>
/// <param name="opcodes">Operation codes for limitation.</param>
/// <param name="preAnnouced">Card's id prepared to annouce.</param>
/// <returns>Card's id to annouce.</returns>
public override int OnAnnounceCard(IList<int> opcodes, int preAnnouced)
{
const int OPCODE_OR = 0x40000005;
const int OPCODE_ISCODE = 0x40000100;
IList<int> codes = new List<int>();
foreach (int opcode in opcodes) {
if (opcode != OPCODE_OR && opcode != OPCODE_ISCODE)
{
codes.Add(opcode);
}
}
// if annouced card not in required list, return random card from list.
if (!codes.Contains(preAnnouced))
{
Logger.DebugWriteLine("No annouced card in required list, annouce randomly.");
return codes[Program.Rand.Next(codes.Count)];
}
return base.OnAnnounceCard(opcodes, preAnnouced);
}
// shuffle List<ClientCard> // shuffle List<ClientCard>
public List<ClientCard> CardListShuffle(List<ClientCard> list) public List<ClientCard> CardListShuffle(List<ClientCard> list)
{ {
......
...@@ -189,16 +189,14 @@ namespace WindBot.Game.AI ...@@ -189,16 +189,14 @@ namespace WindBot.Game.AI
} }
/// <summary> /// <summary>
/// Called when bot is going to annouce a card, to check whether it's legel(to avoid error) /// Called when bot is going to annouce a card
/// For full implement of opcodes, see ygopro-core/playerop.cpp#is_declarable
/// </summary> /// </summary>
/// <param name="opcodes">Operation codes for limitation.</param> /// <param name="avail">Available card's ids.</param>
/// <param name="preAnnouced">Card's id prepared to annouce.</param>
/// <returns>Card's id to annouce.</returns> /// <returns>Card's id to annouce.</returns>
public virtual int OnAnnounceCard(IList<int> opcodes, int preAnnouced) public virtual int OnAnnounceCard(IList<int> avail)
{ {
// For overriding // For overriding
return preAnnouced; return 0;
} }
public void SetMain(MainPhase main) public void SetMain(MainPhase main)
......
namespace WindBot.Game.AI
{
public static class Opcodes
{
public const int OPCODE_ADD = 0x40000000,
OPCODE_SUB = 0x40000001,
OPCODE_MUL = 0x40000002,
OPCODE_DIV = 0x40000003,
OPCODE_AND = 0x40000004,
OPCODE_OR = 0x40000005,
OPCODE_NEG = 0x40000006,
OPCODE_NOT = 0x40000007,
OPCODE_ISCODE = 0x40000100,
OPCODE_ISSETCARD = 0x40000101,
OPCODE_ISTYPE = 0x40000102,
OPCODE_ISRACE = 0x40000103,
OPCODE_ISATTRIBUTE = 0x40000104;
}
}
\ No newline at end of file
...@@ -95,6 +95,7 @@ namespace WindBot.Game ...@@ -95,6 +95,7 @@ namespace WindBot.Game
m_materialSelector = null; m_materialSelector = null;
m_option = -1; m_option = -1;
m_yesno = -1; m_yesno = -1;
m_announce = 0;
m_place = 0; m_place = 0;
if (Duel.Player == 0 && Duel.Phase == DuelPhase.Draw) if (Duel.Player == 0 && Duel.Phase == DuelPhase.Draw)
...@@ -734,14 +735,18 @@ namespace WindBot.Game ...@@ -734,14 +735,18 @@ namespace WindBot.Game
/// <summary> /// <summary>
/// Called when the AI has to declare a card. /// Called when the AI has to declare a card.
/// </summary> /// </summary>
/// <param name="opcodes">Operation lists.</param> /// <param name="avail">Available card's ids.</param>
/// <returns>Id of the selected card.</returns> /// <returns>Id of the selected card.</returns>
public int OnAnnounceCard(IList<int> opcodes) public int OnAnnounceCard(IList<int> avail)
{ {
if (m_announce == 0) int selected = Executor.OnAnnounceCard(avail);
return Executor.OnAnnounceCard(opcodes, 89631139); // Blue-eyes white dragon if (avail.Contains(selected))
return selected;
return Executor.OnAnnounceCard(opcodes, m_announce); if (avail.Contains(m_announce))
return m_announce;
else if (m_announce > 0)
Logger.WriteErrorLine("Pre-announced card cant be used: " + m_announce);
return avail[0];
} }
// _ Others functions _ // _ Others functions _
......
...@@ -1445,11 +1445,152 @@ namespace WindBot.Game ...@@ -1445,11 +1445,152 @@ namespace WindBot.Game
packet.ReadByte(); // player packet.ReadByte(); // player
int count = packet.ReadByte(); int count = packet.ReadByte();
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
{
opcodes.Add(packet.ReadInt32()); opcodes.Add(packet.ReadInt32());
IList<int> avail = new List<int>();
IList<NamedCard> all = NamedCardsManager.GetAllCards();
foreach (NamedCard card in all)
{
if (card.HasType(CardType.Token) || (card.Alias > 0 && card.Id - card.Alias < 10)) continue;
Stack<int> stack = new Stack<int>();
for (int i = 0; i < opcodes.Count; i++)
{
switch (opcodes[i])
{
case Opcodes.OPCODE_ADD:
if (stack.Count >= 2)
{
int rhs = stack.Pop();
int lhs = stack.Pop();
stack.Push(lhs + rhs);
}
break;
case Opcodes.OPCODE_SUB:
if (stack.Count >= 2)
{
int rhs = stack.Pop();
int lhs = stack.Pop();
stack.Push(lhs - rhs);
}
break;
case Opcodes.OPCODE_MUL:
if (stack.Count >= 2)
{
int rhs = stack.Pop();
int lhs = stack.Pop();
stack.Push(lhs * rhs);
}
break;
case Opcodes.OPCODE_DIV:
if (stack.Count >= 2)
{
int rhs = stack.Pop();
int lhs = stack.Pop();
stack.Push(lhs / rhs);
}
break;
case Opcodes.OPCODE_AND:
if (stack.Count >= 2)
{
int rhs = stack.Pop();
int lhs = stack.Pop();
bool b0 = rhs != 0;
bool b1 = lhs != 0;
if (b0 && b1)
stack.Push(1);
else
stack.Push(0);
}
break;
case Opcodes.OPCODE_OR:
if (stack.Count >= 2)
{
int rhs = stack.Pop();
int lhs = stack.Pop();
bool b0 = rhs != 0;
bool b1 = lhs != 0;
if (b0 || b1)
stack.Push(1);
else
stack.Push(0);
}
break;
case Opcodes.OPCODE_NEG:
if (stack.Count >= 1)
{
int rhs = stack.Pop();
stack.Push(-rhs);
}
break;
case Opcodes.OPCODE_NOT:
if (stack.Count >= 1)
{
int rhs = stack.Pop();
bool b0 = rhs != 0;
if (b0)
stack.Push(0);
else
stack.Push(1);
}
break;
case Opcodes.OPCODE_ISCODE:
if (stack.Count >= 1)
{
int code = stack.Pop();
bool b0 = code == card.Id;
if (b0)
stack.Push(1);
else
stack.Push(0);
}
break;
case Opcodes.OPCODE_ISSETCARD:
if (stack.Count >= 1)
{
if (card.HasSetcode(stack.Pop()))
stack.Push(1);
else
stack.Push(0);
}
break;
case Opcodes.OPCODE_ISTYPE:
if (stack.Count >= 1)
{
if ((stack.Pop() & card.Type) > 0)
stack.Push(1);
else
stack.Push(0);
}
break;
case Opcodes.OPCODE_ISRACE:
if (stack.Count >= 1)
{
if ((stack.Pop() & card.Race) > 0)
stack.Push(1);
else
stack.Push(0);
}
break;
case Opcodes.OPCODE_ISATTRIBUTE:
if (stack.Count >= 1)
{
if ((stack.Pop() & card.Attribute) > 0)
stack.Push(1);
else
stack.Push(0);
}
break;
default:
stack.Push(opcodes[i]);
break;
}
}
if (stack.Count == 1 && stack.Pop() != 0)
avail.Add(card.Id);
} }
// not fully implemented if (avail.Count == 0)
Connection.Send(CtosMessage.Response, _ai.OnAnnounceCard(opcodes)); throw new Exception("No avail card found for announce!");
Connection.Send(CtosMessage.Response, _ai.OnAnnounceCard(avail));
} }
private void OnAnnounceNumber(BinaryReader packet) private void OnAnnounceNumber(BinaryReader packet)
......
...@@ -37,6 +37,9 @@ ...@@ -37,6 +37,9 @@
<PropertyGroup> <PropertyGroup>
<ApplicationIcon>WindBot.ico</ApplicationIcon> <ApplicationIcon>WindBot.ico</ApplicationIcon>
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Mono.Data.Sqlite"> <Reference Include="Mono.Data.Sqlite">
<HintPath>.\Mono.Data.Sqlite.dll</HintPath> <HintPath>.\Mono.Data.Sqlite.dll</HintPath>
...@@ -120,6 +123,7 @@ ...@@ -120,6 +123,7 @@
<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\Opcodes.cs" />
<Compile Include="Game\AI\Zones.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" />
......
No preview for this file type
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