3
\$\begingroup\$

Jass is a trick-taking game for four players and the national card game of Switzerland. It is played with a 36-card deck, four suits each with ranks 6, 7, 8, 9, 10, J, Q, K, A. We will be using French suits and ranks here for familiarity; German cards are more commonly used but this does not change the essence of gameplay.

Each deal is played in one of six ways: either there is a trump suit or it is the notrump Obenabe or Undenufe. The card ranking in each of these contracts is

  • Trump suit: (high) J, 9, A, K, Q, 10, 8, 7, 6 (low)
  • Side suits in a trump suit game, Obenabe: (high) A, K, Q, J, 10, 9, 8, 7, 6 (low)
  • Undenufe: (high) 6, 7, 8, 9, 10, J, Q, K, A (low)

What sets Jass apart from other trick-taking games is that you may play a trump on a non-trump lead even if you could otherwise follow suit. The full card play rules follow – in the following situations you must play a card from the corresponding set if that set is nonempty, otherwise you may play any card:

Situation Set
Obenabe/Undenufe Cards of led suit
Trump suit, non-trump lead, can follow suit Cards of led suit and overtrumps
Trump suit, non-trump lead, cannot follow suit All cards except undertrumps
Trump suit, trump lead Trumps except trump jack

Here an overtrump is a trump higher than all trumps played to this trick so far; it may win this trick. An undertrump is the opposite, one that cannot win this trick. You can never be forced to play the highest trump, the jack, over other cards.

As usual, a trick is won by the highest trump in it if there is one, else by the highest card of the suit led, and the winner of a trick leads to the next.

Task

Given a 9×4 matrix of cards representing the play of a Jass deal and a game type (♧◇♡♤ trump or Obenabe or Undenufe), determine whether all the card play rules were followed and output a truthy or falsy value accordingly.

The four columns of the matrix represent the four players' hands in playing order going to the right and cycling back, and the nine rows are the tricks in chronological order downwards. The initial lead is the top-left entry of the matrix.

Here is an example matrix for a deal with hearts as trump:

h9 s6 h7 hQ
h6 s7 hJ hA
sQ s9 sA d8
hT sK sT c8
s8 d6 sJ cJ
cA cK c9 cQ
c6 cT h8 dJ
c7 d7 dQ dA
hK d9 dK dT

The first player leads the ♡9 and it wins the trick, so he leads the second trick with ♡6. That is won by the third player with ♡J, so he leads to the third trick with ♤A. And so on.

You may assume that all 36 cards are included in the matrix. You may use any reasonable format to represent the cards and the matrix of cards, but that representation must be the same across the six game types.

This is ; fewest bytes wins.

Test cases

The game type is indicated above the play matrix, cdhs for the corresponding trump suit or ou or Obenabe/Undenufe. For clarity each trick winner is bracketed – you may not take in this additional information.

Truthy

h
(h9)s6 h7 hQ
 h6 s7(hJ)hA
 sQ s9(sA)d8
(hT)sK sT c8
 s8 d6(sJ)cJ
(cA)cK c9 cQ
 c6 cT(h8)dJ
 c7 d7 dQ(dA)
(hK)d9 dK dT

This is the example matrix above. The first two tricks demonstrate the elevated trump jack and nine (Puur, Nell). The fourth and seventh tricks show that you can play trumps even when you can follow suit.

c
(c9)s6 cT c8
 h7 hA(c6)h6
 d9 d7 d6(dA)
 s9(hK)h9 hJ
 dT(dK)h8 dQ
 sK(sA)sJ s7
 cK hQ(cA)hT
(cQ)sQ sT s8
 c7(cJ)dJ d8

The first trick demonstrates holding up the Puur as only trump on a trump lead. The seventh trick shows that you can undertrump if you have no other choice.

u
(c6)cA cT cJ
(c7)cK cQ c8
 h7(h6)hK h8
 hQ hT c9(h9)
 d9 dA dK(d6)
 d8(d7)dT dQ
 s9(hJ)sA hA
 sQ sK sJ(s6)
 s8 sT s7(dJ)

An Undenufe round, showing the inverted rankings.

o
 c6 s6(cK)c9
 cJ s7(cQ)c8
(cA)d9 cT h6
(c7)sJ hK d7
 sQ hQ(sA)s9
 hJ(hA)h7 dJ
 s8(hT)h9 sK
 d8(h8)d6 sT
 dT dK dQ(dA)

An Obenabe round, analogous to notrump in bridge.

Falsy

d
 cQ c9 c8(cA)
 hJ h9(hA)h6
(d9)dK h8 hQ
(sA)s6 sQ sJ
(sK)s7 s9 c6
(hK)s8 cJ h7
 cT dT(dQ)c7
(dA)sT d8 cK
 d7(dJ)d6 hT

In the third trick here the second player undertrumped when it could be avoided, which is not allowed. All other plays are legal.

u
(d6)dK dJ dA
(d7)dT sJ dQ
(d8)h9 hQ d9
(h6)hT sA hJ
(h7)sQ cQ hK
 s7(s6)sT sK
 cA cK(c9)s9
 s8 c8(c6)cT
 hA(c7)cJ h8

In the seventh trick the fourth player did not follow suit.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Feels like I'm just doing your homework for you for some college class. But I did write a script to calculate winners, but your test cases seem to be wrong. You say "Trump suit: (high) J, 9, A, K, Q, 10, 8, 7, 6 (low)", but your test cases with a trump suit don't follow that ranking consistently.

My script is already quite long and hasn't even come close to the full extent of what the question is asking. This just calculates the winner of the tricks. I might finish it another day if I feel like it, not sure.

#!/usr/bin/emacs --script
(require 'cl-lib)
(setq trump (pop argv))
(setq tricks (read argv))
(setq rankings (list
                (cons "A" 14)
                (cons "K" 13)
                (cons "Q" 12)
                (cons "J" 11)
                (cons "T" 10)
                )
      )

(defun test (tester leader)
  (if (string= (car tester) (car leader))
      (funcall (if (string= trump "u") #'<
                 (if (string= trump "o") #'>
                   #'(lambda (a b)
                       (if (= a 11) t
                         (if (= b 11) nil
                           (if (= a 9) t
                             (if (= b 9) nil
                               (> a b)
                               )))))))
               (cdr tester) (cdr leader))
    (if (string= (car tester) trump)
        t
      nil
      )
    )
  )
(setq dealer-index 0)
(defun winner (trick)
  (let ((m (elt trick dealer-index)))
    (cl-loop for c in trick do
             (if (test c m)
                 (setq m c)
               )
             )
    m
    )
  )
(cl-loop for trick in tricks do
         (cl-loop for c in trick do
                  (let ((fs (if (eq (winner trick) c) "(%s%s)"" %s%s ")))
                   (princ (format fs (car c)(or (car (rassoc (cdr c) rankings)) (cdr c))))
                   )
                  )
         (setq dealer-index (cl-position (winner trick) trick))
         (princ "\n")
         )
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.