I suspect that even the simplest pruning of the game tree -- collapsing random effects, avoiding friendly-fire, collapsing unit placement, collapsing card play order -- will give ridiculous speed ups. My hope is that a reasonable class-specific AI will be able to branch forward a few turns.
You could get near instantaneous full-game simulations by never branching and just playing randomly (using cards weights). Unfortunately, there's a huge gap in program-complexity between computing one possible outcome and computing all possible outcomes. Especially when you have the intention of inserting hooks that can analyze this process and eventually simplify it. Additionally, it's been difficult to ensure the simulator will function like the real game. For example, tonight I was stepping through Youtube videos to figure out how Coldlight Oracle draw (2 cards per player) is ordered: [A,B,A,B], [B,A,B,A], [A,A,B,B], [B,B,A,A], ... The other week I was reading about Pint-sized + Summoning Portal. There's a long list of "bugs" that have been useful for deconstructing the internal game logic.
w/r/t the card schema, I'm glad I finally found a representation that has allowed me to add a lot of cards without requiring additional language tweaks. I've handwritten 684? card implementations so far, and I can't tell you how many times I got half way through the list and realized my current language isn't sufficiently expressive or too ambiguous
In an upcoming post, I'll outline some of the supported features and explain their various required/optional arguments:
- Boolean Auras (Taunt, Shield, Charge, Windfury, Stealth, Untargetable, Stunned, Frigid, Poisonous, ...)
- Valued Auras (Deathrattle, TempAura, SpellPower, Attack, Health, Events, ...)
- Events (OnDeath, OnAttack, OnSummon, OnDamageHealed, OnTurnStart, OnTurnEnd, OnSecret, OnOverload, ...)
- Actions (Draw, Discard, Return, Transform, Destroy, Copy, Resurrect, Damage, Heal, Choose, SplitDamage, Control, Consume, ...)
- Card Features (Do, Battlecry, Choose, Combo, ...)
- Game Features (AddMana, DestroyMana, AddCost, SetCost, ...)
- Modifiers (AddAttack, AddArmor, AddHealth, TempAttack, SetHealth, ...)
- Selection Functions (Pick, SelectAll, SelectRandom, WithRoot, WithAdj, SummonIntercept, TargetRedirect, ...)
- Logic Functions (Repeat, Count, IfAura, IfSelect, ...)
There is still some functionality that I am still refactoring:
- Betrayal/Gladiator Longbow (ImmuneWhileAttacking)
- Gorehowl (AttackAsDurability)
- Holy Wrath (unsure about what shit can occur between the Draw and the spell attack, can I have variable "LastCardCost")
Things on my radar:
- develop a simple to write Before/After test suite (GameStateInitial + [action list] + GameStateFinal)
- create tons of examples to test card functionality
- first-generation test: confirm Initial = Final
- second-generation test: find the set of [action list]'s that gets you from GameStateInitial to GameStateFinal, confirm [action list] is a member of this set.