The Shield Wall

18

Contexto histórico

A parede do escudo é uma formação de guerra tática que remonta a pelo menos 2500 aC. Consistia em guerreiros sobrepondo seus escudos com os de seus companheiros para formar um 'muro'. O apelo da tática vem do fato de que mesmo o guerreiro mais não qualificado poderia lutar em um muro desde que tivesse um escudo e uma arma. Devido à proximidade das muralhas, havia pouco espaço para se movimentar, e a batalha geralmente se transformava em uma partida de luta travada com armas afiadas.

O desafio

Sua tarefa é criar um programa ou função que, considerando duas matrizes / listas / vetores de guerreiros como entrada, decida o resultado da batalha. As listas representarão uma parede de escudos de linha única e seguirão uma notação específica:

Vikings:

Os guerreiros nórdicos tinham um ímpeto feroz de batalha. Durante o final de 8 a meados do século 11, os vikings dinamarqueses invadiram os reinos da Grã-Bretanha em busca de riquezas e terras cultiváveis. Para os propósitos deste desafio, estes são os guerreiros dos vikings:

  • O Jarl: geralmente encontrado guiando seus homens do centro da muralha, os jarls eram os líderes das hordas viking. Leva 15 de dano para morrer e causa 2 de dano por rodada.
  • O Berserker: Embora a fantasia tenha distorcido muito a imagem dos berserkers, esses guerreiros eram conhecidos por lutar em uma fúria de transe, sem nenhum tipo de proteção além de seus escudos. Recebe 6 de dano ao dado e causa 3 de dano por rodada.
  • Os Cchefes dos chefes eram homens ricos que tinham homens livres a seu serviço. Eles geralmente teriam conquistado grande glória e riquezas em batalha. Leva 10 de dano para morrer e causa 2 de dano por rodada.
  • The Free Mpt: Guerreiros que serviram a um chefe. Eles juraram lutar por seus senhores até a morte. Recebe 8 de dano ao dado e causa 1 de dano por rodada.
  • Os Skald: Skalds, geralmente traduzidos como bardos, eram homens livres que foram contratados para escrever poemas, histórias ou canções sobre os grandes feitos dos guerreiros nórdicos. Recebe 8 de dano e morre a cada guerreiro adjacente 1 de bônus. Skalds não causam dano. Guerreiros não podem ganhar mais de 1 bônus de dano dessa maneira.

Saxões:

Os saxões chegaram a se estabelecer na Grã-Bretanha da Europa continental após o fim do Império Romano no século V. Para os propósitos deste desafio, há os guerreiros dos saxões:

  • O Earl: Ealdormen , comumente chamado Earls, eram membros da alta nobreza. Eles geralmente possuíam grandes extensões de terra e tinham centenas ou até milhares de homens jurados. Leva 20 de dano para morrer e causa 1 de dano por rodada.
  • A Knoite: por falta de um termo melhor, os cavaleiros eram nobres menores que possuíam alguma terra. Na maioria dos casos, os cavaleiros eram servos jurados de um conde. Leva 10 de dano para morrer e causa 2 de dano por rodada.
  • O Warrior: homens comuns, geralmente nobres menores sem terra ou camponeses que serviam a cavaleiro. Quando adjacente a um Cavaleiro ou Conde, os guerreiros recebem um bônus de dano +1. Recebe 8 de dano ao dado e causa 2 de dano por rodada.
  • O Fyrd: O fyrd era uma milícia semelhante grupo de homens livres, geralmente agricultores pobres, que iria trazer qualquer arma (ou arma semelhante a agricultura implementar), tiveram de lutar na parede. Recebe 5 de dano ao dado e causa 1 de dano por rodada.
  • Os Pmais sacerdotes: os sacerdotes eram muito valorizados na cultura saxã primitiva, sendo arautos das palavras de Deus. Sacerdotes recebem 15 pontos de dano para morrer e previnem até 1 ponto de dano a cada guerreiro adjacente. Os padres não causam dano. Os sacerdotes não podem impedir mais de 1 dano a um guerreiro.

A parede

Paredes se encontram em seus centros. A cada rodada, cada guerreiro atribui dano ao guerreiro diretamente à sua frente ou, se não houver guerreiro vivo à sua frente, o guerreiro vivo na diagonal adjacente com menos saúde restante. Se houver um empate, escolha o guerreiro mais próximo da borda da parede.

Exemplo:

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.

Regras:

  • Aplicam-se lacunas padrão .
  • Você pode usar qualquer método conveniente de IO .
  • Este é o , e o código mais curto (em bytes, por idioma) vence.
  • Você não pode presumir que as listas terão o mesmo comprimento, mas sempre serão alinhadas em seus centros (sempre haverá um número ímpar de guerreiros em cada lista se as listas tiverem tamanhos diferentes).
  • Você pode emitir qualquer valor de verdade / falsey. Por favor, especifique na sua resposta os equivalentes de "Vitória Viking / Saxônica".
  • O perdedor é determinado quando todos os guerreiros de um muro estão mortos.
  • Se você acabar com paredes que não são alinhadas durante a execução do código, alinhe-as o mais centralmente possível, deixando um guerreiro extra na parede mais longa para o lado direito. Por exemplo:

      [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]
    
  • Sinta-se à vontade para tentar testar seu código com qualquer configuração de paredes, não apenas as dos casos de teste.

Casos de teste:

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

Existem algumas imprecisões históricas. Sinta-se livre para apontá-los e eu farei o meu melhor para corrigi-los.

J. Sallé
fonte
Podemos definir outros símbolos em vez das primeiras letras dos nomes, por exemplo, números 0-9?
precisa saber é o seguinte
@NieDzejkob sure thing. Apenas certifique-se de especificar em sua resposta quais símbolos foram usados ​​para qual guerreiro.
J. Sallé
3
Seria considerado trapaça ter a entrada como suas propriedades e não como letras? (exemplo como (health, damage, damagebonus, protbonus))
HyperNeutrino
@HyperNeutrino Não tenho muita certeza, mas acho que tudo bem? Não vejo como isso poderia lhe dar uma grande vantagem. Como eu disse a NieDzejkob, contanto que você especifique em sua resposta o que representa cada guerreiro, siga em frente.
J. Sallé

Respostas:

3

Python 2 , 576 573 565 554 540 549 bytes

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'

Experimente online!

TFeld
fonte
Se bem entendi, este bit: (5in V[i-1:i+2:2])implica que skalds adjacentes podem causar danos. Você pode precisar de um ...*(V[i]!=5)lá. Teste:print f([S,S],[P]) # says V but should be a Draw
ngn
Graças @ngn para que :)
TFeld
2

APL (Dyalog Classic) , 128 bytes

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

Experimente online!

Há duas funções no link TIO: gé a função golfed acima e fé uma função ungolfed que aceita um par de strings, as converte em uma representação adequada e chama a função golfed.

A entrada são cinco matrizes: ttipos de guerreiros como ints; lvida; ddanificar; bque tipos de guerreiros dão bônus quando adjacentes; pmesmo para proteção. As matrizes consistem em duas linhas - Vikings e Saxões. Se seus guerreiros não são o mesmo número, as matrizes devem ser preenchidas com 0, embora não necessariamente centralizadas. O resultado é 1/ ¯1para vitória Viking / Saxon ou 0empate.

{
  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
}
ngn
fonte