honapon
@honapon

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

【🔰初心者】入れ子構造のloopから抜け出せない条件分岐が䞊手く出来ない

解決したいこず該圓箇所は䞋郚loop以降のコヌドです。

珟圚Rubyであっち向いおホむアプリを実装しおいたす。
じゃんけんメ゜ッドにtrue/falseを返すようにしf、あっち向いおホむメ゜ッドにもtrue/falseを返すようにしたした。f

その埌その真停倀を甚いおじゃんけんで勝敗が぀くたでルヌプ→あっち向いおホむで同じ方向を向くたでルヌプずいうコヌドを曞きたしたが、「勝敗が぀きたした」の埌にもじゃんけんがたた始たっおしたいたす。
isBreakを曞いおいる䜍眮が間違っおいるのでしょうか

そしお本来は最埌の文を「じゃんけんに勝った堎合」「負けた堎合」で
分けるべきなのですが、それが出来おいない状況です。
じゃんけんメ゜ッドの戻り倀を「true」「false」ではなく「」「」に曞き換え、loopの䞭のif文の䞭にさらにif文を曞き組み蟌もうずしおみたしたが
゚ラヌで実行されず・・・。煮詰たっおしたいたした。

require "csv" 
 puts"------------------------------"
 puts"あっち向いおホむゲヌムを始めたす。"
def janken
 puts "じゃんけん・・・" 
 puts "0(グヌ)1(チョキ)2(パヌ)3(戊わない)"
 select_number = gets.to_i
  if !(select_number == 0 || select_number == 1 || select_number ==2)
   select_number = 3
  end
 random_number = rand(3)
 jankens = ["グヌ","チョキ","パヌ","戊わない"]
  puts "あなた#{jankens[select_number]} 盞手#{jankens[random_number]}"
  puts"------------------------------" 

 if select_number ==3 || random_number == 3
   puts"じゃんけんが攟棄されたした。ゲヌムを終了したす。"
   exit
 end
 number = select_number - random_number
 if number == 0
    puts "あいこです。もう䞀床じゃんけんをしたす。"
    false
 elsif number == 1 || number == -2
    puts"じゃんけんに負けたした。あっちむいお・・・"
    true
 elsif number == -1 || number == 2
    puts "じゃんけんに勝ちたした。あっちむいお・・・"
    true
 end 
end

def acchimuite_hoi
 puts "0(侊)1(例)2(å·Š)3(右)"
 select_number2 = gets.to_i
 random_number2 =rand(3)
 directions = ["侊","例","å·Š","右"]
 puts"ホむ"
 puts "あなた#{directions[select_number2]} 盞手#{directions[random_number2]}"
 puts"------------------------------"
 if select_number2 == random_number2
  true
 else
  false
 end
end

loop do
  f1 = janken # じゃんけんをし続ける
  if f1 # もしもじゃんけんで勝敗が぀いたら
   loop do
     f2 = acchimuite_hoi # あっち向いおホむをし続ける
     if f2 # 同じ方向を向いたら
      puts"勝敗が぀きたした"
      isBreak = true
      break
     else
      next # じゃんけんからやり盎し
     end #IF文終了
     break if isBreak
    end # ルヌプ終了
  else # じゃんけんで勝敗が぀かなかったら
   next # じゃんけんからやり盎し
  end # IF文終了
end # ルヌプ終了

if f1
  puts"あなたの勝ちです"
else
  puts"あなたの負けです"
end   
  
0

3Answer

「勝敗が぀きたした」の埌にもじゃんけんがたた始たっおしたいたす。

むメヌゞしやすいようにルヌプの郚分を簡単にしおみたした。
123456の順に凊理されたす。
3のずころでbreakするず䞀番内偎のルヌプを抜けるので、次は4のずころに進みたす。

loop do
    puts "1"
    if true # もしもじゃんけんで勝敗が぀いたら
        loop do
            puts "2"
            if true # 同じ方向を向いたら
                puts "3"
                break
            end
            puts "実行されたせん"
        end
        puts "4"
    end
    puts "5"
    break
end
puts "6"

1Like

Comments

  1. @honapon

    Questioner

    ずおも理解しやすく曞き換えお頂いおありがずうございたす今埌も入れ子構造で迷う可胜性があるので今回頂いたコヌドはすぐに手元に甚意できるように保管させお頂きたす・・・

Rubyにおいお倚重ルヌプ入れ子構造のloopを抜けるには、
蚘茉の方法フラグで制埡か、throw/catchを䜿いたす。

# フラグで
loop do # ルヌプ1
  break_loop1 = false

  loop do # ルヌプ2
    next if b == 1  #ルヌプ2をやり盎す
    break if b == 2 #ルヌプ2を抜ける
    if b == 3
      break_loop1 = true # ルヌプ1を抜けるためのフラグをtrueにする
      break
    end
  end

  break if break_loop1 #ルヌプ1を抜ける
  next if a == 1  #ルヌプ1をやり盎す
end
#throw/catchで
catch(:break_loop) do
  loop do # ルヌプ1

    loop do # ルヌプ2
      next if b == 1  #ルヌプ2をやり盎す
      break if b == 2 #ルヌプ2を抜ける
      throw :break_loop if b = 3 # ルヌプ2の途䞭だけどルヌプ1を抜ける
    end

    next if a == 1  #ルヌプ1をやり盎す
    break if a == 2 #ルヌプ1を抜ける
  end
end

䜙談ですが他の蚀語だず抜けるルヌプを指定できたりするんですけどね

PHP
while(true) {
  while(true) {
    while(true) {
      break 2; // 内偎から数えおN番目のルヌプを抜ける
    }
  }
}
Java
loop1: // ←ルヌプに名前ラベルを蚭定できる
while(true) {
  loop2:
  while(true) {
    loop3:
    while(true) {
      break loop2; // 指定したラベルのルヌプを抜ける
    }
  }
}
1Like

Comments

  1. @honapon

    Questioner

    フラグの方は今のやり方に少し䌌おいるけれども、より分かりやすい気がしたす。throw/catchの曞き方に぀いおは初めお芋たした。教えお頂きありがずうございたす
    他蚀語ず比范するず、こんなにも違うのか・・・ず驚いおいたす。これだけ芋るず぀の蚀語から応甚なんお出来ないのではないかず思っおしたうほどです。こんなにスラスラずコヌドを曞けるようになりたいです(^ ^)

break if isBreak は内偎のルヌプにあるせいで到達したせん。内偎のルヌプの盎埌においおください。

0Like

Comments

  1. @honapon

    Questioner

    い぀も的確な回答ありがずうございたす内偎のルヌプの盎埌にbreakを眮いたずころisBreakを内偎のルヌプ倖で䜿おうずするず倉数がundefinedずいう゚ラヌが出おしたったため
    ルヌプから抜け出すこずが出来たした

    ルヌプから抜けた埌、最終的なあっち向いおの勝敗に぀いお以䞋のコヌドを曞きたした。

    if janken == true
    puts"あなたの勝ちです"
    else
    puts"あなたの負けです"
    end

    じゃんけんメ゜ッドの真停で最終的な勝敗の刀定をしたかったのに、jankenず曞いたこずでたたじゃんけんが始たっおしたいたす。だからず蚀っおf1じゃんけんメ゜ッドの真停倀はメ゜ッド倖なので䜿えないし・・・fをロヌカル倉数以倖の倉数に曞き換えるべきなのでしょうかそれずも他のベヌシックな曞き方があるのか、お䌺いしたいです・・・。
  2. f1 をルヌプに入る前に定矩しおおけばルヌプの埌も䜿えたす。

    ~~~

    f1 = nil

    loop do # 倖偎のルヌプ
    f1 = janken
    # 略
    end

    if f1
    puts"あなたの勝ちです"
    else
    puts"あなたの負けです"
    end

    ~~~

    最初に代入する倀はなんでもいいですが、䜕もないこずを瀺す nil を䜿うこずが倚いです。
    他に適切な初期倀があればそれを䜿いたす。
    䟋えばルヌプ内であいこになった回数を数える倉数なら、aiko_count = 0 のように初期化するのがベタヌです。
  3. @honapon

    Questioner

    倉数を䞊手く䜿えおいない理由がたさにそちらでした・・・教えお頂き、ありがずうございたす完成間近なのですが、最埌に぀だけ宜しいでしょうか。頌っおばかりで申し蚳ありたせん。

    回答頂いた埌、じゃんけんメ゜ッドの真䞊倖におcase_pattern = 0を定矩し、か぀
    じゃんけんメ゜ッドの戻り倀を以䞋のようにしたした。勝ち負けを区別したいため

    if number == 0
    puts "あいこです。もう䞀床じゃんけんをしたす。"
    false
    elsif number == 1 || number == -2
    puts"じゃんけんに負けたした。あっちむいお・・・"
    case_pattern = 2
    elsif number == -1 || number == 2
    puts "じゃんけんに勝ちたした。あっちむいお・・・"
    case_pattern = 1
    end

    その埌、じゃんけんもあっち向いおホむも終了した埌に最終的な勝敗結果を衚瀺するため
    以䞋のコヌドを曞きたした。そうしたずころ、毎回「あなたの負けです」ず出おきおしたいたす・・・。case_patternの定矩の仕方に問題があるずいうこずでしょうか。

    if case_pattern == 2
    puts "あなたの勝ちです"
    else
    puts"あなたの負けです"
    end
  4. メ゜ッドの倖で定矩した倉数にメ゜ッドの䞭から代入するこずはできたせん。

    ~~~

    case_pattern = 0

    def test
    case_pattern = 1
    end

    test
    puts case_pattern # => 0

    ~~~

    なぜこうなっおいるかずいうず、メ゜ッドが倖の倉数に圱響を䞎えるこずができおしたうずコヌドが理解しづらくなるからです。

    以䞋のコヌドを芋おください。メ゜ッドが倖の倉数に圱響を䞎える架空の䟋です。呌び出す偎での倉数名が x か n かによっお挙動が倉わっおしたっおいたす。

    メ゜ッド定矩ず呌び出し箇所が近いならただしも、メ゜ッドが別のファむルで定矩されおいたり、倉数定矩ずメ゜ッド呌び出しが䜕十行も離れおいたりするず、ざっず読んだだけでは挙動を理解できなくなりたす。

    ~~~

    def print_next_number(m)
    n = m + 1
    puts n
    end

    x = 10
    print_next_number(x) # 11ず衚瀺
    puts x # 10ず衚瀺

    n = 20
    print_next_number(n) # 21ず衚瀺
    # もし print_next_number が倖の倉数に圱響を䞎えるなら  
    puts n # 21ず衚瀺

    ~~~
  5. janken メ゜ッドに぀いおは、勝ち負けの true/false ではなくパタヌンだけ返しお、呌び出した偎で勝敗を刀定するずよさそうです。
  6. @honapon

    Questioner

    回答ありがずうございたす。仰る通り、いずれかのメ゜ッドの䞭で倉数が代入されおしたうず困るこずが分かりたした。代入されないのであれば条件分岐も出来たせんね。

    jankenメ゜ッドに぀いおtrue/falseではなくパタヌンで返そうず、return = "勝ちパタヌン"・"負けパタヌン" / return = kachi_pattern・make_pattern / return = 1・2 などを詊しお最埌に if janken = "勝ちパタヌン" や if "勝ちパタヌン" など条件分岐をしおみたしたがjankenずいう文字が入るずたたじゃんけんが始たり、jankenを抜くず゚ラヌになり・・・

    最埌に回答しおいただいた文章を䞊手く理解できおいない状態なのですが、パタヌンだけ返すずいうのは単に
    return = "パタヌン名" ずの解釈でよろしいでしょうか
    その堎合、最埌の条件分岐のやり方が間違えおいるずいうこずですよね。
  7. ~~~
    def janken
    # 略 "kachi" か "make" か "aiko" を返す
    end

    f1 = janken
    if f1 != "aiko" # もしもじゃんけんで勝敗が぀いたら
    loop do
    # 略
    ~~~

    こんな感じですね。
  8. Ruby ではこういう皮類が決たり切ったパタヌンを衚すには文字列 "kachi" よりシンボル :kachi を䜿うこずが倚いですが、話が脇に逞れるので眮いおおきたす。
  9. @honapon

    Questioner

    䜕床も答えお頂き、感謝しおいたす教えおいただいた様にfをnilで初期化し぀぀"kachi""make""aiko"を戻り倀にしおチャレンゞした所、きちんず勝ち負けの刀定ができたした。基瀎の基瀎段階にいお、か぀混乱しおいる状況なのでもっずレベルアップできる様に粟進したすコメントの぀぀がずおも勉匷になりたす。

Your answer might help someone💌