soydos/pusoy_dos2

Structure Ideas

Closed this issue · 5 comments

Couple of ideas for simpler/flexible structure.

Cards

I think cards only need to have rank and suit, and possibly joker/wildcard flag.

{
  rank: enum,
  suit: enum,
  joker?: boolean,
}

Jokers

Feels a bit dirty having the joker flag, and before a joker is played, it has no rank or suit, so maybe the rank and suit enum can contain a Joker type. Then a joker would be

{
  rank: Rank.Joker,
  suit: Suit.Joker
}

If we assume that joker is always the strongest possible card, the comparisons don't even need to know anything extra like intended rank and suit. Not sure how feasible this is though, seems tricky to make the comparison function work out the best value for the joker, and would probably cause confusion amongst players if we didn't display a real value.

Maybe best is to do it this way but have a separate struct for PlayedCard which has intended rank/suit value.

Rules

Currently rules are made up of suit order and reversed boolean.
Might be worth thinking about having the rules made up of suit order and rank order.
Then instead of setting reversed = true we would just reverse the suit order and rank order arrays.
Seems a little more complicated, but it simplifies comparison, and allows for potential complex rulesets,
e.g. suits reverse but ranks stay the same, 3's become top card, or "chess mode" where kings are the weakest.

Probably we don't need such complicated game rules, but if it isn't too difficult to implement, then there are no downsides compared to the current way.

Actually rules also include hands, and player order, though they feel different to the comparison rules. If we could incorporate a way to represent them too in the rules, then potentially we could have very different games using the same code, just by writing new rules.

@benbrunton
check out the simple_cards branch of all three repos (need to have all three on that branch to work) for an implementation of the above cards system. I've managed to get rid of a few structs (SuitContext and HandCard) and retain the same functionality (that I can tell).
I haven't done anything on rules, and in fact the sorting is still based on the card types enums, not game rules or anything.

I'm on board with the idea of simple cards and keeping the rules within the game, but I'm not a fan of having a suit and rank of Joker. I'm much happier keeping the bool on PlayedCard and having a card of type enum to handle the joker. It could look something as simple as :

pub enum Card {
    Face(Rank, Suit),
    Joker,
}

But I believe this more accurately represents the joker model.

Take a look at simple_cards2 branch on this repo and pd-ui. It's actually a bit simpler than simple_cards too. Still a lot of work to be done in order to work the comparisons, but I think the general idea of making cards dumb holds. I also stand by the model of having Jokers distinct from standard cards!

Let me know what you think so we can move forward and put in some functionality!

Looks good, I made some small adjustments.

  • Made the Standard a struct instead of tuple. Makes it much nicer on the frontend, and I prefer the explicitness of having named rank and suit.
  • I also added some serde attributes which make it easy for the frontend.
  • I also made jokers work. Though they are just 2♠ for now until we add the select Rank/Suit feature.
  • The text displaying the hand also indicates if a joker is used or not.

I made a simplified version of some way we might do the sorting/comparisons. Only uses rank but trivial to add suit sorting too (same as your original method in cards)

sort:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=5afa0884dbda3d98a971ee4273744c6d

compare:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=abe537f3381d7e1248c8c33863a8d7c8

I'm sure there's a cleverer, more efficient way to do it, my rust is just too rusty.