Tavern Brawls in Fireplace

This has been a fun couple of weeks with commits from two new contributors! I’m very happy about the generally positive feedback on the quality of Fireplace. I even wrote some contributing guidelines for the occasion.

Since Tavern Brawls have come out, I have been focusing on separating rules from the Game object itself. 14f7e61 begins the separation by creating a BaseGame object and removing The Coin (random start) and Mulligan from it.

The default Game object is now declared as Game(MulliganRules, CoinRules, BaseGame). This is one of the rare times where mixins actually shine.

It’s very elegant, but still not ideal. I would much prefer a system where I can declaratively write rules for the Game object, just like I write them for regular Cards. Brawls could reuse such a system as well.

The first three Brawls are now implemented:

None of them was particularly hard once the mechanics for them were in place. Banana Brawl was the trickiest of the bunch, requiring a slight rework of death preparation logic to allow for subclassing. In addition, I had to implement caching in RandomCardGenerator so that I could simply implement the “random banana” logic as a RandomBanana evaluator:

class RandomBanana(RandomCardGenerator):
	cards = ("EX1_014t", "TB_006", "TB_007", "TB_008")

Since cards is a property on RandomCardGenerator, I could just override it with a static list. It’s worth noting that in the real Banana Brawl, the picks are probably weighted. This would still be very easy to do, by overriding the pick() method which simply calls random.choice() in the default implementation.

As a sidenote, the Wild Magic Hero Power was the original reason why I started working on Shuffle and Copy. Even though they don’t look related at first glance, down the line, they led to the implementation of recursive actions which I used for Unstable Portal, and now Wild Magic.

Week 4 is currently running. Near-unanimously acclaimed as the most fun Brawl yet. I’m excited to implement it in Fireplace, though I am running up against the issue of intercepting Play actions. I’ll figure it out.

In unrelated news, the codebase has been moved to under_score-style variable/method naming, to align with PEP8. While I don’t agree with all its recommendations, naming style is something I believe should align as much as possible with the official language style. That move accounts for a huge part of the diff below.

50 files changed, 2450 insertions(+), 2177 deletions(-)