oyachai / hearthsim Goto Github PK
View Code? Open in Web Editor NEWGeneric Hearthstone game simulator
License: MIT License
Generic Hearthstone game simulator
License: MIT License
I noticed that there's a profiling test available here:
https://github.com/oyachai/HearthSim/blob/master/src/test/java/com/hearthsim/test/testGame.java
I'm interested in performing some refactorings on this project, and would like to make sure that performance remains acceptable. Right now that test takes around 500ms to run on my machine. I wonder if there are any other benchmarks worth considering and logging? We could even just have a plaintext file in the app with a history of benchmarks for now, perhaps performed on some reference machine like a digital ocean droplet.
Thoughts?
Hi
I opened an irc channel on freenode for my simulator but I'd like to actually welcome anyone interested in hearthstone simulation, theorycrafting or reverse engineering there. I called it #hearthsim tentatively (if that's a problem, let me know and I'll rename it to something else seeing as it has the same name as your software, but I thought it was nicely generic as well). Are you interested?
Update AllSets to BRM and add issues to track new card implementation.
I've started looking at this.
Hello. Great project!
I would be nice if the project contained at least one example setup file so that one could get up and running quicker. It doesn't have to be anything special, but it's kind of a downer to start out by having to figure out how to write one.
Thanks!
What's the idea with the allMinionsFifoList. It looks to only be used by 'handleDeadMinons'. Is there a reason you couldn't just loop through each player's minions?
First off, nice project! I like what you have done so far. I love being able to download the executable and instantly check out the app. That accessibility to the project is what grabbed me.
Is there a road map or list of needed features and priorities? I'm particularly interested in the direction the user interface should go. For example, has a web front end been considered? Will you be able to view a game turn by turn?
Is the intention to allow decks of any size and not be forced to choose a hero or is that just something that hasn't been implemented yet?
What about match-ups. Will the simulations be a single deck verses deck or will it be one deck verses a set of decks?
I'm just trying to get a sense of where the project is headed and yes, I realize you are still implementing the cards. Thanks!
Hi!
I'm working on a very similar project to this one, over at https://github.com/danielyule/hearthstone-simulator. Ours is written in Python, but has an almost identical focus. Obviously, there's enough room for two simulators, written in different languages, but I think it makes sense to coordinate, for example in any exporting or importing format.
Java might be really useful, since both HearthStats and Hearthtracker are written in that language. I chose Python because I wanted to use SciPy for my analysis out the other side.
If you're interested in working together, let me know. We've got a mailing list at https://groups.google.com/forum/#!forum/hearthstone-simulator-dev, or you can shoot me an email at [email protected].
Looking through the list of unimplemented cards shows two cards with adjacent auras
ReferenceCard(EX1_565, Flametongue Totem, Minion, Basic, Common, 2, Shaman, Adjacent minions have +2 Attack., [AdjacentBuff, Aura], 0, 3, null, true)
ReferenceCard(EX1_162, Dire Wolf Alpha, Minion, Classic, Common, 2, Neutral, Adjacent minions have +1 Attack., [AdjacentBuff, Aura], 2, 2, null, true)
As it is currently written, deepCopy uses reflection to obtain the constructor of the currently class which proves to be a gigantic performance hit. According to some rough profiling I did, approximately 13% of execution time is spent on a single line of code in this method : "copy =getClass().newInstance();".
Since reflection lookup as is currently done is roughly 10x as expensive as just instantiating it using the new operator (see http://stackoverflow.com/questions/435553/java-reflection-performance) we could probably achieve about a 10% speedup if we can figure out how to implement this without reflection so I definitely think that this is a worthwhile optimization if it can be done.
One idea that I've had would be to use some sort of lookup table to store constructors so that reflection happens only once as opposed to millions of time since it would be hard to provide the functionality of deepCopy without any reflection at all.
These were pulled out of the all collectible cards implemented
test. I ignored all GvG cards and Eaglehorn Bow since it depends on Secrets which are not implemented yet (see #34). The four weapons below should be relatively straightforward to implement.
I can certainly do this but I didn't want to overlap with whatever you were working on.
23:01:12.333 [main] WARN c.h.test.json.ReferenceCardSpec - com.hearthsim.json.registry.ReferenceCard(DS1_188, Gladiator's Longbow, Weapon, Classic, Epic, 7, Hunter, Your hero is Immune while attacking., null, 5, null, 2, true) 23:01:12.334 [main] WARN c.h.test.json.ReferenceCardSpec - com.hearthsim.json.registry.ReferenceCard(EX1_411, Gorehowl, Weapon, Classic, Epic, 7, Warrior, Attacking a minion costs 1 Attack instead of 1 Durability., null, 7, null, 1, true) 23:01:12.334 [main] WARN c.h.test.json.ReferenceCardSpec - com.hearthsim.json.registry.ReferenceCard(EX1_133, Perdition's Blade, Weapon, Classic, Rare, 3, Rogue, Battlecry: Deal 1 damage. Combo: Deal 2 instead., [Battlecry, Combo], 2, null, 2, true) 23:01:12.335 [main] WARN c.h.test.json.ReferenceCardSpec - com.hearthsim.json.registry.ReferenceCard(FP1_021, Death's Bite, Weapon, Curse of Naxxramas, Common, 4, Warrior, Deathrattle: Deal 1 damage to all minions., [Deathrattle], 4, null, 2, true)
Combo has not been implemented yet and a whole bunch of cards need it:
ReferenceCard(EX1_133, Perdition's Blade, Weapon, Classic, Rare, 3, Rogue, <b>Battlecry:</b> Deal 1 damage. <b>Combo:</b> Deal 2 instead., [Battlecry, Combo], 2, null, 2, true)
ReferenceCard(EX1_131, Defias Ringleader, Minion, Classic, Common, 2, Rogue, <b>Combo:</b> Summon a 2/1 Defias Bandit., [Combo], 2, 2, null, true)
ReferenceCard(EX1_613, Edwin VanCleef, Minion, Classic, Legendary, 3, Rogue, <b>Combo:</b> Gain +2/+2 for each card played earlier this turn., [Combo], 2, 2, null, true)
ReferenceCard(NEW1_005, Kidnapper, Minion, Classic, Epic, 6, Rogue, <b>Combo:</b> Return a minion to its owner's hand., [Combo], 5, 3, null, true)
ReferenceCard(EX1_134, SI:7 Agent, Minion, Classic, Rare, 3, Rogue, <b>Combo:</b> Deal 2 damage., [Combo], 3, 3, null, true)
ReferenceCard(CS2_073, Cold Blood, Spell, Classic, Common, 1, Rogue, Give a minion +2 Attack. <b>Combo:</b> +4 Attack instead., [Combo], null, null, null, true)
ReferenceCard(EX1_124, Eviscerate, Spell, Classic, Common, 2, Rogue, Deal $2 damage. <b>Combo:</b> Deal $4 damage instead., [Combo], null, null, null, true)
ReferenceCard(EX1_137, Headcrack, Spell, Classic, Rare, 3, Rogue, Deal $2 damage to the enemy hero. <b>Combo:</b> Return this to your hand next turn., [Combo], null, null, null, true)
ReferenceCard(GVG_047, Sabotage, Spell, Goblins vs Gnomes, Epic, 4, Rogue, Destroy a random enemy minion. <b>Combo</b>: And your opponent's weapon., [Combo], null, null, null, true)
ReferenceCard(GVG_022, Tinker's Sharpsword Oil, Spell, Goblins vs Gnomes, Common, 4, Rogue, Give your weapon +3 Attack. <b>Combo:</b> Give a random friendly minion +3 Attack., [Combo], null, null, null, true)
Do we need both patterns? It looks like they are testing the exact same thing:
I've been trimming out a ton of duplicated test code in the Java tests but don't get why we need both of these.
What is the purpose of using the IdentityLinkedList? I swapped it out for a regular linkedlist and noticed that just one test failed. It's fairly unusual to see an obscure data structure like this used, perhaps we could find another solution? Any light shed on the reason for its use would be appreciated!
BRM added mechanics around the number of minions that died this turn but Kel'Thuzad also needs this info.
Dealing with Resurrect will probably be more complicated, though, so that is excluded from this issue.
ReferenceCard(FP1_013, Kel'Thuzad, Minion, Curse of Naxxramas, Legendary, 8, Neutral, At the end of each turn, summon all friendly minions that died this turn., null, 6, 8, null, true, null)
ReferenceCard(BRM_025, Volcanic Drake, Minion, Blackrock Mountain, Common, 6, Neutral, Costs (1) less for each minion that died this turn., null, 6, 4, null, true, Dragon)
ReferenceCard(BRM_009, Volcanic Lumberer, Minion, Blackrock Mountain, Rare, 9, Druid, <b>Taunt</b> Costs (1) less for each minion that died this turn., [Taunt], 7, 8, null, true, null)
ReferenceCard(BRM_003, Dragon's Breath, Spell, Blackrock Mountain, Common, 5, Mage, Deal $4 damage. Costs (1) less for each minion that died this turn., null, null, null, null, true, null)
ReferenceCard(BRM_001, Solemn Vigil, Spell, Blackrock Mountain, Common, 5, Paladin, Draw 2 cards. Costs (1) less for each minion that died this turn., null, null, null, null, true, null)
Hi awesome project, I will try to contribute to it, I've 19 years in java... and around 3 with Encog and Machine Learning project... lets see if we can predict some stuff..
On the other hand I found a missing classe at the repository:
com.hearthsim.card.ImplementedCardList;
Could you please create a lib folder with the current versions you are using, or post it at the Readme?
Thanks !!
I started refactoring the tribal classes to rely on a field instead of explicit classes. The first wave: MrHen@82b323a
Is there a particular reason the different tribal classes exist? Or can I continue along this path and remove them?
Cards like Tundra Rhino or Warsong Commander alter cards as they come into play.
ReferenceCard(EX1_084, Warsong Commander, Minion, Basic, Free, 3, Warrior, Whenever you summon a minion with 3 or less Attack, give it <b>Charge</b>., null, 2, 3, null, true)
ReferenceCard(GVG_104, Hobgoblin, Minion, Goblins vs Gnomes, Epic, 3, Neutral, Whenever you play a 1-Attack minion, give it +2/+2., null, 2, 3, null, true)
For some reason, this test method has been failing on the second assertion (and seemingly only on the second assertion) 1 out of every couple hundred runs.
Cards that mess with casting costs.
ReferenceCard(EX1_616, Mana Wraith, Minion, Classic, Rare, 2, Neutral, ALL minions cost (1) more., [Aura], 2, 2, null, true, null)
ReferenceCard(EX1_076, Pint-Sized Summoner, Minion, Classic, Rare, 2, Neutral, The first minion you play each turn costs (1) less., [Aura], 2, 2, null, true, null)
ReferenceCard(EX1_608, Sorcerer's Apprentice, Minion, Classic, Common, 2, Mage, Your spells cost (1) less., [Aura], 3, 2, null, true, null)
ReferenceCard(CS2_227, Venture Co. Mercenary, Minion, Classic, Common, 5, Neutral, Your minions cost (3) more., [Aura], 7, 6, null, true, null)
ReferenceCard(FP1_017, Nerub'ar Weblord, Minion, Curse of Naxxramas, Common, 2, Neutral, Minions with <b>Battlecry</b> cost (2) more., [Aura], 1, 4, null, true, null)
ReferenceCard(GVG_006, Mechwarper, Minion, Goblins vs Gnomes, Common, 2, Neutral, Your Mechs cost (1) less., [Aura], 2, 3, null, true, Mech)
Millhouse and Loatheb are probably fairly similar but they live in #107. I left out cards that affect cards in hand (e.g., Shadowstep or Call Pet). I also left out Clockwork Giant.
There is a way already to do battle cries, but I've been looking and I can't seem to find any code to handle death rattles. Is this correct or am I just missing it?
BRM added "if you're holding a Dragon" mechanics.
ReferenceCard(BRM_034, Blackwing Corruptor, Minion, Blackrock Mountain, Common, 5, Neutral, <b>Battlecry</b>: If you're holding a Dragon, deal 3 damage., [Battlecry], 5, 4, null, true, null)
ReferenceCard(BRM_033, Blackwing Technician, Minion, Blackrock Mountain, Common, 3, Neutral, <b>Battlecry:</b> If you're holding a Dragon, gain +1/+1., [Battlecry], 2, 4, null, true, null)
ReferenceCard(BRM_029, Rend Blackhand, Minion, Blackrock Mountain, Legendary, 7, Neutral, <b>Battlecry:</b> If you're holding a Dragon, destroy a <b>Legendary</b> minion., [Battlecry], 8, 4, null, true, null)
ReferenceCard(BRM_004, Twilight Whelp, Minion, Blackrock Mountain, Common, 1, Priest, <b>Battlecry:</b> If you're holding a Dragon, gain +2 Health., [Battlecry], 2, 1, null, true, Dragon)
There are three PRs that seem to be old/stale. Are there any plans for them?
Have you given any thought to producing a game history that would be easily understood by humans? I know there is the GameDetailedRecord, but it's not easily digested. It would be great to have something similar to what you see along the side while you're playing hearthstone.
IE.,
Player 1 turn:
plays card x to position 0
position 1 minion attacks enemy hero
Player 2 turn:
uses hero ability against enemy minion 0.
etc.
I think this would be really useful for debugging AI decisions. Once we get more of the cards implemented I'm interested in trying to create a really great AI, and I think creating a format that allowed us to easily watch what the AI's do would help a lot.
What's missing are descriptions of the edges between boardmodels in the record.
Any thoughts?
I was going over code coverage looking for missing test cases and noticed that summoned_
is never used for anything. It looks like it was tracking whether a minion was summoned as a result of battlecry? Is this still necessary or can I remove it?
Silence is not well supported in the current version.
Cards with effects that randomly target things. This list does not include multiple effects in one shot (e.g., Mad Bomber).
ReferenceCard(GVG_059, Coghammer, Weapon, Goblins vs Gnomes, Epic, 3, Paladin, <b>Battlecry:</b> Give a random friendly minion <b>Divine Shield</b> and <b>Taunt</b>., [Battlecry], 2, null, 3, true, null)
ReferenceCard(GVG_043, Glaivezooka, Weapon, Goblins vs Gnomes, Common, 2, Hunter, <b>Battlecry:</b> Give a random friendly minion +1 Attack., [Battlecry], 2, null, 2, true, null)
ReferenceCard(NEW1_019, Knife Juggler, Minion, Classic, Rare, 2, Neutral, After you summon a minion, deal 1 damage to a random enemy., null, 3, 2, null, true, null)
ReferenceCard(EX1_085, Mind Control Tech, Minion, Classic, Rare, 3, Neutral, <b>Battlecry:</b> If your opponent has 4 or more minions, take control of one at random., [Battlecry], 3, 3, null, true, null)
ReferenceCard(GVG_099, Bomb Lobber, Minion, Goblins vs Gnomes, Rare, 5, Neutral, <b>Battlecry:</b> Deal 4 damage to a random enemy minion., [Battlecry], 3, 3, null, true, null)
ReferenceCard(GVG_072, Shadowboxer, Minion, Goblins vs Gnomes, Rare, 2, Priest, Whenever a character is healed, deal 1 damage to a random enemy., null, 2, 3, null, true, Mech)
ReferenceCard(GVG_075, Ship's Cannon, Minion, Goblins vs Gnomes, Common, 2, Neutral, Whenever you summon a Pirate, deal 2 damage to a random enemy., null, 2, 3, null, true, null)
ReferenceCard(EX1_407, Brawl, Spell, Classic, Epic, 5, Warrior, Destroy all minions except one. <i>(chosen randomly)</i>, null, null, null, null, true, null)
ReferenceCard(EX1_617, Deadly Shot, Spell, Classic, Common, 3, Hunter, Destroy a random enemy minion., null, null, null, null, true, null)
ReferenceCard(GVG_001, Flamecannon, Spell, Goblins vs Gnomes, Common, 2, Mage, Deal $4 damage to a random enemy minion., null, null, null, null, true, null)
GvG added a bunch of 50% to attack wrong target cards.
ReferenceCard(GVG_054, Ogre Warmaul, Weapon, Goblins vs Gnomes, Common, 3, Warrior, 50% chance to attack the wrong enemy., null, 4, null, 2, true)
ReferenceCard(GVG_066, Dunemaul Shaman, Minion, Goblins vs Gnomes, Rare, 4, Shaman, <b>Windfury, Overload: (1)</b> 50% chance to attack the wrong enemy., [Windfury], 5, 4, null, true)
ReferenceCard(GVG_112, Mogor the Ogre, Minion, Goblins vs Gnomes, Legendary, 6, Neutral, All minions have a 50% chance to attack the wrong enemy., null, 7, 6, null, true)
ReferenceCard(GVG_065, Ogre Brute, Minion, Goblins vs Gnomes, Common, 3, Neutral, 50% chance to attack the wrong enemy., null, 4, 4, null, true)
ReferenceCard(GVG_088, Ogre Ninja, Minion, Goblins vs Gnomes, Rare, 5, Rogue, <b>Stealth</b> 50% chance to attack the wrong enemy., [Stealth], 6, 6, null, true)
What's the story with cardlist.csv?
I see there is a python script that generates a java file based off the csv, and the java file is used for the card picker in the GUI I imagine. Does that sound right?
Was the cardlist.csv file originally written by hand? I'd like to write something to produce a list of unimplemented cards, using java reflection (looking at classes), and comparing to the AllSets.json file. Probably I could replace this csv business in the process as well as long as I understand the use cases around it.
What's the plan for implementing secrets? I'm looking through the cards left to implement and secret related ones are a good chunk.
ReferenceCard(EX1_045, Ancient Watcher, Minion, Classic, Rare, 2, Neutral, Can't Attack., null, 4, 5, null, true, null)
ReferenceCard(EX1_298, Ragnaros the Firelord, Minion, Classic, Legendary, 8, Neutral, Can't Attack. At the end of your turn, deal 8 damage to a random enemy., null, 8, 8, null, true, null)
This weekend I had way too much extra time and dug deep into the battlecry code looking to find a more common solution for targeting and tracking actions. I found one but it ended up impacting every card with a targetable battlecry and has fairly drastic implications on how we handle things.
I'll try to get a PR out in the next few days but hopefully you aren't in the middle of any major refactoring. If so, I'll try to handle the merging so you don't have to.
I am moving the tests around to match the new card organization
Some auras aren't really "undoable". These need a different system.
ReferenceCard(NEW1_029, Millhouse Manastorm, Minion, Classic, Legendary, 2, Neutral, <b>Battlecry:</b> Enemy spells cost (0) next turn., [Battlecry], 4, 4, null, true, null)
ReferenceCard(EX1_315, Summoning Portal, Minion, Classic, Common, 4, Warlock, Your minions cost (2) less, but not less than (1)., [Aura], 0, 4, null, true, null)
ReferenceCard(DS1_178, Tundra Rhino, Minion, Basic, Common, 5, Hunter, Your Beasts have <b>Charge</b>., null, 2, 5, null, true, Beast)
ReferenceCard(GVG_122, Wee Spellstopper, Minion, Goblins vs Gnomes, Epic, 4, Mage, Adjacent minions can't be targeted by spells or Hero Powers., [Aura], 2, 5, null, true, null)
ReferenceCard(FP1_030, Loatheb, Minion, Curse of Naxxramas, Legendary, 5, Neutral, <b>Battlecry:</b> Enemy spells cost (5) more next turn., [Battlecry], 5, 5, null, true, null)
The game doesn't classify all of these as Auras but we can still implement that way for now.
How do you feel about reorganizing how the card files are laid out? If we group things by:
Then our subfolders won't continue to grow and grow as we implement new cards. It's already getting to be somewhat of a pain to deal with all of the Minion cards living in the same folder.
ReferenceCard(EX1_595, Cult Master, Minion, Classic, Common, 4, Neutral, Whenever one of your other minions dies, draw a card., null, 4, 2, null, true, null)
ReferenceCard(EX1_531, Scavenging Hyena, Minion, Classic, Common, 2, Hunter, Whenever a friendly Beast dies, gain +2/+1., null, 2, 2, null, true, Beast)
ReferenceCard(GVG_063, Bolvar Fordragon, Minion, Goblins vs Gnomes, Legendary, 5, Paladin, Whenever a friendly minion dies while this is in your hand, gain +1 Attack., null, 1, 7, null, true, null)
ReferenceCard(GVG_106, Junkbot, Minion, Goblins vs Gnomes, Epic, 5, Neutral, Whenever a friendly Mech dies, gain +2/+2., null, 1, 5, null, true, Mech)
ReferenceCard(GVG_116, Mekgineer Thermaplugg, Minion, Goblins vs Gnomes, Legendary, 9, Neutral, Whenever an enemy minion dies, summon a Leper Gnome., null, 9, 7, null, true, Mech)
ReferenceCard(GVG_040, Siltfin Spiritwalker, Minion, Goblins vs Gnomes, Epic, 4, Shaman, Whenever another friendly Murloc dies, draw a card. <b>Overload</b>: (1), null, 2, 5, null, true, Murloc)
Thermaplugg and Bolvar are the oddball ones, here.
So I've been doing all of this refactoring but I figured I should kind of write down how I'm expecting this to play out.
While I was working on implementing various cards I noticed a ton of common behaviors and started getting annoyed at how much copy/paste was happening. I began moving stuff into the Effect classes in order to group the logic and make the individual class files much lighter. Now, most new card implementations are about choosing from a library of known Effects.
The Filters that have been added were originally intended to be a way to apply effects across full groups of minions or to "pick one of these at random". After they were added, though, I realized that there was a whole bunch of duplicated looping logic for dealing with groups of minions.
So at this point, there are three main concepts behind card implementation:
The actual implementations are all over the place right now as I slowly convert the main game logic to understand and deal with these and, currently, this means there is some amount of overhead in the interactions. But the goal is to bring everything to a point where implementing cards just asks four questions:
Virtually everything from Battlecries to Spell Effects to Triggered Effects can be processed with these four questions and most Hearthstone cards reuse common answers to these questions.
The piece after that will be optimizing the performance and memory usage around Effects/Filters/Iterators. Right now, I am using a primary CharacterIterator and a HandIterator but there is opportunity to streamline that. Instead of worrying about those details right now, though, I'm getting the cards implemented and making sure there aren't any problems with the overall concept.
One of the hopes that I have for this is to define the Effects well enough that we can automatically save time/memory if we detect Effects that don't need, say, a full HearthTreeNode to operate. I just added a SimpleEffect interface in order to deal with the Auras and it seems to work just fine.
Hopefully that all makes sense to you and thanks for having the patience to let me rampage through the code base changing everything. :)
Hello,
I really liked the project and I am very interested in it. However, to understand it and be able to contribute, I would import it into an IDE (Eclipse or Netbeans). Is there a project created for any IDE? If not, how can I turn the source code in an IDE project?
Thank you very much.
Celso.
Currently, Aura handling is a mess and there are bugs associated with mind controlling (Mind Control, Cabal Shadow Priest, etc) a minion that applies Auras (Stormwind Champion, etc).
My current thinking is to move the Aura handling to BoardModel and adding a MinionWithAura interface that all minions with Aura effects implement. BoardModel will check for this interface in placeMinion(...) and removeMinion(...) and apply/remove any auras necessary through the interface.
As a head's up, I'm messing around with the deathrattles because I started working on Dark Cultist without realizing we didn't have a common mechanism for RNG targeting on deathrattle.
So... don't mess with Sylvanas. ;)
All of the various getCharacter variants are starting to bug me and I want to collapse things into a common pattern. Which of these is preferred?
public Minion getCurrentPlayerCharacter(int index) {
return getCharacter(PlayerSide.CURRENT_PLAYER, index);
}
public Minion getCharacter(PlayerSide playerSide, int index) {
PlayerModel playerModel = modelForSide(playerSide);
return index == 0 ? playerModel.getHero() : playerModel.getMinions().get(index - 1);
}
Example usage:
Minion cTargetMinion = cNode.data_.getCurrentPlayerCharacter(targetCharacterIndex);
Minion cTargetMinion = cNode.data_.getCharacter(PlayerSide.CURRENT_PLAYER, targetCharacterIndex);
I don't have a strong preference other than wanting only one.
ReferenceCard(EX1_145, Preparation, Spell, Classic, Epic, 0, Rogue, The next spell you cast this turn costs (3) less., null, null, null, null, true, null)
ReferenceCard(BRM_018, Dragon Consort, Minion, Blackrock Mountain, Rare, 5, Paladin, <b>Battlecry:</b> The next Dragon you play costs (2) less., [Battlecry], 5, 5, null, true, Dragon)
I noticed that gradle uses checkstyle and I can set that up to be more aggressive about unifying code style. Right now there are apparently a bunch of differences between our IDEs. What do you want for:
{
after a new block (e.g., if(blah && other) {
). Common choices are same line or new line.if(truthy) doSomething;
be if(truthy) { doSomething; }
?if
, for
(e.g. if (thisMinionPlayerSide == damagedPlayerSide) {
versus if(thisMinionPlayerSide == damagedPlayerSide) {
new DeathrattleDamageAll((byte) 2)
into new DeathrattleDamageAll((byte)2)
.)this.foo
?There are obviously lots of other settings but these are the ones I've seen matter recently.
I have a working version of importing spell damage numbers (e.g., 4 for Soulfire) in from the .json file. It is taking me a little time to convert all the constructors for spell cards to no longer need that value. This is just a head's up to let you know I'm messing with it.
I have these two minions implemented in a branch. After #66 gets merged I'll prep for another PR.
I'd like to setup this project to build itself on Travis. Would be nice to know that master is always green. Thoughts?
Hey, would you mind granting me collaborator access? It would easy workflow a little, and I'll keep my work to branches and pull requests. If not that's cool, I'll put up a pull request for updating travis email notifications as right now only collaborators get them.
Cheers,
-Kal
By using randomly generated decks, I've found a very strange bug that occurs very often with a variety of cards, but especially Dark Cultist. What seems to happen is that it first targets a valid minion, however, somewhere along the line the board state loses this minion so when it tries to find the index again it for some reason returns either an index greater than the size of the lists or -1 (which means it couldn't find it in the player's minion list).
I'm not entirely sure why this is happening, but I'm going to try and add functionality to the random deck generator (DeckFactory under util) to see if this issue can be isolated to a few cards or whether it is a problem on the part of the AI itself.
I would appreciate any insight into this because right now this bug is causing about 50% of random deck games to generate an exception.
For instance:
gradlew runSim -Phsparam="examples/example2/masterParams.hsparam"
Generates this output:
C:\Users\MrHen\Source\Repos\HearthSim>gradlew runSim -Phsparam="examples/example2/masterParams.hsparam"
Parallel execution is an incubating feature.
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:runSim
18:39:01,954 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@57a3af25 - Added status listener of type [ch.qos.logback.core.status.OnConsoleStatusListener]
18:39:01,987 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@57a3af25 - Setting ReconfigureOnChangeFilter scanning period to 10 seconds
18:39:01,987 |-INFO in ReconfigureOnChangeFilter{invocationCounter=0} - Will scan for changes in [[C:\Users\MrHen\Source\Repos\HearthSim\build\resources\main\logback.groovy]] every 10 seconds.
18:39:01,987 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@57a3af25 - Adding ReconfigureOnChangeFilter as a turbo filter
18:39:01,993 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@57a3af25 - Using current interpretation time, i.e. now, as time reference.
18:39:02,006 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@57a3af25 - About to instantiate appender of type [ch.qos.logback.core.FileAppender]
18:39:02,008 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@57a3af25 - Naming appender as [logfile]
18:39:02,103 |-INFO in ch.qos.logback.core.FileAppender[logfile] - File property is set to [log/debug.2015-04-20.log]
18:39:02,107 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@57a3af25 - About to instantiate appender of type [ch.qos.logback.core.FileAppender]
18:39:02,107 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@57a3af25 - Naming appender as [dangerLog]
18:39:02,113 |-INFO in ch.qos.logback.core.FileAppender[dangerLog] - File property is set to [log/danger_zone.2015-04-20.log]
18:39:02,119 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@57a3af25 - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
18:39:02,121 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@57a3af25 - Naming appender as [systemOut]
18:39:02,131 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@57a3af25 - Setting level of logger [ROOT] to ALL
18:39:02,137 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@57a3af25 - Attaching appender named [logfile] to Logger[ROOT]
18:39:02,139 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@57a3af25 - Attaching appender named [systemOut] to Logger[ROOT]
18:39:02,140 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@57a3af25 - Attaching appender named [dangerLog] to Logger[ROOT]
18:39:02.147 INFO HearthSimMain [main]: starting sim from file: examples/example2/masterParams.hsparam
18:39:02.217 ERROR HearthSimConstructed [Thread-1]: Error! com.hearthsim.exception.HSInvalidCardException: Unknown card: GoldshireFootman
18:39:02.220 ERROR HearthSimConstructed [Thread-1]: Error! com.hearthsim.exception.HSInvalidCardException: Unknown card: GoldshireFootman
18:39:02.221 ERROR HearthSimConstructed [Thread-1]: Error! com.hearthsim.exception.HSInvalidCardException: Unknown card: GoldshireFootman
18:39:02.223 ERROR HearthSimConstructed [Thread-1]: Error! com.hearthsim.exception.HSInvalidCardException: Unknown card: GoldshireFootman
18:39:02.225 ERROR HearthSimConstructed [Thread-1]: Error! com.hearthsim.exception.HSInvalidCardException: Unknown card: GoldshireFootman
18:39:02.225 ERROR HearthSimConstructed [Thread-1]: Error! com.hearthsim.exception.HSInvalidCardException: Unknown card: GoldshireFootman
18:39:02.226 ERROR HearthSimConstructed [Thread-1]: Error! com.hearthsim.exception.HSInvalidCardException: Unknown card: GoldshireFootman
18:39:02.231 ERROR HearthSimConstructed [Thread-1]: Error! com.hearthsim.exception.HSInvalidCardException: Unknown card: GoldshireFootman
18:39:02.232 ERROR HearthSimConstructed [Thread-1]: Error! com.hearthsim.exception.HSInvalidCardException: Unknown card: GoldshireFootman
18:39:02.233 ERROR HearthSimConstructed [Thread-1]: Error! com.hearthsim.exception.HSInvalidCardException: Unknown card: GoldshireFootman
18:39:02.237 INFO HearthSimConstructed [main]: completed simulation of 10 games in 0.07 seconds on 1 thread(s)
18:39:02.238 INFO HearthSimConstructed [main]: average time per game: 0.01 seconds
18:39:02.238 INFO HearthSimConstructed [main]: games won by player 1: 0
BUILD SUCCESSFUL
Total time: 2.184 secs
C:\Users\MrHen\Source\Repos\HearthSim>
I contacted yourkit about obtaining an open source license for profiling and they've agreed to it. We just need to add an acnkowledgement in the readme that we used it. Please contact me via email , [email protected] , as they would like first/last names for everyone getting a license and then I'll hook it up!
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.