Hitung Skor Doppelkopf

9

pengantar

Doppelkopf adalah permainan kartu tradisional Jerman untuk 4 pemain. Dek terdiri dari 48 kartu (9, 10, Jack, Queen, King, Ace dari masing-masing suit sementara setiap kartu ada di permainan dua kali), sehingga setiap pemain mendapat 12 kartu pada awal putaran.

Selalu ada 2 tim yang ditentukan oleh distribusi Queens of Clubs. 2 pemain yang memegang Queens membentuk sebuah tim dan bermain melawan 2 pemain lainnya. Tim dengan Queens of Clubs disebut "Re" -team, yang tanpa "Contra" -team.
Di awal putaran, tidak ada yang tahu siapa yang ada di tim mana. Distribusi tim akan terungkap dalam kemajuan putaran, yang menambah banyak strategi untuk permainan.

Game ini terdiri dari 12 trik. Para pemain yang memenangkan trik mendapatkan semua 4 kartu di dalamnya. Setiap kartu memiliki nilai tertentu (King menghitung 4, Ace menghitung 11 misalnya), semua kartu bersama-sama berjumlah hingga 240 poin yang merupakan hasil tertinggi yang mungkin.

Pada akhir putaran, poin dihitung dan tim dengan jumlah poin tertinggi memenangkan putaran. Kemudian ronde selanjutnya dimulai ...

Tantangan

Setiap putaran memiliki skor tertentu yang ditentukan oleh jumlah poin yang didapat tim pemenang dan pengumuman potensial. Anda harus menulis sebuah program yang mengambil distribusi titik dan pengumuman potensial (lihat penjelasan di bawah) sebagai input dan output skor putaran dan pemenang.

Perhitungan skor

Seperti yang disebutkan ada Re dan tim Contra. Juga ada kemungkinan maksimum 240 poin dalam satu putaran. Re-team harus mendapatkan 121 poin untuk menang, sementara Contra-team hanya perlu 120. Ada juga kemungkinan untuk mengumumkan "Re" atau "Contra" di awal putaran jika Anda berpikir bahwa Anda akan memenangkan permainan. . Dengan melakukan ini, Anda meningkatkan skor.

Berikut adalah aturan penilaian:

  • +1 untuk memenangkan permainan
  • +1 jika tim yang kalah memiliki kurang dari 90 poin ("Keine 90")
  • +1 jika tim yang kalah memiliki kurang dari 60 poin ("Keine 60")
  • +1 jika tim yang kalah memiliki kurang dari 30 poin ("Keine 30")
  • +1 jika tim yang kalah memiliki 0 poin ("Schwarz")
  • +2 untuk pengumuman Contra
  • +2 untuk pengumuman Re
  • +1 jika tim Contra menang ("Gegen die Alten")

Catatan: Pengumuman Kembali / Kontra selalu berlaku, terlepas dari pemenangnya. Lihat contoh di testcases di bawah ini.

Masukan dan keluaran

Input untuk program ini adalah skor Re-team dan pengumuman potensial Re atau Contra. Karena selalu ada 240 poin dalam game, Anda dapat dengan mudah menghitung skor Contra-team.

Input akan berupa string tunggal yang memiliki skor Re-team terlebih dahulu, diikuti oleh pengumuman potensial, sementara "R" untuk Re dan "C" untuk Contra. Jika keduanya diumumkan, Re akan selalu didahulukan.

Output akan menjadi skor pertandingan diikuti oleh tim yang menang ("C" untuk Contra, "R" untuk Re)

Aturan

  • Kiriman Anda dapat berupa program atau fungsi lengkap. Jika Anda memilih yang terakhir, sertakan contoh cara memintanya.
  • Input dapat disediakan oleh argumen fungsi-atau baris perintah atau input pengguna.
  • Output dapat diberikan sebagai nilai balik atau dicetak ke layar.
  • Celah standar berlaku.
  • Byte-Count terendah, menang!

Testcases

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)

Catatan singkat: Saya mengabaikan beberapa aturan (seperti solo dan poin bonus) dengan tujuan untuk menjaga tantangan tetap sederhana. Jadi jika Anda sudah terbiasa dengan game, jangan bingung :)

Selamat Coding!

Denker
sumber

Jawaban:

4

CJam, 47 46 byte

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

Jalankan semua test case.

Hmm, secara konseptual tantangan ini sangat sederhana, tetapi ternyata sangat sulit untuk bermain golf.

Martin Ender
sumber
Setuju, ketika saya mencoba bermain golf ini, saya mencapai sekitar 100 byte dengan bahasa golf. Saya menyerah segera setelah itu.
TheCoffeeCup
4

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

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

Cobalah online!

Ahh, sudah terlalu lama sejak aku menggunakan Labyrinth. Selalu menyenangkan untuk bermain golf. :)

Penjelasan

Ini agak ketinggalan jaman sekarang. Struktur keseluruhan program masih sama, tetapi beberapa detail telah berubah. Saya akan memperbarui ini nanti. Ini adalah solusi sebelumnya, untuk referensi:

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

Mari kita uraikan skornya sedikit:

  • Jika kita menghitung karakter setelah angka dalam input, sebut saja M, maka akan ada 2M+1poin dalam skor akhir, untuk menang, Re, dan Contra.
  • Jika skornya 120 atau kurang, Contra menang dan skor bertambah dengan 1.
  • Melihat skor yang kalah, kita dapat (integer) membaginya dengan 30 untuk menentukan poin tambahan. Itu memiliki tiga masalah: 1. nilai meningkat ke arah yang salah, jadi kita perlu mengurangi dari skor (dan menambahkan 3 untuk memperbaikinya). 2. Ini memberikan poin tambahan untuk hasil yang persis 120, yang perlu kita singkirkan. 3. Ini belum menangani hasil 0 (untuk pihak yang kalah), tetapi kita dapat memasukkannya dengan mengubah 0 menjadi -1 (karena putaran divisi integer Labyrinth mengarah ke arah -∞).

Cukup banyak cara kerjanya. Sp3000 memposting primer yang bagus untuk Labyrinth hari ini, jadi saya memutuskan untuk mencurinya. :)

  • Labyrinth berbasis stack dan dua dimensi, dengan eksekusi dimulai pada karakter yang dikenal pertama. Ada dua tumpukan, tumpukan utama dan tumpukan pembantu, tetapi sebagian besar operator hanya bekerja di tumpukan utama. Kedua tumpukan tidak berdasar, diisi dengan nol.
  • Di setiap cabang labirin, bagian atas tumpukan diperiksa untuk menentukan ke mana harus pergi berikutnya. Negatif belok kiri, nol lurus ke depan dan positif belok kanan.
  • Digit tidak mendorong diri mereka sendiri (seperti yang mereka lakukan di Befunge,> <> atau Prelude) - sebaliknya mereka "menambahkan diri mereka sendiri" ke atas tumpukan, dengan mengalikan bagian atas dengan 10 dan menambahkan diri mereka sendiri.

Jadi eksekusi dimulai pada (baris pertama, dengan penunjuk instruksi (IP) berjalan dengan benar. (cukup putar bagian atas tumpukan utama -1dan }geser ke tumpukan tambahan, di mana kita bisa melupakannya. Program ini benar-benar dimulai dengan ?yang membaca bilangan bulat dari STDIN. IP kemudian menemui jalan buntu dan berbalik.

}menggeser input ke stack bantu dan (menurunkan nol ke -1. Ini akan menjadi skor akhir. Kami sekarang memasuki loop searah jarum jam yang sangat ketat:

;)
,)

The ))bertahap skor oleh dua (jadi saat pertama kali kita pergi melalui loop, skor menjadi 1, skor untuk menang). Kemudian ,membaca sebuah karakter. Selama itu bukan EOF, loop berlanjut. ;membuang karakter, karena kita tidak peduli apakah itu Ratau Cdan ))menambahkan dua untuk skor lagi. Ini akan mengulangi 0, 1 atau 2 kali tergantung pada input.

Kami meninggalkan loop, ketika kami menekan EOF, bagian atas tumpukan akan menjadi -1. Kami kemudian menjalankan bagian linier ini:

`20{:}-

Ini `adalah negasi unary, jadi kita dapatkan 1, lalu 20mengubahnya menjadi 120. {:}mendapat salinan integer input dari stack bantu dan -menghitung perbedaannya dengan 120. Kita dapat menggunakan tanda hasil ini untuk menentukan siapa yang menang.

  1. Jika hasilnya negatif, Re menang dan kami mengambil jalur utara, menjalankan:

    ;}82{_240{-#;
    

    ;membuang hasil ini, }menggeser skor menjauh, 82menempatkan dirinya (kode karakter R) di bagian bawah tumpukan utama, {mendapatkan skor kembali di atas, _240{-mengurangi input bilangan bulat dari 240 sehingga kami dapat bekerja dengan poin Contra (pihak yang kalah).

    Ini #;hanya untuk memastikan bahwa kita memiliki nilai bukan nol pada stack sehingga kita dapat menggabungkan kedua jalur dengan andal.

  2. Jika hasilnya positif, Contra menang dan kami mengambil jalur selatan, menjalankan:

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

    The #mendorong kedalaman tumpukan yang 1. Ini dikurangi dari skor sebelum kita tambahkan 2dengan )). 67menempatkan dirinya (kode karakter C) di bagian bawah tumpukan utama. {{mendapatkan nilai-nilai lainnya kembali.

  3. Jika hasilnya nol, Contra masih menang. Namun, itulah kasus 120/120 di mana kita perlu menambahkan poin tambahan ke skor akhir (lihat di atas). Itu sebabnya jalur ini tidak mendorong 1 dengan #, tetapi sebaliknya hanya meninggalkan nol sehingga -hanya menghapus nol itu dari tumpukan.

Tumpukan sekarang disatukan kembali dan kami telah menghitung semuanya kecuali bagian di mana kami membagi dengan 30. Tapi pertama-tama, kita perlu mengubah skor nol menjadi -1. Itulah yang dilakukan jalan memutar kecil ini:

("
`"~

Tidak `mempengaruhi nol, "adalah no-op dan ~negasi bitwise. Bitwise BUKAN dari 0yang -1diperlukan. Jika skornya positif, maka `buatlah negatif, (turunkan dengan 1dan ~batalkan kedua operasi itu sekaligus.

#0/#--!.@

Kedalaman tumpukan sekarang 3 (karakter sisi yang menang, skor total sejauh ini, dan poin sisi yang kalah), jadi #mendorong 3. 0mengubahnya menjadi 30, /apakah pembagian. #mendorong yang lain 3yang dikurangi dan hasilnya pada gilirannya dikurangi dari skor akhir. !mencetaknya sebagai integer, .mencetak sisi yang menang sebagai karakter dan @mengakhiri program.

Martin Ender
sumber
3

JavaScript (ES6), 106

Sekitar 100 byte dengan bahasa non 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)

Uji

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
sumber
Hanya sekitar dua kali jumlah byte jawaban CJam ... tidak buruk ^^
Denker
2

ES6, 92 byte

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*2melebih-lebihkan skor dengan 1 jika Re menang jadi saya harus mengurangi rlagi. !(n%120)+3-((r?240-n:n)/30|0)adalah apa yang saya buat dengan merangkum aturan untuk mencetak "Keine"; Saya sangat berharap batas-batasnya adalah 31, 61 dan 91 karena itu akan membuat formula 4-((r?269-n:29+n)/30|0).

Neil
sumber