Berechnen Sie den Doppelkopf Score

9

Einführung

Doppelkopf ist ein traditionelles deutsches Kartenspiel für 4 Spieler. Das Deck besteht aus 48 Karten (9, 10, Jack, Queen, King, Ace jeder Farbe, während jede Karte zweimal im Spiel ist), sodass jeder Spieler zu Beginn einer Runde 12 erhält.

Es gibt immer 2 Mannschaften, die durch die Verteilung der Queens of Clubs bestimmt werden. Die 2 Spieler, die die Queens halten, bilden ein Team und spielen gegen die anderen 2 Spieler. Das Team mit den Queens of Clubs heißt "Re" -Team, das ohne ist das "Contra" -Team.
Zu Beginn der Runde weiß niemand, wer in welchem ​​Team ist. Die Teamverteilung wird im Verlauf der Runde bekannt gegeben, was dem Spiel viel Strategie verleiht.

Das Spiel besteht aus 12 Tricks. Die Spieler, die einen Stich gewinnen, erhalten alle 4 Karten. Jede Karte hat einen bestimmten Wert (König zählt 4, Ass zählt 11), alle Karten zusammen ergeben 240 Punkte, was das höchstmögliche Ergebnis darstellt.

Am Ende einer Runde werden die Punkte gezählt und das Team mit der höchsten Punktzahl gewinnt die Runde. Dann beginnt dann die nächste Runde ...

Die Herausforderung

Jede Runde hat eine bestimmte Punktzahl, die sich nach der Anzahl der Punkte des Gewinnerteams und möglichen Ankündigungen richtet. Sie müssen ein Programm schreiben, das die Punkteverteilung und mögliche Ankündigungen (siehe Erklärung unten) als Eingabe verwendet und die Punktzahl der Runde und den Gewinner ausgibt.

Die Punkteberechnung

Wie bereits erwähnt gibt es ein Re- und ein Contra-Team. Außerdem sind in einer Runde maximal 240 Punkte möglich. Das Re-Team muss 121 Punkte erhalten, um zu gewinnen, während das Contra-Team nur 120 Punkte benötigt. Es besteht auch die Möglichkeit, zu Beginn der Runde "Re" oder "Contra" anzukündigen, wenn Sie glauben, dass Sie das Spiel gewinnen werden . Auf diese Weise erhöhen Sie die Punktzahl.

Hier sind die Bewertungsregeln:

  • +1 für den Gewinn des Spiels
  • +1 wenn das verlierende Team weniger als 90 Punkte hat ("Keine 90")
  • +1 wenn das verlierende Team weniger als 60 Punkte hat ("Keine 60")
  • +1 wenn das verlierende Team weniger als 30 Punkte hat ("Keine 30")
  • +1 wenn die unterlegene Mannschaft 0 Punkte hat ("Schwarz")
  • +2 für eine Ankündigung von Contra
  • +2 für eine Ankündigung von Re
  • +1 wenn das Contra Team gewonnen hat ("Gegen die Alten")

Hinweis: Re / Contra-Ankündigungen gelten immer, unabhängig vom Gewinner. Siehe Beispiele in den folgenden Testfällen.

Ein- und Ausgabe

Die Eingabe in das Programm ist die Punktzahl des Re-Teams und mögliche Ankündigungen von Re oder Contra. Da es immer 240 Punkte im Spiel gibt, können Sie die Punktzahl des Contra-Teams einfach berechnen.

Die Eingabe ist eine einzelne Zeichenfolge, die zuerst die Punktzahl des Re-Teams enthält, gefolgt von den möglichen Ankündigungen, während "R" für Re und "C" für Contra steht. Wenn beide angekündigt wurden, wird Re immer an erster Stelle stehen.

Die Ausgabe ist die Punktzahl des Spiels, gefolgt vom Gewinnerteam ("C" für Contra, "R" für Re).

Regeln

  • Ihre Einreichung kann ein vollständiges Programm oder eine Funktion sein. Wenn Sie sich für Letzteres entscheiden, geben Sie ein Beispiel zum Aufrufen an.
  • Die Eingabe kann durch Funktions- oder Befehlszeilenargumente oder Benutzereingaben erfolgen.
  • Die Ausgabe kann als Rückgabewert bereitgestellt oder auf dem Bildschirm gedruckt werden.
  • Es gelten Standardlücken .
  • Niedrigste Byte-Anzahl gewinnt!

Testfälle

Input -> Output (Explanation)

145R  -> 3R  (Re won, +1 for winning, +2 for Re-Announcement)
120   -> 2C  (Contra won, +1 for winning, +1 for winning as Contra)
80C   -> 5C  (Contra won, +1 for winning, +1 for no 90, +1 for winning as Contra, +2 for Contra-Announcement)
240R  -> 7R  (Re won, +1 for winning, +1 for no 90, +1 for no 60, +1 for no 30, +1 for no points for the losing team, +2 for Re-announcedment)
90    -> 2C  (Contra won, +1 for winning, +1 for winning as Contra)
110RC -> 6C  (Contra won, +1 for winning, +1 for winning as Contra, +2 for Re-Announcement, +2 for Contra-Announcement)
110R  -> 4C  (Contra won, +1 for winning, +1 for winnins as Contra, +2 for Re-Announcement)
184C  -> 5R  (Re won, +1 for winning, +1 for no 90, +1 for no 60, +2 for Contra-Announcement)

Kurzer Hinweis: Ich habe absichtlich einige Regeln (wie Soli und Bonuspunkte) weggelassen, um die Herausforderung einfach zu halten. Also, wenn Sie bereits mit dem Spiel vertraut sind, seien Sie nicht verwirrt :)

Viel Spaß beim Codieren!

Denker
quelle

Antworten:

4

CJam, 47 46 Bytes

L~]_,2*\0=:S121<:AS240S-e<_g3@30/-Te>--+A"RC"=

Führen Sie alle Testfälle aus.

Hmm, konzeptionell ist diese Herausforderung wirklich einfach, aber es ist überraschend schwierig, Golf zu spielen.

Martin Ender
quelle
Als ich dies versuchte, war ich damit einverstanden, dass ich mit einer Golfsprache auf ungefähr 100 Bytes kam. Ich gab sehr bald danach auf.
TheCoffeeCup
4

Labyrinth , 136 103 94 92 87 84 76 74 69 61 Bytes

 (}?
;)
,)
`
2
0:
 {
_-+}}82"
}"     {{"(#0/#--!.@
 -=-)}67 )

Probieren Sie es online aus!

Ahh, es ist viel zu lange her, seit ich Labyrinth benutzt habe. Es ist immer eine große Freude, Golf zu spielen. :) :)

Erläuterung

Das ist jetzt etwas veraltet. Die Gesamtstruktur des Programms ist immer noch dieselbe, aber einige Details haben sich geändert. Ich werde das später aktualisieren. Dies ist die vorherige Lösung als Referenz:

 (}?
;)
,)
`
2
0 }82{_240{- ("
{ ;        #;`"~#0/#--!.@
:}-"-))}67{{
  ;#

Lassen Sie uns die Partitur etwas aufschlüsseln:

  • Wenn wir die Zeichen nach der Zahl in der Eingabe zählen, nennen wir es M, dann gibt es 2M+1Punkte in der Endnote für das Gewinnen, Re und Contra.
  • Wenn die Punktzahl 120 oder weniger beträgt, gewinnt Contra und die Punktzahl wird um erhöht 1.
  • Wenn wir uns die verlorene Punktzahl ansehen, können wir sie (ganzzahlig) durch 30 teilen, um die zusätzlichen Punkte zu bestimmen. Das hat jedoch drei Probleme: 1. Der Wert steigt in die falsche Richtung, daher müssen wir ihn von der Punktzahl abziehen (und 3 hinzufügen, um dies zu korrigieren). 2. Dies ergibt einen zusätzlichen Punkt für ein Ergebnis von genau 120, das wir loswerden müssen. 3. Es wird noch kein Ergebnis von 0 (für die Verliererseite) verarbeitet, aber wir können es einschließen, indem wir 0 in -1 verwandeln (da Labyrinths ganzzahlige Division in Richtung rundet -∞).

So funktioniert der Code. Sp3000 hat heute eine gute Grundierung für Labyrinth veröffentlicht, also habe ich beschlossen, sie zu stehlen. :) :)

  • Das Labyrinth ist stapelbasiert und zweidimensional. Die Ausführung beginnt mit dem ersten erkannten Zeichen. Es gibt zwei Stapel, einen Hauptstapel und einen Hilfsstapel, aber die meisten Bediener arbeiten nur am Hauptstapel. Beide Stapel sind bodenlos und mit Nullen gefüllt.
  • In jedem Zweig des Labyrinths wird die Oberseite des Stapels überprüft, um festzustellen, wohin als nächstes zu gehen ist. Negativ ist links abbiegen, Null ist geradeaus und positiv ist rechts abbiegen.
  • Ziffern drücken sich nicht selbst (wie in Befunge,> <> oder Prelude) - stattdessen "hängen" sie sich an die Spitze des Stapels an, indem sie die Spitze mit 10 multiplizieren und sich selbst hinzufügen.

Die Ausführung beginnt also (in der ersten Zeile, wobei der Anweisungszeiger (IP) nach rechts zeigt. (verwandelt einfach die Oberseite des Hauptstapels in -1und }verschiebt sie zum Hilfsstapel, wo wir es vergessen können. Das Programm beginnt wirklich mit dem, ?der die Ganzzahl aus STDIN liest. Die IP trifft dann eine Sackgasse und dreht sich um.

}verschiebt den Eingang zum Hilfsstapel und (dekrementiert eine weitere Null auf -1. Dies wird das Endergebnis sein. Wir treten jetzt in eine sehr enge Schleife im Uhrzeigersinn ein:

;)
,)

Das ))erhöht die Punktzahl um zwei (wenn wir also das erste Mal durch die Schleife gehen, wird die Punktzahl zur 1Punktzahl für den Gewinn). Dann ,liest ein Zeichen. Solange dies nicht EOF ist, wird die Schleife fortgesetzt. ;verwirft den Charakter, weil es uns egal ist, ob es war Roder Cund ))fügt der Punktzahl erneut zwei hinzu. Dies wird je nach Eingabe 0, 1 oder 2 Mal wiederholt.

Wir verlassen die Schleife, wenn wir EOF getroffen haben, wird die Spitze des Stapels sein -1. Wir führen dann diesen linearen Teil aus:

`20{:}-

Das `ist eine unäre Negation, also bekommen wir sie 1und 20verwandeln sie dann in eine 120. {:}Ruft eine Kopie der Eingabe-Ganzzahl vom Hilfsstapel ab und -berechnet die Differenz mit 120. Wir können das Vorzeichen dieses Ergebnisses verwenden, um festzustellen, wer gewonnen hat.

  1. Wenn das Ergebnis negativ ist, hat Re gewonnen und wir gehen den nördlichen Weg und führen Folgendes aus:

    ;}82{_240{-#;
    

    ;verwirft dieses Ergebnis, }verschiebt die Punktzahl weg, 82setzt sich (Zeichencode von R) am unteren Rand des Hauptstapels ab, {holt die Punktzahl wieder nach oben, _240{-subtrahiert die ganzzahlige Eingabe von 240, damit wir mit den Punkten von Contra (der verlierenden Seite) arbeiten können.

    Dies #;soll nur sicherstellen, dass der Stapel einen Wert ungleich Null enthält, damit wir beide Pfade zuverlässig verbinden können.

  2. Wenn das Ergebnis positiv ist, hat Contra gewonnen und wir gehen den südlichen Weg und führen Folgendes aus:

    ;#"-))}67{{#;
    

    Das #drückt die Stapeltiefe, die ist 1. Dies wird von der Punktzahl abgezogen , bevor wir hinzufügen , 2mit )). 67setzt sich (Zeichencode von C) am unteren Rand des Hauptstapels. {{erhält die anderen Werte zurück.

  3. Wenn das Ergebnis Null ist, hat Contra immer noch gewonnen. Dies ist jedoch der Fall 120/120, für den wir dem Endergebnis einen zusätzlichen Punkt hinzufügen müssen (siehe oben). Deshalb drückt dieser Pfad keine 1 mit #, sondern lässt nur die Null, so dass die -Null einfach vom Stapel entfernt wird.

Die Stapel sind jetzt wieder zusammengefügt und wir haben alles berücksichtigt, außer dem Teil, in dem wir durch 30 teilen. Aber zuerst müssen wir eine Null-Punktzahl in -1 verwandeln. Das macht dieser kleine Umweg:

("
`"~

Das `wirkt sich nicht auf eine Null aus, "ist ein No-Op und ~ist eine bitweise Negation. Das bitweise NICHT von 0ist -1wie erforderlich. Wenn die Punktzahl stattdessen positiv war, `wird sie negativ, (dekrementiert sie um 1und ~macht beide Operationen auf einmal rückgängig.

#0/#--!.@

Die Stapeltiefe ist nun 3 (die Gewinnerseite des Charakter, die Gesamtpunktzahl so weit, und die Seite der Verlierer der Punkte), so #drückt 3. 0macht es zu einem 30, /macht die Teilung. #drückt einen anderen, 3der subtrahiert wird, und dieses Ergebnis wird wiederum vom Endergebnis subtrahiert. !druckt es als Ganzzahl, .druckt die Gewinnerseite als Zeichen und @beendet das Programm.

Martin Ender
quelle
3

JavaScript (ES6), 106

Rund 100 Bytes mit einer Sprache ohne Golf.

x=>([,r,t]=x.match`(\\d+)(.*)`,t=1+t.length*2,w=r>120?(r=240-r,'R'):(++t,'C'),t+!r+(r<30)+(r<60)+(r<90)+w)

Prüfung

f=x=>(
  [,r,t]=x.match`(\\d+)(.*)`,
  t=1+t.length*2,
  w=r>120?(r=240-r,'R'):(++t,'C'),
  t+!r+(r<30)+(r<60)+(r<90)+w
)

console.log=x=>O.textContent+=x+'\n'

test=[
['145R', '3R'], //(Re won, +1 for winning, +2 for Re-Announcement)
['120',  '2C'], //(Contra won, +1 for winning, +1 for winning as Contra)
['80C',  '5C'], //(Contra won, +1 for winning, +1 for no 90, +1 for winning as Contra, +2 for Contra-Announcement)
['240R', '7R'], //(Re won, +1 for winning, +1 for no 90, +1 for no 60, +1 for no 30, +1 for no points for the losing team, +2 for Re-announcedment)
['90',   '2C'], //(Contra won, +1 for winning, +1 for winning as Contra)
['110RC','6C'], //(Contra won, +1 for winning, +1 for winning as Contra, +2 for Re-Announcement, +2 for Contra-Announcement)
['110R', '4C'], //(Contra won, +1 for winning, +1 for winnins as Contra, +2 for Re-Announcement)
['184C', '5R'], //(Re won, +1 for winning, +1 for no 90, +1 for no 60, +2 for Contra-Announcement)
]
  
test.forEach(t=>{
  var i=t[0],k=t[1],r=f(i)
console.log((k==r?'OK ':'KO ')+i+' -> '+r+(k!=r?' (expected: '+k+')':''))
})
<pre id=O></pre>

edc65
quelle
Nur etwa doppelt so viele Bytes wie die CJam-Antwort ... nicht schlecht ^^
Denker
2

ES6, 92 Bytes

s=>(p=s.match(/\d+|./g),n=+p[0],r=n>120,p.length*2-r+!(n%120)+3-((r?240-n:n)/30|0)+"CR"[+r])

p.length*2überschätzt die Punktzahl um 1, wenn Re gewinnt, also muss ich rerneut subtrahieren . !(n%120)+3-((r?240-n:n)/30|0)ist das, was ich mir ausgedacht habe, um die Regeln für die Bewertung von "Keine" zusammenzufassen. Ich wünschte, die Grenzen wären 31, 61 und 91 gewesen, da dies die Formel ergeben hätte 4-((r?269-n:29+n)/30|0).

Neil
quelle