Magic: The Gathering Combat with Abilities


16

ที่เกี่ยวข้อง

เป้าหมาย:

ให้สองสิ่งมีชีวิตที่มีความสามารถในการต่อสู้ที่เป็นตัวเลือกคืนค่าที่ไม่เหมือนใคร

การป้อนข้อมูล:

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

[P,T,"<abilities>"]สิ่งมีชีวิตแต่ละคนจะได้รับในรูปแบบของ มันจะเป็นในรูปแบบ[P,T], [P,T,""]หรือ[P,T,0]ถ้ามันไม่มีความสามารถที่คุณเลือกในแบบฟอร์ม P เป็นจำนวนเต็ม> = 0, T เป็นจำนวนเต็ม> = 1 <abilities>เป็นเซตย่อยของ"DFI"หรือสามารถแสดงผ่านหมายเลข / บิตสตริงเดียวหากคุณต้องการ ลำดับธงขึ้นอยู่กับคุณเช่นกัน

กลศาสตร์การต่อสู้:

สัตว์แต่ละตัวมีสองสถิติพลังและความเหนียวในลำดับนั้นและความสามารถเสริม พลังของสิ่งมีชีวิตคือ> = 0 ความเหนียวของสิ่งมีชีวิตคือ> = 1

สิ่งมีชีวิตแต่ละตัวจะสร้างความเสียหายเท่ากับพลังของสิ่งมีชีวิตที่ตรงข้ามพร้อมกัน หากค่ามากกว่าหรือเท่ากับความเหนียวของคู่ต่อสู้มันจะตาย (ยกเว้นว่ามันไม่สามารถทำลายได้)

ตัวอย่าง: อลิซคือ a 2/2, บ็อบเป็น3/4ทั้งที่ไม่มีความสามารถ อลิซจะทำความเสียหายให้กับ Bob 2 ครั้งและรับความเสียหาย 3 อย่างกลับคืนมา ความเหนียวของอลิซคือ 2 ดังนั้นมันจะตายความเหนียวของบ็อบคือ 4 ดังนั้นมันจะมีชีวิตอยู่

มีเพียง 3 ความสามารถเสริมที่เราจะพิจารณาในการนี้ (แม้ว่าจะมีมากขึ้นในเกม) สิ่งเหล่านี้จะเป็นธงตัวละครหนึ่งตัว:

  • [D] eathtouch: จำนวนความเสียหายใด ๆ (X> 0) ถือว่าเป็นอันตราย
  • [F] irst Strike: จะทำความเสียหายก่อนเป็นลำดับสามารถฆ่าสิ่งมีชีวิตอื่นก่อนที่มันจะโจมตีกลับได้ หากสัตว์ทั้งสองมี First Strike ให้แก้ไขการต่อสู้ตามปกติ
  • [I] ndestructible: ไม่มีความเสียหายใด ๆ ที่ถือเป็นความตายรวมถึง Deathtouch

เอาท์พุท:

ค่าที่สอดคล้องกันสำหรับแต่ละสี่กรณีต่อไปนี้ กรุณาระบุสี่ค่าในคำตอบของคุณ ตัวอย่างค่าส่งคืนเป็น parens:

  • ไม่มีสัตว์ตาย (0)
  • สิ่งมีชีวิตที่ 1 เสียชีวิต (1)
  • สิ่งมีชีวิตที่สองเสียชีวิต (2)
  • สัตว์ทั้งสองเสียชีวิต (3)

กฎ:

  • ข้อมูลเข้ารับประกันว่าจะมีสิ่งมีชีวิตที่มีรูปแบบสองอย่าง
  • หากคุณใช้ตัวอักษรสำหรับความสามารถคุณสามารถสมมติว่าพวกเขาได้รับคำสั่งตามที่คุณต้องการ แต่โพสต์คำสั่งที่ใช้หากเกี่ยวข้อง
  • หากคุณใช้หมายเลข / บิตสตริงสำหรับความสามารถให้โพสต์สิ่งที่คุณกำลังใช้เข้ารหัส เช่น111เป็นD/F/I, 7คือD/F/I, ฯลฯ
  • หากสิ่งมีชีวิตไม่มีความสามารถก็สามารถนำมาเป็น[P,T, ""]หรือเทียบเท่าจำนวน
  • ต้องห้ามช่องโหว่มาตรฐาน
  • นี่คือเพื่อให้ได้รหัสที่สั้นที่สุด

ตัวอย่าง:

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 ใช่ มีกฎที่เกี่ยวข้องอีกเล็กน้อย แต่ใน MtG "Can'ts" trump "Cans" ดังนั้นหน้าที่ทำลายไม่ได้ Deathstrike แก้ไขให้ชัดเจนยิ่งขึ้น
Veskah

1
@ fəˈnɛtɪk มันยังคงได้รับความเสียหายมันก็ไม่ได้ตายจากมัน โปรดจำไว้ว่าคำถามนั้นเป็นไปในทางที่ผิดเช่นกัน มันควรจะเป็น "ตัวทำลายถาวร [ทำลายไม่ได้] จะไม่ถูกทำลายโดยความเสียหายร้ายแรงและพวกเขาไม่สนใจการกระทำของรัฐที่ตรวจสอบความเสียหายร้ายแรง "
ปีเตอร์เทย์เลอร์

4
" หากสิ่งมีชีวิตไม่มีความสามารถจะต้องมีการแยกวิเคราะห์เป็น [P, T] [P, T," "] ไม่ถูกต้อง " เป็นกฎที่ไม่ดี มันแยกแยะกับภาษาที่มีการพิมพ์ที่แข็งแกร่งไม่มีประโยชน์
ปีเตอร์เทย์เลอร์

2
@PeterTaylor ฉันต้องการเก็บอาร์เรย์ที่ขรุขระ แต่คุณพูดถูกว่ามันไม่ได้ทำให้ดีขึ้น ดังนั้นกฎได้ถูกลบออก
Veskah

1
@Veskah ฉันสามารถใช้ "D", "F", "I" เป็นตัวเลขได้หรือไม่? D => 0, F => 1, I => 2
Luis felipe De jesus Munoz

คำตอบ:


6

Perl 5 , 248 ไบต์

... โดยไม่มีช่องว่างและบรรทัดใหม่:

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 }

ลองออนไลน์!

เวอร์ชันที่ไม่อัปโหลดของฉันพร้อมการทดสอบสิบรายการจาก @Veskah (OP) การทดสอบผ่าน:

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 ไบต์

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)

ฉันกำลังใช้หมายเลขบิตแมปความสามารถ D = 4 F = 2 I = 1 ทำจะเป็น"DFI" 7การส่งออกของฉันคือการเสียชีวิตทั้ง0ที่ 1 เสียชีวิต12 เสียชีวิตทั้งสองเสียชีวิต23

ทดสอบกับ:

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)

นี่เป็นรหัสทำงานแรกของฉัน

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

ซึ่งฉันลดลงถึงกลางนี้:

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
}

ยินดีต้อนรับสู่ PPCG! และวิธีแก้ปัญหาแรกที่ดีมาก :) ฉันเห็นศักยภาพในการเล่นกอล์ฟต่อไป แต่ฉันใช้มือถือของฉันหลังจากเบียร์สองสามตัวดังนั้นจึงไม่สามารถทดสอบได้อย่างถูกต้อง
ปุย

ต่อไปนี้คือการประหยัดอย่างรวดเร็วขนาด 7 ไบต์: tio.run/##bc/RbsIgFAbg@z0FuxgBd7RwNEu2SPcgjERKtak1ZVHjle/…
Shaggy

@Shaggy ทำได้ดีนี่! แน่นอนโอเปอเรเตอร์คอมม่า - noob ผม
James

1
พวกเราทุกคนใหม่ครั้งเดียว :)
Shaggy

3

JavaScript (ES6), 83 76 ไบต์

รับอินพุตเป็น 6 อาร์กิวเมนต์ที่ต่างกัน: 2 x (พลัง, ความเหนียว, ความสามารถ) ความสามารถคาดว่าจะเป็น bitmasks กับ:

  • 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

ลองออนไลน์!

แสดงความคิดเห็น

(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 ไบต์

การเล่นกอล์ฟเป็นอย่างมากต้องขอบคุณ catcat และ 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);}

-DZ=P,T,F,p,t,f)คอมไพล์ด้วย

ลองออนไลน์!

เราตรวจสอบ (อิสระเนื่องจากความสมมาตรของกลศาสตร์การต่อสู้) ว่าสัตว์แต่ละตัวมีชีวิตรอดจากการต่อสู้หรือไม่ซึ่งจะเกิดขึ้นหากทั้งสองเป็นจริง:

  • สิ่งมีชีวิตที่ไม่สามารถทำลาย;
  • สิ่งมีชีวิตนั้นมีการโจมตีครั้งแรกและอีกสิ่งหนึ่งไม่ได้และพลังของมันจะมากกว่าหรือเท่ากับความทรหดของผู้อื่น (ดังนั้นเราอาจไม่สนใจความตายของผู้อื่น)
  • สิ่งมีชีวิตอื่นไม่ได้สัมผัสความตายและพลังของมันน้อยกว่าความทนทานของเรา

(เงื่อนไขเดิมมีความสำคัญมากกว่า)

อินพุตมีพลังและความแกร่งเป็นจำนวนเต็มและความสามารถเป็นบิตฟิลด์ (1 = ไม่สามารถทำลายได้ 2 = Death touch, 4 = การโจมตีครั้งแรก), เอาต์พุตยังเป็นบิตฟิลด์ (1 = สิ่งมีชีวิตแรกที่รอดชีวิต, 2 = สิ่งมีชีวิตที่สอง)


1
ใช้มาโคร-DZ=P,T,F,p,t,f) 96 ไบต์ - ลองออนไลน์!
Logern

การใช้P=…แทนที่จะreturn …ขึ้นบรรทัดใหม่จะนำคุณไปที่ 85 ไบต์

นอกจากนี้ -3 ไบต์โดยการแทนที่ดำเนินการทางตรรกะ&&, ||มีค่าที่เหมาะสม&,|

2

เรติน่า 0.8.2 , 123 ไบต์

\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

ลองออนไลน์! การเชื่อมโยงรวมถึงกรณีทดสอบแม้ว่าฉันแทน9สำหรับ99999ความเร็ว การป้อนข้อมูลใช้ตัวอักษรที่DFIแม้จะต้องนำหน้าD Iผลผลิตอยู่ในรูปแบบของ1การมีชีวิตอยู่และ0สำหรับแม่พิมพ์ คำอธิบาย:

\d+
$*

แปลงสถิติเป็นเอกภาพ

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

แลกเปลี่ยนสถิติชั่วคราว

F(.*)F
$1

สองFยกเลิก

1+D
1

Death Touch ลดค่า Toughness ของคู่ต่อสู้ลง 1

1*(,1+)I
$1

ทำลายไม่ได้ทำให้ Power ของฝ่ายตรงข้ามลดลงเป็น 0

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

สลับความเหนียวกลับมาตอนนี้คุณมี P2, T1, F1; P1, T2, F2

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

หากค่าความเหนียวสูงกว่าพลังของฝ่ายตรงข้ามจะมีชีวิตรอด

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

หากทั้งสองจะตายคนที่มี First Strike จะมีชีวิตอยู่

F

ไม่เช่นนั้นการโจมตีครั้งแรกจะไม่สร้างความแตกต่าง


1

C ++, 177 131 127 121 ไบต์

นี่คือทางออกที่ไม่สั้นของฉันใน C ++ ความสามารถเป็น 3 บิตสำหรับแต่ละสิ่งมีชีวิต:

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

และมันจะคืนค่า0 : หากไม่มีใครตาย1 : ถ้าสิ่งมีชีวิตแรกตายไป2 : ถ้าสิ่งมีชีวิตที่สองตายและ3 : ถ้าสิ่งมีชีวิตทั้งสองตาย

[](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;}

ลองออนไลน์!

C ++, 85 81 ไบต์ (ทางเลือก)

โดยการโกงเล็กน้อยและจับตัวแปรในแลมบ์ดาและไม่ผ่านพวกมันเป็นอาร์กิวเมนต์มันเป็นไปได้ที่จะลดลงถึง 81 ไบต์ ฉันไม่รู้ว่านี่เป็นวิธีแก้ปัญหาที่ยอมรับได้หรือไม่ดังนั้นฉันจึงโพสต์ไว้เป็นทางเลือก

[&]{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;}

ลองออนไลน์!


นี่คือcode-golfคาดว่าจะมีการแฮ็กดังกล่าวหากไม่จำเป็นเพื่อที่จะแข่งขัน ... เว้นแต่ว่าคุณกำลังใช้ภาษาโค้ดกอล์ฟที่ออกแบบมาเพื่อจุดประสงค์ซึ่งเปลี่ยนแปลงเกมเล็กน้อย
3D1T0R

1

Perl 5, 245 ไบต์

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

ทำงานด้วย -lapE

Ungolfed:

# 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" แปลว่า "พลังของคุณนั้นทวีคูณด้วยความเหนียวของศัตรู" และ "ทำลายไม่ได้" แปลว่า "พลังของศัตรูตอนนี้เป็นศูนย์" โดยที่ก่อนหน้านี้จะเป็นแบบอย่าง รหัสทำงานสองรอบหนึ่งรอบที่ผู้โจมตีคนแรกเท่านั้นที่ได้รับการโจมตีและอีกที่ที่ผู้โจมตีที่ไม่ใช่ผู้โจมตีคนแรกเท่านั้นที่สามารถโจมตีได้ หากรอบแรกส่งผลให้เสียชีวิตรอบที่สองจะไม่เกิดขึ้น เนื่องจากเราจัดการกับ Deathtouch และไม่สามารถทำลายได้ในตอนเริ่มต้น "ความตาย" นั้นง่ายเหมือนการตรวจสอบว่าความเหนียวนั้นมากกว่าศูนย์หรือไม่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.