2016年8月31日水曜日

Ruby Warrior をやってみる(Level9)

はい、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.

0 件のコメント:

コメントを投稿