Berapa skor tangan Scopa saya?

14

Saya suka tantangan permainan kartu jadi saya membuat yang ini untuk permainan kartu Italia Scopa. Keluarga saya telah memainkan game ini sejak dahulu kala. Ini memiliki sistem penilaian yang sangat menarik yang seharusnya menyenangkan untuk bermain golf. Saya akan memposting jawaban dalam R untuk memulai yang menyenangkan, bahwa saya yakin orang akan meningkat

Tantangannya: mencari tahu jumlah poin yang dicetak dalam putaran Scopa, mengingat kartu yang ditangkap pemain selama putaran sebagai input.

Ada 40 kartu di dek Scopa. Jika Anda menggunakan dek internasional Anda menghapus 8s, 9s, dan 10s, meninggalkan A, 2,3,4,5,6,7, Q, J, K di masing-masing suit. 1 Ada dua pemain atau kemitraan, dan setelah setiap putaran, semua kartu akhirnya ditangkap oleh satu atau dua pemain lainnya. Skor dihitung sebagai berikut (informasi lebih lanjut di sini ):

  • Pemain dengan skor kartu terbanyak 1 poin.
  • Pemain dengan berlian paling banyak (atau koin jika menggunakan dek Italia) mencetak 1 poin.
  • Pemain dengan 7 berlian (atau koin), yang dikenal sebagai sette bello atau tujuh cantik, skor 1 poin.
  • Pemain dengan skor primiera tertinggi 1 poin. Skor primiera pemain adalah jumlah dari skor kartu bernilai tertinggi yang ditangkap oleh pemain dalam setiap suit (lihat tabel di bawah). Jika Anda tidak memiliki setidaknya satu kartu di setiap suit, Anda kehilangan secara default bahkan jika skor Anda akan melebihi skor lawan Anda. Dalam kasus yang sangat jarang terjadi bahwa tidak ada pemain yang memiliki setidaknya satu kartu di setiap suit, pemain dengan primiera yang lebih tinggi akan mencetak poin. 2

Tabel skor primiera

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

Jadi seorang pemain dapat mencetak paling banyak 4 poin dalam satu putaran. 3 Jika ada dasi, yang memungkinkan untuk kartu, berlian, atau primiera , tidak ada yang mendapat nilai.

Penting untuk disadari bahwa karena setiap kartu harus ditangkap oleh salah satu dari dua pemain, Anda dapat menyimpulkan kartu apa yang harus diambil oleh pemain lain walaupun Anda hanya tahu kartu apa yang diambil oleh satu pemain. Anda harus melakukan ini untuk menilai primiera dengan benar .

Aturan tantangan

Memasukkan

Kode Anda harus diambil sebagai input kartu yang diambil oleh satu pemain selama putaran Scopa.

Input harus dalam format string, di mana satu karakter mewakili peringkat setiap kartu dan satu karakter yang sesuai. Ini menghilangkan celah potensial untuk lulusskor primiera secara langsung sebagai input. Konversi peringkat kartu keskor primiera harus dilakukan dalam program. Namun Anda dapat memilih untuk menggunakan string tunggal yang dipisahkan oleh spasi atau koma, array string, atau format lainnya. Misalnya jika Anda memilih untuk menyandikan peringkat sebagai76A5432QJKdan cocok karenaDCHSAnda dapat menggunakan input seperti['7D', '6H', 'QD', 'JS']atau'7D,6H,QD,JS'.

Keluaran

Integer dari 0 hingga 4 mewakili skor pemain.

Kemenangan

Jawaban terpendek dalam byte menang!

Uji kasus

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

Skor 4 : 1 poin untuk> 20 kartu, 1 poin untuk> 5 berlian, 1 poin untuk 7 berlian, dan 1 poin untuk skor 78 di primiera (7,7,7,5 di mana lawan memiliki 7,6,5, K untuk 64)

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

Skor 0 : <= 20 kartu, <= 5 berlian, no 7 berlian, dan hanya skor 69 di primiera (7,7,4,3 di mana lawan memiliki 7,7,6, K untuk 70)

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

Skor 3 : 1 poin untuk> 20 kartu, 1 poin untuk> 5 berlian, 1 poin untuk 7 berlian. The primiera akan 63 (7,7,7) dan lawan hanya bisa mencetak 51 (7, Q, Q, Q) tapi karena tangan ini tidak memiliki sekop kehilangan titik secara default.

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

Skor 3 : <= 20 kartu, 1 poin untuk> 5 berlian, 1 poin untuk 7 berlian. The primiera hanya skor 51 (7, Q, Q, Q) dan lawan bisa mencetak 63 (7,7,7) tapi karena tangan lawan tidak memiliki berlian tangan ini memenangkan primiera titik secara default.

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

Skor 3 : <= 20 kartu, 1 poin untuk> 5 berlian, 1 poin untuk 7 berlian. Meskipun tangan ini tidak memiliki sekop, ia masih memenangkan primiera dengan skor 63 hingga 57 (7,7,7 berbanding 7,6,6) karena tangan lawan tidak memiliki berlian.

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

Skor 2 : <= 20 kartu, 1 poin untuk> 5 berlian, 1 poin untuk 7 berlian. Tangan ini tidak memiliki sekop, dan tangan lawan tidak memiliki berlian. Lawan memenangkan primiera dengan skor 63 hingga 41 (7,7,7 lawan 7, Q, Q).

[] (array kosong)

Skor 0


1: Setidaknya di keluarga kami, Jack mengalahkan Queen di Scopa tetapi ini tidak relevan untuk tujuan mencetak gol.

2: Saya sudah memainkan game ini sejak kecil dan belum pernah melihat itu terjadi tetapi kode Anda lebih baik untuk menangani kasus itu!

3: Ada poin bonus untuk skor "sweep" selama putaran yang saya abaikan untuk tujuan tantangan ini.

qdread
sumber
1
Apakah setiap peringkat harus diwakili oleh karakter yang berbeda?
Gagang Pintu
@ Doorknob Tidak belum tentu, tetapi setidaknya dalam solusi yang saya kerjakan saya merasa perlu untuk memiliki karakter unik untuk setiap peringkat untuk mendapatkan semua kasus uji yang benar.
qdread
@Tangkapan yang bagus sekali. terima kasih
qdread

Jawaban:

6

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

Cobalah 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

Ini digunakan ;865432000untuk mewakili 76A5432QJKmasing-masing, dan pakaian dalam huruf kecil. (Pilihan karakter adalah karena mengurangi 38 dari masing-masing memberikan nilai primiera mereka, tetapi kita tidak pernah benar-benar melakukannya karena hanya perbedaan relatif yang penting.)

Kami tidak memeriksa apakah salah satu pemain kehilangan jas karena itu tidak perlu - karena semua kartu dihitung sebagai 38 ditambah nilai aktualnya, jika seseorang kehilangan jas, skor tertinggi yang bisa mereka dapatkan adalah (21 + 38) * 3 = 177, yang kurang dari (10 + 38) * 3 + 21 + 38 = 203, skor terendah yang bisa didapat pemain lain. Kami tidak dapat memiliki dua pemain yang kehilangan jumlah suit yang tidak nol, karena seorang pemain hanya bisa kehilangan 0, 1, atau 2 suit, dan jika seseorang kehilangan 2 suit, mereka memiliki semua kartu dari 2 suit yang lain.

Gagang pintu
sumber
4

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

Ini adalah solusi sebagian besar karena @digEmAll, dalam bentuk fungsi.

Cobalah 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 bawah ini adalah yang terbaik dari upaya saya yang biasa-biasa saja lama untuk 209 byte.

sunting: bermain golf dengan aliasing beberapa fungsi, lalu dengan mengambil ide Doorknob untuk menambahkan konstanta pada skor alih-alih memeriksa setelan.

suntingan berikutnya: menyingkirkan beberapa redundansi dan kemudian memasukkan beberapa perbaikan dari Giuseppe

sunting berikutnya: -2 bytes berkat digEmAll

Saya buruk dalam hal ini, jadi saya yakin seseorang dapat memperbaiki ini jika mereka mau meluangkan waktu. Saya merasa seperti itu sapplydan functionsangat panjang dan bisa menyingkirkan mereka tetapi saya tidak tahu caranya. Input adalah string dua karakter dalam notasi standar.

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
sumber
1
Anda mungkin bisa mendapatkan bantuan di chatroom golf R , digEmAll bahkan orang Italia!
Giuseppe
1
Hanya beberapa saran tetapi jika Anda dapat menukar titik koma hanya dengan baris baru (yang terlihat sebagai satu byte dalam R), ini merupakan pertukaran gratis yang membuat jawaban Anda lebih mudah dibaca. Juga, periksa Try It Online yang merupakan pelari kode online jika Anda belum. Tidak diperlukan, tapi sekali lagi, senang digunakan. Ia bahkan dapat menghasilkan posting CGCC
Veskah
1
253 byte - Saya tidak sepenuhnya yakin ini akan berhasil, karena saya sebagian besar mencoba set golf yang biasa, tetapi merasa bebas untuk menguji dan memberi tahu saya.
Giuseppe
1
209
digEmAll
2

JavaScript (ES6),  171  163 byte

Mengambil input sebagai satu set kartu, menggunakan representasi standar mereka.

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)

Cobalah online!

Berkomentar

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
sumber
2

05AB1E , 41 byte

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

Cobalah online atau periksa semua test case .

Setelan DCHSmasing-masing diwakili oleh 0123. Peringkat 7A65432KJQmasing-masing diwakili oleh0123456789 . Itu diambil sebagai string, bukan bilangan bulat, seperti yang dipersyaratkan oleh tantangan (tapi kemudian 05AB1E mengubahnya menjadi bilangan bulat bila diperlukan pula).

Seperti dalam solusi lain, kami menambahkan konstanta besar (14) untuk setiap skor primiera untuk membuat pemeriksaan untuk jas yang hilang tidak perlu.

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
```
Grimmy
sumber
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

Cobalah di db <> biola .

Andrei Odegov
sumber
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

Cobalah online! Tautan termasuk kasus uji. Penjelasan:

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

Buat daftar semua 40 kartu.

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

Keluarkan kartu yang dipegang pemain.

T`67AJQK`8960

Ganti setiap peringkat dengan urutannya, yaitu 9 untuk 7dan 10 kurang dari nilainya untuk kartu lainnya.

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

Urutkan kartu berdasarkan jenis dan urutan.

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

Hitung jumlah kartu dalam setiap suit dan juga tangkap kartu dengan peringkat tertinggi di setiap suit, dapatkan berlian tertinggi dua kali.

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

Periksa apakah berlian tertinggi adalah 7.

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

Hapus semua kartu tertinggi jika salah satu kartu tidak memiliki kartu.

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

Konversikan kartu tertinggi menjadi skor unary dan jumlahkan semuanya. Konversi juga jumlah kartu dan panjang kartu menjadi unary.

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

Skor poin jika total, berlian, atau primiera, lebih tinggi.

1

Total skor.

Neil
sumber
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)}

Cobalah online!

Setelan peta ke 1234 (4 adalah berlian), nilai peta ke 0123456789. Program ini mengubah kasus uji menjadi format yang diterima:

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

Tujuan saya hanya untuk mengalahkan implementasi Python terkemuka: D

Daniel LaVine
sumber
1

Python 3 , 249 245 239 238 byte

-4 byte terima kasih kepada @ovs

-6 byte berkat @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'

Cobalah online!

Black Owl Kai
sumber
1
2 byte lebih sedikit dengan int('0734569c00'[int(x[0])],13)dan if x[1]<'E'dapat ditulis sebagaiif'E'>x[1]
ovs
all(s in''.join(C)for s in S)dapat disingkat menjadi not S.strip(''.join(C)), menghemat 6 byte
movatica