Simula una battaglia tra due creature


16

Benvenuto, coraggioso giocatore di golf! Oggi ti troverai nel bel mezzo di una grande battaglia tra un folletto e 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!

La sfida

La tua sfida è simulare una battaglia, come quella sopra. Riceverai input in questo modulo:

creatureName health strength defense accuracy agility

Ad esempio, la battaglia tra il folletto e l'elfo sarebbe:

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

La prima e la seconda creatura alterneranno gli attacchi.

  • Stampa "creatureName attacca altroCreatureName!"
  • Controlla se la creatura schiva. La creatura schiverà un attacco se (i suoi tempi di agilità rand () divisi per 2) sono maggiori di (la precisione dei tempi di attaccante rand ()).
    • Se la creatura schiva, stampa "creaturaName schiva!"
    • Altrimenti, calcola il danno inflitto sottraendo (i tempi di forza dell'attaccante rand ()) e (i tempi di difesa del difensore rand () diviso per 2). Il danno minimo è 1. Stampa "creatureName colpisce otherCreatureName per danni (x)!" Quindi stampa 'creatureName ha (x) salute rimanente.' a meno che la salute della creatura non sia pari o inferiore a 0, nel qual caso ...
      • Se la salute della creatura è pari o inferiore a 0, stampa "creatureName è stato ucciso!" e termina il programma.

Regole

  • Il codice più corto vince.
  • Non stampare letteralmente "creatureName", ma sostituiscilo con il nome della creatura. Non stampare "(x) danni" o "(x) salute;" sostituirli con l'importo effettivo. (Devo specificare questo perché alcune persone sono molto creative nel piegare le regole.: P)

2
Perché complicare le specifiche dimezzando l'agilità e la difesa?
Peter Taylor,

@Peter Perché altrimenti le battaglie impiegarono troppo tempo.
Maniglia della porta

2
Il mio punto era: perché non modificare l' ingresso, ad esempio in goblin 50 40 18 3 2 elf 50 35 15 4 5?
Peter Taylor,

@Peter Meh, è ​​sembrato troppo strano - perché la difesa dovrebbe essere molto più bassa? Comunque, è un puzzle; nessun motivo per non: P
Maniglia della porta

Penso che non sia chiaro se "creaturaName abbia (x) salute rimasta". dovrebbe essere stampato nell'ultimo round (quando la creatura viene uccisa), e nel caso in cui dovrebbe (ho supposto che non dovrebbe) se (x) dovrebbe essere sempre 0 o può essere un numero negativo.
epidemia,

Risposte:


4

APL ( 249 244 242)

Questa volta lo stile procedurale, quindi (almeno in Dyalog) devi incollarlo in una finestra dell'editor. L'ho chiamatoG (la prima riga è il nome, l'ho incluso perché è così che appare nella finestra dell'editor, quindi probabilmente dovrebbe essere contato).

sol
⎕ML ← 3
DA ← {(⊂ ↑ ⍵), ⍎¨1 ↓ ⍵} ¨ ↓ 2 6⍴A⊂⍨ '' ≠ A ← ⍞
→ 5
⎕ ← (↑ D) 'schiva!'
AD ← DA
⎕ ← (↑ A) 'attacchi', '!', ⍨ ↑ D
→ 4 / ⍨> /? A [6], D [5]
⎕ ← A [1], 'hits', D [1], 'per', 'danni!', ⍨D [2] - ← 1⌈ -? / A [3], ⌈D [4] ÷ 2
→ 12 / ⍨D [2] ≤0
⎕ ← D [1], 'ha', D [2], 'salute rimasta!'
→ 5
⎕ ← D [1], 'è stato ucciso!'

(modifica: usato GOTO numerici invece di etichette di linea. Si scopre che (almeno in Dyalog) tutta la definizione di un'etichetta X:è impostata Xsul numero di linea, quindi potrebbe anche usare direttamente i numeri.)


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

Esegui con perl -nM5.010(o perl -nE '<code>'). Per meta , l' -ninterruttore conta come un personaggio in più. Non ci sono trucchi da golf fantasiosi in questo codice, tranne forse l'uso di $=come variabile danno per salvare un int.

Modifica: si spera che il calcolo del danno sia corretto ora.


6

CoffeeScript 454 432

Passa una stringa bper ottenere i risultati. Ho pensato che sarebbe stato più divertente avere un output grafico animato, quindi ho messo insieme una demo. Basta cambiare la casella di input per cambiare statistiche e nomi. Le immagini da jpg.to che è l'API google-images non ufficiale.

Demo Super Action

simulatore di battaglia in azione

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

Ingressi consigliati (suggerisci i tuoi):

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 è fantastico! : DI accetterebbe questa risposta se potessi accettarne due, ma ho detto nelle regole che il più breve sarebbe accettato, e posso accettare solo una risposta :( Quindi +1. E voldemort 9999ahah: D
Maniglia

@Doorknob, come bonus extra, puoi assegnargli numeri come 10e42, ma il tuo browser potrebbe bloccarsi ...
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}

Il mio primo codice golf entry; come l'analisi di tale metodo è oltre me :)

È corretto leggere l'input dai parametri della riga di comando (ad es. ruby battle.rb goblin 50 40 35 3 2 elf 50 35 30 4 5)?

Ideone corre


Sì, va bene.
Maniglia della porta

5

JavaScript; 347 341 333

Come faccio sempre, inizierò con la mia soluzione:

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: apparentemente assegnando console.loga una variabile si rompe su alcuni browser, quindi ecco lo stesso codice con una dichiarazione di funzione:

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}

Stavo pensando di cambiarlo in alert, ma sarebbe solo un male: P


ottengo un a Uncaught TypeError: Illegal invocationcausa di a=console.log. non dovresti legare l' consoleoggetto come contesto, ad esempio a=console.log.bind(console)?
C5H8NNaO4

@ C5H Hmm, è strano. Per me funziona.
Maniglia della porta

Ho appena controllato in Firefox, Safari e Chrome, in Firefox funziona =) Chrome mi dà sopra e Safari un TypeError
C5H8NNaO4

@ C5H :( Forse potrei sostituirlo con alert, ma sarebbe molto fastidioso: P
Maniglia

: P Sì, sarebbe davvero fastidioso, ma almeno salverebbe "6" caratteri ed eviterà TypeError =) Ma suppongo che sia Ok, almeno gira su Firefox =)
C5H8NNaO4

4

Python: 393

Ho stretto un po 'più forte, se avessi 3 probabilmente avrei potuto fare print = pper accorciarlo di qualche altro, ma non credo che ci sia molto rimasto in questo.

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"

Penso che la gente stia saltando il fatto che se si ha una buona condizione nel ciclo, non è necessario verificare se l'obiettivo è al di sotto della salute.


Controllo due volte lo stato, nell'intestazione del ciclo per terminare la battaglia, e nel ciclo per stampare "è stato ucciso" o "colpi ...", perché il doppio controllo dello stato è più corto di un extra console.log
console.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.")))

Uscita campione:

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!   

Modifica note: +1 personaggio, ho perso il "!" dopo "schiva"
Oh e ho dimenticato di inserire effettivamente un output dopo "Output di esempio" Ho
cambiato l'intestazione in JavaScript, come suggerisce @tbodt


Perché non lo chiami JavaScript per evitare di confondere le persone?
martedì

@tbodt Non pensavo che avrebbe confuso le persone =) Invece lo ha cambiato in Javascript
C5H8NNaO4

3

R: 387 caratteri

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 sviluppato, con rientri e commenti, per chiarire le cose:

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 caratteri

Dopo un paio di notti su questo non riesco ad avvicinarmi nemmeno alle altre voci (non così sorprendente per C #). Sospetto ancora margini di miglioramento. Nessun trucco particolarmente intelligente.

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

ha commentato:

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])
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.