The game engine for the card game Hearthstone written in C++17. Used in AAIA'17 Data Mining Challenge: Helping AI to Play Hearthstone to generate training/validation datasets.
- No dependency
- (Free/Automatically) whole program optimization
Use template programming to move workload to compile-time as much as possible. With C++14/17 features like std::variant, SFINAE and much more, we can write structured code with zero overhead.
- Game state maintains the underlying game state.
- Flow control makes sure the game follows the rule.
- Cards implements all the cards.
- Decks collects all types of deck.
According to Hearthstone's rule, a game is divided into several turns, and a player can perform several main actions at each turn. There are only four main actions:
- Play a card
- Attack
- Use hero power
- End turn
In a main action, it is sometimes needed to provide further action parameters like choose a spell target or choose where to put the minion. To provide these parameters, we need to implement a callback first.
#include "FlowControl/IActionParameterGetter.h"
class MyActionParameterGetter : public FlowControl::IActionParameterGetter
{
// implementation
};
Hearthstone is a game with a lot of randomness. All the random outcomes will be fetched from the provided callback. Once you fix the random outcomes from your random callback, this becomes a deterministic game.
#include "state/IRandomGenerator.h"
class MyRandomGenerator : public state::IRandomGenerator
{
// implementation
};
#include "FlowControl/FlowController.h"
void test()
{
state::State game_state;
MyActionParameterGetter action_cb;
MyRandomGenerator random_cb;
FlowControl::FlowContext context(random_cb, action_cb);
Prepare(); // Prepare hero/hero-power/deck/hand...
FlowControl::FlowController controller(game_state, context);
controller.PlayCard(0); // Play the first card
}
Refer to e2e test for a full examples.
This library uses some language features only available in the latest C++17, so compiler newer than gcc 7.0+ or Visual Studio 2017 Preview 2.1+ is needed. Please refer to the build folder for working examples.
Enable the /bigobj option for Visual Studio.
This is a header-only implementation. If the compiler is not smart enough, all the headers have to be re-compiled each time. A programmer can always choose to move the implementation detail to another compilation unit.
Refer to the card-dispatcher compilation unit for an example to separate out implementation details for client cards and flow controller.