マジック:能力を備えた集会戦闘


16

関連する

ゴール:

オプションの戦闘能力を持つ2つのクリーチャーが与えられた場合、どのクリーチャーが死んだかを表す一意で一貫した値を返します。

入力:

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

各クリーチャーはの形で与えられ[P,T,"<abilities>"]ます。フォーム、、または機能がない場合は、フォーム[P,T]で選択します。Pは0以上の整数、Tは1以上の整数です。はのサブセットであるか、必要に応じて単一の数値/ビット文字列で表すことができます。フラグの順序もあなた次第です。[P,T,""][P,T,0]<abilities>"DFI"

戦闘力学:

各クリーチャーには、パワーとタフネスの順序の2つのステータス、およびオプションの能力があります。クリーチャーのパワーは> = 0です。クリーチャーのタフネスは> = 1です。

各クリーチャーは、同時に相手のクリーチャーにそのパワーに等しいダメージを与えます(先制攻撃がない限り)。値が対戦相手のタフネス以上である場合、(破壊できない場合を除いて)死にます。

例:アリスはaで2/2、ボブはaで3/4、両方とも能力がありません。アリスはボブに2ダメージを与え、代わりに3ダメージを与えます。アリスのタフネスは2なので死んでしまい、ボブのタフネスは4なので死んでしまいます。

このために検討するオプション機能は3つだけです(ただし、ゲームにはさらに多くの機能があります)。これらは1文字のフラグになります。

  • [D] eathtouch:任意の量のダメージ(X> 0)は致命的と見なされます。
  • [F] irst Strike:最初にダメージを与え、攻撃する前に他のクリーチャーを殺すことができます。両方のクリーチャーに先制攻撃がある場合、通常どおり戦闘を解決します。
  • [I] ndestructible:Deathtouchを含め、致命的と見なされるダメージはありません。

出力:

次の4つのケースのそれぞれの一貫した値。答えに4つの値を明記してください。括弧内の戻り値の例:

  • どちらのクリーチャーも死亡しなかった(0)
  • 最初のクリーチャーが死亡した(1)
  • 2番目のクリーチャーが死亡した(2)
  • 両方のクリーチャーが死亡しました(3)

ルール:

  • 入力には、正しくフォーマットされた2つのクリーチャーが存在することが保証されています。
  • 能力にキャラクターを使用している場合、キャラクターが希望通りに注文されていると想定できますが、関連する場合は使用された注文を掲載します。
  • 能力に数値/ビット文字列を使用している場合は、使用しているエンコーディングを投稿してください。例:111is D/F/I7is 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では「できません」が「缶」に勝ちます。機能的には、IndestructibleはDeathstrikeを無視します。より明確にするためにそれを編集
ヴェスカ

1
@ fəˈnɛtɪk、それはまだダメージを受けます、それで死なないだけです。気を付けて、質問もルールを誤って述べています。「[破壊不能]パーマネントは致命的なダメージによって破壊されず、致命的なダメージをチェックする状態ベースのアクションを無視します」。
ピーターテイラー

4
クリーチャーに能力がない場合は、[P、T]として解析する必要があります。[P、T、 ""]は無効です "は悪いルールです。強力なタイピングの言語を差別化することはありません。
ピーターテイラー

2
@PeterTaylorギザギザの配列を維持したいのですが、改善されないのは間違いありません。したがって、ルールは削除されました
ベスカ

1
@Veskah「D」、「F」、「I」を数字として使用できますか?D => 0, F => 1, I => 2
ルイスフェリペデジェススムニョス

回答:


6

Perl 5 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)からの10個のテストを含む私の未使用バージョンは、テストに合格します。

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、2番目に死んだ2、両方とも死んだ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
Shaggy

@Shaggy。良いですね!もちろん、カンマ演算子-私はなんということでしょう。
ジェームズ

1
私たちはかつてまったく新しい人でした:)
シャギー

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バイト

ceilingcatと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 =デスタッチ、4 =先攻)、出力もビットフィールド(1 =最初のクリーチャーが生き残り、2 = 2番目のクリーチャーが生き残る)です。


1
-DZ=P,T,F,p,t,f) 96バイトの
ローガン

改行のP=…代わりに使用return …して改行を削除すると、85バイトになります。

また、-3論理演算子を置換することによってバイト&&||ビット単位で&|

2

Retina 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

オンラインでお試しください!リンクにはテストケースが含まれていますが、速度の代わりに使用999999ました。入力文字を使用していますDFIが、D必須のに先行I。出力は、1サバイバル0用とダイ用の形式です。説明:

\d+
$*

統計を単項に変換します。

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

統計を一時的に交換します。

F(.*)F
$1

2 F秒間キャンセルします。

1+D
1

デスタッチは、相手のタフネスを1に下げます。

1*(,1+)I
$1

Indestructableは、相手のパワーを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

それ以外の場合、First Strikeは違いをもたらしません。


1

C ++、177の 131 127 121バイト

これがC ++でのそれほど短くないソリューションです。能力はクリーチャーごとに3ビットです:

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

そして、単に0を返します:誰も死なない場合、1:最初のクリーチャーが死ぬ場合、2: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であり、競争するために必要ではない場合、そのようなハッキングが予想されます...ゲームを少し変更する専用のcode-golfing言語を使用している場合を除きます。
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」は「あなたの力に敵のタフネスが乗じられた」に変換され、「破壊不能」は「敵の力がゼロになった」に変換され、後者が先例を取っています。コードは2回実行されます。1回目は最初の攻撃者のみが攻撃を行い、1回目は非最初の攻撃者のみが攻撃できるようにします。最初のラウンドで死亡した場合、2番目のラウンドは発生しません。すでにデスタッチを扱っており、最初は破壊できないため、「死」はタフネスがゼロより大きいかどうかをチェックするのと同じくらい簡単です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.