Стіна щита


18

Історичні передумови

Стіна щита - це тактичне військове формування, яке сягає щонайменше 2500 р. До н. Він складався з воїнів, що перекривали свої щити зі своїми супутниками, утворюючи «стіну». Привабливість тактики випливає з того, що навіть самий некваліфікований воїн міг битися в стіні, доки у них був щит і зброя. Через близькість стін було мало місця для пересування, і битва, як правило, перетворювалась на колючий поєдинок, який бився з гострою зброєю.

Змагання

Ваше завдання - створити програму або функцію, яка з урахуванням двох масивів / списків / векторів воїнів визначає результат битви. Списки представлятимуть однолінійну стіну щитів, і вони дотримуватимуться конкретних позначень:

Вікінги:

Північні воїни мали жорстокий потяг до бою. В кінці 8 до середини 11 століття датські вікінги вторглися в королівства Британії, шукаючи багатства та оброблювану землю. Для цього завдання це воїни вікінгів:

  • JARL: Зазвичай знайшов провідну свої людина від центру стіни, Ярл були лідерами вікінга орд. Наносить 15 збитків, щоб померти, і завдає 2 збитки за раунд.
  • BErserker: Хоча фантазія сильно скручені образ Берсерк, ці воїни були відомі битися в транс , як лють без будь - якого захисту, крім щитів. Приносить 6 збитків загинути і завдає 3 збитки за раунд.
  • CHieftain: Вожді були багатими людьми , які мали вільні людина на їх обслуговування. Зазвичай вони заслужили велику славу і багатство в бою. Приносить 10 збитків загинути і завдає 2 збитки за раунд.
  • Безкоштовні Men: Воїни, які служили аташе. Вони присягалися боротися за своїх панів до смерті. Приносить 8 збитків загинути і завдає 1 збиток за раунд.
  • SKald: Skalds, зазвичай перекладається як барда, були вільними людьми , які були найняті , щоб писати вірші, розповіді або пісні про великі подвиги скандинавських воїнів. Приносить 8 збитків загинути і наносить кожному суміжному воїну 1 бонусний збиток. Шкоди не завдають шкоди. Таким чином воїни не можуть отримати більше 1 бонусного збитку.

Сакси:

Саксони приїхали оселитися у Британію з континентальної Європи після розпаду Римської імперії у V столітті. Для цілей цього виклику є воїни саксів:

  • EARL: Ealdormen , зазвичай називають Earls, були членами вищого дворянства. Зазвичай вони тримали великі потоки землі і мали сотні, а то й тисячі заклятих людей. Приносить 20 збитків загинути і завдає 1 збиток за раунд.
  • KНіч: З- за відсутності кращого терміну, що лицарі були невеликі дворяни, які володіли ділянку землі. У більшості випадків лицарі були заклятими слугами графу. Приносить 10 збитків загинути і завдає 2 збитки за раунд.
  • У Warrior: Загальні чоловіки, як правило , дрібні дворяни без землі або селян, які служили лицар. Примикаючи до лицаря чи графа, воїни отримують бонус +1 ушкодження. Приносить 8 збитків загинути і завдає 2 збитки за раунд.
  • FYRD: фірд була міліція, як група вільних людей, як правило , бідних фермерів, які б принести будь-яку зброю (або зброю, як сільське господарство реалізації) вони повинні були боротися в стіні. Приносить 5 збитків загинути і завдає 1 збиток за раунд.
  • У Priest: Священики були високо оцінені на початку саксонської культури, будучи вісниками слів Бога. Священики беруть 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 .
  • Це , тому найкоротший код (у байтах, на кожній мові) виграє.
  • Ви не можете припустити, що списки матимуть однакову довжину, але вони завжди будуть невідчужуваними у своїх центрах (у кожному списку завжди буде непарна кількість воїнів, якщо списки мають різний розмір).
  • Ви можете вивести будь-яке значення truthy / falsey. Будь ласка, вкажіть у своїй відповіді еквіваленти "Перемоги вікінгів / саксів".
  • Невдаха визначається, коли всі воїни стіни мертві.
  • Якщо ви коли-небудь стикаєтеся зі стінами, невідчужуваними під час виконання коду, вирівняйте їх якомога центральніше, залишивши одного зайвого воїна на довшій стіні праворуч. Наприклад:

      [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é

3
Чи вважатиметься обманом прийняття вкладів як їх властивостей, а не букв? (приклад як (health, damage, damagebonus, protbonus))
HyperNeutrino

@HyperNeutrino Я не зовсім впевнений, але я думаю, це було б добре? Я не бачу, як це могло б дати вам велику перевагу. Як я казав NieDzejkob, поки ви вкажете у своїй відповіді, що представляє кожен воїн, ідіть за цим.
J. Sallé

Відповіді:


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])означає, що сусідні скальди можуть завдати шкоди. Вам може знадобитися ...*(V[i]!=5)там. Тест:print f([S,S],[P]) # says V but should be a Draw
ngn

@ngn Дякую за це :)
TFeld

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

Вхід складається з п'яти матриць: tтипи воїнів як ints; 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
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.