peter1591 / hearthstone-ai Goto Github PK
View Code? Open in Web Editor NEWA Hearthstone AI based on Monte Carlo tree search and neural nets written in modern C++.
A Hearthstone AI based on Monte Carlo tree search and neural nets written in modern C++.
Refines on state::State:
Requirement
Notes
A /wd4127 compiler option is added to suppress this warning
Dead entries should call aura update at least one more time,
to remove the aura enchantments.
Maybe a aura manager?
CardManipulator's Damage() calls
BoardManipulator's CalculateFinalDamageAmount()
which calculate spell damage for spell/secret cards
So, client cards should not add spell damage by itself?
Two lines affected in common.h:
https://github.com/peter1591/hearthstone-ai/blob/master/pilot_run/include/game-engine/cards/common.h#L118 which redeclares https://github.com/peter1591/hearthstone-ai/blob/master/pilot_run/include/game-engine/cards/common.h#L112
and
https://github.com/peter1591/hearthstone-ai/blob/master/pilot_run/include/game-engine/cards/common.h#L161 which redeclares https://github.com/peter1591/hearthstone-ai/blob/master/pilot_run/include/game-engine/cards/common.h#L155
Client card needs:
but should not touch:
Cards manipulator: set zone, set zone position, etc.
Characters manipulator: all above, attack/defend
Minion manipulator: all above, enchant, aura,
They should have hierarchy like this.
Gladiator's Longbow
Gorehowl
When a card is drawn
remove all its enchantments
restore the aura to default value in card database
(maybe it got silenced before going to graveyard)
In this sense,
maybe we can just store card_id when cards are in deck
or, in other words,
we only need to store the whole Cards::CardData when cards are in HAND / PLAY zone
Freezed twice --> thaw at once
Taunted twice --> broken at once
Divine shield twice --> broken at once
stealth twice --> shown at once
Also, the minion stat can be reduced to below zero since some stats (e.g., taunt) can be removed during game flow (e.g., attack)
Currently the minions are stored in a c++ list container,
when insert, the other iterators are still valid (as opposite to the std::vector)
In current code, we have implemented our own consistency-checking mechanism,
and when a minion is inserted, the consistency-checking framework will invalidate all other iterators
this is not necessary as long as the std::list is used.
Note: when a minion is removed, the other iterators are still valid in std::list,
BUT!! the iterators pointing to the removed minion should be invalidated.
However, since we have no tracking info for such iterators, all iterators are marked invalidated.
This is a desired behavior since the game engine should not introduce such behavior.
Refer to Gladiator's Longbow
Apply an enchantment (make it immune), and remove it after attack
Some cost modifiers are attached to the entire game (i.e., board), or attached to a particular player
Some of them are permanent effects, some of them are one-turn effects, and some of them are aura effects.
How to deal with them?
Don't use vector, use hash table instead
Client cards should consider to use categorized event triggers instead
First I added log.config to C:\Users[username]\AppData\Local\Blizzard\Hearthstone and added
[Achievements]
LogLevel=1
FilePrinting=true
ConsolePrinting=true
ScreenPrinting=false
[Power]
LogLevel=1
FilePrinting=true
ConsolePrinting=true
ScreenPrinting=false
If this is needed please add to documentation.
The I follow your directions: Opened C# project under path\hearthstone-ai-master\vs_projects\GameEngineUI
Then I run it. Everything compiles and runs. I see a window with 1 button. I press the button a file picker appears. What do I do?
I see from the code it wants to know where the cpp dll is. I click on it, but then it just pops up with a number (427549). What does this mean? How can I get what the best move is?
Use hash table to identify which tree nodes can be shared
TODO: do we really want to share tree nodes?
Do we need to switch to simulation mode within a main action?
For example,
A main action is to decide from (PLAY-CARD, HERO-POWER, END-TURN)
Assume we were in selection mode at this main action node, the UCB policy is used to determined from these choices.
Assume we choose the PLAY-CARD action
Assume this is the FIRST TIME we make this choice, so a new node is added to the game tree.
Now, do we want to switch to simulation mode?
In current design, we only switch to simulation mode after this MAIN ACTION + SUB ACTIONS are done.
That is, we switch to simulation after
严重性 代码 说明 项目 文件 行 禁止显示状态
错误 CS0103 当前上下文中不存在名称“GameEngineCppWrapper” GameEngineUI D:\Code\hearthstone-ai-master\hearthstone-ai-master\vs_projects\GameEngineUI\Form1.cs 32 活动的
Death rattle is triggered by play order
Maybe we can use event trigger to check death
Then no need for play order anymore
Need to store (un)enchanted states in entity?
Or, when we need to update/re-calculate enchanted states, we...
aura enchantment should be applied in-order
You play an Amani Berserker and Enrage it, giving it 5 Attack. You then play Humility on it, giving it 1 Attack. You then heal and Enrage it a second time - the new Enrage is at the end of order of play, going after the Humility effect and it now has 4 Attack.
use std::variant
each enchantment entry is either an 'normal enchantment', or an 'aura enchantment'
Runtime analysis of a execution hot path is crucial. It sometimes make a JIT out-performed a static program like C++.
Profile-guided optimization maybe a rescue for this.
https://textslashplain.com/2016/01/10/getting-started-with-profile-guided-optimization/
g++ optimization flags:
-fprofile-generate
-fprofile-use
-fprofile-dir
already replaced by return value
return false: remove it from container
Pros:
Cons:
Notes:
the event listened by the enchantment should be registered after a new minion became a copy of the minion.
add a new test:
Water Elemental + Betrayal
Emperor Cobra + Betrayal
http://hearthstone.gamepedia.com/Betrayal
So maybe the 'freezing attack' and 'poisonous attack' should be implemented via event triggers
In StaticEventTriggerrer.h line 17, class 'Invoker' doesn't resolve. Did you mean to use class 'Invoker2'?
client cards use manipulators, not directly using state::State or FlowControl::FlowContext
enchantments should have a method:
state::State state;
Implement state.Manipulate() to replace: state::Manipulators::StateManipulator(state)
In some states, only a subset of actions are valid
In current implementation
Since later, a policy network might be used to
Some thoughts
As title
Hello @peter1591, I wanted to ask you about the project structure. So I've been trying to resolve https://github.com/zappybiby/hearthstone-ai/issues/1 but I am not seeing any obvious issues with compiling or anything like that.
Now I'm wondering if any of the projects you have in the main repo (HearthstoneAI, MCTS, and vs_projects) are linked together in some way. I've never dealt with a repo with multiple projects (and I am new to coding as well) so the structure here confuses me. Maybe we should rename the solutions? Sorry for being a newbie! I hope to add more to this project soon after I get this resolved.
manipulator postfix can be removed,
and the underlying POD structures can be added with the 'Data' postfix
Restart mechanism for invalid actions
Some of the choices might lead to an invalid action.
Remember a tree in both selection and simulation stage.
This tree is rooted from the last main action,
and will be traversed again from this root once an invalid
game state is detected.
When an invalid state is reached, we cannot finish the current MCTS episode, since that particular move is actually invalid.
Several approaches can be done in this situation.
A tree is established in selection stage, so we can mark a child as invalid easily.
As discuss in the issue #45, the simulation engine should be able to generate valid actions. At least, with a high probability to generate a valid action.
If we have a tree for simulation, we can remember which action is invalid, and restart quickly.
Since there's a high chance to have an invalid action when picking up a playable card (happens when no crystal left), we should make it fast.
But, for performance, we should lower down the rate of an invalid state as much as possible.
What happens if there's no tree for simulation, and an invalid state is reached during simulation? We can have a linear (not a tree) data structure to record the black-list choices along the path.
A linear data structure to record the black-list choices along the chosen path.
Assumption: If a state is valid before random. Then, ALL random outcome should yields a valid state.
That is,
`
// Make a choice, and modify the progress accordingly
//@return the choice
int Select(Progress & progress);
// Report if a choice leading to an invalid state
void ReportInvalid(Progress & progress)
`
Similar to tag framework
Pros:
Cons:
Current decision:
In current implementation,
before applying each action (i.e., play-card, attack, hero-power, or end-turn)
the game state is saved on stack
This game state is restored if the action is actually an invalid action and make the application failed.
We can make the game state to be copy-on-write,
and support the fast response for those methods which are probably invoked when applying an invalid action
Since there are many discussions on the efficiency of copy-on-write data structures,
it's better to delay after we've done some profiling.
Check all battlecry
--> they should all apply Targetable() filter
Check all spell target
--> they should all apply SpellTargetable() filter
What situations lead to an invalid state?
also,
As with Stealth, Taunt minions that are Immune have their Taunt ability temporarily suppressed, and can thus be bypassed.
specify event type in template parameter
check enchantment existence in framework
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.