Simulasikan pertempuran antara dua makhluk

16

Selamat datang, pegolf kode yang berani! Hari ini Anda akan berdiri di tengah-tengah pertempuran hebat antara goblin dan peri!

    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!

Tantangan

Tantangan Anda adalah untuk mensimulasikan pertempuran, seperti yang di atas. Anda akan menerima input dalam formulir ini:

creatureName health strength defense accuracy agility

Misalnya, pertempuran antara goblin dan elf adalah:

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

Makhluk pertama dan kedua akan berganti serangan.

  • Cetak 'creatureName menyerang otherCreatureName!'
  • Periksa untuk melihat apakah makhluk itu berkelit. Makhluk itu akan menghindari serangan jika (kelincahan kali rand () dibagi 2) lebih besar dari (ketepatan waktu penyerang rand ()).
    • Jika makhluk berkelit, cetak 'kreaturName berkelit!'
    • Kalau tidak, hitung kerusakan yang ditangani dengan mengurangi (kekuatan kali penyerang rand ()) dan (waktu pertahanan lawan rand () dibagi 2). Kerusakan minimum adalah 1. Cetak 'creatureName hits otherCreatureName untuk (x) kerusakan!' Kemudian, cetak 'creatureName memiliki (x) kesehatan tersisa.' kecuali kesehatan makhluk itu 0 atau kurang, dalam hal ini ...
      • Jika kesehatan makhluk itu 0 atau kurang, cetak 'creatureName telah dibunuh!' dan akhiri program.

Aturan

  • Kode terpendek menang.
  • Jangan benar-benar mencetak 'creatureName,' tetapi ganti dengan nama creature. Jangan cetak '(x) kerusakan' atau '(x) kesehatan;' gantilah dengan jumlah aktual. (Saya harus menentukan ini karena beberapa orang sangat kreatif dengan membengkokkan aturan.: P)
Gagang pintu
sumber
2
Mengapa menyulitkan spec dengan mengurangi separuh kelincahan dan pertahanan?
Peter Taylor
@ Peter Karena kalau tidak, pertempurannya terlalu lama.
Gagang Pintu
2
Maksud saya adalah: mengapa tidak mengubah input misalnya ke goblin 50 40 18 3 2 elf 50 35 15 4 5?
Peter Taylor
@ Peter Meh, itu sepertinya terlalu aneh - mengapa pertahanannya menjadi jauh lebih rendah? Bagaimanapun, itu adalah teka-teki; tidak ada alasan untuk tidak: P
Gagang Pintu
Saya pikir tidak jelas apakah 'creatureName memiliki (x) kesehatan yang tersisa.' harus dicetak pada putaran terakhir (ketika makhluk itu disembelih), dan jika itu harus (saya anggap tidak seharusnya) jika (x) harus selalu 0 atau bisa menjadi angka negatif.
epidemi

Jawaban:

4

APL ( 249 244 242)

Gaya prosedural kali ini, jadi (setidaknya dalam Dyalog) Anda harus menempelkan ini ke jendela editor. Saya menamainya G(baris pertama adalah nama, saya sudah memasukkannya karena itulah yang muncul di jendela editor sehingga mungkin harus dihitung).

G
⎕ML ← 3
DA ← {(⊂ ↑ ⍵), ⍎¨1 ↓ ⍵} ¨ ↓ 2 6⍴A⊂⍨ '' ≠ A ← ⍞
→ 5
⎕ ← (↑ D) 'berkelit!'
AD ← DA
⎕ ← (↑ A) 'serangan', '!', ⍨ ↑ D
→ 4 / ⍨> /? A [6], D [5]
⎕ ← A [1], 'hit', D [1], 'for', 'damage!', ⍨D [2] - ← 1⌈ - /? A [3], ⌈D [4] ÷ 2
→ 12 / ⍨D [2] ≤0
⎕ ← D [1], 'memiliki', D [2], 'tersisa kesehatan!'
→ 5
⎕ ← D [1], 'telah dibunuh!'

(edit: GOTO numerik yang digunakan alih-alih label garis. Ternyata (dalam Dyalog setidaknya) semua yang didefinisikan oleh sebuah label X:diatur Xke nomor baris, jadi sebaiknya gunakan angka-angka itu secara langsung.)

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

Jalankan dengan perl -nM5.010(atau perl -nE '<code>'). Per meta , -nsakelar dihitung sebagai satu karakter tambahan. Tidak ada trik golf mewah dalam kode ini, kecuali mungkin penggunaan $=sebagai variabel kerusakan untuk menyimpan int.

Sunting: Semoga perhitungan kerusakan sudah benar sekarang.

Ilmari Karonen
sumber
6

CoffeeScript 454 432

Lewati sebuah string buntuk mendapatkan hasil. Saya pikir akan lebih menyenangkan untuk memiliki output animasi grafis, jadi saya mengumpulkan demo. Cukup ganti kotak input untuk mengubah statistik dan nama. Gambar-gambar dari dari jpg.to yang merupakan API google-gambar tidak resmi.

Demo Aksi Super

simulator pertempuran dalam aksi

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

Input yang Disarankan (sarankan untuk Anda sendiri):

charmander 50 40 25 3 2 bulbasaur 90 30 40 4 5
voldemort 9999 10 5 1 1 batman 20 50 10 1010 30
Perampok
sumber
Wow, bagus sekali! : DI akan menerima jawaban ini jika saya dapat menerima dua, tetapi saya mengatakan dalam aturan bahwa yang terpendek akan diterima, dan saya hanya dapat menerima satu jawaban :( Jadi +1. Dan voldemort 9999haha: D
Doorknob
@Doorknob, sebagai bonus tambahan, Anda dapat memberikan nomor seperti itu 10e42, tetapi browser Anda dapat membeku ...
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}

Entri golf kode pertama saya; bagaimana definisi metode mem-parsing di luar saya :)

Apakah boleh membaca input dari parameter baris perintah (mis. ruby battle.rb goblin 50 40 35 3 2 elf 50 35 30 4 5)?

Ideone dijalankan

epidemi
sumber
Ya itu tidak apa-apa.
Gagang Pintu
5

JavaScript; 347 341 333

Seperti yang selalu saya lakukan, saya akan memulai dengan solusi saya sendiri:

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: tampaknya menetapkan console.loguntuk istirahat variabel pada beberapa browser, jadi inilah kode yang sama dengan deklarasi fungsi sebagai gantinya:

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}

Saya sedang berpikir untuk mengubahnya alert, tetapi itu hanya akan jahat: P

Gagang pintu
sumber
saya mendapatkan Uncaught TypeError: Illegal invocationkarena a=console.log. tidakkah Anda harus mengikat consoleobjek sebagai konteks, misalnya a=console.log.bind(console)?
C5H8NNaO4
@ C5H Hmm, itu aneh. Ini bekerja untuk saya.
Gagang Pintu
Baru saja memeriksanya di Firefox, Safari dan Chrome, di Firefox berfungsi =) Chrome memberi saya di atas, dan Safari TypeError
C5H8NNaO4
@ C5H :( Mungkin saya bisa menggantinya dengan alert, tapi itu akan sangat mengganggu: P
Gagang Pintu
: P Ya itu akan sangat menjengkelkan, tapi setidaknya itu akan menyelamatkan "6" karakter dan menghindari TypeError =) Tapi saya kira itu Ok, setidaknya itu berjalan di Firefox =)
C5H8NNaO4
4

Python: 393

Aku meremas sedikit lebih keras, jika aku punya 3 aku mungkin bisa lakukan print = puntuk mempersingkat beberapa lagi, tapi aku tidak berpikir ada banyak yang tersisa dalam yang satu ini.

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"

Saya pikir orang melewatkan bahwa jika Anda memiliki kondisi yang baik di loop, Anda tidak perlu memeriksa apakah targetnya di bawah kesehatan.


sumber
Saya memeriksa kesehatan dua kali, di header loop untuk mengakhiri pertempuran, dan di loop untuk mencetak "telah terbunuh" atau "hit ...", karena pemeriksaan kesehatan ganda lebih pendek daripada konsol tambahan.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.")))

Output sampel:

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!   

Edit catatan: karakter +1, saya melewatkan "!" setelah "dodges"
Oh dan saya lupa untuk benar-benar menaruh output setelah "Contoh output"
Mengubah header menjadi JavaScript, seperti yang disarankan oleh @tbodt

C5H8NNaO4
sumber
Mengapa Anda tidak menyebutnya JavaScript untuk menghindari orang yang membingungkan?
tbodt
@tbodt Saya tidak berpikir itu akan membingungkan orang =) Menggantinya ke Javascript
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}

Atau dikembangkan sepenuhnya, dengan lekukan dan komentar, untuk membuat segalanya lebih jelas:

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

C # - 464 453 karakter

Setelah beberapa malam dalam hal ini saya tidak bisa mendekati entri lainnya (tidak mengejutkan bagi C #). Saya kira masih ada ruang untuk perbaikan. Tidak ada trik khusus yang pintar.

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

Berkomentar:

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
sumber
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])
Pasang kembali Monica
sumber