Магія: Збір боротьби зі здібностями


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.

Кожне створіння одночасно заподіює шкоду, що дорівнює протилежному створінню (якщо тільки один не завдає удару). Якщо значення більше або дорівнює міцності опонента, воно загине (якщо тільки воно не може бути непорушним).

Приклад: Аліса - 2/2Боб, а 3/4обидва не мають здібностей. Аліса зробить 2 шкоди Бобу і завдає 3 збитки взамін. Міцність Аліси - 2, тому вона помре, міцність Боба - 4, і вона житиме.

Є лише 3 необов'язкові здібності, які ми розглянемо для цього (хоча в грі є більше). Це будуть одні символьні прапори:

  • [D] eathtouch: Будь-яка сума шкоди (X> 0) вважається летальною.
  • [F] перший страйк: Спочатку завдає шкоди, зможе вбити іншу істоту, перш ніж вона зможе атакувати назад. Якщо обидва істоти мають перший удар, вирішіть бій як звичайний.
  • [I] не руйнуються: жодна сума шкоди не вважається смертельною, включаючи Deathtouch.

Вихід:

Будь-яке послідовне значення для кожного з наступних чотирьох випадків. Укажіть, будь ласка, чотири значення у своїй відповіді. Приклад зворотного значення в паренах:

  • Жодна істота не загинула (0)
  • Перша істота померла (1)
  • 2-ма істота померла (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" козирять "Банки". Настільки функціонально Незнищенна ігнорує Смерть. Відредаговано, щоб бути більш чітким
Веська,

1
@ fəˈnɛtɪk, це все ще приносить шкоду, від цього просто не вмирає. Зауважте, питання також неправильно застосовує правило. Це повинно бути " [Незнищенні] постійні особи не знищуються смертельними ушкодженнями, і вони ігнорують дії, засновані на державі, що перевіряють наявність смертельних збитків ".
Пітер Тейлор

4
" Якщо істота не має здібностей, вона повинна бути проаналізована як [P, T]. [P, T," "] недійсне ", це неправильне правило. Він дискримінує мови з сильним набором тексту без жодної користі.
Пітер Тейлор

2
@PeterTaylor Я хочу тримати нерівні масиви, але ти маєш рацію, що це не робить його кращим. Таким чином правило було знято
Веска

1
@Veskah Чи можна вважати цифри "D", "F", "Я"? 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 1, ні 22 , обидва померли 3.

Тести з:

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. Хороший! Звичайно, оператор з комами - який я ноб.
Джеймс

1
Ми всі були колись новими :)
Shaggy

3

JavaScript (ES6), 83 76 байт

Приймає дані як 6 різних аргументів: 2 x (потужність, міцність, здібності). Можливості очікуються як біт-маски з:

  • 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 байт

Дуже багато гольфу завдяки стельовій коті і Логерну.

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 = Смертний дотик, 4 = Перший удар), вихід - також бітфілд (1 = Перша істота виживає, 2 = Виживає друга).


1
Використання макроса -DZ=P,T,F,p,t,f) 96 байт - Спробуйте в Інтернеті!
Логерн

Використання 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 знижує стійкість супротивника до 1.

1*(,1+)I
$1

Незнищенна знижує потужність противника до 0.

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

Вимкніть жорсткість назад, тому тепер у вас є P2, T1, F1; P1, T2, F2

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

Якщо міцність вище, ніж сила противника, то вона виживає.

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

Якщо обоє загинуть, виживає той, який пройшов Перший удар.

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

Спробуйте в Інтернеті!


Це код-гольф , такі хаки очікуються, якщо цього не потрібно, щоб змагатися ... якщо ви не використовуєте цільові мови кодового гольфу, що дещо змінює гру.
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

Безголівки:

# 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" означає "ваша сила тепер множиться на міцність вашого ворога", а "незнищенна" перекладається на "сила вашого ворога тепер дорівнює нулю", при цьому останні мають прецедент. Код проходить два раунди, один, у якому атакують лише першочергові, а другий, де можуть атакувати лише не перших нападників. Якщо перший раунд призведе до смерті, другий раунд не відбудеться. Оскільки ми вже мали справу зі смертельним дотиком і незнищенним на початку, "смерть" така ж проста, як перевірити, чи міцність більше нуля чи ні.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.