我的Scopa手的分数是多少?


14

我喜欢纸牌游戏的挑战,所以我是为意大利纸牌游戏Scopa制作的。自古以来,我的家人就一直在玩这种游戏。它有一个非常有趣的计分系统,对高尔夫来说应该很有趣。我将在R中发布答案以开始乐趣,我相信人们会有所改善。

挑战:鉴于玩家在这一轮中捕获的卡牌作为输入,计算出Scopa回合中得分的数量。

Scopa牌组中有40张卡片。如果您使用的是国际牌,则删除8、9和10,在每套西装中保留A,2、3、4、5、6、7,Q,J,K。1有两个玩家或合伙企业,每轮比赛结束后,所有纸牌最终被两个玩家中的一个抓获。得分计算如下(此处有更多信息):

  • 数最多的玩家得分1分。
  • 拥有最多钻石(如果使用意大利套牌,则为硬币)的玩家获得1分。
  • 拥有7颗钻石(或硬币)的玩家,称为sette bello或漂亮的7颗,得分为1分。
  • 拥有最高级初阶球员的球员得到1分。玩家的原始分数是该玩家在每套西装中捕获的最高价值卡的分数总和(请参见下表)。如果每套西装中至少没有一张牌,即使您的得分超过对手的得分,您也会默认丢失。在极少见的情况下,每位球员都没有至少一张牌的情况下,具有较高初等总得分的球员得分。2

原始评分表

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

因此,一个玩家最多可以在一个回合中得分4分。3如果出现平局,这对于卡,钻石或初等都可能,则没有人得分。

重要的是要意识到,由于每张纸牌必须由两名玩家之一抓取,因此即使您只知道一位玩家拿了哪些卡,也可以推断另一位玩家必须拿过哪些卡。您需要执行此操作才能正确对primiera评分。

挑战规则

输入值

您的代码应将一轮Scopa期间单个玩家捕获的卡作为输入。

输入必须采用字符串格式,其中一个字符代表每张卡的等级,一个字符代表其卡号。这消除了将原始分数直接作为输入传递的潜在漏洞。卡等级到原始分数的转换必须在程序中完成。但是,您可以选择使用由空格或逗号分隔的单个字符串,字符串数组或任何其他格式。例如,如果您选择将等级编码为76A5432QJK和适合,则DCHS可以使用诸如['7D', '6H', 'QD', 'JS']或的输入'7D,6H,QD,JS'

输出量

从0到4的整数,表示玩家的分数。

获奖

以字节为单位的最短答案胜出!

测试用例

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

得分4:> 20张卡片可得1分,> 5钻石可得1分,钻石7得1分,普里米耶拉(78,7,7,5,其中对手有7,6,5, K为64)

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

得分0:<= 20张牌,<= 5颗钻石,没有7颗钻石,并且在原始等级中仅得分69 (7,7,4,3,其中对手有7,7,6,K代表70)

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

得分3:> 20张卡片1分,> 5钻石1分,7钻石1分。该primiera将是63(7,7,7),而对手只能得分51(7,Q,Q,Q),但由于这手有没有黑桃失去默认点。

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

分数3:<= 20张卡片,> 5颗钻石1分,7颗钻石1分。该primiera唯一得分51(7,Q,Q,Q)和对手能得分63(7,7,7),但由于对手的手有没有钻石这一手赢得primiera默认点。

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

分数3:<= 20张卡片,> 5颗钻石1分,7颗钻石1分。即使这只手没有黑桃,但由于对手的手没有钻石,因此它仍然以63:57(7,7,7对7,6,6)的优势赢得初选

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

得分2:<= 20张卡片,> 5颗钻石1分,7颗钻石1分。这只手没有黑桃,对手的手没有钻石。对手以63:41的比分赢得初选(7,7,7对7,7,Q,Q)。

[] (空数组)

分数0


1:至少在我们的家庭中,杰克在斯科帕区的排名超过皇后区,但这与计分目的无关。

2:我从小就开始玩这个游戏,但从未见过这种情况,但是您的代码最好能够处理这种情况!

3:在本轮比赛中,“扫奖”获得了一些加分,而我为此挑战而忽略了这一点。


1
每个等级都必须用不同的字符表示吗?
门把手

@Doorknob不一定,但是至少在我正在研究的解决方案中,我发现有必要为每个等级使用一个唯一的角色,以使所有测试用例正确。
qdread

@肮脏的好收获。谢谢
qdread19 19/09/26

Answers:


6

红宝石,156个 153字节

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

在线尝试!

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

;865432000用来代表76A5432QJK分别,并且西装是小写的。(选择字符是因为从每个字符中减去38会得到其原始值,但实际上我们从来没有这样做,因为只有相对差异很重要。)

我们不会检查是否有任何一方因为不必要而缺衣服-因为所有牌都算为38加其实际值,如果有人缺衣服,他们可以获得的最高分数是(21 + 38)* 3 = 177,小于(10 + 38)* 3 + 21 + 38 = 203,这是其他玩家可以获得的最低分数。我们不能让两个玩家缺少不相等的非零套数,因为一个球员只能缺少0、1或2套西服,并且如果某人缺少2套西服,他们将拥有其他2套西服的所有牌。


4

R,320 298 265 238 229 224 211 209 179字节

这主要是由于@digEmAll以函数形式提供的解决方案。

在线尝试!

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)

以下是我对209个字节的平庸尝试中最好的一次。

编辑:通过混叠一些功能,然后采用Doorknob的想法,在分数中添加常数而不是检查花色,来降低高尔夫运动的难度。

下一个编辑:摆脱了一些冗余,然后合并了Giuseppe的一些改进

下一个编辑:-2个字节,感谢digEmAll

我对此很糟糕,所以我敢肯定,如果有人愿意花些时间,可以在此方面有所改进。我觉得,sapply而且function很长,可以摆脱它们,但是我不知道怎么做。输入是标准表示法中的两个字符的字符串。

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
您可能可以在R高尔夫聊天室获得帮助,digEmAll甚至是意大利人!
朱塞佩

1
只是一些建议,但是如果您可以将分号替换为换行符(在R中看起来是一个字节),则这是一次免费交换,使您的答案更具可读性。另外,如果您还没有在线试用,请尝试在线试用。不需要,但再次使用非常好。它甚至可以生成
CGCC

1
253字节 -我不太确定这是否行得通,因为我主要尝试的是普通的高尔夫运动,但请随时进行测试并告知我。
朱塞佩



2

JavaScript(ES6), 171  163字节

使用其标准表示,将输入作为一组卡输入。

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)

在线尝试!

已评论

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个字节

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

在线尝试检查所有测试用例

西装 DCHS分别用表示0123。等级7A65432KJQ分别由0123456789。根据质询的要求,它们被当作字符串,而不是整数(但是05AB1E仍会在需要时将它们转换为整数)。

像在其他解决方案中一样,我们为每个基本得分添加一个大常数(14),以使得不必检查丢失的衣服。

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

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

db <> fiddle上尝试。


1

视网膜0.8.2,334字节

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

在线尝试!链接包括测试用例。说明:

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

创建所有40张卡的列表。

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

取出玩家持有的卡。

T`67AJQK`8960

将每个等级替换为其排序顺序,该顺序为9,7比其他卡的值低10。

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

按衣服和等级对卡片进行排序。

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

计算每套西装中的纸牌数量,并捕获每套西装中排名最高的纸牌,两次捕获最高的钻石。

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

检查是否最高的钻石是7。

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

如果其中一套西装没有卡,则删除所有最高的卡。

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

将最高的卡转换为一元分数,然后将它们加在一起。还将卡和西服长度的总数转换为一元。

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

如果总分数,钻石分数或原始分数更高,则得分。

1

总分。



1

AWK,235字节

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

在线尝试!

西装映射到1234(4是菱形),值映射到0123456789。此程序将测试用例转换为可接受的格式:

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

我的目标只是击败领先的Python实现:D


1

Python 3中249个245 239 238字节

-4个字节,感谢@ovs

-6个字节,感谢@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'

在线尝试!


1
少2个字节int('0734569c00'[int(x[0])],13)if x[1]<'E'可以写成if'E'>x[1]
ovs

all(s in''.join(C)for s in S)可以缩短为not S.strip(''.join(C)),节省6个字节
movatica
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.