Nothing like a good ol' game of ModTen Disclaimer: ModTen is a fictional card game which was created for the sole purpose of this challenge.

The rules of ModTen

ModTen is played with a standard 52-card deck. Because the full rules are yet to be invented, we're going to focus on the hand ranking exclusively.



A winning hand in ModTen. Graphics from Wikipedia.

Card values

The cards have the following values:


2 to 9: worth their face value
Ten: 0 point
Jack: 3 points
Queen or King: 8 points
Ace: 9 points


Hand values


A ModTen hand is made of two cards. The base value of a hand is obtained by multiplying the value of both cards together and keeping the last digit only (i.e. applying a modulo 10).

For instance, the value of 7♥ - Q♣ is "\$6\$", because \$(7\times8)\bmod 10=6\$.
The only other rule in ModTen is that suited cards are worth more than unsuited ones. By convention, we are going to append a "s" to the value if both cards are of the same suit.

For instance, the value of 9♠ - 5♠ will be noted as "\$5\text{s}\$", because \$(9\times5)\bmod 10=5\$ and the cards are suited.


Hand ranking and winner

The above rules result in 18 distinct hand ranks which are summarized in the following table, from strongest to lowest (or rarest to most common). The probabilities are given for information only.

Given two hands, the hand with the lowest rank wins. If both hands are of the same rank, then it's a draw (there's no tie breaker).

 hand rank | hand value(s) | deal probability
-----------+---------------+------------------
     1     | 9s            | 0.30%
     2     | 3s            | 0.60%
     3     | 1s            | 0.90%
     4     | 7s            | 1.21%
     5     | 5s            | 1.51%
     6     | 3             | 1.81%
     7     | 9             | 2.26%
     8     | 8s            | 2.71%
     9     | 6s            | 3.02%
    10     | 1 or 7        | 3.62% each
    11     | 2s or 4s      | 3.92% each
    12     | 5             | 4.98%
    13     | 0s            | 5.43%
    14     | 8             | 8.14%
    15     | 6             | 9.95%
    16     | 2             | 11.76%
    17     | 4             | 13.57%
    18     | 0             | 16.74%


The challenge

Given two ModTen hands, output one of three consistent values of your choice to tell whether:


the first player wins
the second player wins
it's a draw


The following rules apply:


A card must be described by its rank in upper case (2, 3, ..., 9, T, J, Q, K or A) followed by its suit in lower case (c, d, h or s, for clubs, diamonds, hearts and spades).
You may use "10" instead of "T" but any other substitution is prohibited.
As long as the above rules are followed, you may take the hands in any reasonable and unambiguous format. You are allowed to take the rank and the suit as two distinct characters rather than a single string.

Some valid input formats are:


"7c Qh 8s Ks"
[["7c","Qh"], ["8s","Ks"]]
[[['7','c'], ['Q','h']], [['8','s'], ['K','s']]]
etc.

Instead of using 3 consistent distinct values, your output may also be negative, positive or zero. Please specify the output format used in your answer.
This is code-golf.


Test cases

Player 1 wins

["Js","3s"], ["Ks","Kh"]
["7h","9h"], ["9s","7c"]
["Ah","5s"], ["Ts","8s"]
["Ts","8s"], ["Jh","2s"]
["4h","8s"], ["Qh","Ks"]


Player 2 wins

["Th","8d"], ["6s","Kd"]
["Jc","5c"], ["3s","9s"]
["Jc","Jd"], ["9h","Ah"]
["2d","4d"], ["3h","3s"]
["5c","4c"], ["3c","2c"]


Draw

["Js","3s"], ["3d","Jd"]
["Ah","Ac"], ["3d","9s"]
["Qc","Kc"], ["6d","4d"]
["2d","3d"], ["3s","2s"]
["Ts","9c"], ["4h","5d"]
Python 3, 114 110 bytes

lambda m,n:p(*n)-p(*m)
R=b&quot;T 2J45UNK9RL&lt;3SLM;QAK:O&gt;=/678&quot;
v=R.find
p=lambda i,s,j,t:R[s==t::2][v(j)*v(i)%10+3]

Try it online!
@Arnauld proposed the idea of merging the card value and rank table strings. After some attempts I managed to craft a merged string R=&quot;T 2J45UNK9RL&lt;3SLM;QAK:O&gt;=/678&quot;, which has the same length as the original card value string. The substring R[6:25]=&quot;UNK9RL&lt;3SLM;QAK:O&gt;=/&quot; serves as the rank table as well as a card value lookup table for 3, 9, A, K, and Q. The ASCII-value decoding of the new rank table has the same ranking effect as the previous rank table.
Using byte strings as input saves 4 bytes.
Using cmp in Python 2 can reduce the solution to 102 bytes, as shown by @xnor's solution.

Python 3, 165 142 130 129 bytes

lambda m,n:p(*n)-p(*m)
v=&quot;T 23456789   J    QA        K&quot;.find
p=lambda i,s,j,t:ord(&quot;HC92FA51GAB4E893D760&quot;[s==t::2][v(j)*v(i)%10])

Try it online!
-23 bytes thanks to @Jonathan Allan
-2 bytes thanks to @ovs
-1 byte thanks to @mypetlion
Ungolfed:
f = lambda hand1, hand2: get_rank(*hand2) - get_rank(*hand1)
def get_rank(v1, suit1, v2, suit2):
    get_card_value = &quot;T 23456789   J    QA        K&quot;.find
    # rank_table = [[17,9,15,5,16,11,14,9,13,6],[12,2,10,1,10,4,8,3,7,0]]
    # rank_table = (&quot;H9F5GBE9D6&quot;,&quot;C2A1A48370&quot;) # Base-18 encoding of ranks
    rank_table = &quot;HC92FA51GAB4E893D760&quot; # Interleaved base-18 encoding

    # ASCII-value decoding has the same ranking effect as base-18 decoding
    return ord(rank_table[suit1 == suit2::2][get_card_value(v2) * get_card_value(v1) % 10])

The function f takes two arguments representing the hand of player 1 and player 2. It returns a positive, negative, or zero value in the case of a player 1 win, a player 2 win, or a draw, correspondingly. Each hand is encoded as a single string, e.g. &quot;7cQh&quot;.