Scopa elimin puanı nedir?


15

Kart oyunu zorluklarını seviyorum, bu yüzden bunu İtalyan kart oyunu Scopa için yaptım. Ailem çok eski zamanlardan beri bu oyunu oynuyor. Golf için eğlenceli olması gereken çok ilginç bir puanlama sistemine sahiptir. Eğlenceyi başlatmak için R'de bir cevap göndereceğim, eminim ki insanlar gelişecek.

Zorluk: Tur sırasında oyuncuya girdi olarak alınan kartlar göz önüne alındığında, bir Scopa turunda atılan puan sayısını belirleyin.

Scopa destesinde 40 kart var. Uluslararası bir güverte kullanıyorsanız, her takımda A, 2,3,4,5,6,7, Q, J, K bırakarak 8s, 9s ve 10'ları kaldırırsınız. 1 İki oyuncu veya ortaklık vardır ve her turdan sonra tüm kartlar iki oyuncudan biri veya diğeri tarafından yakalanır. Puan aşağıdaki gibi sayılır (daha fazla bilgi burada ):

  • En fazla kart alan oyuncu 1 puan alır.
  • En fazla pırlantalı oyuncu (veya İtalyan destesi kullanılıyorsa bozuk para) 1 puan alır.
  • Sette bello veya güzel yedi olarak bilinen 7 elmas (veya madeni para) ile oyuncu 1 puan alır.
  • En yüksek primiera'ya sahip oyuncu 1 puan alır. Bir oyuncunun primiera puanı, oyuncunun her takımda yakaladığı en yüksek değerli kartın puanlarının toplamıdır (aşağıdaki tabloya bakın). Her takımda en az bir kartınız yoksa, puanınız rakibinizin puanını aşsa bile varsayılan olarak kaybedersiniz. Her iki takımın da her takımda en az bir kart bulunmadığı çok nadir durumlarda, primiera toplamı daha yüksek olan oyuncu puanı alır. 2

Primiera skorları tablosu

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

Böylece bir oyuncu bir turda en fazla 4 puan kazanabilir. 3 Kartlar, elmaslar veya primiera için mümkün olan bir kravat varsa , kimse puanı alamaz .

Her kartın iki oyuncudan biri tarafından yakalanması gerektiğinden, yalnızca bir oyuncunun hangi kartları aldığını bilseniz bile diğer oyuncunun hangi kartları alması gerektiğini anlamanız önemlidir. Primiera'yı doğru bir şekilde puanlamak için bunu yapmanız gerekecektir .

Zorluk kuralları

Giriş

Bir Scopa turu sırasında kodunuz tek bir oyuncu tarafından çekilen kartları girdi olarak almalıdır.

Giriş, bir karakterin her bir kartın sırasını ve bir karakterin de uygunluğunu temsil ettiği dize biçiminde olmalıdır. Bu, primiera skorlarını doğrudan girdi olarakgeçirme potansiyel boşluklarını ortadan kaldırır. Kart sıralarının primiera puanlarınadönüşümüprogramda yapılmalıdır. Ancak boşluk veya virgülle ayrılmış tek bir dize, bir dize dizisi veya başka bir biçim kullanmayı seçebilirsiniz. Örneğin, sıraları veya gibi76A5432QJKuygunşekilde kodlamayı seçersenizveyaDCHSgibi girişler kullanabilirsiniz.['7D', '6H', 'QD', 'JS']'7D,6H,QD,JS'

Çıktı

Oyuncunun puanını temsil eden 0 ile 4 arasında bir tam sayı.

Kazanan

Bayt cinsinden en kısa cevap kazanır!

Test senaryoları

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

Skorlar : 20 kart için 1 puan,> 5 elmas için 1 puan, elmas 7 için 1 puan ve primiera'da 78 puan için 1 puan (rakibin 7,6,5 olduğu 7,7,7,5, 64 için K)

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

Skorlar 0 : <= 20 kart, <= 5 elmas, 7 elmas yok ve sadece primiera'da 69 skor var (rakibin 7,7,6, 70 için K olduğu 7,7,4,3)

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

Puanlar : 20 kart için 1 puan,> 5 elmas için 1 puan, 7 elmas için 1 puan. Primiera 63 (7,7,7) olacak ve rakip sadece bu eli hiçbir maça beri 51 (7, Q, Q, Q) ancak varsayılan olarak puan kaybeder puanı.

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

Skorlar 3 : <= 20 kart,> 5 elmas için 1 puan, 7 elmas için 1 puan. Primiera sadece puanları 51 (7, Q, Q, Q) ve rakip 63 (7,7,7) puanı ama rakibin eli hiçbir elmas beri bu el kazanır primiera varsayılan olarak nokta.

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

Skorlar 3 : <= 20 kart,> 5 elmas için 1 puan, 7 elmas için 1 puan. Bu elin maça olmamasına rağmen, hala 63 ila 57 (7,7,7'ye karşı 7,6,6) skorla primiera kazanır, çünkü rakibin elinde elmas yoktur.

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

Skorlar 2 : <= 20 kart,> 5 elmas için 1 puan, 7 elmas için 1 puan. Bu elin maça yok ve rakibin elinde elmas yok. Rakip primiera'yı 63 ile 41 arasında (7,7,7'ye karşı 7, Q, Q) kazanır .

[] (boş dizi)

Puanlar 0


1: En azından ailemizde Jack, Scopa'daki Kraliçe'yi geride bıraktı, ancak bu puanlama amaçlarıyla alakasız.

2: Bu oyunu çocukluğumdan beri oynuyorum ve bunun olduğunu hiç görmedim ama kodunuzun bu davayı ele alması daha iyi olmuştu!

3: Tur sırasında attığım "tarama" için bu puanlar için göz ardı ettiğim bonus puanlar var.


1
Her rütbenin farklı bir karakterle temsil edilmesi gerekiyor mu?
Kapı tokmağı

@Doorknob Gerek yok, ama en azından üzerinde çalıştığım çözümde, tüm test senaryolarını doğru bir şekilde elde etmek için her bir sıralama için benzersiz bir karaktere sahip olmanın gerekli olduğunu gördüm.
qdread

@Grimy iyi yakalama. teşekkürler
qdread

Yanıtlar:


6

Yakut, 156153 bayt

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

Çevrimiçi deneyin!

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

Bu sırasıyla ;865432000temsil etmek için kullanır 76A5432QJKve takım elbise küçük harflidir. (Karakter seçimi, her birinden 38 çıkartılmasının başlangıç ​​değerlerini vermesidir, ancak bunu asla görmüyoruz çünkü sadece göreceli fark önemlidir.)

Her iki oyuncunun da bir takımını kaçırıp kaçırmadıklarını kontrol etmiyoruz çünkü tüm kartlar 38 artı gerçek değerleri olarak sayıldığından, eğer biri takımını kaçırırsa, alabilecekleri en yüksek puan (21 + 38) * 3 = 177, ki bu (10 + 38) * 3 + 21 + 38 = 203 'den daha az, diğer oyuncunun alabileceği en düşük puan. İki oyuncunun eşit olmayan bir sayıdaki takımını kaçırmasını sağlayamayız, çünkü bir oyuncu sadece 0, 1 veya 2 takımını kaybedebilir ve birisi 2 takımını kaçırırsa, diğer 2 takımın tüm kartlarına sahiptir.


4

R 320 298 265 238 229 224 211 209 179 bayt

Bu çoğunlukla @digEmAll nedeniyle bir işlev biçiminde bir çözümdür.

Çevrimiçi deneyin!

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)

Aşağıda 209 baytlık eski vasat girişimlerimin en iyisi var.

Diğerleri

sonraki düzenleme: fazlalıktan kurtuldu ve Giuseppe'dan bazı iyileştirmeler yaptı

sonraki düzenleme: digEmAll sayesinde -2 bayt

Ben bu konuda korkunçum, bu yüzden eminim eğer zaman ayırmaya önem verirse birinin bunu geliştirebilir. Kendimi gibi hissediyorum sapplyve functionsüper uzun ve onlardan kurtulabilirim ama nasıl olduğunu anlayamıyorum. Girişler standart gösterimde iki karakterli dizelerdir.

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 golf sohbet odasında yardım alabilirsiniz , digEmAll bile bir dost İtalyan!
Giuseppe

1
Sadece bir tavsiye ama eğer bir noktalı virgül sadece bir satırsonu (R'de bir bayt gibi görünüyor) takas edebiliyorsanız, cevabınızı daha okunabilir hale getiren ücretsiz bir takastır. Ayrıca, henüz yapmadıysanız çevrimiçi bir kod koşucusu olan Try It Online'a bakın . Gerekli değil, ama yine, kullanımı güzel. CGCC gönderileri bile oluşturabilir
Veskah

1
253 bayt - Ben çoğunlukla olağan golf seti deniyordu çünkü bu işe yarayacağından emin değilim, ama test ve bana bildirin çekinmeyin.
Giuseppe




2

JavaScript (ES6),  171  163 bayt

Standart temsillerini kullanarak girişi bir kart seti olarak alır.

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)

Çevrimiçi deneyin!

Yorumlananlar

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 bayt

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

Çevrimiçi deneyin veya tüm test senaryolarını kontrol edin .

Takımlar DCHSsırasıyla ile temsil edilir 0123. Rütbeler 7A65432KJQsırasıyla ile temsil edilir 0123456789. Bunlar, meydan okuma tarafından istendiği gibi tamsayılar değil, dizeler olarak alınır (ancak 05AB1E, yine de gerektiğinde bunları tamsayılara dönüştürür).

Diğer çözümlerde olduğu gibi, eksik takımları kontrol etmeyi gereksiz kılmak için her primiera skoruna büyük bir sabit (14) ekliyoruz.

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 bayt

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 <> keman üzerinde deneyin .


1

Retina 0.8.2 , 334 bayt

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

Çevrimiçi deneyin! Bağlantı, test senaryolarını içerir. Açıklama:

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

40 kartın bir listesini oluşturun.

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

Oynatıcının sahip olduğu kartları çıkarın.

T`67AJQK`8960

Her bir sıralamayı, 7diğer kartlar için değerinden 9 ve 10'dan düşük olan sıralama düzeniyle değiştirin .

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

Kartları takım elbise ve rütbe göre sıralayın.

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

Her takımdaki kart sayısını sayın ve her takımda en yüksek dereceli kartı yakalayın, en yüksek elması iki kez yakalayın.

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

En yüksek elmasın 7 olup olmadığını kontrol edin.

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

Takımlardan birinde kart yoksa tüm en yüksek kartları silin.

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

En yüksek kartları tekli puanlarına dönüştürün ve toplayın. Ayrıca toplam kart sayısını ve takım uzunluğunu tekli olarak dönüştürün.

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

Toplam, elmas veya primiera daha yüksekse puan kazanın.

1

Skoru topla.


1

AWK , 235 bayt

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

Çevrimiçi deneyin!

Haritayı 1234'e (4 elmastır), değerler 0123456789'a eşleştirir. Bu program test senaryolarını kabul edilen biçime dönüştürür:

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

Amacım sadece önde gelen Python uygulamasını yenmekti: D


1

Python 3 , 249 245 239 238 bayt

@Ovs sayesinde -4 bayt

@Movatica sayesinde -6 bayt

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'

Çevrimiçi deneyin!


1
int('0734569c00'[int(x[0])],13)if x[1]<'E'if'E'>x[1]
İle

all(s in''.join(C)for s in S)kısaltılabilir not S.strip(''.join(C)), 6 bayt tasarruf
movatica
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.