Simula una batalla entre dos criaturas.

16

Bienvenido, valiente golfista de código! ¡Hoy estarás en medio de una gran batalla entre un duende y un 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!

El reto

Tu desafío es simular una batalla, como la anterior. Recibirá información de esta forma:

creatureName health strength defense accuracy agility

Por ejemplo, la batalla entre el duende y el elfo sería:

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

La primera y la segunda criaturas alternarán los ataques.

  • Imprimir 'criaturaName ataca a otroCreatureName!'
  • Comprueba si la criatura esquiva. La criatura esquivará un ataque si (su agilidad multiplicada por rand () dividida entre 2) es mayor que (la precisión del atacante multiplicada por rand ()).
    • Si la criatura esquiva, imprime 'criatura Nombre esquiva!'
    • De lo contrario, calcule el daño infligido restando (la fuerza del atacante multiplicada por rand ()) y (la defensa del defensor multiplica por rand () dividido por 2). El daño mínimo es 1. Imprime 'criaturaName golpea a otroCreatureName por (x) daño!' A continuación, imprima 'criaturaNombre tiene (x) salud restante'. a menos que la salud de la criatura sea 0 o menos, en cuyo caso ...
      • Si la salud de la criatura es 0 o menos, imprime '¡El nombre de la criatura ha sido asesinado!' y terminar el programa.

Reglas

  • El código más corto gana.
  • No imprima literalmente 'creatureName', sino reemplácelo con el nombre de la criatura. No imprima '(x) daños' o '(x) salud;' reemplazarlos con la cantidad real. (Tengo que especificar esto porque algunas personas son muy creativas con la flexión de las reglas.: P)
Pomo de la puerta
fuente
2
¿Por qué complicar las especificaciones reduciendo a la mitad la agilidad y la defensa?
Peter Taylor
@Peter Porque de lo contrario las batallas tomaron demasiado tiempo.
Pomo de la puerta
2
Mi punto fue: ¿por qué no cambiar la entrada, por ejemplo a goblin 50 40 18 3 2 elf 50 35 15 4 5?
Peter Taylor
@ Peter Meh, eso parecía demasiado extraño: ¿por qué la defensa sería mucho más baja? De todos modos, es un rompecabezas; no hay razón para no hacerlo: P
Pomo de la puerta
Creo que no está claro si 'creatureName tiene (x) salud restante'. debe imprimirse en la última ronda (cuando la criatura es asesinada), y en caso de que debería (supuse que no debería) si (x) debería ser siempre 0 o puede ser un número negativo.
epidemia el

Respuestas:

4

APL ( 249 244 242)

Esta vez, el estilo de procedimiento (por lo menos en Dyalog) debe pegar esto en una ventana del editor. Lo nombré G(la primera línea es el nombre, lo he incluido porque así es como aparece en la ventana del editor, por lo que probablemente debería contarse).

sol
⎕ML ← 3
DA ← {(⊂ ↑ ⍵), ⍎¨1 ↓ ⍵} ¨ ↓ 2 6⍴A⊂⍨ '' ≠ A ← ⍞
→ 5
⎕ ← (↑ D) 'esquiva'
AD ← DA
⎕ ← (↑ A) 'ataques', '!', ⍨ ↑ D
→ 4 / ⍨> /? A [6], D [5]
⎕ ← A [1], 'golpes', D [1], 'por', 'daño', ⍨D [2] - ← 1⌈ - /? A [3], ⌈D [4] ÷ 2
→ 12 / ⍨D [2] ≤0
⎕ ← D [1], 'tiene', D [2], '¡salud restante!'
→ 5
⎕ ← D [1], 'ha sido asesinado'

(editar: GOTO numéricos usados ​​en lugar de etiquetas de línea. Resulta que (al menos en Dyalog) toda la definición de una etiqueta X:se establece Xen el número de línea, por lo que también podría usar los números directamente).

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

Corre con perl -nM5.010(o perl -nE '<code>'). Por meta , el -ninterruptor cuenta como un personaje adicional. No hay trucos de golf sofisticados en este código, excepto tal vez el uso de $=la variable de daño para guardar un int.

Editar: Con suerte, el cálculo del daño es correcto ahora.

Ilmari Karonen
fuente
6

CoffeeScript 454 432

Pase una cadena bpara obtener los resultados. Pensé que sería más divertido tener una salida gráfica animada, así que armé una demostración. Simplemente cambie el cuadro de entrada para cambiar las estadísticas y los nombres. Las imágenes de jpg.to, que es la API no oficial de google-images.

Super Action Demo

simulador de batalla en acción

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 (sugiera las suyas):

charmander 50 40 25 3 2 bulbasaur 90 30 40 4 5
voldemort 9999 10 5 1 1 batman 20 50 10 1010 30
Bandido
fuente
¡Wow eso es genial! : DI aceptaría esta respuesta si pudiera aceptar dos, pero dije en las reglas que se aceptaría el más corto, y solo puedo aceptar una respuesta :( Entonces +1. Y voldemort 9999jaja: D
Pomo de la puerta
@Doorknob, como un bono extra, puede darle números como 10e42, pero su navegador puede congelarse ...
Brigand
6

Rubí, 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}

Mi primer código de entrada de golf; cómo esa definición de método analiza está más allá de mí :)

¿Está bien leer la entrada de los parámetros de la línea de comandos (por ejemplo ruby battle.rb goblin 50 40 35 3 2 elf 50 35 30 4 5)?

Ideone run

epidemia
fuente
Si, eso está bien.
Pomo de la puerta
5

JavaScript; 347 341 333

Como siempre hago, comenzaré con mi propia solución:

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}

EDITAR: aparentemente asignando console.loga una variable saltos en algunos navegadores, así que aquí está el mismo código con una declaración de función en su lugar:

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}

Estaba pensando en cambiarlo alert, pero eso sería malo: P

Pomo de la puerta
fuente
me sale un Uncaught TypeError: Illegal invocationpor a=console.log. ¿no tendrías que vincular el consoleobjeto como contexto, por ejemplo a=console.log.bind(console)?
C5H8NNaO4
@ C5H Hmm, eso es extraño. Esto funciona para mi.
Pomo de la puerta
Acabo de comprobarlo en Firefox, Safari y Chrome, en Firefox funciona =) Chrome me da más arriba, y Safari un TypeError
C5H8NNaO4
@ C5H :( Tal vez podría reemplazarlo alert, pero sería muy molesto: P
Pomo de la puerta
: P Sí, eso sería realmente molesto, pero al menos salvaría "6" caracteres y evitaría TypeError =) Pero supongo que está bien, al menos se ejecuta en Firefox =)
C5H8NNaO4
4

Python: 393

Apreté un poco más, si tuviera 3 probablemente podría print = pacortarlo un poco más, pero no creo que quede mucho en este.

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"

Creo que la gente se está saltando que si tiene una buena condición en el circuito, no necesita verificar si el objetivo está por debajo de la salud.


fuente
Compruebo la salud dos veces, en el encabezado del bucle para finalizar la batalla, y en el bucle para imprimir "ha sido asesinado" o "aciertos ...", porque la doble verificación de salud es más corta que una consola adicional.log
C5H8NNaO4
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.")))

Salida de muestra:

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 personaje, me perdí el "!" después de "esquivar"
Ah, y olvidé poner una salida después de "Salida de muestra"
Cambié el encabezado a JavaScript, como sugiere @tbodt

C5H8NNaO4
fuente
¿Por qué no lo llamas JavaScript para evitar confundir a las personas?
tbodt
@tbodt No pensé que confundiría a la gente =) Lo cambié a Javascript en su lugar
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}

O completamente desarrollado, con muescas y comentarios, para aclarar las cosas:

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
}
plannapus
fuente
2

C # - 464 453 caracteres

Después de un par de noches en esto, parece que no puedo acercarme a las otras entradas (no es tan sorprendente para C #). Todavía hay margen de mejora, sospecho. No hay trucos especialmente ingeniosos.

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!");
        }
    }
}
Igby Largeman
fuente
1

Pitón 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])
Reinstalar a Mónica
fuente