盾墙


18

历史背景

盾墙是一种战术战争编队,其历史可以追溯到至少公元前2500年。它由战士与同伴的盾牌重叠构成“墙”组成。这种战术的吸引力来自这样一个事实,即即使是最不熟练的战士,只要拥有盾牌和武器,他们都可以在墙上战斗。由于墙的接近,几乎没有移动的空间,战斗通常变成用锋利的武器进行的激烈比赛。

挑战

您的任务是创建一个程序或函数,以两个战士的数组/列表/向量为输入,来决定战斗的结果。列表将代表单线的屏蔽墙,并且将遵循特定的符号:

维京人:

北欧勇士们发动了激烈的战斗。在8世纪后期到11世纪中叶,丹麦维京人入侵了不列颠王国,寻找财富和可耕地。出于挑战的目的,这些是维京人的战士:

  • JARL:通常发现从壁的中心率众,jarls是海盗成群的领导人。受到15点伤害而死亡,每回合造成2点伤害。
  • Berserker:虽然幻想,极大地扭曲了狂战士的形象,这些战士被称为精神恍惚般狂暴战斗没有任何一种比他们的盾等保护的。造成6点伤害死亡,每回合造成3点伤害。
  • Chieftain:酋长是富人谁在他们的服务了自由人。他们通常会在战斗中赢得巨大的荣耀和财富。造成10点伤害死亡,每回合造成2点伤害。
  • Free Men:担任酋长的战士。他们发誓要为自己的主人而战直到死亡。遭受8点伤害,每回合造成1点伤害。
  • Skald:Skalds,通常译为吟游诗人,是谁雇用了写诗,关于北欧勇士的事迹故事或歌曲的自由人。受到8点伤害死亡,并为每位相邻的战士造成1点额外伤害。骨不会造成伤害。以此方式,战士不能获得超过1点的额外伤害。

撒克逊人:

撒克逊人是在公元5世纪罗马帝国灭亡后从欧洲大陆来到英国定居的。出于此挑战的目的,有撒克逊人的战士:

  • EARL:Ealdormen,通常被称为伯爵,是较高的贵族成员。他们通常占有很大的土地,并且有成百上千的宣誓就职者。遭受20点伤害,每回合造成1点伤害。
  • K夜:由于缺乏一个更好的词中,骑士是谁拥有一些土地未成年贵族。在大多数情况下,骑士是伯爵的宣誓仆人。造成10点伤害死亡,每回合造成2点伤害。
  • Warrior:常见的男人,通常是轻微的贵族没有土地或农民谁担任一个骑士。当与骑士或伯爵相邻时,战士获得+1伤害加成。受到8点伤害,每回合造成2点伤害。
  • F长江三角洲地区:该Fyrd是民兵般的自由人,通常是贫困农民,谁愿意带任何武器(或武器状农具)他们在墙上打组。遭受5点伤害,每回合造成1点伤害。
  • P古老:祭司在撒克逊人早期的文化中被高度重视,是上帝圣言的先驱。牧师死亡时受到15点伤害,并防止相邻的战士遭受1点伤害。牧师不会造成伤害。牧师对战士的伤害不能超过1。

墙壁在其中心彼此相遇。每个回合中,每个战士都会直接对其前方的战士造成伤害,或者,如果前面没有活着的战士,则对角相邻的活着的战士会留下最少的生命值。如果有领带,请选择靠近墙壁边缘的战士。

例:

Vikings
[M,M,M,B,B,C,J,C,B,B,M,M,M]
[F,F,F,W,W,K,E,K,W,W,F,F,F]
Saxons

To make matters easier, let's convert these walls into numbers:
Round 0:
 M M M B B C  J  C  B B M M M
[8,8,8,6,6,10,15,10,6,6,8,8,8]
[5,5,5,8,8,10,20,10,8,8,5,5,5]
 F F F W W K  E  K  W W F F F

Round 1: Notice that 2 of the Saxons' warriors are adjacent to Knights, so they have a +1 damage bonus.
 M M M B B C J  C B B M M M
[7,7,7,4,3,8,14,8,3,4,7,7,7]
 | | | | | | || | | | | | |
[4,4,4,5,5,8,18,8,5,5,4,4,4]
 F F F W W K E  K W W F F F

Round 2: 
 M M M B B C J  C B B M M M
[6,6,6,2,0,6,13,6,0,2,6,6,6]
 | | | | | | || | | | | | |
[3,3,3,2,2,6,16,6,2,2,3,3,3]
 F F F W W K E  K W W F F F

Round 3: Remember to collapse the arrays to account for dead warriors. Also, notice that the 2 outermost Fyrd are now attacking the diagonally adjacent viking. 
   M M M B C J  C B M M M
  [4,5,4,0,4,12,4,0,4,5,4]
  /| | | | | || | | | | |\
[2,2,2,1,0,4,14,4,0,1,2,2,2]
 F F F W W K E  K W W F F F

Round 4: Notice once again the saxon Warriors next to the Knights dealing 3 damage:
   M M M C J  C M M M
  [2,4,1,2,11,2,1,4,2]
  /| | | | || | | | |\
[2,1,1,0,2,12,2,0,1,1,2]
 F F F W K E  K W F F F
Round 5:
 M M M C J  C M M M
[1,3,0,0,10,0,0,3,1]
 | | | | || | | | |
[1,0,0,0,10,0,0,0,1]
 F F F K E  K F F F

Round 6: 
    M M J M M
   [1,2,9,2,1]
     \| | |/   
     [0,8,0]
      F E F
Rounds 7 and 8:
      M M J M M         M M J M M
     [1,2,8,2,1]       [1,2,8,2,1]
         \|/               \|/ 
         [4]               [0]
          E                 E  

Output: Viking victory.

规则:

  • 默认漏洞适用。
  • 您可以使用任何方便的IO方法
  • 这是,因此最短的代码(每种语言以字节为单位)获胜。
  • 可能不会假定列表的长度相同,但是它们始终在中心对齐(如果列表的大小不同,则每个列表中的战士总数始终为奇数)。
  • 您可以输出任何真实/错误值。请在您的答案中指定 “维京人/撒克逊人的胜利”的等效内容。
  • 当一堵墙的所有战士都死了时,才是失败者。
  • 如果最终在执行代码过程中遇到无法对齐的墙,请使其尽可能居中对齐,从而在右侧较长的墙上保留一个额外的战士。例如:

      [M,M,M,J,M,M,M]
        [K,E,K,W];
    
          [B,B,B,J]    
    [K,K,W,W,K,E,K,W,W,K,K]
    
  • 随意尝试使用任何隔离墙设置测试您的代码,而不仅仅是测试用例中的那些设置。

测试用例:

V: [M,M,B,C,B,C,J,C,B,C,B,M,M]
S: [F,F,W,K,W,K,E,K,W,K,W,F,F]
O: Viking victory.
------------------------------
V: [M,M,M,M,M,M,M,M,M,M]
S: [W,W,W,W,W,W,W,W,W,W]
O: Saxon victory.
------------------------------
V: [B,C,M,B,C,M,M,C,B,M,C,B,M]
S:   [W,F,W,F,E,E,E,F,W,F,W]
O: Viking victory.
------------------------------
V:         [B,B,B,J,B,B,B]
S: [W,W,W,W,K,K,K,E,K,K,K,W,W,W,W]
O: Saxon victory.
------------------------------
V: [J]
S: [E]
O: Viking victory.
------------------------------
V: [C,C,C,C,B,B,M,M,M,M,J,J,J,M,M,M,M,B,B,C,C,C,C]
S: [K,K,K,K,K,K,K,K,K,K,W,E,W,K,K,K,K,K,K,K,K,K,K]
O: Saxon victory.
------------------------------
V: [M,M,S,C,B,J,B,C,S,M,M]
S: [F,K,P,W,K,E,K,W,P,K,F]
O: Saxon victory.
------------------------------
V: [S,S,S,...,S]
S: [P,P,P,...,P]
O: UNDEFINED (since both priests and skalds deal no damage, you can output anything here.)
------------------------------

有一些历史上的错误。随时指出它们,我会尽力解决它们。



我们可以定义其他符号而不是名称的首字母吗,例如数字0-9?
NieDzejkob

@NieDzejkob肯定的事情。只要确保您在答案中指定哪个符号用于哪个战士即可。
J.Sallé17年

3
将输入作为其属性而不是字母视为欺骗吗?(例如(health, damage, damagebonus, protbonus)
HyperNeutrino

@HyperNeutrino我不确定,但我认为可以吗?我不认为这可以给您带来很大的优势。正如我告诉NieDzejkob一样,只要您在回答中指定代表每个战士的东西,那就去争取。
J.Sallé17年

Answers:


3

Python 2中576个 573 565 554 540 549字节

O=[(0,0)]
g=lambda D,W,i:D[i-1]*(W[i-1]<1)+D[i]+D[i+1]*(W[i+1]<1)
h=lambda*V:[v for v in zip(*V)if v[1]>0]
def f(v,s):
 l,L=len(v),len(s);m=max(l,L);a,b=(L-l)/2,(l-L)/2;V,U=zip(*O+O*a+v+O*a+O+O);S,T=zip(*O+O*b+s+O*b+O+O);z=[0]*(m+2);w=z[:];r=range(1,m+1);U=list(U);T=list(T)
 for i in r:w[i]=[0,2,3,2,1,0][V[i]]+(5in V[i-1:i+2:2])*(V[i]<5);z[i]=[0,1,2,2+({1,2}&set(S[i-1:i+2:2])>set()),1,0][S[i]]
 for i in r:U[i]-=g(z,V,i);d=g(w,S,i);T[i]-=d-(d>0)*(5in S[i-1:i+2:2])
 V=h(V,U);S=h(S,T)
 if([],[])<(V,S)!=(v,s):return(f(V,S)if S else'V')if V else'S'

在线尝试!


如果我正确理解,则该位:(5in V[i-1:i+2:2])表示相邻的ald虫造成伤害。您可能需要...*(V[i]!=5)那里。测试:print f([S,S],[P]) # says V but should be a Draw
ngn

@ngn对此表示感谢:)
TF

2

APL(Dyalog Classic),128字节

{t l d b p←(-⌊2÷⍨+/0=⊃⍵)∘⌽¨⍵⋄l+←e+3+/0,0,⍨(0=te←(×≢¨p∩¨h)-⊖d+×≢¨b∩¨h3,/0,t,0⋄⍵≡a←↑¨(⊂↓l>0)/¨¨↓¨t l d b p:00s←+/l>0:×-/s⋄∇a}

在线尝试!

TIO链接中有两个函数:g是上面的golfed函数,f是一个ungolfed函数,它接受一对字符串,将它们转换为合适的表示形式,然后调用golfed函数。

输入是五个矩阵:t战士类型(整数);l生活; d损伤; b哪些战士类型在相邻时会给予加成;p同样的保护。矩阵由两行组成-维京人和撒克逊人。如果战士的编号不同,则矩阵必须填充0,尽管不一定居中。结果是1/ ¯1维京人/萨克森人胜利或0平局。

{
  t l d b p←(-⌊2÷⍨+/0=⊃⍵)∘⌽¨⍵  centre the matrices
   (-⌊2÷⍨+/0=⊃⍵) is a pair of numbers - by how much we should rotate (⌽) the rows
         +/0=⊃⍵  how many dead? (⊃⍵ is the types, dead warriors have type 0)
    -⌊2÷⍨        negated floor of half

  l+←e+3+/0,0,⍨(0=t)×e←(×≢¨p∩¨h)-⊖d+×≢¨b∩¨h←3,/0,t,0  compute and apply effective damage
   h3,/0,t,0  are triples of types - self and the two neighbours
   b∩¨h        for each warrior intersect (∩) h with his bonus-giving set b
   ×≢¨         non-empty? 0 or 1
   d+          add to the damage normally inflicted
              reverse vertically (harm the enemy, not self)
   (×≢¨p∩¨h)   same technique for protections (neighbouring priests)
   e          remember as "e" for "effective damage"; we still need to do the diagonal attacks
   (0=t      zero out the attacks on living warriors
   3+/0,0,⍨    sum triples - each warrior suffers the damage intended for his dead neigbours
   e+          add that to the effective damage
   l+←         decrease life ("e" is actually negative)

  ⍵≡a←↑¨(⊂↓l>0)/¨¨↓¨t l d b p:0  remove dead; if no data changed, it's a draw
  ⍝ ↓¨          split each matrix into two row-vectors
  ⍝ (⊂↓l>0)     boolean mask of warrios with any life left, split in two and enclosed
  ⍝ /¨¨         keep only the survivors
  ⍝ ↑¨          mix the pairs of rows into matrices again, implicitly padding with 0-s
  ⍝ a←          call that "a" - our new arguments
  ⍝ ⍵≡a ... :0  is "a" the same as our original arguments? - nothing's changed, it's a draw

  0∊s←+/l>0:×-/s ⍝ if one team has no members left, they lost
  ⍝ l>0         bitmask of survivors
  ⍝ s←+/l>0     how many in each camp
  ⍝ 0∊          has any of the two armies been annihilated?
  ⍝ :×-/s       if yes, which one? return sign of the difference: ¯1 or 1, or maybe 0

  ∇a ⍝ repeat
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.