Qual è il punteggio della mia mano Scopa?


14

Mi piacciono le sfide del gioco di carte, quindi l'ho realizzato per il gioco di carte italiano Scopa. La mia famiglia gioca a questo gioco da tempo immemorabile. Ha un sistema di punteggio molto interessante che dovrebbe essere divertente da giocare a golf. Invierò una risposta in R per iniziare il divertimento, che sono sicuro che le persone miglioreranno.

La sfida: capire il numero di punti segnati in un round di Scopa, date le carte che il giocatore ha catturato durante il round come input.

Ci sono 40 carte in un mazzo Scopa. Se stai usando un mazzo internazionale rimuovi 8, 9 e 10, lasciando A, 2,3,4,5,6,7, Q, J, K in ogni seme. 1 Ci sono due giocatori o due partenariati e, dopo ogni round, tutte le carte vengono catturate da uno o l'altro dei due giocatori. Il punteggio viene conteggiato come segue (maggiori informazioni qui ):

  • Il giocatore con il maggior numero di carte ottiene 1 punto.
  • Il giocatore con il maggior numero di diamanti (o monete se utilizza il mazzo italiano) ottiene 1 punto.
  • Il giocatore con il 7 di diamanti (o monete), noto come il sette bello o bello sette, segna 1 punto.
  • Il giocatore con la primaera più alta ottiene 1 punto. Il punteggio Primiera di un giocatore è la somma dei punteggi della carta di valore più alto che il giocatore ha catturato in ogni seme (vedere la tabella sotto). Se non hai almeno una carta in ogni seme, perdi per impostazione predefinita anche se il tuo punteggio supererebbe il punteggio del tuo avversario. Nel caso estremamente raro che nessuno dei due giocatori abbia almeno una carta in ogni seme, il giocatore con il totale di primiera più alto segna il punto. 2

Tabella dei punteggi dei primiera

| Rank  | Value |
| ----- | ----- |
| 7     | 21    |
| 6     | 18    |
| A     | 16    |
| 5     | 15    |
| 4     | 14    |
| 3     | 13    |
| 2     | 12    |
| Q,J,K | 10    |

Quindi un giocatore può segnare al massimo 4 punti in un round. 3 Se c'è un pareggio, che è possibile per carte, quadri o primiera , nessuno segna il punto.

È importante rendersi conto che poiché ogni carta deve essere catturata da uno dei due giocatori, puoi dedurre quali carte devono aver preso l'altro giocatore anche se sai solo quali carte sono state prese da un giocatore. Dovrai farlo per segnare correttamente i primiera .

Regole della sfida

Ingresso

Il tuo codice dovrebbe prendere come input le carte catturate da un singolo giocatore durante un round di Scopa.

L'input deve essere in formato stringa, in cui un personaggio rappresenta il rango di ogni carta e un personaggio il suo seme. Questo rimuove la potenziale scappatoia del passaggio deipunteggi dei primiera direttamente come input. La conversione dei ranghi delle carte inpunteggi primiera deve essere effettuata nel programma. Tuttavia, puoi scegliere di utilizzare una singola stringa separata da spazi o virgole, una matrice di stringhe o qualsiasi altro formato. Ad esempio, se si sceglie di codificare le classifiche come76A5432QJKe si adatta comeDCHSsi potrebbe utilizzare input come['7D', '6H', 'QD', 'JS']o'7D,6H,QD,JS'.

Produzione

Un numero intero compreso tra 0 e 4 che rappresenta il punteggio del giocatore.

vincente

Vince la risposta più breve in byte!

Casi test

["7D", "6D", "AD", "5D", "4D", "3D", "2D", "QD", "7C", "6C", "4C", "3C", "2C", "7H", "4H", "2H", "5S", "3S", "QS", "JS", "KS"]

Segna 4 : 1 punto per> 20 carte, 1 punto per> 5 diamanti, 1 punto per il 7 di diamanti e 1 punto per segnare 78 in primiera (7,7,7,5 dove l'avversario ha 7,6,5, K per 64)

["3D", "7C", "6C", "AC", "5C", "4C", "3C", "2C", "QC", "4H", "7S"]

Punteggio 0 : <= 20 carte, <= 5 diamanti, n. 7 di diamanti e segna solo 69 in primiera (7,7,4,3 dove l'avversario ha 7,7,6, K per 70)

[7D", "6D", "AD", "5D", "4D", "3D", "2D", "7C", "6C", "AC", "5C", "4C", "3C", "2C", "7H", "6H", "AH", "5H", "4H", "3H", "2H"]

Punteggio 3 : 1 punto per> 20 carte, 1 punto per> 5 diamanti, 1 punto per 7 di diamanti. La primaera sarebbe 63 (7,7,7) e l'avversario può segnare solo 51 (7, Q, Q, Q) ma poiché questa mano non ha picche perde il punto di default.

["7D", "6D", "AD", "5D", "4D", "3D", "2D", "QD", "JD", "KD", "QC", "QH", "QS"]

Punteggio 3 : <= 20 carte, 1 punto per> 5 diamanti, 1 punto per 7 di diamanti. Il primoera segna solo 51 (7, Q, Q, Q) e l'avversario può segnare 63 (7,7,7) ma poiché la mano dell'avversario non ha diamanti questa mano vince il punto primiera per impostazione predefinita.

["7D", "6D", "AD", "5D", "4D", "3D", "2D", "QD", "JD", "KD", "7C", "7H"]

Punteggi 3 : <= 20 carte, 1 punto per> 5 diamanti, 1 punto per 7 di diamanti. Anche se questa mano non ha picche, vince comunque la primaera con un punteggio da 63 a 57 (7,7,7 contro 7,6,6) perché la mano dell'avversario non ha diamanti.

["7D", "6D", "AD", "5D", "4D", "3D", "2D", "QD", "JD", "KD", "QC", "QH"]

Punteggio 2 : <= 20 carte, 1 punto per> 5 diamanti, 1 punto per 7 di diamanti. Questa mano non ha picche e la mano dell'avversario non ha diamanti. L'avversario vince i primiera con un punteggio da 63 a 41 (7,7,7 contro 7, Q, Q).

[] (matrice vuota)

Punteggi 0


1: Almeno nella nostra famiglia, Jack supera la Regina a Scopa ma questo è irrilevante ai fini del punteggio.

2: Gioco a questo gioco fin dall'infanzia e non l'ho mai visto accadere, ma è meglio che il tuo codice sia in grado di gestire quel caso!

3: Ci sono punti bonus per gli "sweep" segnati durante il round che sto ignorando ai fini di questa sfida.


1
Ogni rango deve essere rappresentato da un personaggio distinto?
Maniglia della porta

@Doorknob No, non necessariamente, ma almeno nella soluzione su cui sto lavorando ho trovato necessario avere un carattere unico per ogni grado per ottenere tutti i casi di test corretti.
qdread,

@Grimy buona cattura. grazie
qdread,

Risposte:


6

Rubino, 156 153 byte

->a{b='';([a[40],a.scan(/.d/)[5],a=~/;d/,'dchs'.gsub(/./){l=a.scan /.(?=#$&)/;l.size<10&&b+=(';865432'.tr(l*'','')+?0)[0];l.max}.sum>b.sum||p]-[p]).size}

Provalo online!

->a{
b='';                # stores primiera of other player
([                   # this array stores all checks
a[40],               # check if >20 cards (>40 characters)
a.scan(/.d/)[5],     # check if >5 diamonds
a=~/;d/,             # check if 7 of diamonds
'dchs'.gsub(/./){    # for each suit, build a string with...
l=a.scan /.(?=#$&)/; # find all cards with this suit
l.size<10&&          # if there are less than 10, the other person has some, so
b+=                  # append to their score string the following:
(';865432'           #   start with all the cards
.tr(l*'','')         #   remove the ones we have
+?0)                 #   add back the JQK at the end
[0];                 #   take the highest
l.max}               # return the highest card that we have
.sum                 # take the sum of the codepoints
>b.sum               # check if it's greater than the other player's sum
||p                  # if not, evaluate to nil
]-[p])               # remove all nils
.size}               # count how many are left

Questo usa ;865432000per rappresentare76A5432QJK rispettivamente, e semi sono in minuscolo. (La scelta dei personaggi è perché sottraendo 38 da ciascuno dà il loro valore di primiera, ma in realtà non lo facciamo mai perché conta solo la differenza relativa.)

Non controlliamo se a nessuno dei giocatori manca un seme perché non è necessario, poiché tutte le carte sono conteggiate come 38 più il loro valore effettivo, se a qualcuno manca un seme, il punteggio più alto che possono ottenere è (21 + 38) * 3 = 177, che è inferiore a (10 + 38) * 3 + 21 + 38 = 203, il punteggio più basso che l'altro giocatore può ottenere. Non possiamo far perdere ai due giocatori un numero diverso di semi diverso da zero, perché a un giocatore possono mancare solo 0, 1 o 2 semi e se a qualcuno mancano 2 semi hanno tutte le carte degli altri 2 semi.


4

R, 320 298 265 238 229 224 211 209 179 byte

Questa è una soluzione principalmente dovuta a @digEmAll, sotto forma di una funzione.

Provalo online!

function(h,S=sum,A=apply,l=99+c(11,8,5:2,6,!1:3)%o%!!1:4)S(S(p<-outer(c(7:2,'A','K','J','Q'),c('D','C','H','S'),paste0)%in%h)>20,S(p[1:10])>5,p[1],S(A(l*p,2,max)-A(l*!p,2,max))>0)

Di seguito è riportato il migliore dei miei vecchi tentativi mediocri per 209 byte.

modifica: abbattuto alias alcune funzioni, quindi prendendo l'idea di Doorknob di aggiungere una costante al punteggio invece di controllare i semi.

modifica successiva: liberarsi della ridondanza e quindi incorporare alcuni miglioramenti da Giuseppe

prossima modifica: -2 byte grazie a digEmAll

Sono terribile in questo, quindi sono sicuro che qualcuno può migliorare su questo se si preoccupano di prendere il tempo. Mi sento come il sapplye functionsono super lungo e potrebbe sbarazzarsi di loro, ma io non riesco a capire come. Gli input sono stringhe di due caratteri nella notazione standard.

function(h,s=sum,l=c(11,8,5:2,6,!1:3)+99)s(length(h)>20,s(grepl('D',h))>5,'7D'%in%h,s(sapply(c('D','C','H','S'),function(i,r=c(7:2,'A','K','J','Q')%in%substr(h[grep(i,h)],1,1))s(l[r][1],-l[!r][1],na.rm=T)))>0)

1
Potresti essere in grado di ottenere aiuto nella chat room di R golf , digEmAll è persino un compagno italiano!
Giuseppe,

1
Solo qualche consiglio ma se puoi scambiare un punto e virgola solo una nuova riga (che sembra essere un byte in R), è uno scambio gratuito che rende la tua risposta più leggibile. Inoltre, controlla Provalo online, che è un corridore di codice online se non l'hai fatto. Non richiesto, ma di nuovo piacevole da usare. Può persino generare post
CGCC

1
253 byte - Non sono del tutto sicuro che funzionerà, dato che stavo principalmente provando il solito set di golf, ma mi sento libero di testare e farmi sapere.
Giuseppe,



2

JavaScript (ES6),  171  163 byte

Accetta input come un set di carte, usando la loro rappresentazione standard.

c=>(c.size>20)+((g=o=>[..."CHSD"].map(s=>[..."JQK2345A67"].map((v,i)=>(S=o^c.has(v+s))?m="111345679"[++n,i]||12:0,n=m=0)|(n?0:T=1,t-=m),T=t=4)|t*T)(1)>g``)+S+(n>5)

Provalo online!

Commentate

c =>                                // c = set of cards
  (c.size > 20) + (                 // +1 point if we have more than 20 cards
    ( g = o =>                      // g is a function taking the flag o (for 'opponent')
      [..."CHSD"].map(s =>          // for each suit s, ending with diamonds:
        [..."JQK2345A67"]           //   for each rank v at position i, sorted from
        .map((v, i) =>              //   lowest to highest primiera score:
          (S = o ^ c.has(v + s)) ?  //     if the player owns this card, set S to 1 and:
            m = "111345679"[++n, i] //       increment n; update m to the score of this
                || 12               //       rank (we use the official score - 9)
          :                         //     else:
            0,                      //       do nothing
          n = m = 0                 //     start with n = m = 0
        ) |                         //   end of inner map()
        ( n ? 0 : T = 1,            //   if n = 0, set T to 1
          t -= m ),                 //   subtract m from t
        T = t = 4                   //   start with T = t = 4
      ) | t * T                     // end of outer map(); yield t * T
    )(1) > g``                      // +1 point if g(1) is greater than g(0)
  ) +                               // (we test this way because the scores are negative)
  S +                               // +1 point if we own the 7 of diamonds
  (n > 5)                           // +1 point if we own more than 5 diamonds

2

05AB1E , 41 byte

39ÝsK‚εg9y@Oy0å•Dδ¿m(/d•₆вy.γT÷}è€àO)}`›O

Provalo online o controlla tutti i casi di test .

I semi DCHSsono rispettivamente rappresentati da0123 . I ranghi 7A65432KJQsono rispettivamente rappresentati da0123456789 . Questi sono presi come stringhe, non come numeri interi, come richiesto dalla sfida (ma poi 05AB1E li converte in numeri interi quando necessario comunque).

Come in altre soluzioni, aggiungiamo una grande costante (14) a ciascun punteggio di Primeera per rendere superflua la verifica dei semi mancanti.

39Ý                      # range 0..39 (the list of all cards in the game)
   sK                    # remove all elements that appear in the input
      ‚                  # pair with the input: [player's hand, opponent's hand]

ε                     }  # map each hand to a list of its 4 subscores:
 g                       #  first subscore: length (number of cards)
 9y@O                    #  second subscore: count elements <= 9 (diamonds)
 y0å                     #  third subscore: is 0 (representing 7D) in the list
            y.γT÷}       #  group the hand by suit
 •Dδ¿m(/d•₆в      è      #  map each rank to its primiera score
                   ۈ    #  maximum primiera score in each suit
                     O   #  fourth subscore: the sum of those

`›                       # for each subscore: is player's > opponent's?
  O                      # sum
```

2

MS SQL Server 2017 , 525 byte

CREATE FUNCTION f(@ NVARCHAR(MAX))RETURNS TABLE RETURN
SELECT q/21+IIF(d>6,2,IIF(d=6,1,0))+IIF(m=0,IIF(n=0 AND a>b,1,0),IIF(n=0 OR a>b,1,0))p
FROM(SELECT SUM(q)q,MAX(IIF(s='D',q,0))d,SUM(a)a,MIN(q)m,SUM(b)b,MIN(10-q)n
FROM(SELECT s,COUNT(k)q,MAX(IIF(r=k,v,0))a,MAX(IIF(r=k,0,v))b
FROM(SELECT LEFT(value,1)r,s,ASCII(RIGHT(value,1))-38 v
FROM STRING_SPLIT('7;,68,A6,5,4,3,2,Q0,J0,K0',','),(VALUES('D'),('C'),('H'),('S'))s(s))d
LEFT JOIN(SELECT LEFT(value,1)k,RIGHT(value,1)u FROM STRING_SPLIT(@,','))a
ON r+s=k+u GROUP BY s)t)t

Provalo su violino db <> .


1

Retina 0.8.2 , 334 byte

$
 ¶234567JQKA
r`.\G
$&C $&D $&H $&S 
+`((\w\w).*¶.*)\2 
$1
T`67AJQK`8960
%O$`(\w)(\w)
$2$1
m`^(?=(...)*)(.C )*(.D )*(.H )*(.S )*
$3;$#1 $#2 $#3 $#4 $#5;${2}${3}${4}$5
m`^(?=(9D))?...;
$#1;
(;(?!.*10).* 0.*;).*
$1
\d[C-S] 
1$&
19\w 
21$*@
\d+(\w )?
$*@
(@)?;(@*) @* (@*).*;(@*)¶@?;((?!\2))?@* @* ((?!\3))?.*;((?!\4))?.*
$#1$#5$#6$#7
1

Provalo online! Il link include casi di test. Spiegazione:

$
 ¶234567JQKA
r`.\G
$&C $&D $&H $&S 

Crea un elenco di tutte le 40 carte.

+`((\w\w).*¶.*)\2 
$1

Rimuovi le carte in possesso del giocatore.

T`67AJQK`8960

Sostituisci ogni valore con il suo ordinamento, che è 9 per 7e 10 in meno del suo valore per le altre carte.

%O$`(\w)(\w)
$2$1

Ordina le carte per seme e rango.

m`^(?=(...)*)(.C )*(.D )*(.H )*(.S )*
$3;$#1 $#2 $#3 $#4 $#5;${2}${3}${4}$5

Conta il numero di carte in ogni seme e cattura anche la carta con il punteggio più alto in ogni seme, catturando il diamante più alto due volte.

m`^(?=(9D))?...;
$#1;

Controlla se il diamante più alto era il 7.

(;(?!.*10).* 0.*;).*
$1

Elimina tutte le carte più alte se uno dei semi non ha carte.

\d[C-S] 
1$&
19\w 
21$*@
\d+(\w )?
$*@

Converti le carte più alte nel loro punteggio unario e sommale insieme. Converti anche il numero totale di carte e lunghezze dei semi in unario.

(@)?;(@*) @* (@*).*;(@*)¶@?;((?!\2))?@* @* ((?!\3))?.*;((?!\4))?.*
$#1$#5$#6$#7

Ottieni punti se il totale, i diamanti o i primiera, sono più alti.

1

Totale del punteggio.



1

AWK , 235 byte

{s[9]=35;s[8]=32;s[7]=30;s[6]=29;s[5]=28;s[4]=27;s[3]=26;s[2]=s[1]=s[0]=24;a[$1 $2]=s[$1]}END{while(i++<4){D=0;for(j=0;j<10;j++){if(a[j i]<1){B[i]=s[j];D++}if(A[i]<a[j i])A[i]=a[j i]}x+=A[i];y+=B[i]}print(20<NR)+(D<5)+(1<a[9 4])+(y<x)}

Provalo online!

I semi sono mappati a 1234 (4 sono diamanti), i valori sono mappati a 0123456789. Questo programma trasforma i casi di test nel formato accettato:

BEGIN{RS=", ";FS="";t[7]=9;t[6]=8;t["A"]=7;t[5]=6;t[4]=5;t[3]=4;t[2]=3;t["Q"]=2;t["J"]=1;t["K"]=0;u["D"]=4;u["C"]=1;u["H"]=2;u["S"]=3}{gsub("[\\[\"\\]]","",$0);print t[$1],u[$2]}

Il mio obiettivo era solo quello di battere l'implementazione leader di Python: D


1

Python 3 , 249 245 239 238 byte

-4 byte grazie a @ovs

-6 byte grazie a @movatica

lambda C:sum([len(C)>20,'7D'in C,len([c for c in C if'E'>c[1]])>5,p(C)>p({n+s for n in'9876543210'for s in S}-C)])
p=lambda C:[not S.strip(''.join(C)),sum(max([(c[1]==s)*int('9gcdefil99'[int(c[0])],22)for c in C]+[0])for s in S)]
S='DcHS'

Provalo online!


1
2 byte in meno con int('0734569c00'[int(x[0])],13)e if x[1]<'E'possono essere scritti comeif'E'>x[1]
ovs

all(s in''.join(C)for s in S)può essere abbreviato in not S.strip(''.join(C)), risparmiando 6 byte
movatica
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.