Điểm số của bàn tay Scopa của tôi là gì?


14

Tôi thích những thử thách trong trò chơi bài nên tôi đã thực hiện bài này cho trò chơi bài Scopa của Ý. Gia đình tôi đã chơi trò chơi này từ thời xa xưa. Nó có một hệ thống tính điểm rất thú vị nên rất thú vị khi chơi golf. Tôi sẽ đăng câu trả lời trong R để bắt đầu cuộc vui, tôi chắc chắn mọi người sẽ cải thiện.

Thử thách: tìm ra số điểm ghi được trong một vòng Scopa, đưa ra các thẻ mà người chơi đã bắt được trong vòng làm đầu vào.

Có 40 thẻ trong bộ bài Scopa. Nếu bạn đang sử dụng một cỗ bài quốc tế, bạn loại bỏ 8, 9 và 10, để lại A, 2,3,4,5,6,7, Q, J, K trong mỗi bộ đồ. 1 Có hai người chơi hoặc quan hệ đối tác, và sau mỗi vòng, tất cả các thẻ cuối cùng bị bắt bởi một hoặc hai người chơi khác. Điểm số được tính như sau (thông tin thêm ở đây ):

  • Người chơi có nhiều thẻ nhất ghi được 1 điểm.
  • Người chơi có nhiều kim cương nhất (hoặc tiền xu nếu sử dụng bộ bài Ý) ghi được 1 điểm.
  • Người chơi có 7 viên kim cương (hoặc tiền xu), được gọi là sette bello hoặc bảy người đẹp, ghi được 1 điểm.
  • Người chơi có primiera cao nhất ghi được 1 điểm. Điểm số primiera của người chơi là tổng số điểm của thẻ có giá trị cao nhất mà người chơi đã chụp trong mỗi bộ đồ (xem bảng bên dưới). Nếu bạn không có ít nhất một thẻ trong mỗi bộ đồ, bạn sẽ bị mất theo mặc định ngay cả khi điểm của bạn vượt quá điểm của đối thủ. Trong trường hợp cực kỳ hiếm khi không có người chơi nào có ít nhất một thẻ trong mỗi bộ đồ, người chơi có tổng số primiera cao hơn sẽ ghi điểm. 2

Bảng điểm số primiera

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

Vì vậy, một người chơi có thể ghi nhiều nhất 4 điểm trong một vòng. 3 Nếu có một chiếc cà vạt, có thể dùng cho thẻ, kim cương hoặc primiera , không ai ghi được điểm.

Điều quan trọng là phải nhận ra rằng vì mỗi thẻ phải được bắt bởi một trong hai người chơi, bạn có thể suy ra những thẻ mà người chơi khác phải lấy ngay cả khi bạn chỉ biết người chơi đã lấy thẻ nào. Bạn sẽ cần phải làm điều này để ghi một cách chính xác primiera .

Quy tắc thử thách

Đầu vào

Mã của bạn sẽ lấy làm đầu vào các thẻ được bắt bởi một người chơi trong một vòng Scopa.

Đầu vào phải ở định dạng chuỗi, trong đó một ký tự đại diện cho thứ hạng của mỗi thẻ và một ký tự phù hợp với nó. Điều này loại bỏ lỗ hổng tiềm năng của việc vượt quađiểm số primiera trực tiếp làm đầu vào. Việc chuyển đổi thứ hạng thẻ thànhđiểm số primiera phải được thực hiện trong chương trình. Tuy nhiên, bạn có thể chọn sử dụng một chuỗi được phân tách bằng dấu cách hoặc dấu phẩy, một chuỗi các chuỗi hoặc bất kỳ định dạng nào khác. Ví dụ: nếu bạn chọn mã hóa thứ hạng76A5432QJKvà phù hợp nhưDCHSbạn có thể sử dụng các đầu vào như['7D', '6H', 'QD', 'JS']hoặc'7D,6H,QD,JS'.

Đầu ra

Một số nguyên từ 0 đến 4 đại diện cho điểm của người chơi.

Chiến thắng

Câu trả lời ngắn nhất trong byte chiến thắng!

Các trường hợp thử nghiệm

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

Điểm 4 : 1 điểm cho> 20 thẻ, 1 điểm cho> 5 kim cương, 1 điểm cho 7 viên kim cương và 1 điểm cho 78 điểm trong primiera (7,7,7,5 trong đó đối thủ có 7,6,5, K cho 64)

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

Điểm 0 : <= 20 thẻ, <= 5 kim cương, không 7 kim cương và chỉ đạt 69 điểm trong primiera (7,7,4,3 trong đó đối thủ có 7,7,6, K cho 70)

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

Điểm 3 : 1 điểm cho> 20 thẻ, 1 điểm cho> 5 kim cương, 1 điểm cho 7 kim cương. Các primiera sẽ là 63 (7,7,7) và đối thủ chỉ có thể điểm 51 (7, Q, Q, Q) nhưng kể từ khi bàn tay này không có người mai nó sẽ mất điểm theo mặc định.

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

Điểm 3 : <= 20 thẻ, 1 điểm cho> 5 kim cương, 1 điểm cho 7 kim cương. Các primiera chỉ điểm 51 (7, Q, Q, Q) và đối thủ có thể ghi bàn 63 (7,7,7) nhưng vì tay của đối phương không có kim cương tay này thắng primiera điểm theo mặc định.

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

Điểm 3 : <= 20 thẻ, 1 điểm cho> 5 kim cương, 1 điểm cho 7 kim cương. Mặc dù tay này không có bóng, nhưng nó vẫn thắng primiera với số điểm từ 63 đến 57 (7,7,7 so với 7,6,6) vì tay của đối phương không có kim cương.

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

Điểm 2 : <= 20 thẻ, 1 điểm cho> 5 kim cương, 1 điểm cho 7 kim cương. Bàn tay này không có thuổng, và tay của đối thủ không có kim cương. Đối thủ chiến thắng primiera với số điểm từ 63 đến 41 (7,7,7 so với 7, Q, Q).

[] (mảng trống)

Điểm 0


1: Ít nhất trong gia đình của chúng tôi, Jack vượt xa Nữ hoàng ở Scopa nhưng điều này không liên quan cho mục đích ghi bàn.

2: Tôi đã chơi trò chơi này từ khi còn nhỏ và chưa bao giờ thấy điều đó xảy ra nhưng mã của bạn có thể xử lý trường hợp đó tốt hơn!

3: Có những điểm thưởng cho "số lần quét" được ghi trong vòng mà tôi bỏ qua cho mục đích của thử thách này.


1
Có phải mỗi cấp bậc phải được đại diện bởi một nhân vật riêng biệt?
Doorknob

@Doorknob Không nhất thiết, nhưng ít nhất trong giải pháp tôi đang làm việc tôi thấy cần phải có một ký tự duy nhất cho mỗi cấp bậc để có được tất cả các trường hợp thử nghiệm đúng.
qdread

@Grimy bắt tốt. cảm ơn
qdread

Câu trả lời:


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}

Hãy thử trực tuyến!

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

Điều này sử dụng ;865432000để đại diện 76A5432QJKtương ứng, và phù hợp là chữ thường. (Việc lựa chọn các ký tự là vì trừ 38 từ mỗi ký tự cho giá trị primiera của chúng, nhưng chúng tôi thực sự không bao giờ làm như vậy vì chỉ có sự khác biệt tương đối mới quan trọng.)

Chúng tôi không kiểm tra xem một trong hai người chơi có thiếu một bộ đồ hay không bởi vì nó không cần thiết - vì tất cả các thẻ được tính là 38 cộng với giá trị thực của họ, nếu ai đó thiếu một bộ đồ, điểm số cao nhất họ có thể nhận được là (21 + 38) * 3 = 177, nhỏ hơn (10 + 38) * 3 + 21 + 38 = 203, điểm thấp nhất mà người chơi khác có thể nhận được. Chúng tôi không thể thiếu hai người chơi thiếu số lượng bộ quần áo khác nhau, bởi vì một người chơi chỉ có thể thiếu 0, 1 hoặc 2 bộ quần áo, và nếu ai đó thiếu 2 bộ đồ thì họ có tất cả các thẻ của 2 bộ đồ kia.


4

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

Đây là một giải pháp chủ yếu là do @digEmAll, dưới dạng một hàm.

Hãy thử trực tuyến!

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)

Dưới đây là những nỗ lực tầm thường cũ nhất của tôi cho 209 byte.

chỉnh sửa: đánh gôn bằng cách đặt bí danh một số chức năng, sau đó bằng cách lấy ý tưởng của Doorknob về việc thêm hằng số vào điểm số thay vì kiểm tra các bộ quần áo.

chỉnh sửa tiếp theo: loại bỏ một số dư thừa và sau đó kết hợp một số cải tiến từ Giuseppe

chỉnh sửa tiếp theo: -2 byte nhờ digEmAll

Tôi rất tệ về điều này, vì vậy tôi chắc chắn ai đó có thể cải thiện vấn đề này nếu họ quan tâm đến việc dành thời gian. Tôi cảm thấy như sapplyfunctionsiêu dài và có thể thoát khỏi chúng nhưng tôi không thể tìm ra cách. Đầu vào là các chuỗi hai ký tự trong ký hiệu chuẩn.

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)

1
Bạn có thể nhận được sự giúp đỡ trong phòng chat golf R , digEmAll thậm chí là một người Ý!
Giuseppe

1
Chỉ là một vài lời khuyên nhưng nếu bạn có thể hoán đổi một dấu chấm phẩy chỉ là một dòng mới (có vẻ là một byte trong R), thì đó là một trao đổi miễn phí giúp câu trả lời của bạn dễ đọc hơn. Ngoài ra, hãy kiểm tra Dùng thử trực tuyến , một trình chạy mã trực tuyến nếu bạn chưa có. Không bắt buộc, nhưng một lần nữa, tốt đẹp để sử dụng. Nó thậm chí có thể tạo các bài đăng CGCC
Veskah

1
253 byte - Tôi không hoàn toàn chắc chắn rằng nó sẽ hoạt động, vì tôi chủ yếu thử bộ golf thông thường, nhưng hãy thử và cho tôi biết.
Giuseppe



2

JavaScript (ES6),  171  163 byte

Đưa đầu vào dưới dạng một bộ thẻ, sử dụng biểu diễn tiêu chuẩn của chúng.

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)

Hãy thử trực tuyến!

Đã bình luận

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

2

05AB1E , 41 byte

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

Hãy thử trực tuyến hoặc kiểm tra tất cả các trường hợp thử nghiệm .

Bộ quần áo DCHS tương ứng được đại diện bởi 0123. Cấp bậc7A65432KJQ tương ứng được đại diện bởi 0123456789. Chúng được lấy dưới dạng chuỗi, không phải số nguyên, theo yêu cầu của thử thách (nhưng sau đó 05AB1E chuyển đổi chúng thành số nguyên khi cần dù sao đi nữa).

Như trong các giải pháp khác, chúng tôi thêm một hằng số lớn (14) vào mỗi điểm số primiera để làm cho việc kiểm tra các bộ đồ bị thiếu không cần thiết.

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

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

Hãy thử nó trên db <> fiddle .


1

Võng mạc 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

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. Giải trình:

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

Tạo một danh sách tất cả 40 thẻ.

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

Loại bỏ các thẻ người chơi giữ.

T`67AJQK`8960

Thay thế mỗi thứ hạng theo thứ tự sắp xếp của nó, là 9 cho 7và 10 ít hơn giá trị của nó cho các thẻ khác.

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

Sắp xếp các thẻ theo bộ đồ và cấp bậc.

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

Đếm số lượng thẻ trong mỗi bộ đồ và cũng chiếm được thẻ được xếp hạng cao nhất trong mỗi bộ đồ, bắt được viên kim cương cao nhất hai lần.

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

Kiểm tra xem kim cương cao nhất là 7.

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

Xóa tất cả các thẻ cao nhất nếu một trong những bộ quần áo không có thẻ.

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

Chuyển đổi các thẻ cao nhất thành điểm số unary của họ và tổng hợp chúng lại với nhau. Đồng thời chuyển đổi tổng số thẻ và độ dài phù hợp thành đơn nguyên.

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

Điểm số nếu tổng, kim cương hoặc primiera, cao hơn.

1

Tổng số điểm.



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

Hãy thử trực tuyến!

Phù hợp với bản đồ đến 1234 (4 là kim cương), giá trị bản đồ thành 0123456789. Chương trình này chuyển đổi các trường hợp thử nghiệm thành định dạng được chấp nhận:

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

Mục tiêu của tôi chỉ là đánh bại việc triển khai Python hàng đầu: D


1

Python 3 , 249 245 239 238 byte

-4 byte nhờ @ovs

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

Hãy thử trực tuyến!


1
Ít hơn 2 byte với int('0734569c00'[int(x[0])],13)if x[1]<'E'có thể được viết làif'E'>x[1]
ovs

all(s in''.join(C)for s in S)có thể rút ngắn xuống not S.strip(''.join(C)), tiết kiệm 6 byte
Movatica
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.