O programa pede por um monstro. Se você digitar @Dragao@, então a variável da @classe_monstro@
irá conter a string @"Dragao"@. Dentro do @eval@ algumas strings serão adicionadas juntas
para formar a string @"monstro = Dragao.new"@. E quando o @eval@ executa essa string, a
variável @monstro@ contém um objeto @Dragao@. Pronto pra batalha.
Isso é maravilhoso! Agora podemos deixar que o jogador escolha um monstro! Claro, estamos
confiando no jogador para que ele forneça uma classe real de monstro. Se eles digitarem
@BruxaBotanica@ e não existe a classe @BruxaBotanica@, eles terão uma exceção jogada na sua cara.
Então, em resumo, o @eval@ permite que você crie um código a medida que prossegue. O que
pode ser útil e pode ser perigoso ao mesmo tempo.
Os métodos @instance_eval@ e @class_eval usado na metaprogramação para a classe @Criatura@
são levemente diferente do normal @eval@. Esses dois métodos especiais passam o código assim
como o @eval@ faz, mas eles mergulham em classes e objetos e passam o código lá.
<pre>
# O método instance_eval executa o código como se ele fosse executado dentro
# do objeto do método de instância.
irb> drgn = Dragao.new
irb> drgn.instance_eval do
irb> @nome = "Tobias"
irb> end
irb> drgn.instance_variable_get( "@nome" )
=> "Tobias"
# O método class_eval executa o código se estiver dentro da definição de classe.
irb> Dragao.class_eval do
irb> def nome; @nome; end
irb> end
irb> drgn.nome
=> "Tobias"
</pre>
Como você pode ver acima, os métodos @instance_eval@ e @class_eval@ também podem pegar um bloco
de código ao invés de uma string. O que é exatamente como as coisas foram feitas no Labirinto de Dwemthy.
h3. Bastante instrução depreciante e Ardilosa Justaposição -- Onde está o Labirinto de Dwemthy??
Vá com cuidado -- aqui está *a outra metade do LABIRINTO DE DWEMTHY!!*
*Adicione essas linhas a @dwemthy.rb@.*
<pre>
class Criatura
# Este método aplica um golpe recebido durante uma luta.
def golpear( dano )
aumento_poder = rand( carisma )
if aumento_poder % 9 == 7
@vida += aumento_poder / 4
puts "[Aumento de poderes mágicos de #{ self.class } #{ aumento_poder }!]"
end
@vida -= dano
puts "[#{ self.class } está morto.]" if @vida <= 0
end
# Este método obtém uma rodada em uma luta.
def lutar( inimigo, arma )
if vida <= 0
puts "[#{ self.class } está muito morto para lutar!]"
return
end
# Ataca o opononte
seu_golpe = rand( forca + arma )
puts "[Você golpeia com #{ seu_golpe } pontos de dano!]"
inimigo.golpear( seu_golpe )
# Retaliação
p inimigo
if inimigo.vida > 0
inimigo_golpe = rand( inimigo.forca + inimigo.arma )
puts "[Seu inimigo golpeia com #{ inimigo_golpe } pontos de dano!]"
self.golpear( inimigo_golpe )
end
end
end
class LabirintoDwemthy < Array
alias _inspect inspect
def inspect; "#<#{ self.class }#{ _inspect }>"; end
def method_missing( meth, *args )
resposta = first.send( meth, *args )
if first.vida <= 0
shift
if empty?
puts "[Uauu. Você dizimou o Labirinto de Dwemthy!]"
else
puts "[Prepare-se. #{ first.class } surgiu.]"
end
end
resposta || 0
end
end
</pre>
Esse código adiciona dois métodos a @Criatura@. O método @golpear@ que reage ao golpe de outra
@Criatura@. E o método @lutar@ que permite que você coloque os seus próprios golpes contra aquela @Criatura@.
Quando a sua @Criatura@ leva um golpe, um pouco da defesa contribui e o seu valor @carisma@ é usado para gerar um aumento de
poder. Não me peça para explicar os segredos por trás deste fenômeno. Um número aleatório é escolhido, uma matemática
simples é feita e se você tiver sorte, você consegue alguns pontos vitais. @@vida += aumento_poder / 4@.
Então o golpe do inimigo está dado. @@vida -= dano@. É assim que o método da @Criatura#golpear@ trabalha.
O método @lutar@ checa se a sua @Criatura@ está viva. Em seguida, um golpe aleatório
é dado no seu oponente. Se o seu oponente sobreviver a este golpe, ele ganha uma
chance de atacar de volta. Estas são as atividades do método @Criatura#lutar@.
Irei explicar o @LabirintoDwemthy@ em um segundo. Realmente explicarei. Estou me divertindo fazendo isso.
Por hora, vamos nos concentrar em golpear e lutar.
h3. Apresentando: Você.
Você talvez tenha trabalhado com derivações neste coelho. Mas o oficial
Paradigma de Dwemthy explicitamente denota o código -– e os caracteres todos juntos -–
inscritos abaixo. *Salve isto como @rabbit.rb@.*
<pre>
class Coelho < Criatura
caracteristicas :bombas
vida 10
forca 2
carisma 44
arma 4
bombas 3
# bumeranguinho
def ^( inimigo )
lutar( inimigo, 13 )
end
# a espada do herói é ilimitada!!
def /( inimigo )
lutar( inimigo, rand( 4 + ( ( inimigo.vida % 10 ) ** 2 ) ) )
end
# alface irá formar a sua força e extras substâncias indigestas
# voarão na cara de seu oponente!!
def %( inimigo )
alface = rand( carisma )
puts "[Saudável alface lhe dá #{ alface } pontos de vida!!]"
@vida += alface
lutar( inimigo, 0 )
end
# bombas, mas você possui somente três!!
def *( inimigo )
if @bombas.zero?
puts "[HUMM!! Você está sem bombas!!]"
return
end
@bombas -= 1
lutar( inimigo, 86 )
end
end
</pre>