So sánh hai tay bài xì phé


14

Thử thách:

Đưa ra hai ván bài năm lá, xác định tay bài nào thắng theo thứ hạng tiêu chuẩn của ván bài xì phé .

Đầu vào:

Mười thẻ được phân tách bằng khoảng trắng từ stdin hoặc làm đối số dòng lệnh, tùy theo bạn thích. Năm thẻ đầu tiên là tay của Người chơi 1 trong khi năm thẻ cuối cùng là tay của Người chơi 2. Mỗi thẻ sẽ là một chuỗi hai chữ cái có dạng RS trong đó R là xếp hạng và S là phù hợp. Các cấp bậc dao động từ 2-9, T cho mười và J, Q, K và A cho Jack, Queen, King và Ace tương ứng. Các bộ đồ lần lượt là H, D, C, S cho Trái tim, Kim cương, Câu lạc bộ và Spades. Bạn phải xuất số lượng người chơi thắng: '1' hoặc '2'.

Ví dụ về Thẻ:

AS - the Ace of Spades
QD - the Queen of Diamonds
2C - the Two of Clubs
TH - the Ten of Hearts

Ví dụ đầu vào cho đầu ra:

5H 5C 6S 7S KD 2C 3S 8S 8D TD -> 2

Giải thích: Người chơi 1 có Cặp đôi trong khi Người chơi 2 có Cặp đôi.

5D 8C 9S JS AC 2C 5C 7D 8S QH -> 1

Giải thích: Cả Người chơi đều không có gì đặc biệt, nhưng thẻ cao của Người chơi 1 là Ace trong khi Thẻ cao của Người chơi 2 là Nữ hoàng.

2D 9C AS AH AC 3D 6D 7D TD QD -> 2

Giải thích: Người chơi 1 có Ba Ách, Người chơi 2 có Flush of Diamonds.

4D 6S 9H QH QC 3D 6D 7H QD QS -> 1

Giải thích: Cả hai người chơi đều có Cặp Nữ hoàng, nhưng thẻ cao thứ hai của Người chơi 1 là Chín trong khi Người chơi 2 là Bảy.

Các quy tắc và làm rõ:

  • Tham khảo bảng xếp hạng tiêu chuẩn của tay bài poker để biết chi tiết so sánh tay bài.
  • Bạn có thể cho rằng không có thẻ lặp lại trong mỗi cặp tay.
  • Bạn có thể cho rằng có một người chiến thắng nhất định trong mỗi trường hợp.
  • Suit không phải là yếu tố để xếp hạng của một bàn tay. Ví dụ: hai tuôn ra hoàng gia của các bộ quần áo khác nhau là bằng nhau (do đó, bất kỳ đầu vào nào mà cả hai người chơi có tuôn ra hoàng gia đều không hợp lệ theo quy tắc trước).
  • Vì đây là mã golf, câu trả lời ngắn nhất sẽ thắng.

Ghi chú:


Xin lỗi nếu có bất cứ điều gì tôi đã bỏ lỡ! Đây là câu hỏi golf mã đầu tiên của tôi.
Commando

Điều này tương tự với câu hỏi gần đây codegolf.stackexchange.com/q/23743/15599 và phiên bản 5 thẻ được tham chiếu trong đó. Tuy nhiên, những câu hỏi chỉ yêu cầu đặt tên cho loại tay. Một sự khác biệt lớn ở đây là nếu cả hai người chơi có cùng một loại tay, chúng tôi phải xác định loại nào tốt hơn theo cấp bậc thẻ (ví dụ: đối với hai cặp, ai có cặp thứ nhất, cặp thứ hai tốt nhất và nếu cần một thẻ duy nhất.) nó không phải là một bản sao Luôn luôn tìm kiếm các câu hỏi tương tự, liên kết chúng, (tôi thấy bạn đã làm) và sẵn sàng bảo vệ tại sao nó không phải là một bản sao trước khi đăng.
Cấp sông St

Nếu flop và hand giống nhau thì sao?
Ismael Miguel

@IsmaelMiguel Không có flop trong phiên bản này. Đơn giản là có hai bàn tay riêng biệt phải được đánh giá với nhau.
Commando

1
Đã giải quyết trước đó cho 10 thẻ tại đây
Hasturkun

Câu trả lời:


2

Haskell - 352 339 ký tự

import Data.List
v h=10*(sum$map(\l->l*l)g)+b g:k where
  (g,k)=unzip$reverse$sort$map(\r->(length r,head r))$group$sort$map(maybe 0 id.(`elemIndex`"23456789TJQKA").head)h
  b(1:_)=f(map(!!1)h)+t k;b _=0
f(y:z)|all(==y)z=75;f _=0
t[y,_,_,_,z]|y-z==4=70;t[12,3,2,1,0]=65;t _=0
w(a,b)|v a>v b="1\n";w _="2\n"
main=interact$w.splitAt 5.words

Chạy:

& echo "5H 5C 6S 7S KD 2C 3S 8S 8D TD" | runhaskell 25056-Poker.hs 
2

& echo "5D 8C 9S JS AC 2C 5C 7D 8S QH" | runhaskell 25056-Poker.hs 
1

& echo "2D 9C AS AH AC 3D 6D 7D TD QD" | runhaskell 25056-Poker.hs 
2

& echo "4D 6S 9H QH QC 3D 6D 7H QD QS" | runhaskell 25056-Poker.hs 
1

Ungolf'd và nhận xét, vì vậy bạn có thể thấy techinque:

import Data.List

value :: [String] -> [Int]
value hand = 10 * (sum $ map (\l->l*l) groups) + bonus groups : kicker
    -- ^ Value of a hand is 10 times the sum of the squares of the group lengths
    -- plus the straight & flush bonus, followed by the kicker (to break ties)
    -- This 10 * sum-of-squares + bonus works out to put the hands in category
    -- order, and then they only need to be ordered by card ranks.
  where
    -- | The cards are sorted into groups by matching rank, then the groups
    -- sorted by length and rank: For example: "7C 7D 7H QS 2S" will becomes
    -- [(3,7),(1,Q),(1,2)]. This is like a run-length encoding. Finally, the
    -- groups lengths, and the kicker ranks are taken apart into two lists.
    -- N.B: kicker here includes the ranks of the groups, unlike the poker term.

    (groups,kicker) = unzip             -- split apart
        $ reverse $ sort                -- reverse sort by (length,rank)
        $ map (\r->(length r,head r))   -- turn groups into (length,rank) pairs
        $ group $ sort                  -- group sorted ranks
        $ map (maybe 0 id . (`elemIndex`"23456789TJQKA") . head) hand
            -- take first letter of each card in the hand, and map to [0..12]

    -- | Give a bonus for flush and straight to hands with five cards,
    -- or equivalently hands where the largest group length is just 1
    bonus (1:_ ) = flush (map (!!1) hand)   -- flush takes the suits of the hand
                   + straight kicker        -- straight takes the ranks
    bonus _      = 0

    -- | A flush is if all suits match the first suit
    flush (y:z) | all (==y) z = 75
                | otherwise   =  0

    -- | There are two kinds of straight.
    -- N.B: If there are five groups, then there are no duplicate ranks
    straight [y,_,_,_,z] | y-z == 4 = 70    -- normal, high to low
    straight [12,3,2,1,0]           = 65    -- ace is low, but it sorts high
    straight _                      =  0

wins :: ([String], [String]) -> String
wins (a,b) | value a > value b = "1\n"
           | otherwise         = "2\n"

main = interact $ wins . splitAt 5 . words

2

Python - 774 722 707 698 685 ký tự

import sys
t,q,e,u='--23456789TJQKA','SDCH',enumerate,len
_=lambda c,i=0:chr(97+c[i])
def j(s):
 v,g,l=[0]*15,[0]*4,''
 for c in s:
  r,s=c[0],c[1];v[t.find(r)]+=1;g[q.find(s)]+=1
 c,h,k,m,f=0,0,[0,0,[],[],[]],0,0
 for x,i in e(v):
  for b in[2,3,4]:
   if i==b:k[b]+=[x]
 v[1]=v[14]
 for x,i in e(v):
  if i:
   c+=1
   if c==5:m,h=1,x
   if i==1:l+=_([x])
  else:c=0
 f,l,d=max(g)//5*2,l[::-1],'';z=f+m
 if z==3:d='z'+l
 if k[4]:d='y'+_(k[4])+l
 if k[2] and k[3]:d='x'+_(k[3])+_(k[2])
 if z==2:d='w'+l
 if z==1:d='v'+_([h])
 if k[3]:d='u'+_(k[3])+l
 if u(k[2])>1:d='t'+_(k[2],1)+_(k[2])+l
 if u(k[2])==1>u(k[3]):d='s'+_(k[2])+l
 return d or l
p=sys.argv
print(1+(j(p[1:6])<j(p[6:])))

Tôi đã chọn tạo một chuỗi cho mỗi tay đại diện cho nó, bắt đầu bằng một ký tự cho loại tay, tiếp theo là các ký tự mô tả biến thể cụ thể của loại (ví dụ: bạn vừa có 4 thẻ nào?), Tiếp theo là các giá trị của các thẻ còn lại trong trường hợp hòa (nếu cả hai người chơi có cùng một cặp, thẻ thứ 5 sẽ phải quyết định ai thắng). Tôi đã thử nghiệm nó khá rộng rãi, nhưng tôi không thực sự chơi bài xì phé, vì vậy tôi hy vọng tôi đã làm đúng. Ngoài ra, tôi biết nó chưa được đánh gôn hoàn toàn, tôi có thể cạo đi vài chục ký tự sau này.


Giết 5 ký tự với _=lambda c:chr(97+c). Ngoài ra, bạn có một số khoảng trắng không cần thiết sau :s và =s. Cuối cùng, sử dụng ;thay vì các dòng mới để phân tách các câu lệnh để giảm khoảng trắng được sử dụng để thụt lề.
dùng12205

Đẹp một với lambda, cảm ơn!
Tal

2

JavaScript - 526 508

function a(b){b=b.split(" ");var c=b.splice(5,5),d=[],e=[],r=[8,9,5,6,1,2,3,10,4,7],A=14,K=13,Q=12,J=11,S={"S":1,"C":2,"H":4,"D":8};for(i=0;i<5;i++){d.push(b[i].split('')[1]);b[i]=b[i].split('')[0];e.push(c[i].split('')[1]);c[i]=c[i].split('')[0]}function p(w,m){var v,i,o,s=1<<w[0]|1<<w[1]|1<<w[2]|1<<w[3]|1<<w[4];for(i=-1,v=o=0;i<5;i++,o=Math.pow(2,w[i]*4)){v+=o*((v/o&15)+1)}v=v%15-((s/(s&-s)==31)||(s==0x403c)?3:1);v-=(m[0]==(m[1]|m[2]|m[3]|m[4]))*((s==0x7c00)?-5:1);return r[v]}alert(p(b,d)>p(c,e)?1:2)}

sử dụng:

a("5H 5C 6S 7S KD 2C 3S 8S 8D TD");

vô dụng:

function a(b) {
b = b.split(" ");
var c=b.splice(5,5),
        d=[],
        e=[],
        r=[8,9,5,6,1,2,3,10,4,7],
        A=14,
        K=13,
        Q=12,
        J=11,
        S={"S":1,"C":2,"H":4,"D":8};

    for (i=0;i<5;i++) {
        d.push(b[i].split('')[1]);
        b[i] = b[i].split('')[0];
        e.push(c[i].split('')[1]);
        c[i] = c[i].split('')[0];   
    }

function p(w,m){
  var v, i, o, s = 1<<w[0]|1<<w[1]|1<<w[2]|1<<w[3]|1<<w[4];
  for (i=-1, v=o=0; i<5; i++, o=Math.pow(2,w[i]*4)) {v += o*((v/o&15)+1);}
  v = v % 15 - ((s/(s&-s) == 31) || (s == 0x403c) ? 3 : 1);
  v -= (m[0] == (m[1]|m[2]|m[3]|m[4])) * ((s == 0x7c00) ? -5 : 1);
  return r[v];
}

alert(p(b,d)>p(c, e)?1:2);
}

nguồn


1

perl, 801 733 ký tự

Tôi tin rằng đây là một triển khai khá đơn giản. Về cơ bản, đối với mỗi tay, chúng tôi sắp xếp các bộ đồ và khuôn mặt riêng biệt. Sau đó, chúng tôi tạo một bản sao khác của các khuôn mặt với con át chủ bài thấp để chúng tôi có thể kiểm tra sức căng với con át chủ bài thấp. Sau đó, chúng tôi xác định nếu chúng tôi có một tuôn ra hoặc thẳng, và thẻ cao là gì. Sau đó, chúng tôi chỉ kiểm tra các trận đấu theo thứ tự điểm số (đầu tiên chúng tôi kiểm tra các lần xả thẳng, sau đó là bốn trong số các loại, v.v.). Điểm thực tế chỉ là sự kết hợp của loại tay theo sau là các giá trị khuôn mặt của các thẻ theo thứ tự chúng quan trọng (đó là _s () trong phiên bản không được đánh dấu, u () trong phiên bản chơi gôn). Đây là:

@l{2..9,qw(T J Q K A)}=2..14;sub u{join"",map{$_>9?$_:"0$_"}shift,ref$_[0]?$$_[0]:map{$h[$_]}@_}sub e{$p[$_[0]-1]-1==$p[$_[0]]}sub f{@p=@_;e(1)&&e(2)&&e(3)&&e 4}sub h{$h[$_[0]]==$h[$_[1]]}sub i{h(@_[0,1])&&h @_[2,3]}sub t{@s=sort map{substr($_,1)}@_;$f=$s[0]eq$s[4];@l=@h=sort{$b<=>$a}map{$l{substr($_,0,1)}}@_;@l=(@l[1..4],1)while$l[0]==14;$s=0;if(f@l){$s=1;$h=$l[0]}else{$h=$h[0];$s=1 if f@h}$f&&$s?u 9,\$h:h(4,1)?u 7,4,0:h(3,0)?u 7,3,4:i(4,3,2,0)?u 6,0,4:i(4,2,1,0)?u 6,4,0:$f?u 5,0:$s?u 4,\$h:h(4,2)?u 3,4,0,1:h(3,1)?u 3,3,0,4:h(2,0)?u 3,2..4:i(4,3,2,1)?u 2,2,4,0:i(4,3,1,0)?u 2,1,4,2:i(3,2,1,0)?u 2,1,3,4:h(4,3)?u 1,4,0,1,2:h(3,2)?u 1,3,0,1,4:h(2,1)?u 1,2,0,3,4:h(1,0)?u 1,1..4:u 0,0..4}print t(@ARGV[0..4])gt t(@ARGV[5..9])?1:2

Và đây là tương đương ít chơi gôn:

use strict;
use warnings;

# ace high or low in straights, otherwise high
# T = ten, J = jack, Q = queen, K = king, A = ace

# 0 high card
# 1 one pair
# 2 two pair
# 3 3 of a kind
# 4 straight
# 5 flush
# 6 full house
# 7 four of a kind
# 9 straight flush (royal flush a subclass of straight flush)

my %l;@l{2..9,qw(T J Q K A)}=2..14;
sub score {
  my @suits = sort map { substr($_,1) } @_;
  my @faces_h = sort { $b <=> $a } map { $l{substr($_,0,1)} } @_;
  my @faces_l = @faces_h;
  @faces_l = (@faces_l[1..4], 1) while $faces_l[0] eq 14;
  my $is_flush = $suits[0] eq $suits[4];
  my ($is_straight, $high_card);
  if($faces_l[0]-1==$faces_l[1] &&
     $faces_l[1]-1==$faces_l[2] &&
     $faces_l[2]-1==$faces_l[3] &&
     $faces_l[3]-1==$faces_l[4]) {
    $is_straight=1;
    $high_card = $faces_l[0];
  } else {
    $high_card = $faces_h[0];
    if($faces_h[0]-1==$faces_h[1] &&
       $faces_h[1]-1==$faces_h[2] &&
       $faces_h[2]-1==$faces_h[3] &&
       $faces_h[3]-1==$faces_h[4]) {
      $is_straight=1;
    }
  }
  return _s(9, \$high_card) if $is_flush && $is_straight;
  return _s(7, 4,0) if $faces_h[4] == $faces_h[1];
  return _s(7, 3,4) if $faces_h[3] == $faces_h[0];
  return _s(6, 0,4) if $faces_h[4] == $faces_h[3] && $faces_h[2] == $faces_h[0];
  return _s(6, 4,0) if $faces_h[4] == $faces_h[2] && $faces_h[1] == $faces_h[0];
  return _s(5, 0) if $is_flush;
  return _s(4, \$high_card) if $is_straight;
  return _s(3, 4,0,1) if $faces_h[4] == $faces_h[2];
  return _s(3, 3,0,4) if $faces_h[3] == $faces_h[1];
  return _s(3, 2,3,4) if $faces_h[2] == $faces_h[0];
  return _s(2, 2,4,0) if $faces_h[4] == $faces_h[3] && $faces_h[2] == $faces_h[1];
  return _s(2, 1,4,2) if $faces_h[4] == $faces_h[3] && $faces_h[1] == $faces_h[0];
  return _s(2, 1,3,4) if $faces_h[3] == $faces_h[2] && $faces_h[1] == $faces_h[0];
  return _s(1, 4,0,1,2) if $faces_h[4] == $faces_h[3];
  return _s(1, 3,0,1,4) if $faces_h[3] == $faces_h[2];
  return _s(1, 2,0,3,4) if $faces_h[2] == $faces_h[1];
  return _s(1, 1,2,3,4) if $faces_h[1] == $faces_h[0];
  return _s(0, 0..4);
}

sub _s {
  join "", map { $_ > 9 ? $_ : "0$_" } shift,
    ref $_[0] ? $$_[0] : map { $faces_h[$_] } @_
  # my @a=@_;
  #  if(ref $a[1]) {
  #    $a[1]=${$a[1]};
  #  } else {
  #    $a[$_]=$faces_h[$a[$_]] for 1..$#a;
  #  }
  #  join "", map { $_ < 10 ? "0$_" : $_ } @a;
}

my @p1 = @ARGV[0..4];
my @p2 = @ARGV[5..9];

my $s1 = score(@p1);
my $s2 = score(@p2);
print $s1 gt $s2 ? 1 : 2;

AH 2C 3S 4S 5D 6C 7S 7C 7D TDtạo ra một kết quả 2, nhưng tôi nghĩ rằng một nhịp đập thẳng của ba loại
ossifrage squeamish
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.