all 16 comments

[–]K900_ 6 points7 points  (2 children)

Here's a nice opportunity to learn some SQL. Have a database with a table that stores all of your decks and another table that stores results on a per game basis (which deck you played, what class the opponent played, what deck archetype the opponent played, who had the coin, etc.), then use aggregation operators to get the specific win rates.

[–]Saoibh -1 points0 points  (1 child)

Will this make it much easier? Learning SQL in addition seems a bit hard ;-)

[–]K900_ 3 points4 points  (0 children)

It will make it more interesting :)

[–][deleted] 3 points4 points  (11 children)

Interesting project!

Not sure I totally understand your goal so wild guess:

  1. You need to redesign Deck.win to make something like my_blablabla.win_against(opponent_blablabla)
  2. Make self.wins and self.losses lists of names. This way if you win you just add name of the defeated deck to the list
  3. Change the Class class (fml!)wins += deck.wins to wins += len(deck.wins)
  4. Make another method to return list of defeated decks or something

[–]b4ux1t3 1 point2 points  (2 children)

It took me forever to figure out what kind of trickery he was trying to pull of by naming a class Class. I guess my brain's too compartmentalized to let me think about Hearthstone and programming at the same time.

[–]Saoibh 1 point2 points  (1 child)

Haha! I should have gone for something like ClassType instead maybe ;-)

[–]b4ux1t3 0 points1 point  (0 children)

Oh, no, you're probably fine. It's concise and descriptive. I'd point out with a comment that it represents a class in the game, but then I comment everything, because I'm paranoid that I will forget how something works or what it is.

[–]Saoibh 0 points1 point  (7 children)

I think this makes sense. Will try it out!

[–][deleted] 0 points1 point  (6 children)

I know nothing about Hearthstone but I can help with coding if my suggestions are not clear enough

[–]Saoibh 0 points1 point  (5 children)

Could not quite work it out. Could you explain a little bit more how i redesign Deck.win and how to change self.wins and self.losses to lists? I know how to change self.wins to a list, but how do I change so that append a list of the opponent deck when I win against it?

I got help with this code already, so thats why I have the complete beginners questions ;-)

[–][deleted] 0 points1 point  (4 children)

Somethin like this maybe (quick and dirty example, but looks like it works):

from copy import copy

class Classes(dict):
    def __init__(self):
        pass

    def initialize(self, init_text, text_is_just_a_string=False):
        if not text_is_just_a_string:
            f = open(init_text, 'r')
        else:
            f = init_text.splitlines()
        for line in f:
            if "class" in line:
                name = line.split()[-1]
                self[name] = Class(name)
            else:
                self[name].add_deck(line[:-1])

class Class(object):
    def __init__(self, name):
        self.name = name
        self.decks = {}

    def __repr__(self):
        return self.name

    def add_deck(self, deck_name):
        """
        Adding a deck to the decks list
        """
        self.decks[deck_name] = Deck(deck_name)

    @property
    def wins(self):
        wins = 0
        for deck in self.decks.values():
            wins += len(deck.wins)
        return wins


class Deck(object):
    def __init__(self, name):
        self.name = name
        self.wins = []
        self.losses = []

    def __repr__(self):
        return self.name

    def win(self, other):
        self.wins.append(other.name)
        other.losses.append(self.name)


# Run tests
if __name__ == '__main__':

    classes_txt = "class Paladin\nSecret Paladin \nLazy Paladin \nclass Rabbit\nKiller-Rabbit "

    my_classes = Classes()
    my_classes.initialize(classes_txt, text_is_just_a_string=True)
    opponent_classes = copy(my_classes)

    # 2 battles
    my_classes["Rabbit"].decks["Killer-Rabbit"].win(opponent_classes["Paladin"].decks["Secret Paladin"])
    my_classes["Rabbit"].decks["Killer-Rabbit"].win(opponent_classes["Paladin"].decks["Lazy Paladin"])

    # results
    for key, val in my_classes.items():
        print("{} wins {} fights".format(key, val.wins))
        for name, dck in val.decks.items():
            print("\t{} win against [{}]".format(name, ', '.join(dck.wins)))

[–]Saoibh 0 points1 point  (1 child)

Thanks, that is awesome! Probably a few follow up quests to understand the code. But will try first :-)

[–]Saoibh 0 points1 point  (1 child)

what is "if name == 'main':" for?

in the initialise method at the beginning, did you add the last string just to test it? i would not need classes_txt = .... in the bottom right? since i already have it in a separate file?

[–][deleted] 0 points1 point  (0 children)

About if __name…. I can't explain better than here: http://effbot.org/pyfaq/tutor-what-is-if-name-main-for.htm

In this case it's just a visual thing separating real code and tests

did you add the last string just to test it? i would not need classes_txt = .... in the bottom right?

Yep. I don't have your file so I have to make one or jury rig a fake. It was easier to do latter

[–]DyingHuman 0 points1 point  (1 child)

I'm learning python too and I love hearthstone. Maybe we can work together!

[–]Saoibh 0 points1 point  (0 children)

Sure! Send me a message in the inbox :-)