はい、Ruby Warrior の Level9 です。
説明を意訳する
毎度の事ながら、説明文を意訳します。
Time to hone your skills and apply all of the abilities that you have
learned. Watch your back.
これまで学んだ全てのスキルを使って頑張って。
後ろの攻撃に注意。
こんな感じですかね。
先に書いてしまいますが、この Level9 で一旦のクリアになるようです。
なので、こういう文面になっているようです。
前レベルのコードをそのまま実行
これまで通り、前レベルクリアのコードをそのまま実行してみます。。。
見事にフルボッコにあって敵一人倒さずに終了してしまいました。さすが最終レベル。
さて、どうする?
開始直後に前後 3 マスに敵が配置されています。
そして、開始時点で戦士は右に向いています。
右の緑の敵は、目の前に行かないと攻撃してきませんが、後ろの弓持ちは、最初の位置からでも攻撃してきます。
ここの判定が難しいです。
攻撃された方向がメソッド等で取得できるのであれば良いのですが、ただダメージを貰ったという内容だけではどの方向に向けば良いか判定する方法が分かりませんでした。
なので、ここは説明文にあった忠告通り、最初は後ろを向いてそこからゲームをスタートする様にしました。
最初の向きを変える部分は、クラス変数を用意して最初の一度だけ方向を転換する実装としました。
ここの部分がちょっとかっこ悪いような気がしますが、勝てば官軍ということで。。。
さあ!反撃だ!?
初期の方向転換ができたので、早速攻撃を開始していきます。
弓持ちについては、開始位置からこちらも弓で攻撃すれば倒すことが出来ます。
しかし、その後前回のコードのままにすると、左に進み、捕虜を一人助けて、そのまま階段へすすみクリアしてしまいます。。。
どうやら、階段へ進みさえすればこのゲームはクリアとなるので、いいっちゃ良いんですが、右にも捕虜がいるので、全員助けてクリアしたい物です。
どうすれば良いか考えた所、汎用性は無い気がしますが、目の前の敵を倒した後に再度周り 3 マスを検索して敵がいれば方向を転換するようにしました。
これで、最初の位置で弓持ちを倒したら後ろを向いて緑の敵の方向を総なめし、壁にあたった所で向きを替え、最終的には階段へ向かうようになりました。
これがコードだ
class Player def initialize @health = 20 @first_pivot = false end def play_turn(warrior) @warrior = warrior unless @first_pivot @first_pivot = true return warrior.pivot! end return warrior.pivot! if feel_wall? return warrior.rescue! if feel_captive? three_space_captive? if decrease_health? if pinch_health? warrior.walk!(:backward) else if check_enemy? warrior_attack! elsif three_space_enemy? warrior_pivot? ? warrior.pivot! : warrior_arrow_attack! else warrior_walk! end end else if max_health? if three_space_captive? warrior_walk! elsif three_space_enemy? warrior_pivot? ? warrior.pivot! : warrior_arrow_attack! else warrior_walk! end else warrior.rest! end end @health = warrior.health end def three_space_captive? spaces = @warrior.look spaces.each do |space| return true if space.captive? end false end def three_space_enemy? spaces = @warrior.look spaces.each do |space| return true if space.enemy? end spaces = @warrior.look(:backward) spaces.each do |space| return true if space.enemy? end false end def warrior_pivot? spaces = @warrior.look spaces.each do |space| return false if space.enemy? end spaces = @warrior.look(:backward) spaces.each do |space| return true if space.enemy? end false end def decrease_health? @health > @warrior.health end def pinch_pinch_health? @warrior.health <= 5 end def pinch_health? @warrior.health <= 5 end def max_health? @warrior.health == 20 end def feel_captive? @warrior.feel.captive? end def feel_wall? @warrior.feel.wall? end def check_enemy? @warrior.feel.enemy? || @warrior.feel(:backward).enemy? end def warrior_walk! @warrior.walk! end def warrior_attack! @warrior.attack! end def warrior_arrow_attack! @warrior.shoot! end end
まとめ
前にも書いたとおり、もっと汎用性をもたせれるのかもしれませんが、その都度の実装でなんとかクリアすることができました。
一旦更新を途絶えさせてからの再開でしたので、モチベーションが若干下がっていたのですが、一旦の区切りを付けることができ、良かったかと思っています。
あらたなレベルに進むかは決めていませんが、また余裕ができたらやってみたいと思います。それでは。
Written with StackEdit.