liteversion
liteversion

Reputation: 69

How can I make an animation within a shell script?

I've recently started coding and made this coin flip code. Now I want to make an animation for it but I have no clue how to make such an animation. Does anyone have any ideas how I start making this? What programs?

I haven't tried anything yet, but this is the code used for the coin flip.

printf "(H) heads or (T) tails"
read user_choice
if [ $user_choice != H ] && [ $user_choice != T ]; then
  echo invalid choice defaulting to heads
 $user_choice=H=1
 $user_choice=T=2
fi
#value of 1 is heads, 2 is Tails
computer_choice=$(($RANDOM% 2 + 1))
if [ $computer_choice == 1 ]; then
  echo computer chooses heads
elif [ $computer_choice == 2 ]; then
echo computer chooses tails
fi
if [ $computer_choice == 1 ] && [ $user_choice = H ]; then
  echo you win!
else
if [ $computer_choice == 2 ] && [ $user_choice = T ]; then
    echo you win!
  else
    echo you lose
  fi
fi

Upvotes: 3

Views: 6219

Answers (4)

liteversion
liteversion

Reputation: 69

the correct code:

printf "(H) heads or (T) tails"
read user_choice
if [ $user_choice != H ] && [ $user_choice != T ]; then
  echo invalid choice defaulting to heads
 $user_choice=H
 $user_choice=T
fi
#value of 1 is heads, 2 is Tails
# begin config
minsteps=6
maxsteps=10
sleepytime=0.125
# end config

frames=(
    '  |  '
    ' ( ) '
    '( S )'
 )

sides=(H T)

side=$(($RANDOM% 2 ))

for (( step = 0; step < maxsteps; step++ ))
do
   for (( frame = 0; frame < 3; frame++ ))
    do
        if (( frame == 2 ))
        then
            f=${frames[frame]/S/${sides[side]}}    # swap H or T for S (templat$
            (( side ^= 1 ))    # toggle H/T
        else
            f=${frames[frame]/S/${sides[side]}}
            (( side ^= 2 ))    # toggle H/T
        fi
        printf '\r%s' "$f"
        # if showing a side and some flips have taken place and a 50% chance
        if (( frame == 2 && step > minsteps && RANDOM > 16383 ))
        then
            break 2    # exit both loops, we're done
        fi
        sleep "$sleepytime"
    done
done

printf '\n'
if [ ${sides[side]} == T ] && [ $user_choice = H ]; then
  echo you win!
else
if [ ${sides[side]} == H ] && [ $user_choice = T ]; then
    echo you win!
  else
    echo you lose
  fi
fi

printf  "would you like to play again? (Y) or (N)"
read Y_N
if [ $Y_N == Y ]; then
exec bash coin.sh
else
echo ok good bye
fi

Upvotes: 1

Dennis Williamson
Dennis Williamson

Reputation: 360325

Based on Walter A's answer:

#!/bin/bash

# begin config
minsteps=12
maxsteps=20
sleepytime=0.2
# end config

frames=(
    '  |  '
    ' ( ) '
    '( S )'
 )

sides=(H T)

side=$(($RANDOM % 2))

read -r -p "(H) heads or (T) tails" user_choice

user_choice=${user_choice^^}    # upper case the input (not available in Bash 3.2)

if [[ $user_choice == H ]]
then
    user_choice=0
elif [[ $user_choice == T ]]
then
    user_choice=1
else
    printf '%s\n' "invalid choice, defaulting to heads"
    user_choice=0
fi

for (( step = 0; step < maxsteps; step++ ))
do
    for (( frame = 0; frame < 3; frame++ ))
    do
        if (( frame == 2 ))
        then
            f=${frames[frame]/S/${sides[side]}}    # swap H or T for S (template char)
            computer_choice=$side
            (( side ^= 1 ))    # toggle H/T
        else
            f=${frames[frame]}
        fi
        printf '\r%s' "$f"
        # if showing a side and some flips have taken place and a 50% chance
        if (( frame == 2 && step > minsteps && RANDOM > 16383 ))
        then
            break 2    # exit both loops, we're done
        fi
        sleep "$sleepytime"
    done
done

printf '\n'

if [[ $user_choice == $computer_choice ]]
then
  printf '%s\n' "you win!"
else
  printf '%s\n' "you lose"
fi

Upvotes: 0

Walter A
Walter A

Reputation: 20022

simple animation:

#!/bin/bash

for ((i=0;i<10;i++)); do
   printf "\r  |  "
   sleep 0.2
   printf "\r ( )  "
   sleep 0.2
   printf "\r( H )"
   sleep 0.2
   printf "\r ( )  "
   sleep 0.2
   printf "\r  |  "
   sleep 0.2
   printf "\r ( )  "
   sleep 0.2
   printf "\r( T ) "
   sleep 0.2
   printf "\r ( )  "
   sleep 0.2
done

EDIT:
When you want to remove the coin from the output when finished, add

printf "\r    \r"

after the loop.
When you want to randomly finish on T or H, add

   if (( $RANDOM % 2 )); then
      printf "\r( H )\n"
      computer_choice=1
   else
      printf "\r( T )\n"
      computer_choice=2
   fi

after the loop.

Upvotes: 1

Davide Spataro
Davide Spataro

Reputation: 7482

One way to do it is to have all frames of the animation in a separate text file (see here for an example). Then what you simply do is:

  • for each of the frames:
    • clear the screen and draw the current frame

See this for more details: https://github.com/hugomd/parrot.live

Upvotes: 3

Related Questions