Files
Wizard/wizard_server/game_logic/tests/test_rules.py
T
marvinandClaude Opus 5.5 21a2b044d9 Trump card: draw from the stack, no trump for wizards and jesters
- Deal the hands from the shuffled stack and draw the trump card from it,
  so the trump card is in nobody's hand and cannot be played
- A wizard or jester as trump card means no trump suit (previously a
  wizard let the dealer choose); remove the trump selection phase, the
  ChooseTrump action, the trump picker UI and the AI trump actions
- Completed tricks carry their round's trump card, so the table keeps
  showing the matching trump card while the last trick of a round is
  displayed
- Card corners are no longer rotated, so 6 and 9 cannot be confused
- Trump label explains why there is no trump (wizard, jester, last round)
- Tests: trump card never dealt, special cards give no trump, tricks keep
  their trump card

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 10:28:53 +02:00

89 lines
2.6 KiB
Python

from wizard_game import Suit, card_by_id
from wizard_game.cards import JESTER_ID_OFFSET, WIZARD_ID_OFFSET
from wizard_game.rules import lead_suit, legal_cards, round_score, total_rounds, trick_winner
def num(suit: Suit, rank: int):
return card_by_id(suit.index * 13 + rank - 1)
WIZ1 = card_by_id(WIZARD_ID_OFFSET)
WIZ2 = card_by_id(WIZARD_ID_OFFSET + 1)
JES1 = card_by_id(JESTER_ID_OFFSET)
JES2 = card_by_id(JESTER_ID_OFFSET + 1)
def test_total_rounds():
assert [total_rounds(n) for n in (3, 4, 5, 6)] == [20, 15, 12, 10]
def test_card_ids_are_consistent():
card = num(Suit.GREEN, 7)
assert card.suit is Suit.GREEN and card.rank == 7
assert WIZ1.is_wizard and JES1.is_jester
def test_lead_suit():
assert lead_suit([]) is None
assert lead_suit([num(Suit.RED, 3), num(Suit.BLUE, 5)]) is Suit.RED
assert lead_suit([JES1, num(Suit.BLUE, 5)]) is Suit.BLUE
assert lead_suit([JES1, JES2]) is None
assert lead_suit([WIZ1, num(Suit.BLUE, 5)]) is None
assert lead_suit([JES1, WIZ1, num(Suit.BLUE, 5)]) is None
def test_must_follow_suit():
hand = [num(Suit.RED, 1), num(Suit.BLUE, 2), WIZ1, JES1]
assert set(legal_cards(hand, [num(Suit.RED, 9)])) == {num(Suit.RED, 1), WIZ1, JES1}
def test_free_play_without_lead_suit_cards():
hand = [num(Suit.GREEN, 1), num(Suit.BLUE, 2), JES1]
assert set(legal_cards(hand, [num(Suit.RED, 9)])) == set(hand)
def test_free_play_after_wizard_lead():
hand = [num(Suit.RED, 1), num(Suit.BLUE, 2)]
assert set(legal_cards(hand, [WIZ1])) == set(hand)
def test_first_wizard_wins():
trick = [num(Suit.RED, 13), WIZ1, WIZ2]
assert trick_winner(trick, Suit.RED) == 1
def test_trump_beats_lead_suit():
trick = [num(Suit.RED, 13), num(Suit.BLUE, 2), num(Suit.BLUE, 5)]
assert trick_winner(trick, Suit.BLUE) == 2
def test_highest_lead_suit_wins_without_trump():
trick = [num(Suit.RED, 3), num(Suit.GREEN, 13), num(Suit.RED, 10)]
assert trick_winner(trick, None) == 2
assert trick_winner(trick, Suit.YELLOW) == 2
def test_jester_lead_then_suit():
trick = [JES1, num(Suit.GREEN, 2), num(Suit.RED, 13)]
assert trick_winner(trick, None) == 1
def test_only_jesters_first_wins():
assert trick_winner([JES1, JES2], Suit.RED) == 0
def test_round_score():
assert round_score(0, 0) == 20
assert round_score(3, 3) == 50
assert round_score(2, 0) == -20
assert round_score(1, 4) == -30
def test_trump_suit_from_trump_card():
from wizard_game.rules import trump_suit
assert trump_suit(num(Suit.YELLOW, 4)) is Suit.YELLOW
assert trump_suit(WIZ1) is None
assert trump_suit(JES1) is None
assert trump_suit(None) is None