LoginSignup
0
0

More than 3 years have passed since last update.

while文における繰り返し処理内での変数の加算について

Posted at

Rubyプログラムを書いていて詰まってしまいましたので質問をこちらに投稿させていただきます。

現在、ネット上でrubyのプログラムでの事例としてよくでてくるドラゴンクエストのプログラムを作ってみようと思い作成中です。

実装したい仕様としては以下になります。

想定仕様

  • スライム(敵)が表れてスライムのhp(ヒットポイント)がなくなるまで攻撃する
  • スライムのhp(ヒットポイント)は6とする
  • 攻撃はターン性になっており、先行は常に自分
  • 自分(戦士)のhp(ヒットポイント)は10とする
  • スライム(敵)の攻撃によりダメージは常に1とする
  • 自分は攻撃(なぐる)と回復呪文(ホイミ)を毎ターン選択可能
  • 自分の攻撃は1.2.3の中からランダムでスライム(敵)のhpを削る
  • 回復呪文(ホイミ)ではhpは10まで回復する
  • ただし、回復呪文はたまに失敗する(呪文使用時点での自分のhpで条件付け)
  • 攻撃(なぐる)と回復呪文(ホイミ)以外を選択した場合は強制的にターン終了とし、スライムのターンにうつる

ざっとこんな感じです。

質問事項

while文のなかで繰り返し処理をしていく中で、自分(戦士)の攻撃の数字が積みあがっていくような処理が書けません。

具体的には、
【第1ターン】
 先行:戦士の攻撃。スライムに2のダメージ。
 高校:スライムの攻撃。戦士に1のダメージ。
【第2ターン】
 先行:戦士の攻撃。スライムに2のダメージ。
 高校:スライムの攻撃。戦士に1のダメージ。
【第3ターン】
 先行:戦士の攻撃。スライムに2のダメージ。
 高校:スライムの攻撃。戦士に1のダメージ。
 ※自分(戦士)の攻撃はたまたま3回連続で2が出たと仮定。

上記のような場合、2×3=6でスライムを倒せるはずです。
しかし数字が積みあがっていっていないようで、永遠に繰り返されます。

実際のコードが以下になります。

puts "スライムがあらわれた"

hp = 6
damage = 0
ownhp = 10
while damage < hp do
  puts ""
  puts "戦士のターン"
  puts "攻撃を選んでください。1:なぐる 2:ホイミ"
  attack = gets.to_i
  damage=[1,2,3].sample
    if attack == 1
      puts "戦士の攻撃。"
      puts "スライムに「#{damage}」のダメージ"
      damage += damage
    elsif attack == 2
      case ownhp
        when 10
        puts ""
        puts "戦士はホイミを唱えた。しかし戦士は元気いっぱい!何もおこらなかった。"
        when 1..4,6..8
        puts ""
        puts "戦士はホイミを唱えた。戦士は元気いっぱいになった。"
        else
        puts ""
        puts "呪文に失敗した。"
      end
    else
      puts ""
      puts "選択肢にないコマンドです。ターンを終了します。"
    end
  if damage < 6
  puts ""
  puts "スライムのターン" 
  puts "スライムの攻撃。戦士に「1」のダメージ" 
  ownhp -=1
  end
end

puts "戦士はスライムを倒した。経験値10を手に入れた。"

上記です。

実はスライムを倒す場合があります。それは自分(戦士)の攻撃で3が出た場合になります。

試しに、

①1か2が数回出て、合計6に達していてもも終わらない場合
②3が出て終わる場合

上記のそれぞれのirbでのコード記載します。

①2が数回でても終わらない場合

※便宜上、3が出ないように変形して実施おります

ec2-user:~/environment/ruby-book $ ruby lib/dorakue.rb
スライムがあらわれた

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
1
戦士の攻撃。
スライムに「2」のダメージ

スライムのターン
スライムの攻撃。戦士に「1」のダメージ

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
1
戦士の攻撃。
スライムに「1」のダメージ

スライムのターン
スライムの攻撃。戦士に「1」のダメージ

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
1
戦士の攻撃。
スライムに「1」のダメージ

スライムのターン
スライムの攻撃。戦士に「1」のダメージ

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
1
戦士の攻撃。
スライムに「1」のダメージ

スライムのターン
スライムの攻撃。戦士に「1」のダメージ

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
1
戦士の攻撃。
スライムに「1」のダメージ

スライムのターン
スライムの攻撃。戦士に「1」のダメージ

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
1
戦士の攻撃。
スライムに「2」のダメージ

スライムのターン
スライムの攻撃。戦士に「1」のダメージ

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
1
戦士の攻撃。
スライムに「2」のダメージ

スライムのターン
スライムの攻撃。戦士に「1」のダメージ

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
1
戦士の攻撃。
スライムに「2」のダメージ

スライムのターン
スライムの攻撃。戦士に「1」のダメージ

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
1
戦士の攻撃。
スライムに「1」のダメージ

スライムのターン
スライムの攻撃。戦士に「1」のダメージ

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
1
戦士の攻撃。
スライムに「2」のダメージ

スライムのターン
スライムの攻撃。戦士に「1」のダメージ

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
1
戦士の攻撃。
スライムに「2」のダメージ

スライムのターン
スライムの攻撃。戦士に「1」のダメージ

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
1
戦士の攻撃。
スライムに「2」のダメージ

スライムのターン
スライムの攻撃。戦士に「1」のダメージ

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
1
戦士の攻撃。
スライムに「1」のダメージ

スライムのターン
スライムの攻撃。戦士に「1」のダメージ

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
1
戦士の攻撃。
スライムに「2」のダメージ

スライムのターン
スライムの攻撃。戦士に「1」のダメージ

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
1
戦士の攻撃。
スライムに「2」のダメージ

スライムのターン
スライムの攻撃。戦士に「1」のダメージ

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
1
戦士の攻撃。
スライムに「1」のダメージ

スライムのターン
スライムの攻撃。戦士に「1」のダメージ

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
1
戦士の攻撃。
スライムに「2」のダメージ

スライムのターン
スライムの攻撃。戦士に「1」のダメージ

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
^CTraceback (most recent call last):
        2: from lib/dorakue.rb:10:in `<main>'
        1: from lib/dorakue.rb:10:in `gets'
lib/dorakue.rb:10:in `gets': Interrupt

強制的に終わらせました。

②3が出て終わる場合

ec2-user:~/environment/ruby-book $ ruby lib/dorakue.rb
スライムがあらわれた

戦士のターン
攻撃を選んでください。1:なぐる 2:ホイミ
1
戦士の攻撃。
スライムに「3」のダメージ
戦士はスライムを倒した。経験値10を手に入れた。

このような感じです。

考えられる要因

damage += damage

ダメージを積み重ねていくために書いたコードで上記の部分が間違えているのだと思いますが、どういう風に直せばよいのかわかりません。
3が出た場合は3+3=6で倒せているのだと思います。
つまり、繰り返し処理というよりはその周回の中だけで足されてしまっている形になっております。

ご教示いただければ嬉しいです。

どうぞよろしくお願いいたします。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0