はさみロックゲームのループが正しく続かないのはなぜですか?

はさみロックゲームのループが正しく続かないのはなぜですか?

私はbo3はさみロックゲームを作っています。これまで、私はネクタイを除くすべての条件で動作しました。同点が発生したら、Iから1を引くだけでゲームを「再作成できる」という意味です。しかし、うまくいかないようで、その理由を理解していません。

これは私のコードです。

#!/bin/bash

#rock beats scissors, scissors beats paper, paper beats rock, 
userwin=0
compwin=0

printf "Welcome to rock paper scissors. "

for i in {1..3}
do
    printf "Type 'r', 'p', or 's': "

    #get users selection
    read user

    #detect input and assign it to a num that will be used to check against computer.
    if [[ $user == [rR] || $user == "Rock" || $user == "rock" ]]
      then
        user="r"
    elif [[ $user == [sS] || $user == "scissors" || $user == "Scissors" ]]
      then
        user="s"
    elif [[ $user == [pP] || $user == "paper" || $user == "Paper" ]]
      then
        user="p"
    else
        printf "Not a valid submission, you entered: %s\n" "$user"
    fi

   #get random number between 1 and 9
   comp=$(shuf -i 1-9 -n 1)

   #detect what number it was and assign either r p s to it. 
   if ((1<=comp && comp<=3))
     then 
       comp="r"
       printf "Computer chooses rock\n"
   elif ((4<=comp && comp<=6))
     then
       comp="s"
       printf "Computer chooses scissors\n"
   elif ((6<=comp && comp<=9))
     then
       comp="p"
       printf "Computer chooses paper\n"
   else
       printf "not in range?"
   fi

   #find out who won
   if [[ $user == "$comp" ]]
     then
        i=$((i-1))
        printf "It's a tie, remake!\n"
   elif [[ $user == "r" && $comp == "p" ]]
     then
       printf "You lose!\n"
       compwin=$((compwin+1))
   elif [[ $user == "p" && $comp == "r" ]]
     then  
       printf "You win!\n"
       userwin=$((userwin+1))
   elif [[ $user == "s" && $comp == "r" ]]
     then  
       printf "You lose!\n"
       compwin=$((compwin+1))
   elif [[ $user == "r" && $comp == "s" ]]
     then  
       printf "You win!\n"
       userwin=$((userwin+1))
   elif [[ $user == "p" && $comp == "s" ]]
     then  
       printf "You lose!\n"
       compwin=$((compwin+1))
   elif [[ $user == "s" && $comp == "p" ]]
     then  
       printf "You win!\n"
   else
       printf "something is borked"
   fi

   if [[ $userwin == 2 ]]
     then
       printf "You win the bo3!\n"
       break
   elif [[ $compwin == 2 ]]
     then
       printf "You lose the bo3!\n"    
       break
   else
      reali=$((i+1))
      printf "\nGame %s start\n" "$reali"
   fi

done

失敗したゲームの例は次のとおりです。

noah: [~/myFiles/scripts] ./rps.sh
Welcome to rock paper scissors. Type 'r', 'p', or 's': r
Computer chooses rock
It's a tie, remake!

Game 1 start
Type 'r', 'p', or 's': r
Computer chooses paper
You lose!

Game 3 start
Type 'r', 'p', or 's': r
Computer chooses scissors
You win!

Game 4 start
noah: [~/myFiles/scripts]

何か私のIの整数がめちゃくちゃになったようですが、bash -xを使用してもなぜそうするのかわかりません。経験のある人はこれを確認できますか?

ベストアンサー1

forこのようなループ内では変数を変更できませんbash。ああ…できますが、繰り返しには影響しません。 Cでおなじみの計算ループではありません。

最小限の例:

#!/bin/bash
for i in {1..3}
do
    echo $i
    i=$((i-1))
    echo $i
done

明らかに、次のように印刷されます。

./b.sh 
1
0
2
1
3
2

Kusalanandaが提案したように、条件文を含む標準ループを使用することをお勧めします。

#!/bin/bash
i=0
while ((i++ < 3)); do
    echo $i
    # your code here
    #i=$((i-1))
    #echo $i
done

また、以下の以前の提案を維持しますが、上記の提案は間違いなく優れています。


実行ボリュームを変更するには、無限ループを使用して内部で独自の変数を処理することをお勧めします。次のようなことを行う必要があります(例:増分2、そうでなければ決して終了しません):

#!/bin/bash
i=1
while true; do
    if [[ $i > "3" ]]; then
        break
    fi
    echo $i
    i=$((i-1))
    echo $i

    i=$((i+2))
done

おすすめ記事