LoginSignup
16
15

More than 5 years have passed since last update.

shellスクリプトでタイピングゲーム書いてみた

Last updated at Posted at 2014-08-13

端末から1文字ずつ読み込むにはreadではなくsttyコマンドを使います。
これとddコマンドを組み合わせています。

また、tputコマンドでカーソルを移動させています。

#!/bin/sh
#
# Reference Web sites:
#   http://d.hatena.ne.jp/anmino/20091029/1256806944
#   http://www.geocities.jp/abandonment_cat/cygwin/bshell/read.html
#   http://www.ibm.com/developerworks/jp/aix/library/au-learningtput/
#

declare -i x_position=`expr \`tput lines\` / 3`
declare -i y_position=`expr \`tput  cols\` / 3`

function string_generator() {

    string[1]="Behold, Laputa's thunder."
    string[2]="Stay hungry, stay foolish!"
    string[3]="Innovation distinguishes between a leader and a follower"
    string[4]="Your time is limited, so don't waste it living someone else's life."
    string[5]="Life is like riding a bicycle. To keep your balance you must keep moving."
    string[6]="Everything should be made as simple as possible, but not simpler."
    string[7]="We never surrender"
    string[8]="Life is not fair; get used to it."
    string[9]="You can always become better."
    string[10]="Don't find fault, find a remedy"

    echo ${string[$(((RANDOM%10) + 1))]}

}

function set_timer() {
    if   [ `uname` == "Darwin" ] ; then
        echo `printf '%.3f' \`date '+%s'\``
    elif [ `uname` == "Linux" ] ; then
        echo `printf '%.3f' \`date '+%s.%N'\``
    fi
}

##############
###  main  ###
##############

###  set invisible cursor  ###
tput civis

###  set terminal in raw mode  ###
stty raw -echo

###  # of characters you type  ###
characters=0

###  # of typing  ###
typing=0

###  start timer  ###
start=`set_timer`

for itry in {1..10}; do

    ###  clear display  ###
    clear

    ###  set typing word  ###
    string="`string_generator`"

    ###  increase total # of characters  ###
    characters=`expr ${characters} + ${#string}`

    ###  print information  ###
    tput cup ${x_position} ${y_position}
    echo "Type following sentence (type '|' to quit)" 

    ###  stop if # of characters of ${string} is zero  ###
    while [ ${#string} -gt 0 ] ; do

        ###  set length of the string  ###
        declare -i string_length=${#string}

        ###  print the remaining string  ###
        tput cup `expr ${x_position} + 5` `expr ${y_position} + ${string_length}` ; printf " "
        tput cup `expr ${x_position} + 5` ${y_position}
        echo "${string}"

        flag=0

        while [ "${flag}" == 0 ] ; do

            ###  increase total # of typing  ###
            let typing=${typing}+1

            ###  real time input => ${char}  ###
            tput cup `expr ${x_position} + 5` ${y_position}
            tput cnorm
            char=`dd bs=1 count=1 2>/dev/null`
            tput civis

            ###  if ${char} matches the first character of ${string}...  ###
            if [ "${char}" == "${string:0:1}" ] ; then
              flag=1
              break 1
            fi

            ###  "|" is defined as an escape key  ###
            if [ "${char}" == "|" ] ; then
              clear
              stty -raw echo
              tput cnorm
              exit
            fi

            ###  beep for wrong typing  ###
            echo '\a'

        done

        ###  if the first character of ${string} is blank...  ###
        if [ "${string:0:1}" == " " ] ; then
            string=`echo ${string} | sed -e 's|^\s||'`
        ###  cut the first character of ${string}...  ###
        else
            string=`echo ${string} | sed -e 's|^.||'`
        fi

    done

done

###  stop timer (in mill-seconds)  ###
stop=`set_timer`

###  unset terminal in raw mode  ###
stty -raw echo

###  set visible cursor  ###
tput cnorm

###  print the result  ###
clear
tput cup ${x_position} ${y_position}
echo "     --- Your Score ---"

time=`echo "scale=3;${stop}-${start}" | bc`

tput cup `expr ${x_position} + 2` ${y_position}
if   [ `uname` == "Darwin" ] ; then
  echo "total time        : "${time} "[sec]"
elif [ `uname` == "Linux" ] ; then
  echo "total time        : "${time} "[msec]"
fi

tput cup `expr ${x_position} + 4` ${y_position}
echo "total characaters : "${characters} "[characters]"

tput cup `expr ${x_position} + 6` ${y_position}
echo "# of typing       : "${typing} "[typing]"

tput cup `expr ${x_position} + 8` ${y_position}
echo "accuracy          : "`echo "scale=3;${characters}/${typing}*100" |bc` "[%]"

tput cup `expr ${x_position} + 10` ${y_position}
echo "typing speed      : "`echo "scale=3;${time}/${characters}" | bc` "[sec/character]"

tput cup `expr ${x_position} + 12` ${y_position}
echo "hit return key"
read *

clear

gistにもアップしてあります

16
15
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
16
15