Phép thuật: Cuộc chiến tập hợp với khả năng


16

Liên quan

Mục tiêu:

Cho hai sinh vật với khả năng chiến đấu tùy chọn, trả lại các giá trị duy nhất nhưng phù hợp đại diện cho sinh vật nào đã chết, nếu có.

Đầu vào:

#Longest form:
[[P,T, "<abilities>"], [P,T, "<abilities>"]]
#Shortest form:
[[P,T], [P,T]]

Mỗi sinh vật sẽ được đưa ra dưới dạng [P,T,"<abilities>"]. Nó sẽ ở dạng [P,T], [P,T,""]hoặc [P,T,0]nếu nó không có khả năng, sự lựa chọn của bạn về hình thức. P là số nguyên> = 0, T là số nguyên> = 1. <abilities>là một tập hợp con của "DFI", hoặc có thể được biểu diễn thông qua một số / chuỗi đơn nếu bạn muốn. Thứ tự của các cờ cũng tùy thuộc vào bạn.

Cơ chế chiến đấu:

Mỗi sinh vật có hai chỉ số, Sức mạnh và Độ bền theo thứ tự đó và các khả năng tùy chọn. Sức mạnh của một sinh vật là> = 0. Độ bền của một sinh vật là> = 1.

Mỗi sinh vật sẽ đồng thời gây sát thương tương đương với sức mạnh của nó với sinh vật đối nghịch (trừ khi người đó có đòn tấn công đầu tiên). Nếu giá trị lớn hơn hoặc bằng độ dẻo dai của đối thủ, nó sẽ chết (trừ khi không thể phá hủy).

Ví dụ: Alice là một 2/2, Bob là một 3/4, cả hai đều không có khả năng. Alice sẽ gây 2 sát thương cho Bob và nhận lại 3 sát thương. Độ dẻo dai của Alice là 2 nên nó sẽ chết, độ dẻo dai của Bob là 4 nên nó sẽ sống.

Chỉ có 3 khả năng tùy chọn chúng tôi sẽ xem xét cho việc này (mặc dù có nhiều hơn trong trò chơi). Đây sẽ là một cờ nhân vật:

  • [D] eathtouch: Bất kỳ lượng sát thương nào (X> 0) đều được coi là gây chết người.
  • [F] irst Strike: Sẽ gây sát thương trước, có thể giết chết sinh vật kia trước khi nó có thể tấn công trở lại. Nếu cả hai sinh vật đều có Đột kích, Giải quyết chiến đấu như bình thường.
  • [I] ndesturation: Không có lượng sát thương nào được coi là gây chết người, kể cả Deathtouch.

Đầu ra:

Bất kỳ giá trị phù hợp cho mỗi trong bốn trường hợp sau đây. Hãy nêu bốn giá trị trong câu trả lời của bạn. Ví dụ giá trị trả về trong parens:

  • Không có sinh vật nào chết (0)
  • Sinh vật thứ 1 đã chết (1)
  • Sinh vật thứ 2 đã chết (2)
  • Cả hai sinh vật đã chết (3)

Quy tắc:

  • Đầu vào được đảm bảo có hai sinh vật được định dạng chính xác.
  • Nếu bạn đang sử dụng các ký tự cho các khả năng, bạn có thể cho rằng họ đã ra lệnh theo cách bạn muốn nhưng đăng đơn hàng được sử dụng nếu có liên quan.
  • Nếu bạn đang sử dụng một số / chuỗi bit cho các khả năng, hãy đăng mã hóa bạn đang sử dụng. ví dụ: 111D/F/I, 7D/F/I, v.v.
  • Nếu một sinh vật không có khả năng, nó cũng có thể được coi là [P,T, ""]hoặc số tương đương
  • Lỗ hổng tiêu chuẩn Cấm
  • Đây là nên mã ngắn nhất sẽ thắng.

Ví dụ:

Input: [[2,2], [1,1]]
Output: 2nd Dies

Input: [[0,2], [0,1]] #0/2 vs 0/1
Output: Neither Die

Input: [[2,1], [2,1]] #2/1 vs 2/1
Output: Both Die

Input: [[1,1, "D"], [2,2]] #1/1 Deathtoucher vs 2/2 
Output: Both Die

Input: [[2,2], [0,1, "D"]] #2/2 vs 0/1 Deathtoucher
Output: 2nd Dies

Input: [[2,2], [1,1, "DF"]] #2/2 vs 1/1 Deathtouch First-striker 
Output: 1st Dies

Input: [[0,2, "D"], [0,1, "DF"]] #0/2 Deathtoucher vs 0/1 Deathtouch First-striker
Output: Neither Die

Input: [[2,2], [2,2, "F"]] #2/2 vs 2/2 First-striker
Output: 1st Dies

Input: [[2,2, "I"], [1,1, "DF"]] #2/2 Indestructible vs 1/1 Deathtouch First-striker
Output: 2nd Dies

Input: [[9999,9999], [1,1, "I"]] #9999/9999 vs 1/1 Indestructible
Output: Neither Die

Input: [[2,2, "F"], [1,1, "F"]] #2/2 First-Striker vs 1/1 First-Striker
Output: 2nd Dies

#9/9 Deathtouch, Indestructible First-Striker vs 9/9 Deathtouch, Indestructible First-Striker
Input: [[9,9, "DFI"], [9,9, "DFI"]] 
Output: Neither Die

1
@ user71546 Vâng. Có thêm một chút quy tắc liên quan nhưng trong MtG, "Can'ts" át "Lon". Vì vậy, về mặt chức năng, Không thể phá hủy bỏ qua Deathstrike. Đã chỉnh sửa để rõ ràng hơn
Veskah

1
@ fəˈnɛtɪk, nó vẫn nhận sát thương, nó không chết vì nó. Tâm trí bạn, câu hỏi làm sai quy tắc quá. Nó phải là " [Không thể phá hủy] vĩnh viễn không bị phá hủy bởi thiệt hại gây chết người, và họ bỏ qua hành động dựa trên trạng thái kiểm tra thiệt hại gây chết người ".
Peter Taylor

4
" Nếu một sinh vật không có khả năng, nó phải được phân tích cú pháp là [P, T]. [P, T," "] không hợp lệ " là một quy tắc tồi. Nó phân biệt đối xử với các ngôn ngữ với gõ mạnh mẽ không có lợi.
Peter Taylor

2
@PeterTaylor Tôi muốn giữ các mảng lởm chởm nhưng bạn nói đúng rằng nó không làm cho nó tốt hơn. Do đó, quy tắc đã được gỡ bỏ
Veskah

1
@Veskah Tôi có thể lấy "D", "F", "I" làm số không? D => 0, F => 1, I => 2
Luis felipe De jesus Munoz

Câu trả lời:


6

Perl 5 , 248 byte

... không có khoảng trắng và dòng mới:

sub c{eval'
(P,T,A,p,t,a)=@_;
     A=~/F/&&a!~/F/&&a!~/I/ ? c( P,2e9,A=~s/F//r,p,t, a         )
    :a=~/F/&&A!~/F/&&A!~/I/ ? c( P,T, A,        p,2e9,a=~s/F//r )
    : do{
        P=1e9 ifA=~/D/&&P>0;
        p=1e9 ifa=~/D/&&p>0;
        T=3e9 ifA=~/I/;
        t=3e9 ifa=~/I/;
        T-=p;
        t-=P;
        T>0&&t>0  ? 0
            : T>0 ? 2
            : t>0 ? 1
            :       3
}'=~s,[pta],\$$&,gri }

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

Phiên bản chưa được chỉnh sửa của tôi với mười bài kiểm tra từ @Veskah (OP), các bài kiểm tra đã vượt qua:

sub co { #combat
    my($p1,$t1,$a1, $p2,$t2,$a2)=@_; #p=power, t=toughness, a=abilities
    $a1=~s/F// and $a2=~s/F// if "$a1$a2"=~/F.*F/; #both F, no F
    return co($p1,2e9,$a1=~s/F//r, $p2,$t2,$a2        ) if $a1=~/F/ && $a2!~/I/;
    return co($p1,$t1,$a1,         $p2,2e9,$a2=~s/F//r) if $a2=~/F/ && $a1!~/I/;
    $p1=1e9 if $a1=~/D/ and $p1>0;
    $p2=1e9 if $a2=~/D/ and $p2>0;
    $t1=3e9 if $a1=~/I/;
    $t2=3e9 if $a2=~/I/;
    $t1-=$p2;
    $t2-=$p1;
    $t1<=0 && $t2<=0 ? "Both Die"
   :$t1<=0           ? "1st Dies"
   :$t2<=0           ? "2nd Dies"
                     : "Neither Die"
}

my @test=map{[/Input: .*? (\d+),(\d+)(?:,\s*"([FDI]+)")?
                      .*? (\d+),(\d+)(?:,\s*"([FDI]+)")?
           .*? Output: \s* (1st.Dies|2nd.Dies|Both.Die|Neither.Die)? /xsi]}
         split/\n\n/,join"",<DATA>;
my $t=0;
for(@test){ $t++;
  my $r=co(@$_);#result
  $r=~s,0,Neither Die,; $r=~s,3,Both Die,;
  print $$_[-1]=~/^$r/
    ? "Ok $t\n"
    : "Not ok, combat $t --> $r, wrong! (".join(",",@$_).")\n"
}
__DATA__
Input: [[2,2], [1,1]]
Output: 2nd Dies

Input: [[0,2], [0,1]] #0/2 vs 0/1
Output: Neither Die

Input: [[2,1], [2,1]] #2/1 vs 2/1
Output: Both Die

Input: [[1,1, "D"], [2,2]] #1/1 Deathtoucher vs 2/2
Output: Both Die

Input: [[2,2], [0,1, "D"]] #2/2 vs 0/1 Deathtoucher
Output: 2nd Dies

Input: [[2,2], [1,1, "DF"]] #2/2 vs 1/1 First-strike, Deathtoucher
Output: 1st Dies

Input: [[2,2], [2,2, "F"]] #2/2 vs 2/2 First-striker
Output: 1st Dies

Input: [[2,2, "I"], [1,1, "DF"]] #2/2 Indestructible vs 1/1 First-strike, Deatht.
Output: 2nd Dies

Input: [[99999,99999], [1,1, "I"]] #99999/99999 vs 1/1 Indestructible
Output: Neither Die

Input: [[2,2, "F"], [1,1, "F"]] #2/2 First-Striker vs 1/1 First-Striker
Output: 2nd Dies

4

JavaScript, 137 125 120 111 byte

i=>(k=(a,b)=>!(b[2]%2)&&a[0]/(a[2]<=3)>=b[1],[c,d]=i,g=c[2]&2,h=k(c,d),j=k(d,c),d[2]&2-g&&(g?h&&2:j&&1)||j+2*h)

Tôi đang sử dụng số bitmap cho khả năng D = 4 F = 2 I = 1 ta "DFI"sẽ 7. Đầu ra của tôi là Không chết 0, 1 chết 1, 2 chết2 , Cả hai đều chết 3.

Các thử nghiệm với:

f([[2, 2, 0], [1,1, 0]]); // 2
f([[0, 2, 0], [0,1, 0]]); // 0
f([[2, 1, 0], [2,1, 0]]); // 3
f([[1, 1, 4], [2,2, 0]]); // 3
f([[2, 2, 0], [0,1, 4]]); // 2
f([[2, 2, 0], [1,1, 6]]); // 1
f([[2, 2, 0], [2,2, 2]]); // 1
f([[2, 2, 1], [1,1, 6]]); // 2
f([[99999, 99999, 0], [1,1, 1]]); // 0
f([[2, 2, 2], [1,1, 2]]); // 2)

Đây là mã làm việc đầu tiên của tôi

const kills = (c1, c2) => { // Return true if c1 kills c2
    if (c2[2] % 2) {
        console.log("Indestructible");
        return false;
    }
    const c1p = c1[0] / (c1[2] <= 3); // Infinity if Deathtoucher && P > 0
    const c2t = c2[1];
    return c1p >= c2t;
}
const f = (input) => {
    console.log("Match:", input);
    const [c1, c2] = input;
    const f1 = (c1[2] & 2);
    const f2 = (c2[2] & 2);
    if (f2 !== f1) {
        if (f1) {
            if (kills(c1, c2)) {
                console.log("c1 killed c2 in first round");
                return 2;
            }
        } else {
            if (kills(c2, c1)) {
                console.log("c2 killed c1 in first round");
                return 1;
            }
        }
    }
    return kills(c2, c1) + 2 * kills(c1, c2);
};

Mà tôi giảm xuống trung gian này:

const f = i => {
    const k = (a, b) => !(b[2] % 2) && a[0] / (a[2] <= 3) >= b[1];
    const [c, d] = i;
    const g = c[2] & 2;
    const h = k(c, d);
    const j = k(d, c);
    return d[2] & 2 - g &&
        (g  ? h && 2
            : j && 1
        ) || j + 2 * h
}

Chào mừng đến với PPCG! Và giải pháp đầu tiên rất hay :) Tôi có thể thấy một số tiềm năng để chơi gôn hơn nhưng tôi đang dùng điện thoại, sau một vài loại bia nên không thể kiểm tra đúng cách.
Xù xì

Tuy nhiên, đây là cách tiết kiệm 7 byte nhanh chóng: tio.run/##bc/RbsIgFAbg@z0FuxgBd7RwNEu2SPcgjERKtak1ZVHjle/ tựa
Shaggy

@ Shaggy. Đẹp quá Tất nhiên là toán tử dấu phẩy - tôi là một người mới.
James

1
Tất cả chúng ta đều mới một lần :)
Shaggy

3

JavaScript (ES6), 83 76 byte

Có đầu vào là 6 đối số riêng biệt: 2 x (Sức mạnh, Độ bền, Khả năng). Khả năng được dự kiến ​​là bitmasks với:

  • 1
  • 2
  • 4

0123

(p,t,a,P,T,A)=>(x=A<4&&p>=T|a&!!p)&(y=a<4&&P>=t|A&!!P)&&(a^A)&2?a+2>>1:x*2+y

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

Đã bình luận

(p, t, a, P, T, A) => // (p, t, a) = arguments for the first player (P1)
                      // (P, T, A) = arguments for the second player (P2)
  ( x =               // x is a flag which means 'P1 can kill P2',
                      // regardless of the 'First Strike' abilities
    A < 4 &&          // it is set to 1 if P2 is not Indestructible and:
    p >= T |          //   the power of P1 is greater than or equal to the toughness of P2
    a & !!p           //   or the power of P1 is not zero and P1 has the Death Touch
  ) &                 //
  ( y = a < 4 &&      // y is the counterpart of x and is computed the same way
    P >= t |          //
    A & !!P           //
  ) &&                // if both x and y are set
  (a ^ A) & 2 ?       // and exactly one player has the First Strike:
    a + 2 >> 1        //   return 2 if P1 has the First Strike, or 1 otherwise
  :                   // else:
    x * 2 + y         //   return the default outcome: x * 2 + y

3

C (gcc) , 114 113 95 byte

Rất nhiều môn golf nhờ vào trần nhà và Logern.

g(Z{return F&1|F&4&&!(f&4||P<t)||!(f&2)&T>p;}
f(Z{return g(Z+2*g(p,t,f,P,T,F);}

Biên dịch với -DZ=P,T,F,p,t,f).

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

Chúng tôi kiểm tra (một cách độc lập, vì tính đối xứng của cơ học chiến đấu) liệu mỗi sinh vật có sống sót sau trận chiến hay không, điều này xảy ra nếu một trong hai điều đó là đúng:

  • sinh vật là không thể phá hủy;
  • sinh vật này tấn công lần đầu VÀ người kia không VÀ sức mạnh của nó lớn hơn hoặc ngang bằng với sự cứng rắn của người khác (do đó chúng ta có thể coi thường cái chết của người khác);
  • sinh vật khác không có cảm giác chết chóc VÀ sức mạnh của nó kém hơn sự dẻo dai của chúng ta.

(Các điều kiện trước đây quan trọng hơn).

Đầu vào là sức mạnh và độ dẻo dai như số nguyên và khả năng như một bitfield (1 = Không thể phá hủy, 2 = Death touch, 4 = Tấn công đầu tiên), đầu ra cũng là một bitfield (1 = Sinh vật thứ nhất sống sót, 2 = Sinh vật thứ hai sống sót).


1
Sử dụng macro -DZ=P,T,F,p,t,f) 96 byte - Hãy thử trực tuyến!
Logern

Sử dụng P=…thay vì return …và loại bỏ dòng mới sẽ đưa bạn tới 85 byte.

Ngoài ra, -3 byte bằng cách thay thế các toán tử logic &&, ||bằng bitwise &,|

2

Võng mạc 0.8.2 , 123 byte

\d+
$*
(.*1)(.*;)(.*1)
$3$2$1
F(.*)F
$1
1+D
1
1*(,1+)I
$1
(1+)(F?;1*,)(1+)
$3$2$1
(1*)1*,\1(1+)?
$#2
0(F)?;0(F)?
$#1;$#2
F

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp kiểm tra, mặc dù tôi đã thay 9cho 99999cho tốc độ. Đầu vào sử dụng các chữ cái DFImặc dù Dphải đi trước I. Đầu ra ở định dạng 1cho người sống sót và 0cho chết. Giải trình:

\d+
$*

Chuyển đổi các số liệu thống kê để unary.

(.*1)(.*;)(.*1)
$3$2$1

Trao đổi số liệu tạm thời.

F(.*)F
$1

Hai Fs hủy bỏ.

1+D
1

Death Touch hạ thấp Toughness của đối thủ xuống 1.

1*(,1+)I
$1

Không thể phá hủy làm giảm sức mạnh của đối thủ xuống 0.

(1+)(;1*,)(1+)
$3$2$1

Chuyển Toughness trở lại, vì vậy bây giờ bạn có P2, T1, F1; P1, T2, F2

(1*)1*,\1(1+)?
$#2

Nếu Toughness cao hơn Sức mạnh của đối thủ thì nó sẽ sống sót.

0(F)?;0(F)?
$#1;$#2

Nếu cả hai sẽ chết, người có First Strike vẫn sống sót.

F

Nếu không thì First Strike không có gì khác biệt.


1

C ++, 177 131 127 121 byte

Đây là giải pháp không quá ngắn của tôi trong C ++. Khả năng là 3 bit cho mỗi sinh vật:

  1. D = 0x1 (0001)
  2. F = 0x2 (0010)
  3. I = 0x4 (0100)

Và nó chỉ đơn giản trả về 0 : nếu không ai chết, 1 : nếu sinh vật thứ nhất chết, 2 : nếu sinh vật thứ hai chết và 3 : nếu cả hai sinh vật đều chết.

[](int p,int t,int a,int r,int k,int b){return(a&2&&b^4)^(b&2&&a^4)?1+(a&2):((t<r||b&1&&r)&&a^4)+((k<p||a&1&&p)&&b^4)*2;}

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

C ++, 85 81 byte (Thay thế)

Bằng cách gian lận một chút và nắm bắt các biến trong lambda và không chuyển chúng thành đối số, có thể giảm xuống còn 81 byte. Tôi không biết đó có phải là một giải pháp chấp nhận được hay không nên tôi đăng nó như một giải pháp thay thế.

[&]{s=(a&2&&b^4)^(b&2&&a^4)?1+(a&2):((t<r||b&1&&r)&&a^4)+((k<p||a&1&&p)&&b^4)*2;}

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


Đây là môn đánh gôn , dự kiến ​​sẽ có các bản hack như vậy, để cạnh tranh ... trừ khi bạn sử dụng các ngôn ngữ chơi gôn được xây dựng có mục đích, điều này làm thay đổi trò chơi một chút.
3D1T0R

1

Perl 5, 245 byte

$F[0]*=$F[4]if$F[2]=~/D/;$F[3]*=$F[1]if$F[5]=~/D/;$F[3]=0 if$F[2]=~/I/;$F[0]=0 if$F[5]=~/I/;$F[4]-=$F[0]if$F[2]=~/F/;$F[1]-=$F[3]if$F[5]=~/F/;if($F[1]>0&&$F[4]>0){$F[4]-=$F[0]if$F[2]!~/F/;$F[1]-=$F[3]if$F[5]!~/F/}$_=(0+($F[1]<=0)).(0+($F[4]<=0))

Chạy với -lapE

Ung dung:

# Takes input in one lines, of the form:
# PPP TTT "<abilities>" PPP TTT "<abilities>"

$F[0] *= $F[4] if $F[2] =~ /D/;
$F[3] *= $F[1] if $F[5] =~ /D/;

$F[3] = 0 if $F[2] =~ /I/;
$F[0] = 0 if $F[5] =~ /I/;

$F[4] -= $F[0] if $F[2] =~ /F/;
$F[1] -= $F[3] if $F[5] =~ /F/;

if ($F[1] > 0 && $F[4] > 0) {
    $F[4] -= $F[0] if $F[2] !~ /F/;
    $F[1] -= $F[3] if $F[5] !~ /F/;
}

$_ = (0+ ($F[1] <= 0)) . (0+ ($F[4] <= 0));

"Deathtouch" dịch thành "sức mạnh của bạn bây giờ được nhân lên bởi sự dẻo dai của kẻ thù" và "không thể phá hủy" có nghĩa là "sức mạnh của kẻ thù của bạn bây giờ bằng không", với tiền lệ sau này. Mã này chạy được hai vòng, một vòng chỉ có những tiền đạo đầu tiên được tấn công và một trong những nơi chỉ những người không phải là tiền đạo mới có thể tấn công. Nếu vòng thứ nhất dẫn đến tử vong, vòng thứ hai sẽ không xảy ra. Vì chúng ta đã xử lý deathtouch và không thể phá hủy ngay từ đầu, "cái chết" đơn giản như việc kiểm tra xem độ dẻo dai có lớn hơn 0 hay không.

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.