Імітуйте бій між двома істотами


16

Ласкаво просимо, хоробрий гольфіст! Сьогодні ви будете стояти серед великої битви між гобліном та ельфом!

    goblin attacks elf!
    elf dodges!
    elf attacks goblin!
    elf hits goblin for 13 damage!
    goblin has 37 health left.
    goblin attacks elf!
    goblin hits elf for 1 damage!
    elf has 49 health left.
    elf attacks goblin!
    elf hits goblin for 19 damage!
    goblin has 18 health left.
    goblin attacks elf!
    goblin hits elf for 26 damage!
    elf has 23 health left.
    elf attacks goblin!
    elf hits goblin for 20 damage!
    goblin has been slain!

Змагання

Ваше завдання - імітувати бій, як і вище. Ви отримаєте вхід у цій формі:

creatureName health strength defense accuracy agility

Наприклад, битва між гобліном та ельфом буде:

goblin 50 40 35 3 2 elf 50 35 30 4 5

Перша і друга істоти будуть чергувати атаки.

  • Роздрукувати "CreatureName атакує otherCreatureName!"
  • Перевірте, чи істота ухиляється. Істота ухилятиметься від атаки, якщо (її час спритності rand (), розділене на 2) більший, ніж (разів точність нападника rand ()).
    • Якщо істота ухиляється, надрукуйте "createureName ухиляється!"
    • В іншому випадку обчисліть нанесений збиток, віднімаючи (ранг сили сили нападника ()) та (ранд часу захисту захисника (), розділений на 2). Мінімальний збиток - 1. Роздрукуйте "CreatureName потрапляє у otherCreatureName за (x) збитки!" Тоді надрукуйте "createureName" (x) здоров'я. " якщо тільки здоров'я тварини не дорівнює 0 або менше, в такому випадку ...
      • Якщо здоров'я тварини 0 або менше, надрукуйте "createureName has been kill!" і закінчити програму.

Правила

  • Найкоротший код виграє.
  • Не друкуйте буквально "CreatureName", а замініть його на ім'я істоти. Не друкуйте "(x) шкоду" або "(x) здоров'я"; замінити їх фактичною сумою. (Я мушу вказати це, тому що деякі люди дуже креативні зі згинанням правил.: P)

2
Навіщо ускладнювати специфікацію, вдвічі зменшуючи спритність і захист?
Пітер Тейлор

@Peter Тому що інакше битви тривали занадто довго.
Doorknob

2
Моя думка була: чому б не змінити вхід, наприклад, на goblin 50 40 18 3 2 elf 50 35 15 4 5?
Пітер Тейлор

@ Петер Мех, це здавалося занадто дивним - чому б захист був набагато нижчим? У всякому разі, це загадка; немає причин не робити: P
Doorknob

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

Відповіді:


4

APL ( 249 244 242)

Цього разу процедурний стиль, тому (як мінімум у Dyalog) вам потрібно вставити це у вікно редактора. Я назвав його G(перший рядок - це ім'я, я включив його, оскільки саме так він відображається у вікні редактора, тому його, мабуть, слід порахувати).

Г
⎕ML ← 3
DA ← {(⊂ ↑ ⍵), ⍎¨1 ↓ ⍵} ¨ ↓ 2 6⍴A⊂⍨ '' ≠ A ← ⍞
→ 5
⎕ ← (↑ D) 'ухиляється!'
AD ← DA
⎕ ← (↑ A) 'атаки', '!', ⍨ ↑ D
→ 4 / ⍨> /? A [6], D [5]
⎕ ← A [1], 'удари', D [1], 'за', 'пошкодження!', ⍨D [2] - ← 1⌈ - /? A [3], ⌈D [4] ÷ 2
→ 12 / ⍨D [2] ≤0
⎕ ← D [1], "має", D [2], "здоров'я залишилося!"
→ 5
⎕ ← D [1], "був убитий!"

(відредагувати: використовуються числові GOTO замість міток рядків. Виявляється, що (як мінімум у Dyalog) все, що визначає мітку X:, встановлено Xна номер рядка, тому можна також використовувати ці числа безпосередньо.)


6

Perl, 254 + 1

for((@a[0..5],@b)=split;$a[1]>0;@c=@a,@a=@b,@b=@c){say"$a[0] attacks $b[0]!\n",rand$b[5]/2<rand$a[4]?do{($==rand($a[2])-rand$b[3]/2)<1and$==1;"$a[0] hits $b[0] for $= damage!\n$b[0] has ",($b[1]-=$=)>0?"$b[1] health left.":"been slain!"}:"$b[0] dodges!"}

Виконати з perl -nM5.010(або perl -nE '<code>'). На мета , -nкомутатор вважається одним додатковим символом. У цьому коді немає жодних хитромудрих хитрощів, крім, можливо, використання $=змінної шкоди для збереження int.

Редагувати: Сподіваємось, нарахування шкоди зараз правильне.


6

CoffeeScript 454 432

Передайте рядок до b щоб отримати результати. Я думав, що було б веселіше мати графічний анімований вихід, тому я склав демонстрацію. Просто змініть поле введення, щоб змінити статистику та назви. Фотографії з jpg.to, що є неофіційним API google images.

Демонстрація Super Action

бойовий симулятор в дії

b=(s)->
 r=Math.random
 p=s.split ' '
 n=p.map Number
 l=''
 o=(x...)->l+=x.join(' ')+'!\n'
 while 1|i=!i
  c=(x)->n[i*6+x]*r()
  d=(x)->n[(i||6)+x]*r()
  t=->d(4)/2>c 5
  h=->Math.max c(2)-d(3)/2,1
  a=p[i*6]
  b=p[6+i*-6]
  o a,'attacks',b
  if c(5)/2>d 4
   e=Math.ceil h()
   q=n[(i||6)+1]-=e
   o a,'hits',b,'for',e,'damage'
   o b,'has',q,'health left'if q>0
  else
   o b,'dodges'
  if q<1
   o b,'has been slain'
   break
 l

Рекомендовані введення (запропонуйте свій власний):

charmander 50 40 25 3 2 bulbasaur 90 30 40 4 5
voldemort 9999 10 5 1 1 batman 20 50 10 1010 30

Ого, це чудово! : DI прийняв би цю відповідь, якби я міг прийняти два, але в правилах я сказав, що найкоротший буде прийнятий, і я можу прийняти лише одну відповідь :( Так +1. І voldemort 9999ха-ха: D
Дверна ручка

@Doorknob, як додатковий бонус, ви можете надати йому такі цифри, як 10e42ваш веб-переглядач може замерзнути ...
Brigand

6

Рубі, 292 264

v=$*
def p*a;puts a*' 'end
loop{a,b=v[0],v[6]
w=v.map &:to_i
p a,:attacks,b+?!
w[11]*rand/2>w[4]*rand ? (p b,:dodges!):(h=v[7]=w[7]-=d=[rand(w[2])-rand(w[9])/2,1].max
p a,:hits,b,:for,d,:damage!
p b,:has,h<1?"been slain!":"#{h} health left."
h<1&&exit)
v.rotate!6}

Мій перший запис про гольф з кодом; як аналіз цього методу визначає мене поза межами :)

Чи добре читати вхід з параметрів командного рядка (наприклад ruby battle.rb goblin 50 40 35 3 2 elf 50 35 30 4 5)?

Ideone run


Так, це нормально.
Дверна ручка

5

JavaScript; 347 341 333

Як завжди, я розпочну з власного рішення:

for(m=prompt().split(' '),r=Math.random,a=console.log,c=0,d=6;;){if(a(m[c]+' attacks '+m[d]+'!'),r()*m[c+4]>r()*m[d+5]/2){if(a(m[c]+' hits '+m[d]+' for '+(h=Math.max(~~(r()*m[c+2]-r()*m[d+3]/2),1))+' damage!'),(m[d+1]-=h)<1){a(m[d]+' has been slain!');break}a(m[d]+' has '+m[d+1]+' health left.')}else a(m[d]+' dodges!');t=c;c=d;d=t}

EDIT: мабуть, присвоєння console.logзмінної перерв у деяких браузерах, тому ось такий же код з функцією оголошення замість цього:

for(m=prompt().split(' '),r=Math.random,a=function(x){console.log(x)},c=0,d=6;;){if(a(m[c]+' attacks '+m[d]+'!'),r()*m[c+4]>r()*m[d+5]/2){if(a(m[c]+' hits '+m[d]+' for '+(h=Math.max(~~(r()*m[c+2]-r()*m[d+3]/2),1))+' damage!'),(m[d+1]-=h)<1){a(m[d]+' has been slain!');break}a(m[d]+' has '+m[d+1]+' health left.')}else a(m[d]+' dodges!');t=c;c=d;d=t}

Я думав змінити це alert, але це було б просто злом: P


я отримую Uncaught TypeError: Illegal invocationчерез a=console.log. Ви не повинні зв'язувати consoleоб'єкт як контекст, наприклад a=console.log.bind(console)?
C5H8NNaO4

@ C5H Хм, це не дивно. Це працює для мене.
Дверна ручка

Просто перевірив це в Firefox, Safari та Chrome, у Firefox це працює =) Chrome дає мені вище, а Safari TypeError
C5H8NNaO4

@ C5H :( Можливо, я міг би замінити його alert, але це буде дуже дратувати: P
Doorknob

: P Так, це було б насправді дратувати, але принаймні, це збереже "6" символів і уникає TypeError =) Але я здогадуюсь його Ок, принаймні, він працює на Firefox =)
C5H8NNaO4

4

Пітон: 393

Я стиснувся трохи сильніше, якби у мене було 3, я, мабуть, міг print = pби скоротити його ще на кілька, але я не думаю, що в цьому залишилося багато.

393:

from random import randrange as r
x = input().split()
t=range
a,b=6,0
for i in t(1,6)+t(7,12):x[i]=int(x[i])
while x[b+1] > 0:
 a,b=b,a;print x[a]+" attacks "+x[b]
 if r(x[a+5]/2)>r(x[b+5]):print x[a]+' dodges!';continue
 d=max(r(x[a+2])-r(x[b+3]/2),1);print x[a]," hits ",x[b]," for ",d," damage!";x[b+1]-=d
 if x[b+1]>0:print x[b]," has ",x[b+1]," health left."
print x[b]," has been slain"

399:

from random import randrange as r
x = raw_input().split()
t=range
a,b=6,0
for i in t(1,6)+t(7,12):x[i]=int(x[i])
while x[b+1] > 0:
 a,b=b,a;print x[a]+" attacks "+x[b]
 if r(x[a+5]/2) > r(x[b+5]):print x[a]+' dodges!';continue
 d=max(r(x[a+2])-r(x[b+3]/2),1);print x[a]," hits ",x[b]," for ",d," damage!";x[b+1]-=d                        if x[b+1]>0:print x[b]," has ",x[b+1]," health left."
print x[b]," has been slain"

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


Я перевіряю стан здоров'я двічі, в заголовку циклу, щоб закінчити бій, і в циклі, щоб надрукувати або "було вбито", або "удари ...", тому що подвійна перевірка стану здоров'я коротша, ніж додаткова
консоль.log

4

JavaScript: 340 306

339:

for(m=Math.random,a=prompt().split(" "),c=[a,a.splice(6)],e;0<+c[0][1]&&0<+c[1][1];)c.reverse(),console.log(c[0][0]+" attacks "+c[1][0]+"!\n"+(c[0][4]*m()<c[1][5]*m()/2?c[1][0]+" dodges!":c[0][0]+" hits "+c[1][0]+" for "+(e=1+(c[0][2]*m()-c[1][3]*m()/2|0))+" damage!\n"+c[1][0]+" has "+(0>(c[1][1]-=e)?"been slain!":c[1][1]+" health left.")))

306:

for(var m=Math.random,a=prompt().split(" "),b=a.splice(6),d,e;0<+a[1]&&0<+b[1];d=a,a=b,b=d)console.log(a[0]+" attacks "+b[0]+"!\n"+(a[4]*m()<b[5]*m()/2?b[0]+" dodges!":a[0]+" hits "+b[0]+" for "+(e=a[2]*m()-b[3]*m()/2|0,e<=0?e=1:e)+" damage!\n"+b[0]+" has "+(0>(b[1]-=e)?"been slain!":b[1]+" health left.")))

Вибірка зразка:

goblin attacks elf!
elf dodges!
elf attacks goblin!
elf hits goblin for 21 damage!
goblin has 29 health left.
goblin attacks elf!
elf dodges!
elf attacks goblin!
elf hits goblin for 15 damage!
goblin has 14 health left.
goblin attacks elf!
goblin hits elf for 1 damage!
elf has 49 health left.
elf attacks goblin!
elf hits goblin for 16 damage!
goblin has been slain!   

Редагувати нотатки: символ +1, я пропустив "!" Після "ухилень"
О, і я забув фактично поставити результат після "Зразок виводу"
Змінив заголовок на JavaScript, як підказує @tbodt


Чому б вам не назвати його JavaScript, щоб не плутати людей?
tbodt

@tbodt Я не думав, що це збентежить людей =) Змінив його на Javascript замість цього
C5H8NNaO4

3

R: 387 символів

a=scan(,"");i=as.integer;r=runif;C=cat;X=data.frame(i(a[2:6]),i(a[8:12]));z=1;Y=c(a[1],a[7]);repeat{p=1+z%%2;n=X[,p];m=X[,-p];N=Y[p];M=Y[-p];C(N,"attacks",M,"\n");if(r(1)*n[5]<r(1)*m[5]/2){C(M,"dodges!\n")}else{C(N,"hits",M,"for",d<-max(round(n[2]*r(1)-m[3]*r(1)/2),1),"damages!\n");h=max(m[1]-d,0);if(h){C(M,"has",X[1,-p]<-h,"health left\n")}else{C(M,"has been slained!");break}};z=z+1}

Або всебічно розвинені з відступами та коментарями, щоб зробити речі зрозумілішими:

a=scan(,"")                        # Read stdin as character vector
i=as.integer
r=runif
C=cat
X=data.frame(i(a[2:6]),i(a[8:12])) # Data frame with opponents stats
z=1                                # Turn counter 
Y=c(a[1],a[7])                     # Vector of opponents name
repeat{                            # shorter than while(T)
    p=1+z%%2                       # R indexing starts with 1 not 0
    n=X[,p]                        # Attacking opponent stats
    m=X[,-p]                       # Defending opponent stats
    N=Y[p]                         # Attacking opponent name
    M=Y[-p]                        # Defending opponent name
    C(N,"attacks",M,"\n")          # By default, cat separates elements with a space
    if(r(1)*n[4]<r(1)*m[5]/2){
        C(M,"dodges!\n")
    }else{
        C(N,"hits",M,"for",d<-max(round(n[2]*r(1)-m[3]*r(1)/2),1),"damages!\n")
        h=max(m[1]-d,0)            # Health after the strike
        if(h){                     # If health is not 0
            C(M,"has",X[1,-p]<-h,"health left\n")
        }else{                     # If it is
            C(M,"has been slained!")
            break
            }
    }
    z=z+1
}

2

C # - 464 453 символів

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

using System;using System.Linq;class P{static void Main(string[]a){int D,h=1,z=6;
var n=a.Select(x=>int.TryParse(x,out D)?D:0).ToList();var r=new Random();Func<int>
R=()=>r.Next(101);for(;h>0;z=z>0?0:6){D=(n[8-z]*R()-n[3+z]*R()/2)/100;var d=n[5+z]
*R()/2>n[10-z]*R();h=d?h:n[1+z]-=D=D<1?1:D;Console.Write("{0} attacks {1}!\n"+(d?
"{1} dodges!\n":"{0} hits {1} for {2} damage!\n")+(d?"":"{1} has {3}\n"),a[6-z],a
[z],D,h>0?h+" health left.":"been slain!");}}}

Прокоментував:

using System;
using System.Linq;
class P
{
    static void Main(string[] a)
    {
        int D, // string to int parsing and attack damage 
            h = 1, // health 
            z = 6; // index

        // painful requirement to convert the input strings to integers
        var n = a.Select(x => int.TryParse(x, out D) ? D : 0).ToList();

        // set up a function to return a new random number
        var r = new Random();
        Func<int> R = () => r.Next(101);

        // we'll exit the loop when the defender's health (h) is <= 0.
        // z is used as an index offset to get values out of the list, it flips between 0 an 6 each round
        for (; h > 0; z = z > 0 ? 0 : 6)
        {
            // calculate damage
            D = (n[8 - z] * R() - n[3 + z] * R() / 2) / 100;

            // see if defender dodges
            var d = n[5 + z] * R() / 2 > n[10 - z] * R();

            // subtract health from defender if necessary. store health of defender in h
            h = d ? h : n[1 + z] -= D = D < 1 ? 1 : D;

            // print the round
            Console.Write(
                "{0} attacks {1}!\n" + (d ? "{1} dodges!\n" : "{0} hits {1} for {2} damage!\n") + 
                (d ? "" : "{1} has {3}\n"), a[6 - z], a[z], D, h > 0 ? h + " health left." : "been slain!");
        }
    }
}

1

Пітон 3, 314

from random import*
r=random
p=print
I=input().split()
H=1
while H>0:s,a,H,D,G=map(int,I[2:5:2]+I[7::2]);N=I[6];p(I[0],"attacks",N+"!");I=I[6:]+I[:6];X=max(int(s*r()-D*r()/2),1)*(G*r()/2<a*r());I[1]=H=H-X;X<1and p(N,"dodges!")or p(I[6],"hits",N,"for",X,"damage!\n"+N,"has",["been slain!","%s health left."%H][H>0])
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.