Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103679037
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-04-18 23:09:38

bash版的打字练习
还有一些小问题,欢迎debug
用法: ./scriptname filename
如果不带参数也可^_^
Ctrl+x退出  空格 暂停\继续
2005.12.15 修改trap命令,避免Ctrl+c中断时产生僵尸进程

#!/bin/bash
file=$1
if ! [ -f "${file:=$0}" ]
then
  echo "Usage: $(basename $0) filename"
  exit 1
fi
org_tty=$(stty -g);IFS=""
fifo=$$.pipe
mkfifo $fifo && exec 4<>$fifo && rm $fifo || exit 1
cols=$(tput cols);lines=$(tput lines)
cls=$(tput clear)
bold=$(tput smso);normal=$(tput rmso)
for (( i = 0 ; i < $cols ; i++ ))
do
  base=${base}^
  base0=${base0}-
  base1=${base1}o
done
base1="Game O${base1:10}ver!"
next_index=1
tput civis
live=1
{ tr -cs '[:alnum:]' '[\n*]' <$file
  echo '~'
  for (( i = 1 ; i < $lines ; i++ ))
  do echo
  done } | while (( live )) && read word
do
  if [ "$word" = '~' ]
  then
    eof=1; word=""
  fi
  range=$(( cols - ${#word} + 1 ))
  if (( range > 0 )) && (( next_index > 0 ))
  then
    x[next_index]=$(( RANDOM % range ))
    y[next_index]=0
    s[next_index]=$word
  fi
  echo -n "$cls"
  echo -n "${bold}TT v1.1 S:$score T:$(( hit + miss )) H:$hit M:$miss${normal}"
  next_index=0; safe=1
  for (( i = 1 ; i  do
    if [ "${s[i]}" ]
    then
      (( y[i]++ ))
      if (( lock[i] > 0 ))
      then
        (( lock[i] -= 2 ))
        if (( lock[i] > 0 ))
        then
          safe=0
          tput cup "${y[i]}" "${x[i]}"
          echo -n "$bold${s[i]}$normal"
          tput cup $(( y[i] + lock[i] )) "${x[i]}"
          echo -n "${bold}^$normal"
        else
          (( hit++ ))
          (( score += ${#s[i]} ))
          s[i]="";next_index=$i
        fi
      else
      if (( y[i] >= lines - 1 ))
      then
        (( miss++ ))
        base=${base::${x[i]}}${base0::${#s[i]}}${base:$(( x[i] + ${#s[i]} ))}
        if [ "$base" = "$base0" ]
        then
          live=0
          base=$base1
        fi
        s[i]="";next_index=$i
      else
        safe=0
        tput cup "${y[i]}" "${x[i]}"
        echo -n "${s[i]}"
      fi
      fi
    else
      next_index=$i
    fi
  done
  if (( live )) && (( eof )) && (( safe ))
  then
    tput cup 1 0
    echo -n 'You Win!'
  fi
  if (( aim > 0 ))
  then
    tput cup "${y[aim]}" "${x[aim]}"
    echo "$bold$match$normal"
  fi
  tput cup $(( lines-1 )) 0
  echo -n $base
  while read -srn1 c
  do
    case "$c" in
    $'\377' ) (( ! pause )) && break;;
    $'\030' ) exit;;
    " " ) pause=$(( ! pause ));;
    [[:alnum:]] )
      if (( aim ))
      then
        match=$match$c
        len=$(expr ${s[aim]} : $match)
        if (( len > 0))
        then
          (( type++ ))
          tput cup ${y[aim]} $(( x[aim] + len -1 ))
          echo -n "$bold$c$normal"
          if (( len == ${#s[aim]} ))
          then
            lock[aim]=$(( lines - y[aim] ))
            tput cup ${y[aim]} ${x[aim]}
            echo -n "$bold${s[aim]}$normal"
            aim=0
          fi
        else
          tput cup ${y[aim]} ${x[aim]}
          echo -n "${s[aim]}"
          aim=0
          for (( i = 1 ; i          do
            if (( lock[i] <=0 )) && [ "${s[i]}" ]
            then
              len=$(expr ${s[i]} : $match)
              if (( len > 0 ))
              then
                aim=$i;
                tput cup ${y[aim]} ${x[aim]}
                echo -n "$bold${s[aim]}$normal"
                if (( len == ${#s[aim]} ))
                then
                  lock[aim]=$(( lines - y[aim] ))
                  aim=0
                fi
              fi
            fi
          done
          if (( aim > 0))
          then
            (( type++ ))
            tput cup "${y[aim]}" "${x[aim]}"
            echo "$bold$match$normal"            
          else
            (( typo++ ))
          fi
        fi
      else
        for (( i = 1 ; i        do
          if (( lock[i] <= 0 )) && [ "${s[i]:0:1}" = $c ]
          then
            if (( ${#s[i]} == 1 ))
            then
              lock[i]=$(( lines - y[aim] ))
            else
              aim=$i
              match=$c
            fi
            (( type++ ))
            tput cup ${y[i]} ${x[i]}
            echo -n "$bold$c$normal"         
            break
          fi
        done
        (( aim <= 0 )) && (( typo++ ))
      fi
      ;;
    * ) (( typo++ )) ;;
    esac
  done <&4
done &
while sleep 1;do echo -ne "\377";done >&4 &
timer_pid=$!
trap 'kill $timer_pid &>\dev\null;echo -n $'\030' >&4;wait;stty "$org_tty";tput reset;exit' 0 1 2 3 15
while read -srn1 key && [ "$key" != $'\030' ]
do
  echo -n "$key" >&4
done
echo -n "$key" >&4

阅读(337) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~