İki yaratık arasındaki savaşı simüle et


16

Hoş geldin, cesur kod golfçüsü! Bugün bir cin ve bir elf arasındaki büyük savaşın ortasında duracaksınız!

    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!

Meydan okuma

Zorluğunuz, yukarıdaki gibi bir savaşı simüle etmektir. Bu formdaki girişi alacaksınız:

creatureName health strength defense accuracy agility

Örneğin, cin ve elf arasındaki savaş şöyle olurdu:

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

Birinci ve ikinci yaratıklar sırayla saldırı yapacak.

  • Yazdır 'creatureName diğer saldırılara yaratıldıCreatureName!'
  • Yaratığın kaçıp kaçmadığını kontrol edin. Yaratık (çeviklik süreleri rand () bölü 2) (saldırganın doğruluk süreleri rand ()) 'dan büyükse bir saldırıyı atlatacaktır.
    • Yaratık kaçarsa, 'creatureName kaçar!'
    • Aksi takdirde, (saldırganın kuvvet süreleri rand ()) ve (savunucunun savunma süreleri rand () 2'ye bölünerek) verilen hasarı hesaplayın. Minimum hasar 1'dir. 'CreatureName diğer vuruşlara neden oluyorYaratıcıAdı (x) hasar için!' Sonra 'creatureName'in (x) sağlığı kaldı.' Yaratığın sağlığı 0 veya daha az değilse, bu durumda ...
      • Yaratığın sağlığı 0 veya daha azsa, 'creatureName öldürüldü!' ve programı sonlandırın.

kurallar

  • En kısa kod kazanır.
  • Kelimenin tam anlamıyla 'creatureName' yazmayın, yerine canlının adıyla değiştirin. '(X) hasar' veya '(x) sağlığını yazdırmayın;' bunları gerçek miktarla değiştirin. (Bunu belirtmeliyim çünkü bazı insanlar kuralları bükmekte çok yaratıcılar.: P)

2
Çevikliği ve savunmayı yarıya indirerek özellikleri neden zorlaştırıyorsunuz?
Peter Taylor

@Peter Çünkü aksi takdirde savaşlar çok uzun sürdü.
Kapı tokmağı

2
Benim noktası oldu: değil değiştirmek neden giriş için örneğin goblin 50 40 18 3 2 elf 50 35 15 4 5?
Peter Taylor

@Peter Meh, bu çok tuhaf görünüyordu - savunma neden bu kadar düşük olurdu? Her neyse, bu bir bilmecedir; Hiçbir sebep yok: P
Kapı Tokmağı

Sanırım 'creatureName'in (x) sağlığının kaldığını' belli değil. son turda (yaratık öldürüldüğünde) basılmalı ve eğer (x) her zaman 0 olmalı ya da negatif bir sayı olabilirse (yapmamalıydı).
epidemya

Yanıtlar:


4

APL ( 249 244 242)

Bu kez yordamsal stil, bu yüzden (en azından Dyalog'da) bunu bir düzenleyici penceresine yapıştırmanız gerekir. Ben adlandırdım G(ilk satır adıdır, dahil ettim çünkü editör penceresinde böyle görünüyor, bu yüzden muhtemelen sayılmalıdır).

G,
⎕ML ← 3
DA ← {(⊂ ↑ ⍵), ⍎¨1 ↓ ⍵} ¨ ↓ 2 6⍴A⊂⍨ '' ≠ A ← ⍞
→ 5
⎕ ← (↑ D) 'Dodges!'
AD ← DA
⎕ ← (↑ A) 'saldırılar', '!' ⍨ ↑ D
→ 4 / ⍨> /? A [6], D [5]
⎕ ← [1] A 'hit', D [1], 'için', 'zarar!' ⍨D [2] - ← 1⌈ -? / A [3], ⌈D [4] ÷ 2
→ 12 / ⍨D [2] ≤0
⎕ ← D [1], 'var', D [2], 'sağlık kaldı!'
→ 5
⎕ ← D [1], 'katledildi!'

(edit: satır etiketleri yerine sayısal GOTO'lar kullanıldı. (En azından Dyalog'da) bir etiketin tanımladığı tüm satır numarasına X:ayarlandığını X, bu nedenle sayıları doğrudan da kullanabileceğini gösterir.)


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(Veya perl -nE '<code>') ile çalıştırın . Meta başına , -nanahtar bir ekstra karakter olarak sayılır. Bu kodda süslü golf hileleri yok, belki $=de hasar değişkeni olarak tasarruf etmek için kullanılması int.

Düzenleme: Umarım, hasar hesaplama şimdi doğru.


6

CoffeeScript 454 432

bSonuçları almak için bir dize iletin. Grafik animasyonlu bir çıktı almanın daha eğlenceli olacağını düşündüm, bu yüzden bir demo hazırladım. İstatistikleri ve adları değiştirmek için giriş kutusunu değiştirmeniz yeterlidir. Dan gelen resimler jpg.to gayri resmi google-images API'sıdır.

Süper Aksiyon Demosu

savaş simülatörü eylem

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

Önerilen Girdiler (kendiniz öner):

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

Vay bu harika! : DI, iki tane kabul edebilseydim bu cevabı kabul ederdi, ama kurallarda en kısa olanın kabul edileceğini ve sadece bir cevabı kabul edebileceğimi söyledim :( Yani +1. Ve voldemort 9999haha: D
Kapı Tokmağı

@Doorknob, ekstra bir bonus olarak, ona gibi sayılar verebilirsiniz 10e42, ancak tarayıcınız donabilir ...
Brigand

6

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

İlk kod golf girişim; bu yöntem tanımının ayrışması benden öte :)

Komut satırı parametrelerinden (örn. ruby battle.rb goblin 50 40 35 3 2 elf 50 35 30 4 5) Girişi okumak doğru mudur?

Çalışan kimse


Evet, sorun değil.
Kapı Tokmağı

5

JavaScript; 347 341 333

Her zaman yaptığım gibi, kendi çözümümle başlayacağım:

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: görünüşe göre console.logbazı tarayıcılarda bir değişken mola atama , işte burada yerine bir işlev bildirimi ile aynı kod:

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}

Bunu değiştirmeyi düşünüyordum alert, ama bu sadece kötü olurdu: P


Uncaught TypeError: Illegal invocationçünkü bir olsun a=console.log. consolenesneyi bağlam olarak bağlamanız gerekmez a=console.log.bind(console)mi , örneğin ?
C5H8NNaO4

@ C5H Hmm, bu çok garip. Benim için çalışıyor.
Kapı tokmağı

Sadece Firefox, Safari ve Chrome'da kontrol ettim, Firefox'ta çalışıyor =) Chrome bana yukarıda veriyor ve Safari bir TypeError
veriyor

@ C5H :( Belki onunla değiştirebilirim alert, ama bu çok sinir bozucu olurdu: P
Kapı Tokmağı

: P Evet, bu gerçekten can sıkıcı olurdu, ama en azından "6" karakterleri kurtaracak ve TypeError'ı önleyecek =) Ama tamam olduğunu tahmin ediyorum, en azından Firefox üzerinde çalışıyor =)
C5H8NNaO4 6:13

4

Python: 393

Biraz daha sıktım, eğer 3'üm olsaydı, muhtemelen print = pbirkaç tane daha kısaltmak için yapabilirdim, ama bu konuda çok fazla şey olduğunu düşünmüyorum.

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"

İnsanların döngüde iyi bir durumunuz varsa, hedefin sağlığın altında olup olmadığını kontrol etmenize gerek olmadığını düşünüyorum.


Sağlığı iki kez kontrol ediyorum, savaşı bitirmek için döngü başlığında ve "katledildi" ya da "isabet ..." yazdırmak için döngüde kontrol ediyorum, çünkü çift sağlık kontrolü fazladan bir konsoldan daha kısa.
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.")))

Örnek çıktı:

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!   

Düzenleme notları: +1 karakter, "!" "Dodge" sonra
Oh ve ben aslında "Sample output" sonra bir çıkış koymak unuttum
@tbodt önerdiği gibi başlığı JavaScript olarak değiştirildi


İnsanları karıştırmamak için neden JavaScript demiyorsunuz?
tbodt

@tbodt İnsanların kafasını karıştıracağını düşünmedim =) Bunun yerine Javascript olarak değiştirildi
C5H8NNaO4

3

R: 387 karakter

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}

Veya şeyleri daha net hale getirmek için girintiler ve yorumlarla tamamen geliştirildi:

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 # - 464453 karakter

Birkaç gece sonra bu bile diğer girişlere (C # için şaşırtıcı değil) yakın almak gibi olamaz. Hala iyileştirilmesi için oda şüpheli. Özellikle akıllı numaralar yok.

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

Yorumlananlar:

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])
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.