HearthSim / Hearthstone-Deck-Tracker

A deck tracker and deck manager for Hearthstone on Windows
https://hsreplay.net/downloads/
4.74k stars 1.12k forks source link

Issue with card age when opponent draws multiple card in the same turn #470

Closed bakkandris closed 9 years ago

bakkandris commented 9 years ago

After some turns I have noticed that the age of the newly drawn opponents cards is higher than the current turn count. This I believe can happen when the opponent draws more than one card in the same turn.

HS Log: http://pastebin.com/6An4iLQN Deck Tracker Log: http://pastebin.com/25sNeSiE

It looks to me that (probably after the GvG update) HS logs much more [Power] lines than before which makes the end of turn detection unreliable. (_turnCount gets incremented more often than it should)

azeier commented 9 years ago

The numer of power lines logged looks like the perfect call. Setting the threshold to 30 seems to work, I'll test this for a bit today.

bakkandris commented 9 years ago

I'm note sure if using a threshold is a good solution. At one point while testing I had a _powerCount of 85. Is there no other way to detect the end of the turn?

azeier commented 9 years ago

I strongly agree, but at least pre-gvg I was not able to find one.

bakkandris commented 9 years ago

What about the following lines:

[Power] GameState.DebugPrintPower() - TAG_CHANGE Entity=BVA64 tag=CURRENT_PLAYER value=0 [Power] GameState.DebugPrintPower() - TAG_CHANGE Entity=The Innkeeper tag=CURRENT_PLAYER value=1

These two lines seem to indicate that one players turn ended tag=CURRENT_PLAYER value=0 and the others has started tag=CURRENT_PLAYER value=1.

bakkandris commented 9 years ago

After some testing I found that the above is not 100% reliable either. Under some circumstances HS fails to log the change of the current player.

As an alternative I can see checking the "player" element from a Zone line for changes:

[Zone] ZoneChangeList.ProcessChanges() - id=57 local=False [name=Stampeding Kodo id=61 zone=PLAY zonePos=3 cardId=NEW1_041 player=2] zone from OPPOSING HAND -> OPPOSING PLAY

1 is the player. 2 is the opponent.

azeier commented 9 years ago

The problem with that is that you need to distinguish "start of turn draws" and draws from card effects. I have not yet been able to test how reliable the threshold at 30 is, but maybe combining it with the CURRENT_PLAYER tag might work.

bakkandris commented 9 years ago

I came to the same conclusion. :(

One could also check the color of the end turn button in a similar fashion as the golden card detection is done.

azeier commented 9 years ago

The button has a tendency to not flip if you press it too fast on the first turn :). Plus it has good chances of being hidden by things. I think power messages are still the way to go.

azeier commented 9 years ago

To explain a little further actually, this distinguishing is exactly what the power message count is used for. Most of them are logged at the end of a turn (some kind of "cleanup"?) , which is why the threshold works. Whether it's 80 or 30 does not really matter, what matters is that during the turn there's no more than 30 of those logged. Before GvG, there were never more than ~13 during a turn and I can't imagine that this did fundamentally change.

bakkandris commented 9 years ago

What about checking for power messages above the threshold uninterrupted by any zone messages (or zone messages caught by one of the regexps)? This would avoid possible miracle rouge style long turns to be considered as two turns.

But I agree that the existing solution would work probably for 99% of the cases.

azeier commented 9 years ago

I wasn't really aware of this myself (it's been too long since I touched that code), but that's pretty much what happens: https://github.com/Epix37/Hearthstone-Deck-Tracker/blob/master/Hearthstone%20Deck%20Tracker/HsLogReader.cs#L557

bakkandris commented 9 years ago

Right! I missed that bit.

bakkandris commented 9 years ago

Some further data. In the linked game I had the following situation: Opponent turn: Round 3 (based on available mana on screen), Drawn card numbered as 4 Round 8: Drawn card number 10 (should have been 9 considering the previous glitch in round numbering) BUT Round 9: Card number still 10!

Tracker log: http://pastebin.com/Zw8pJ4YS HS Log: http://www.mediafire.com/download/9y4dw5qg223v6oe/output_log.zip

azeier commented 9 years ago

Is that with the threshold being at 13 or at 30?

Edit: After playing with 30 a bit, it actually missed a regular draw. Trying 25 now.

bakkandris commented 9 years ago

I was playing with 30. However in the same game above I had bot issues. Missed a draw and also had the round number incremented during a turn. Maybe if more approaches are combined it will become more reliable.

azeier commented 9 years ago

changed to 25 with v0.6.6, seems to be at least more reliable for now.

Combining is tricky though. If you increment the turn on either, chances of accidentally incrementing multiple times are pretty high I think.

The solution might be more agressive resetting of the counter. I tried doing it with all zone messages but that didn't work at all.

bakkandris commented 9 years ago

I would combine them like this:

  1. tag=CURRENT_PLAYER, no false positives, if it is there then it means end of turn (worked from me 90% of the time)
  2. if not 1, color of the end turn button can be checked. Glitches of the button could be mitigated by checking the right half of the button which is usually ok even when glitched. Also we can detect glitches if the result is off from the expected average colors and ignore the result.
  3. if all else fails we can use the threshold as now.

Not sure if 2 is worth the effort but it is your call.

bakkandris commented 9 years ago

Another way: look for

[Power] GameState.DebugPrintOptions() - option 0 type=END_TURN mainEntity=

Hopefully this is written for all turn ends.

azeier commented 9 years ago

That does look promising as well! So many new logs since GvG, I really need to have a closer look at the logs again.

azeier commented 9 years ago

[Power] GameState.DebugPrintOptions() - option 0 type=END_TURN mainEntity=

Seems to be logged whenever there's nothing left to do for the player (and, at least against AI, on every opponent turn). Pressing the end turn button does not trigger it.

azeier commented 9 years ago

Okay, I changed it to tag=CURRENT_PLAYER and type=END_TURN now. Judging from the game I played, it seems to work pretty reliably.

thesh0ck commented 9 years ago

The logs show the number of turns in play each card has been with:

TAG_CHANGE Entity=[name=Elven Archer id=31 zone=PLAY zonePos=2 cardId=CS2_189 player=1] tag=NUM_TURNS_IN_PLAY value=1

As far as I can see, everything is logged now in detail. You shouldn't have to specify any limit to how much/little you read. There are clear markers for everything, so logs should just be acted upon as information comes in... the players each line is for are clearly defined so you don't have to do anything special but parse each line independently and apply it to whatever player it belongs to. (either by player= or by the unique id's every thing has that tie it to a player as well.)

I see you saw my other comment where I went into detail on the new logs so I wont go on and on, but you really should look at them. You could do some amazing stuff now and do the stuff you did before. much more easily.

--sh0ck

azeier commented 9 years ago

This seems to be fixed with #494

bakkandris commented 9 years ago

Yes. It is fixed.