Calcule la puntuación de Doppelkopf

9

Introducción

Doppelkopf es un juego de cartas alemán tradicional para 4 jugadores. El mazo consta de 48 cartas (9, 10, Jota, Reina, Rey, As de cada palo mientras cada carta está en el juego dos veces), por lo que cada jugador obtiene 12 al comienzo de una ronda.

Siempre hay 2 equipos que están determinados por la distribución de las Queens of Clubs. Los 2 jugadores que sostienen las reinas forman un equipo y juegan contra los otros 2 jugadores. El equipo con las Queens of Clubs se llama equipo "Re", el que no tiene es el equipo "Contra".
Al comienzo de la ronda, nadie sabe quién está en qué equipo. La distribución del equipo se revelará en el progreso de la ronda, lo que agrega mucha estrategia al juego.

El juego consta de 12 trucos. Los jugadores que ganan un truco obtienen las 4 cartas en él. Cada carta tiene un cierto valor (el Rey cuenta 4, el As cuenta 11, por ejemplo), todas las cartas juntas suman 240 puntos, que es el resultado más alto posible.

Al final de una ronda, se cuentan los puntos y el equipo con la mayor cantidad de puntos gana la ronda. Entonces comienza la siguiente ronda ...

El reto

Cada ronda tiene un cierto puntaje que está determinado por la cantidad de puntos que obtuvo el equipo ganador y los posibles anuncios. Tendrá que escribir un programa que tome la distribución de puntos y los posibles anuncios (vea la explicación a continuación) como entrada y salida del puntaje de la ronda y el ganador.

El cálculo de la puntuación

Como se mencionó, hay un equipo Re y un Contra. También hay un máximo de 240 puntos posibles en una ronda. El Re-equipo tiene que obtener 121 puntos para ganar, mientras que el Contra-equipo solo necesita 120. También existe la posibilidad de anunciar "Re" o "Contra" al comienzo de la ronda si cree que va a ganar el juego. . Al hacer esto, estás aumentando el puntaje.

Aquí están las reglas de puntuación:

  • +1 por ganar el juego
  • +1 si el equipo perdedor tiene menos de 90 puntos ("Keine 90")
  • +1 si el equipo perdedor tiene menos de 60 puntos ("Keine 60")
  • +1 si el equipo perdedor tiene menos de 30 puntos ("Keine 30")
  • +1 si el equipo perdedor tiene 0 puntos ("Schwarz")
  • +2 para un anuncio de Contra
  • +2 para un anuncio de Re
  • +1 si el equipo Contra ganó ("Gegen die Alten")

Nota: Los anuncios de re / contra-anuncio siempre se aplican, independientemente del ganador. Ver ejemplos en los casos de prueba a continuación.

Entrada y salida

La entrada al programa será la puntuación del Re-equipo y los posibles anuncios de Re o Contra. Como siempre hay 240 puntos en el juego, puedes calcular fácilmente el puntaje del Contra-equipo.

La entrada será una sola cadena que tiene el puntaje del Re-equipo primero, seguido de los anuncios potenciales, mientras que "R" es para Re y "C" es para Contra. Si ambos fueron anunciados, Re siempre vendrá primero.

La salida será el puntaje del juego seguido por el equipo ganador ("C" para Contra, "R" para Re)

Reglas

  • Su envío puede ser un programa completo o una función. Si elige este último, incluya un ejemplo sobre cómo invocarlo.
  • La entrada puede proporcionarse mediante argumentos de línea de comando o función o entrada del usuario.
  • La salida puede proporcionarse como valor de retorno o imprimirse en la pantalla.
  • Se aplican lagunas estándar .
  • ¡El conteo de bytes más bajo gana!

Casos de prueba

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)

Nota breve: omití algunas reglas (como solos y puntos de bonificación) a propósito para mantener el desafío simple. Entonces, si ya estás familiarizado con el juego, no te confundas :)

¡Feliz codificación!

Denker
fuente

Respuestas:

4

CJam, 47 46 bytes

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

Ejecute todos los casos de prueba.

Hmm, conceptualmente este desafío es realmente simple, pero es sorprendentemente complicado jugar al golf.

Martin Ender
fuente
De acuerdo, cuando intenté jugar al golf, llegué a unos 100 bytes con un lenguaje de golf. Me di por vencido muy poco después.
TheCoffeeCup
4

Laberinto , 136 103 94 92 87 84 76 74 69 61 bytes

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

Pruébalo en línea!

Ahh, ha pasado demasiado tiempo desde que usé Labyrinth. Siempre es una alegría jugar al golf. :)

Explicación

Esto está un poco desactualizado ahora. La estructura general del programa sigue siendo la misma, pero algunos detalles han cambiado. Actualizaré esto más tarde. Esta es la solución anterior, para referencia:

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

Analicemos un poco el puntaje:

  • Si contamos los caracteres después del número en la entrada, llamémoslo M, entonces habrá 2M+1puntos en la puntuación final, para ganar, Re y Contra.
  • Si el puntaje es 120 o menos, Contra gana y el puntaje se incrementa en 1.
  • Mirando el puntaje perdedor, podemos (entero) dividirlo por 30 para determinar los puntos adicionales. Sin embargo, eso tiene tres problemas: 1. el valor aumenta en la dirección incorrecta, por lo que debemos restarlo del puntaje (y agregarle 3 para corregirlo). 2. Esto da un punto adicional para un resultado de exactamente 120, del cual debemos deshacernos. 3. Todavía no maneja un resultado de 0 (para el bando perdedor), pero podemos incluirlo convirtiendo 0 en -1 (ya que la división entera de Labyrinth se redondea hacia -∞).

Así es más o menos cómo funciona el código. Sp3000 publicó una buena cartilla para Labyrinth hoy, así que decidí robarlo. :)

  • Labyrinth está basado en pila y es bidimensional, y la ejecución comienza en el primer carácter reconocido. Hay dos pilas, una pila principal y una pila auxiliar, pero la mayoría de los operadores solo trabajan en la pila principal. Ambas pilas son sin fondo, llenas de ceros.
  • En cada rama del laberinto, se comprueba la parte superior de la pila para determinar a dónde ir después. Negativo es girar a la izquierda, cero es recto y positivo es girar a la derecha.
  • Los dígitos no se presionan a sí mismos (como lo hacen en Befunge,> <> o Preludio); en cambio, se "anexan" a la parte superior de la pila, multiplicando la parte superior por 10 y sumándose.

Entonces la ejecución comienza (en la primera fila, con el puntero de instrucción (IP) yendo a la derecha. (simplemente convierte la parte superior de la pila principal -1y la }desplaza a la pila auxiliar, donde podemos olvidarnos de ella. El programa realmente comienza con el ?que lee el número entero de STDIN. La IP luego llega a un callejón sin salida y se da vuelta.

}desplaza la entrada a la pila auxiliar y (disminuye otro cero a -1. Este será el puntaje final. Ahora ingresamos en un circuito muy apretado en el sentido de las agujas del reloj:

;)
,)

Los ))incrementos en el marcador por dos (por lo que la primera vez que vamos a través del bucle, la puntuación se convierte 1, la puntuación para ganar). Luego ,lee un personaje. Mientras no sea EOF, el ciclo continúa. ;descarta el personaje, porque no nos importa si fue Ro Cy ))agrega dos a la puntuación nuevamente. Esto se repetirá 0, 1 o 2 veces dependiendo de la entrada.

Dejamos el ciclo, cuando lleguemos a EOF, la parte superior de la pila estará -1. Luego ejecutamos esta parte lineal:

`20{:}-

La `negación es unaria, así que la obtenemos 1, luego la 20convierte en una 120. {:}obtiene una copia del entero de entrada de la pila auxiliar y -calcula la diferencia con 120. Podemos usar el signo de este resultado para determinar quién ganó.

  1. Si el resultado es negativo, Re ganó y tomamos el camino del norte, ejecutando:

    ;}82{_240{-#;
    

    ;descarta este resultado, }aleja el puntaje, se 82coloca (código de carácter R) en la parte inferior de la pila principal, {vuelve a colocar el puntaje en la parte superior, _240{-resta la entrada entera de 240 para que podamos trabajar con los puntos de Contra (el lado perdedor).

    Esto #;es solo para garantizar que tengamos un valor distinto de cero en la pila para que podamos unir ambas rutas de manera confiable.

  2. Si el resultado es positivo, Contra ganó y tomamos el camino sur, ejecutando:

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

    El #empuja la profundidad de la pila que es 1. Esto se resta de la puntuación antes de agregar 2con )). 67se coloca (código de carácter de C) en la parte inferior de la pila principal. {{recupera los otros valores.

  3. Si el resultado es cero, Contra aún gana. Sin embargo, ese es el caso 120/120 para el cual necesitamos agregar un punto extra al puntaje final (ver arriba). Es por eso que esta ruta no empuja un 1 con #, sino que simplemente deja el cero de tal manera que -simplemente elimina ese cero de la pila.

Las pilas ahora están unidas y hemos contabilizado todo, excepto la parte donde dividimos por 30. Pero primero, necesitamos convertir un puntaje cero en -1. Eso es lo que hace este pequeño desvío:

("
`"~

El `no afecta a un cero, "es un no-op y ~es una negación bit a bit. El NO bit a bit 0es el -1requerido. Si el puntaje fue positivo, lo `hace negativo, lo (disminuye 1y ~deshace ambas operaciones de una vez.

#0/#--!.@

La profundidad de la pila ahora es 3 (el personaje del lado ganador, el puntaje total hasta el momento y los puntos del lado perdedor), así que #empuja 3. 0lo convierte en a 30, /hace la división. #empuja a otro 3que se resta y ese resultado a su vez se resta del puntaje final. !lo imprime como un número entero, .imprime el lado ganador como un personaje y @finaliza el programa.

Martin Ender
fuente
3

JavaScript (ES6), 106

Alrededor de 100 bytes con un lenguaje que no es de 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)

Prueba

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
fuente
Solo alrededor del doble del recuento de bytes de la respuesta de CJam ... no está mal ^^
Denker el
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*2sobreestima el puntaje por 1 si Re gana, así que tengo que restar rnuevamente. !(n%120)+3-((r?240-n:n)/30|0)es lo que se me ocurrió para encapsular las reglas para anotar "Keine"; Ojalá los límites hubieran sido 31, 61 y 91, ya que eso habría hecho la fórmula 4-((r?269-n:29+n)/30|0).

Neil
fuente