Search for good deck#59
Conversation
|
Among 10 champions found with We see that green is super dominant, which makes a lot of sense since it has the best vanilla creatures (3/3 for 2, 4/5 for 3, 10/10 for 5: |
…rch-for-good-deck
gcoter
left a comment
There was a problem hiding this comment.
Your code is very clean, well done! I made some comments but we can implement them later, so feel free to merge if you want 🙂
| creature_color_filter = self.legal_creatures_df["color_identity"] == f"['{color}']" | ||
| creature_card_names = self.legal_creatures_df[creature_color_filter]["name"].unique() | ||
| land_color_filter = self.legal_lands_df["color_identity"] == f"['{color}']" | ||
| land_card_names = self.legal_lands_df[land_color_filter]["name"].unique() |
There was a problem hiding this comment.
These variables are relatively constant (they only vary depending on the color) so it would probably be more optimal to create them once and reuse them in add_a_card_at_random (currently if I understand well, they are recomputed at each iteration of the for loop above
| from magic_the_gathering.players.random import RandomPlayer | ||
|
|
||
|
|
||
| def print_execution_time(func): |
There was a problem hiding this comment.
I like the idea of creating a decorator 👍
|
|
||
| def _get_colors_of_deck(deck: OrderedDict[str, object]) -> list[str]: | ||
| color_identities = [card.color_identity for card in deck.values()] | ||
| return list(set([color for color_identity in color_identities for color in color_identity if color != "C"])) |
There was a problem hiding this comment.
What does it mean when the color identity if "C"?
| ) | ||
| # print( | ||
| # f"Probability that decks are equivalently powerful with {wins_of_player_with_most_wins} wins out of {games_count}: {p_decks_are_equivalently_powerful}" | ||
| # ) |
There was a problem hiding this comment.
If you think this print is not relevant anymore, you can remove it rather than commented
| return 0 if wins_count / games_count >= 0.5 else 1 | ||
|
|
||
|
|
||
| def simulate_one_game(decks: list[OrderedDict[str, object]]) -> int: |
There was a problem hiding this comment.
Maybe we could group functions like this one in a module, because otherwise we might duplicate code in different scripts (for instance, run_competition_between_players.py has similar code I think)
| return decks | ||
|
|
||
|
|
||
| def create_hands(game_state: GameState): |
There was a problem hiding this comment.
I introduced the MulliganPhase recently, it could replace this function
| legal_lands_df, | ||
| legal_creatures_df, | ||
| deck_size=20, | ||
| lands_proportion=17 / 40, |
Adds a script to make decks fight each other using the random strategy until a "champion deck" is found.
Looks for an arena champion deck until one is found.
A champion deck is a deck that is tested as significantly better than a random deck
consecutive_test_wins_thresholdtimes in a row.
To identify whether a deck is significantly better than another, we run up to
games_limit_per_testgames between thetwo decks and stop as soon as the probability for the record obtained to happen under the assumption of 50% winrate
is lower than
p_value.The script can be run with
Or on Windows
Output examples (40 cards,
p_value= 0.05, up to 50 games per match-up):Looks like a solid vanilla deck to me, mostly good stats for the cost
Also, started to explore looking for a good deck by upgrading one over and over, by changing one card at random and checking if the new deck beats the old one.