模拟两个生物之间的战斗


16

欢迎,勇敢的代码高尔夫球手!今天,您将站在妖精和精灵之间的激烈战斗中!

    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!

挑战

您的挑战是像上面那样模拟一场战斗。您将以以下形式接收输入:

creatureName health strength defense accuracy agility

例如,小妖精和小精灵之间的战斗将是:

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

第一和第二生物将交替攻击。

  • 打印“ creatureName攻击otherCreatureName!”
  • 检查生物是否躲避。如果(其敏捷度乘rand()除以2)大于(攻击者的准确度乘以rand()),则该生物将躲闪攻击。
    • 如果该生物躲避了,则显示“ creatureName闪避!”。
    • 否则,通过减去(攻击者的力量乘以rand())和(防御者的防御乘以rand()除以2)来计算造成的损害。最小伤害为1。打印“ creatureName击中otherCreatureName造成(x)伤害!”。然后打印“ creatureName还剩(x)健康”。除非生物的生命值等于或小于0,在这种情况下...
      • 如果该生物的生命值等于或小于0,则打印“ creatureName已被杀死!”。并结束程序。

规则

  • 最短的代码获胜。
  • 不要从字面上打印“ creatureName”,而应用生物的名称替换它。不要打印“(x)损坏”或“(x)健康;” 用实际金额替换它们。(我必须指出这一点,因为有些人在改变规则方面很有创造力。

2
为什么通过将敏捷度和防御力减半来使规格复杂化?
彼得·泰勒

@Peter因为否则战斗花费了太长时间。
门把手

2
我的观点是:为什么不将输入更改为goblin 50 40 18 3 2 elf 50 35 15 4 5
彼得·泰勒

@Peter Meh,这似乎太奇怪了-为什么防守会这么低?无论如何,这是一个难题。没有理由不:P
门把手

我认为尚不清楚“ creatureName是否还剩下(x)个健康状态”。应该在最后一轮(被杀死的生物)上打印,并且在(x)应该始终为0或可以为负数的情况下(我认为不应)。
13年

Answers:


4

APL(249 244 242)

这次是程序样式,因此(至少在Dyalog中)必须将其粘贴到编辑器窗口中。我给它起G了名字(第一行是名称,我包括了它,因为它是在编辑器窗口中显示的方式,因此可能应该算在内)。

G
⎕ML←3
DA←{(⊂↑⍵),⍎¨1↓⍵}¨↓26⍴A⊂⍨''≠A←⍞
→5
⎕←(↑D)'闪避!'
AD←DA
⎕←(↑A)'attacks','!',⍨↑D
→4 /⍨> /?A [6],D [5]
⎕←A [1],'hits',D [1],'for','damage!',⍨D[2]-←1⌈-/?A [3],⌈D[4]÷2
→12 /⍨D[2]≤0
⎕←D [1],“有”,D [2],“剩下健康!”
→5
⎕←D [1],'被杀了!'

(编辑:使用数字GOTO代替行标签。结果(至少在Dyalog中)所有定义标签的行都X:设置X为行号,因此也可以直接使用这些数字。)


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(或perl -nE '<code>')运行。对于每个meta-n开关算作一个额外的字符。此代码中没有花哨的高尔夫技巧,除非可以将$=用作损坏变量来保存int

编辑:希望损害计算现在是正确的。


6

CoffeeScript的454 432

传递字符串以b获取结果。我认为拥有图形动画输出会更好玩,因此我将一个演示放在一起。只需更改输入框即可更改统计信息和名称。来自jpg.to的图片,这是非官方的google-images API。

超级动作演示

战斗模拟器在行动

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

推荐输入(建议您自己输入):

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

哇,太好了!:DI如果我可以接受两个答案,我会接受这个答案,但是我在规则中说,最短的答案将被接受,我只能接受一个答案:(所以+1。voldemort 9999哈哈:D
Doorknob

@Doorknob,作为额外的奖励,您可以给它加上数字10e42,但您的浏览器可能会冻结...
Brigand 2013年

6

红宝石,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}

我的第一个高尔夫入门代码;该方法定义如何解析超出了我:)

从命令行参数(例如ruby battle.rb goblin 50 40 35 3 2 elf 50 35 30 4 5)读取输入是否可以?

爱迪生


是的,没关系。
门把手

5

JavaScript; 347 341 333

和往常一样,我将从自己的解决方案开始:

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}

编辑:显然console.log,在某些浏览器上,分配给变量会中断,因此这里是带有函数声明的相同代码:

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}

我当时想将其更改为alert,但这将是邪恶的:P


Uncaught TypeError: Illegal invocationa=console.log。您是否不必将console对象绑定为上下文,例如a=console.log.bind(console)
C5H8NNaO4

@ C5H嗯,很奇怪。这个对我有用。
门把手

刚刚在Firefox,Safari和Chrome中对其进行了检查,在Firefox中它可以工作=)Chrome给了我上面的内容,而Safari出现TypeError
C5H8NNaO4

@ C5H :(也许我可以用代替它alert,但是那会很烦人:P
Doorknob

:P是的,这确实的确令人讨厌,但是至少它将保存“ 6”个字符并避免TypeError =)但我猜它还可以,至少它可以在Firefox上运行=)
C5H8NNaO4 2013年

4

的Python:393

我压得更紧一点,如果我有3个,我可能可以print = p再缩短一些,但是我认为这还剩很多。

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"

我认为人们会跳过,如果您的病情良好,则无需检查目标是否低于健康状况。


我检查了运行状况两次,在循环头中结束了战斗,并在循环中打印了“已被杀死”或“命中...”,因为双重运行状况检查比一个额外的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.")))

样本输出:

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!   

编辑笔记:+1个字符,我错过了“!” 在“闪避”之后,
哦,我忘了在“采样输出”之后实际放一个输出
,如@tbodt所示,将标头更改为JavaScript


您为什么不将其称为JavaScript以避免混淆人们呢?
tbodt

@tbodt我没想到它会让人们感到困惑=)改成了Javascript
C5H8NNaO4

3

R:387个字符

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}

或完全开发,带有缩进和注释,以使情况更清晰:

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个字符

经过两天的晚上,我似乎无法与其他条目接近(对于C#来说并不奇怪)。我怀疑还有改进的余地。没有特别聪明的把戏。

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

评论:

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])
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.