Simule uma batalha entre duas criaturas


16

Bem-vindo, corajoso jogador de golfe! Hoje você estará no meio de uma grande batalha entre um duende e um elfo!

    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!

O desafio

Seu desafio é simular uma batalha, como a anterior. Você receberá informações neste formulário:

creatureName health strength defense accuracy agility

Por exemplo, a batalha entre o duende e o elfo seria:

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

A primeira e a segunda criaturas alternam ataques.

  • Imprimir 'criatName ataca outroCreatureName!'
  • Verifique se a criatura se esquiva. A criatura se esquivar de um ataque se (sua agilidade vezes o rand () dividido por 2) for maior que (a precisão do atacante vezes o rand ()).
    • Se a criatura se esquivar, imprima 'criatName esquiva!'
    • Caso contrário, calcule o dano causado subtraindo (a força do atacante vezes rand ()) e (a defesa do defensor vezes rand () dividido por 2). O dano mínimo é 1. Imprima 'nome da criatura atinge outro nome da criatura por (x) dano!' Em seguida, imprima 'criaturaName com (x) saúde restante'. a menos que a saúde da criatura seja 0 ou menos, nesse caso ...
      • Se a saúde da criatura for 0 ou menos, imprima 'criatNameNome foi morto!' e encerre o programa.

Regras

  • O menor código vence.
  • Não imprima literalmente 'criatName', mas substitua-o pelo nome da criatura. Não imprima '(x) danos' ou '(x) saúde;' substitua-os pela quantidade real. (Preciso especificar isso porque algumas pessoas são muito criativas ao dobrar as regras.: P)

2
Por que complicar as especificações reduzindo pela metade a agilidade e a defesa?
Peter Taylor

@ Peter Porque, caso contrário, as batalhas levavam muito tempo.
Maçaneta

2
Meu argumento era: por que não mudar a entrada, por exemplo, para goblin 50 40 18 3 2 elf 50 35 15 4 5?
Peter Taylor

@ Peter Meh, isso parecia muito estranho - por que a defesa seria muito menor? Enfim, é um quebra-cabeça; não há razão para não: P
Maçaneta da porta

Acho que não está claro se 'criatName está com (x) saúde restante'. deve ser impresso na última rodada (quando a criatura for morta) e, no caso de (suponho que não deveria), se (x) deve ser sempre 0 ou pode ser um número negativo.
Epid

Respostas:


4

APL ( 249 244 242)

Dessa forma, neste procedimento, você deve colá-lo em uma janela do editor (pelo menos no Dyalog). Eu o nomeei G(a primeira linha é o nome, eu o incluí, porque é assim que aparece na janela do editor e, portanto, provavelmente deve ser contada).

G
←ML ← 3
DA ← {(↑ ↑ ⍵), ⍎¨1 ↓ ⍵} ¨ ↓ 2 6⍴A⊂⍨ '' ≠ A ← ⍞
→ 5
⎕ ← (↑ D) 'esquiva!'
AD ← DA
⎕ ← (↑ A) 'ataques', '!', ⍨ ↑ D
→ 4 / ⍨> /? A [6], D [5]
⎕ ← A [1], 'acerta', D [1], 'por', 'dano!', ⍨D [2] - ← 1⌈ - /? A [3], ⌈D [4] ÷ 2
→ 12 / ⍨D [2] ≤0
← D [1], 'has', D [2], 'health left!'
→ 5
← D [1], 'foi morto!'

(edit: usou GOTOs numéricos em vez de rótulos de linha. Acontece que (pelo menos no Dyalog) toda a definição de um rótulo X:é definida Xcomo o número da linha; portanto, é melhor usar os números diretamente.)


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!"}

Corra com perl -nM5.010(ou perl -nE '<code>'). Por meta , o -nswitch conta como um caractere extra. Não há truques de golfe sofisticados neste código, exceto talvez o uso de $=como variável de dano para salvar um int.

Edit: Felizmente, o cálculo do dano está correto agora.


6

CoffeeScript 454 432

Passe uma string bpara obter os resultados. Eu pensei que seria mais divertido ter uma saída gráfica animada, então montei uma demo. Basta alterar a caixa de entrada para alterar estatísticas e nomes. As imagens do jpg.to, que é a API não oficial do google-images.

Super Action Demo

simulador de batalha em ação

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

Entradas recomendadas (sugira a sua):

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

Wow isso é ótimo! : DI aceitaria essa resposta se eu pudesse aceitar duas, mas eu disse nas regras que a menor seria aceita, e só posso aceitar uma resposta :( So +1. E voldemort 9999haha: D
Maçaneta da porta

@Doorknob, como um bônus extra, você pode dar-lhe números como 10e42, mas o seu navegador pode congelar ...
Brigand

6

Ruby, 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}

Minha primeira entrada de código de golfe; como essa definição de método analisa está além de mim :)

Posso ler a entrada dos parâmetros da linha de comando (por exemplo ruby battle.rb goblin 50 40 35 3 2 elf 50 35 30 4 5)?

Ideone run


Sim, está tudo bem.
Maçaneta

5

JavaScript; 347 341 333

Como sempre faço, começarei com minha própria solução:

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: aparentemente atribuindo console.loga uma variável quebra em alguns navegadores, então aqui está o mesmo código com uma declaração de função:

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}

Eu estava pensando em mudar para alert, mas isso seria apenas mau: P


eu recebo um Uncaught TypeError: Illegal invocationpor causa de a=console.log. você não teria que vincular o consoleobjeto como contexto, por exemplo a=console.log.bind(console)?
C5H8NNaO4

@ C5H Hmm, isso é estranho. Funciona para mim.
Maçaneta

Apenas check-lo no Firefox, Safari e Chrome, no Firefox funciona =) Chrome dá-me acima, e Safari um TypeError
C5H8NNaO4

@ C5H :( Talvez eu pudesse substituí-lo por alert, mas isso seria muito chato: P
Doorknob

: P Sim, isso seria de fato chato, mas pelo menos ele iria salvar "6" personagens e evita a TypeError =) Mas eu acho que é Ok, pelo menos, ele é executado no Firefox =)
C5H8NNaO4

4

Python: 393

Eu apertei um pouco mais, se eu tivesse 3, provavelmente poderia fazer print = ppara encurtá-lo um pouco mais, mas acho que não resta muito neste.

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"

Acho que as pessoas estão pulando que, se você tem uma boa condição no circuito, não precisa verificar se o alvo está abaixo da saúde.


Verifico a integridade duas vezes, no cabeçalho do loop para encerrar a batalha e no loop para imprimir "foi slayed" ou "hits ...", porque a verificação de integridade dupla é mais curta que um console
extra.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.")))

Saída de amostra:

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!   

Editar notas: +1 caractere, perdi o "!" depois de "esquiva"
Ah, e esqueci de colocar uma saída depois de "Amostra de saída"
Alterou o cabeçalho para JavaScript, como sugere @tbodt


Por que você não chama JavaScript para evitar confundir as pessoas?
tbodt

@tbodt eu não pensei que iria confundir as pessoas =) mudou para Javascript vez
C5H8NNaO4

3

R: 387 caracteres

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}

Ou totalmente desenvolvido, com recuos e comentários, para tornar as coisas mais claras:

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 caracteres

Depois de algumas noites nisso, não consigo chegar nem perto das outras entradas (não é tão surpreendente para C #). Ainda há espaço para melhorias, suspeito. Não há truques especialmente inteligentes.

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!");}}}

Comentado:

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

Python 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])
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.