Was ist die Punktzahl meiner Scopa-Hand?

14

Ich mag Kartenspielherausforderungen, deshalb habe ich diese für das italienische Kartenspiel Scopa gemacht. Meine Familie spielt dieses Spiel seit jeher. Es hat ein sehr interessantes Punktesystem, das Spaß am Golf machen sollte. Ich werde eine Antwort in R posten, um den Spaß zu starten, von dem ich sicher bin, dass die Leute sich verbessern werden.

Die Herausforderung: Berechnen Sie die Anzahl der Punkte, die in einer Runde von Scopa erzielt wurden, und geben Sie die Karten an, die der Spieler während der Runde als Eingabe erhalten hat.

In einem Scopa-Deck befinden sich 40 Karten. Wenn Sie ein internationales Deck verwenden, entfernen Sie die 8er, 9er und 10er und lassen A, 2,3,4,5,6,7, Q, J, K in jeder Farbe. 1 Es gibt zwei Spieler oder Partnerschaften, und nach jeder Runde werden alle Karten von dem einen oder anderen der beiden Spieler erbeutet. Die Punktzahl wird wie folgt gezählt (weitere Informationen hier ):

  • Der Spieler mit den meisten Karten erhält 1 Punkt.
  • Der Spieler mit den meisten Diamanten (oder Münzen, wenn er das italienische Deck verwendet) erhält 1 Punkt.
  • Der Spieler mit der 7 von Diamanten (oder Münzen), die als " sette bello" oder "beautiful seven" bezeichnet wird, erhält 1 Punkt.
  • Der Spieler mit der höchsten Primiera erhält 1 Punkt. Die Primiera- Punktzahl eines Spielers ist die Summe der Punkte der Karte mit dem höchsten Wert, die der Spieler in jeder Farbe erobert hat (siehe Tabelle unten). Wenn Sie nicht mindestens eine Karte in jeder Farbe haben, verlieren Sie standardmäßig, auch wenn Ihre Punktzahl die Punktzahl Ihres Gegners überschreiten würde. In dem äußerst seltenen Fall, dass keiner der Spieler mindestens eine Karte in jeder Farbe hat, erhält der Spieler mit der höheren Primiera- Summe den Punkt. 2

Tabelle der Primiera-Ergebnisse

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

Ein Spieler kann also höchstens 4 Punkte in einer Runde erzielen. 3 Wenn es ein Unentschieden gibt, das für Karten, Diamanten oder Primiera möglich ist, erhält niemand den Punkt.

Da jede Karte von einem der beiden Spieler erbeutet werden muss, müssen Sie wissen, welche Karten der andere Spieler genommen hat, auch wenn Sie nur wissen, welche Karten ein Spieler genommen hat. Sie müssen dies tun, um primiera richtig zu bewerten .

Herausforderungsregeln

Eingang

Ihr Code sollte die von einem einzelnen Spieler während einer Runde von Scopa erbeuteten Karten als Eingabe nehmen.

Die Eingabe muss im Zeichenfolgenformat erfolgen, wobei ein Zeichen den Rang jeder Karte und ein Zeichen ihre Farbe darstellt. Dies beseitigt die potenzielle Lücke, die Primiera- Scores direkt als Eingabe weiterzugeben . Die Umrechnung der Kartenränge in Primiera Scores muss im Programm erfolgen. Sie können jedoch eine einzelne Zeichenfolge, die durch Leerzeichen oder Kommas getrennt ist, ein Array von Zeichenfolgen oder ein anderes Format verwenden. Zum Beispielwenn Sieentscheiden zu kodieren Reihen wie76A5432QJKund Anzügen wieDCHSSie Eingaben wie nutzen könnten['7D', '6H', 'QD', 'JS']oder'7D,6H,QD,JS'.

Ausgabe

Eine Ganzzahl von 0 bis 4, die die Punktzahl des Spielers darstellt.

Gewinnen

Kürzeste Antwort in Bytes gewinnt!

Testfälle

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

Erzielt 4 : 1 Punkt für> 20 Karten, 1 Punkt für> 5 Diamanten, 1 Punkt für die 7 Diamanten und 1 Punkt für 78 in Primiera (7,7,7,5, wenn der Gegner 7,6,5 hat, K für 64)

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

Punktet 0 : <= 20 Karten, <= 5 Diamanten, keine 7 Diamanten, und punktet nur in Primiera mit 69 (7,7,4,3, wenn der Gegner 7,7,6, K für 70 hat)

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

Punkte 3 : 1 Punkt für> 20 Karten, 1 Punkt für> 5 Diamanten, 1 Punkt für 7 Diamanten. Die Primiera wäre 63 (7,7,7) und der Gegner kann nur 51 (7, Q, Q, Q) erzielen, aber da diese Hand keine Pik hat, verliert sie standardmäßig den Punkt.

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

Punktzahl 3 : <= 20 Karten, 1 Punkt für> 5 Diamanten, 1 Punkt für 7 Diamanten. Die Primiera erzielt nur 51 (7, Q, Q, Q) und der Gegner kann 63 (7,7,7) erzielen, aber da die Hand des Gegners keine Diamanten hat, gewinnt diese Hand standardmäßig den Primiera- Punkt.

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

Punktzahl 3 : <= 20 Karten, 1 Punkt für> 5 Diamanten, 1 Punkt für 7 Diamanten. Auch wenn diese Hand keine Pik hat, gewinnt sie mit einer Punktzahl von 63 zu 57 (7,7,7 versus 7,6,6), weil die Hand des Gegners keine Diamanten hat.

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

Punktzahl 2 : <= 20 Karten, 1 Punkt für> 5 Diamanten, 1 Punkt für 7 Diamanten. Diese Hand hat keine Pik und die Hand des Gegners hat keine Diamanten. Der Gegner gewinnt primiera mit einer Punktzahl von 63 zu 41 (7,7,7 gegen 7, Q, Q).

[] (leeres Array)

Punktzahl 0


1: Zumindest in unserer Familie ist Jack in Scopa Königin, aber dies ist für die Wertung irrelevant.

2: Ich spiele dieses Spiel seit meiner Kindheit und habe das noch nie gesehen, aber Ihr Code sollte diesen Fall besser bewältigen können!

3: Es gibt Bonuspunkte für "Sweeps", die während der Runde erzielt wurden und die ich für diese Herausforderung ignoriere.

qdread
quelle
1
Muss jeder Rang durch ein bestimmtes Zeichen dargestellt werden?
Türklinke
@Doorknob Nein, nicht unbedingt, aber zumindest bei der Lösung, an der ich arbeite, war es notwendig, für jeden Rang einen eindeutigen Charakter zu haben, um alle Testfälle richtig zu machen.
Qdread
@ Grimy guten Fang. danke
qdread

Antworten:

6

Ruby, 156 153 Bytes

->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}

Probieren Sie es 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

Dies wird jeweils verwendet, ;865432000um darzustellen 76A5432QJK, und Anzüge sind in Kleinbuchstaben. (Die Wahl der Zeichen liegt darin, dass durch Subtrahieren von 38 von jedem Zeichen der primäre Wert erhalten wird. Dies wird jedoch nie durchgeführt, da nur der relative Unterschied von Bedeutung ist.)

Wir prüfen nicht, ob einem der Spieler eine Farbe fehlt, da dies unnötig ist. Da alle Karten als 38 plus deren tatsächlicher Wert gezählt werden, beträgt die Höchstpunktzahl (21 + 38) *, wenn jemand eine Farbe fehlt. 3 = 177, was weniger als (10 + 38) * 3 + 21 + 38 = 203 ist, die niedrigste Punktzahl, die der andere Spieler erzielen kann. Wir können nicht zulassen, dass den beiden Spielern eine ungleiche Anzahl von Farben ungleich Null fehlt, weil einem Spieler nur 0, 1 oder 2 Farben fehlen können, und wenn jemand 2 Farben fehlt, haben sie alle Karten der anderen 2 Farben.

Türknauf
quelle
4

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

Dies ist eine Lösung, die hauptsächlich auf @digEmAll in Form einer Funktion zurückzuführen ist.

Probieren Sie es 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)

Unten ist das Beste von meinen alten mittelmäßigen Versuchen für 209 Bytes.

Bearbeiten: Durch Aliasing einiger Funktionen nach unten spielen, dann die Idee von Doorknob übernehmen, der Partitur eine Konstante hinzuzufügen, anstatt die Farben zu überprüfen.

nächste Änderung: Einige Redundanzen wurden beseitigt und einige Verbesserungen von Giuseppe eingebaut

nächste Änderung: -2 Bytes dank digEmAll

Ich bin schrecklich, also bin ich mir sicher, dass jemand das verbessern kann, wenn er sich die Zeit nimmt. Ich fühle mich wie die sapplyund bin functionsuper lang und könnte sie loswerden, aber ich kann nicht herausfinden, wie. Eingaben sind zweistellige Zeichenfolgen in der Standardnotation.

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)
qdread
quelle
1
Möglicherweise können Sie Hilfe im R-Golf-Chatroom erhalten , digEmAll ist sogar ein italienischer Landsmann!
Giuseppe
1
Nur ein Tipp, aber wenn Sie ein Semikolon durch eine neue Zeile tauschen können (dies scheint ein Byte in R zu sein), ist dies ein kostenloser Tausch, der Ihre Antwort lesbarer macht. Schauen Sie sich auch Try It Online an, das ein Online-Codeläufer ist, wenn Sie dies nicht getan haben. Nicht erforderlich, aber wieder schön zu bedienen. Es kann sogar CGCC-Posts generieren
Veskah
1
253 Bytes - Ich bin nicht ganz sicher, ob dies funktionieren wird, da ich meistens die üblichen Golfplätze ausprobiert habe, aber ich kann sie gerne testen und mich informieren.
Giuseppe
1
209
digEmAll
1
Dies sollte auch für 181
funktionieren
2

JavaScript (ES6),  171  163 Byte

Nimmt Eingaben als Kartensatz unter Verwendung ihrer Standarddarstellung entgegen.

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)

Probieren Sie es online!

Kommentiert

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
Arnauld
quelle
2

05AB1E , 41 Bytes

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

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Anzüge DCHSsind jeweils vertreten durch 0123. Die Ränge 7A65432KJQwerden jeweils durch dargestellt 0123456789. Diese werden als Zeichenfolgen verwendet, nicht als Ganzzahlen, wie es die Abfrage erfordert (aber 05AB1E konvertiert sie dann trotzdem in Ganzzahlen, wenn sie benötigt werden).

Wie bei anderen Lösungen fügen wir jeder Primiera-Bewertung eine große Konstante (14) hinzu, um die Prüfung auf fehlende Anzüge überflüssig zu machen.

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
```
Grimmig
quelle
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

Probieren Sie es mit db <> fiddle aus .

Andrei Odegov
quelle
1

Retina 0.8.2 , 334 Bytes

$
 ¶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

Probieren Sie es online! Link enthält Testfälle. Erläuterung:

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

Erstellen Sie eine Liste aller 40 Karten.

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

Entferne die Karten, die der Spieler hält.

T`67AJQK`8960

Ersetzen Sie jeden Rang durch seine Sortierreihenfolge, die 9 für 7und 10 weniger als sein Wert für andere Karten ist.

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

Sortieren Sie die Karten nach Farbe und Rang.

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

Zählen Sie die Anzahl der Karten in jeder Farbe und nehmen Sie die Karte mit dem höchsten Rang in jeder Farbe auf, wobei Sie den höchsten Diamanten zweimal einfangen.

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

Überprüfen Sie, ob der höchste Diamant die 7 war.

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

Löschen Sie alle höchsten Karten, wenn eine der Farben keine Karten enthält.

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

Wandle die höchsten Karten in ihre unäre Punktzahl um und addiere sie. Konvertieren Sie auch die Gesamtzahl der Karten und die Farbenlänge in Unär.

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

Erzielen Sie Punkte, wenn die Summe, die Diamanten oder die Primiera höher sind.

1

Gesamte die Punktzahl.

Neil
quelle
1

AWK , 235 Bytes

{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)}

Probieren Sie es online!

Die Zuordnung der Farben zu 1234 (4 sind Diamanten) und die Zuordnung der Werte zu 0123456789. Dieses Programm wandelt die Testfälle in das akzeptierte Format um:

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]}

Mein Ziel war es, die führende Python-Implementierung zu übertreffen: D

Daniel LaVine
quelle
1

Python 3 , 249 245 239 238 Bytes

-4 Bytes dank @ovs

-6 Bytes dank @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'

Probieren Sie es online!

Schwarze Eule Kai
quelle
1
2 Bytes weniger mit int('0734569c00'[int(x[0])],13)und if x[1]<'E'können alsif'E'>x[1]
ovs
all(s in''.join(C)for s in S)kann auf not S.strip(''.join(C))6 Bytes gekürzt werden
movatica