Simulieren Sie einen Kampf zwischen zwei Kreaturen

16

Willkommen, mutiger Code-Golfer! Heute stehst du inmitten eines großen Kampfes zwischen einem Kobold und einem Elfen!

    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!

Die Herausforderung

Ihre Herausforderung besteht darin, einen Kampf wie den oben genannten zu simulieren. Sie erhalten Eingaben in dieser Form:

creatureName health strength defense accuracy agility

Zum Beispiel wäre der Kampf zwischen dem Kobold und dem Elfen:

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

Die erste und die zweite Kreatur werden abwechselnd angreifen.

  • 'CreatureName attackiert otherCreatureName!'
  • Überprüfe, ob die Kreatur ausweicht. Die Kreatur weicht einem Angriff aus, wenn (seine Beweglichkeit mal rand () geteilt durch 2) größer ist als (die Genauigkeit des Angreifers mal rand ()).
    • Wenn die Kreatur ausweicht, drucke 'creatureName dodges!'
    • Andernfalls berechnen Sie den verursachten Schaden durch Subtrahieren von (Stärke des Angreifers mal rand ()) und (Verteidigung des Verteidigers mal rand () geteilt durch 2). Der minimale Schaden beträgt 1. Drucken Sie 'creatureName trifft otherCreatureName für (x) Schaden!' Dann print 'creatureName hat (x) Gesundheit übrig.' es sei denn, die Gesundheit der Kreatur ist 0 oder weniger. In diesem Fall ...
      • Wenn die Gesundheit der Kreatur 0 oder weniger ist, drucke 'kreaturname wurde getötet!' und beenden Sie das Programm.

Regeln

  • Kürzester Code gewinnt.
  • Drucken Sie nicht buchstäblich 'creatureName', sondern ersetzen Sie es durch den Namen der Kreatur. Gib nicht '(x) Schaden' oder '(x) Gesundheit' aus. Ersetzen Sie sie durch die tatsächliche Menge. (Ich muss das spezifizieren, weil einige Leute sehr kreativ sind, wenn es darum geht, die Regeln zu biegen.: P)
Türknauf
quelle
2
Warum die Spezifikation durch Halbierung der Beweglichkeit und Verteidigung erschweren?
Peter Taylor
@Peter Weil sonst die Schlachten zu lange gedauert haben.
Türklinke
2
Mein Punkt war: warum nicht die Eingabe ändern, zB auf goblin 50 40 18 3 2 elf 50 35 15 4 5?
Peter Taylor
@Peter Meh, das schien einfach zu seltsam - warum sollte die Verteidigung so viel niedriger sein? Wie auch immer, es ist ein Rätsel. Kein Grund, nicht zu: P
Türklinke
Ich denke, es ist nicht klar, ob 'creatureName (x) Gesundheit übrig hat.' sollte in der letzten Runde gedruckt werden (wenn die Kreatur getötet wird), und falls es sollte (ich nahm an, dass es nicht sollte), wenn (x) immer 0 sein sollte oder es eine negative Zahl sein kann.
Epidemie

Antworten:

4

APL ( 249 244 242)

Diesmal im prozeduralen Stil, also (zumindest in Dyalog) müssen Sie dies in ein Editorfenster einfügen. Ich habe es benannt G(die erste Zeile ist der Name, ich habe ihn eingefügt, weil er so im Editorfenster angezeigt wird, also sollte er wahrscheinlich gezählt werden).

G
⎕ML ← 3
DA ← {(⊂ ↑ ⍵), ⍎¨1 ↓ ⍵} ¨ ↓ 2 6⍴A⍴ '' ≠ A ← ⍞
→ 5
⎕ ← (↑ D) 'weicht aus!'
AD ← DA
⎕ ← (↑ A) 'Angriffe', '!', ⍨ ↑ D
→ 4 / ⍨> /? A [6], D [5]
⎕ ← A [1], 'Treffer', D [1], 'Für', 'Schaden!', ⍨D [2] - ← 1⌈ - /? A [3], ⌈D [4] ÷ 2
→ 12 / ⍨D [2] ≤0
⎕ ← D [1], 'hat', D [2], 'Gesundheit übrig!'
→ 5
⎕ ← D [1], "wurde getötet!"

(edit: verwendet numerische GOTOs anstelle von Zeilenbeschriftungen. Es stellt sich heraus, dass (zumindest in Dyalog) alles, was eine Beschriftung definiert X:, Xauf die Zeilennummer gesetzt ist, daher können die Zahlen auch direkt verwendet werden.)

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

Mit perl -nM5.010(oder perl -nE '<code>') ausführen . Per Meta zählt der -nSchalter als ein zusätzliches Zeichen. Keine ausgefallenen Golftricks in diesem Code, außer vielleicht die Verwendung $=als Schadensvariable zum Speichern eines int.

Edit: Hoffentlich ist die Schadensberechnung jetzt korrekt.

Ilmari Karonen
quelle
6

CoffeeScript 454 432

Übergeben Sie eine Zeichenfolge b, um die Ergebnisse zu erhalten. Ich dachte, es würde mehr Spaß machen, eine grafisch animierte Ausgabe zu haben, also habe ich eine Demo zusammengestellt. Ändern Sie einfach das Eingabefeld, um Statistiken und Namen zu ändern. Die Bilder von jpg.to sind die inoffizielle google-images API.

Super Action Demo

Kampfsimulator in Aktion

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

Empfohlene Eingänge (schlagen Sie Ihre eigenen vor):

charmander 50 40 25 3 2 bulbasaur 90 30 40 4 5
voldemort 9999 10 5 1 1 batman 20 50 10 1010 30
Räuber
quelle
Wow! Das ist toll! : DI würde diese Antwort akzeptieren, wenn ich zwei akzeptieren könnte, aber ich sagte in den Regeln, dass die kürzeste akzeptiert würde, und ich kann nur eine Antwort akzeptieren :( Also +1. Und voldemort 9999haha: D
Türklinke
@Doorknob, als zusätzlichen Bonus können Sie Zahlen wie geben 10e42, aber Ihr Browser kann einfrieren ...
Brigand
6

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

Mein erster Code Golf Eintrag; Wie diese Methodendefinition analysiert, ist mir ein Rätsel :)

Ist es in Ordnung, die Eingabe von Befehlszeilenparametern (z. B. ruby battle.rb goblin 50 40 35 3 2 elf 50 35 30 4 5) zu lesen ?

Ideone läuft

Epidemie
quelle
Ja das ist ok
Türklinke
5

JavaScript; 347 341 333

Wie immer beginne ich mit meiner eigenen Lösung:

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}

BEARBEITEN: Anscheinend wird die Zuweisung console.logeiner Variablen in einigen Browsern unterbrochen. Daher hier derselbe Code mit einer Funktionsdeklaration:

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}

Ich dachte darüber nach alert, es zu ändern , aber das wäre einfach böse: P

Türknauf
quelle
Ich bekomme eine Uncaught TypeError: Illegal invocationwegen a=console.log. Müssten Sie das consoleObjekt nicht als Kontext binden , z a=console.log.bind(console).
C5H8NNaO4
@ C5H Hmm, das ist komisch. Für mich geht das.
Türklinke
Habe es gerade in Firefox, Safari und Chrome überprüft, in Firefox funktioniert es =) Chrome gibt mir oben und Safari einen TypeError
C5H8NNaO4
@ C5H :( Vielleicht könnte ich es durch ersetzen alert, aber das wäre sehr ärgerlich: P
Türklinke
: P Ja, das wäre in der Tat ärgerlich, aber zumindest würde es "6" Zeichen speichern und den TypeError vermeiden =) Aber ich denke, es ist in
Ordnung
4

Python: 393

Ich drückte etwas fester, wenn ich 3 hätte, könnte ich es wahrscheinlich print = pum ein paar mehr verkürzen, aber ich glaube nicht, dass in diesem noch viel übrig ist.

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"

Ich denke, die Leute überspringen, dass Sie nicht überprüfen müssen, ob das Ziel unter dem Gesundheitszustand liegt, wenn Sie einen guten Zustand in der Schleife haben.


quelle
Ich überprüfe den Zustand zweimal, in der Kopfzeile der Schleife, um den Kampf zu beenden, und in der Schleife, um entweder "wurde getötet" oder "Treffer ..." zu drucken, weil die doppelte Zustandsprüfung kürzer ist als eine zusätzliche 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.")))

Beispielausgabe:

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!   

Anmerkungen bearbeiten: +1 Zeichen, ich habe das "!" after "dodges"
Oh, und ich habe vergessen, eine Ausgabe nach "Sample output" zu setzen.
Der Header wurde in JavaScript geändert, wie @tbodt vorschlägt

C5H8NNaO4
quelle
Warum nennst du es nicht JavaScript, um die Leute nicht zu verwirren?
Tbodt
@tbodt Ich hätte nicht gedacht, dass es die Leute verwirren würde =)
Änderte
3

R: 387 Zeichen

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}

Oder ausgereift, mit Einrückungen und Kommentaren, um die Dinge klarer zu machen:

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
quelle
2

C # - 464 453 Zeichen

Nach ein paar Nächten kann ich den anderen Einträgen anscheinend nicht einmal mehr nahe kommen (nicht überraschend für C #). Ich vermute immer noch Raum für Verbesserungen. Keine besonders cleveren Tricks.

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

Kommentiert:

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
quelle
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])
Setzen Sie Monica wieder ein
quelle