Skip to content

Instantly share code, notes, and snippets.

@programus
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save programus/01194ca4ad0e2832e34e to your computer and use it in GitHub Desktop.
Save programus/01194ca4ad0e2832e34e to your computer and use it in GitHub Desktop.
guess number game in shell script
#!/bin/sh
# 猜数字游戏Shell版程序
function generateGoal()
{ # 生成被猜数字
# 准备一个包含0-9的池
local pool=($(seq 0 9))
for i in $(seq 0 3)
do
# 从池中随机抽取并删除一个数字
let pick=${RANDOM}%${#pool[@]}
num[$i]=${pool[$pick]}
pool=(${pool[@]:0:$pick} ${pool[@]:$(($pick+1))})
done
echo ${num[@]}
}
function split2array()
{ # 将连续的数字分割成空格分割的形式
local n=$*
echo $n | sed 's/./& /g'
}
function isValidGuess()
{ # 验证输入数字格式是否合理
# 取得不重复字符数量
local n=$(echo $*|tr ' ' '\n'|sort|uniq|wc -l)
if [[ $n -eq 4 ]] && [[ $# -eq 4 ]]
then
# 确认每一位是否为数字
for p in $*
do
case $p in
[^0-9])
# 不是数字,返回错误码1
return 1
esac
done
else
# 不重复字符数量不对,返回错误码2
return 2
fi
}
function readNumber()
{ #从标准输入取得数字并确认合法性
read -p 'You guess: ' input
local a=$(split2array $input)
isValidGuess $a && echo $a
}
function generateHint()
{ #生成线索
#从参数中取得猜数和答案
local guess=($(echo $*|cut -d ' ' -f 1-4))
local goal=($(echo $*|cut -d ' ' -f 5-8))
#初始化A、B的值
local a=0
local b=0
#比较猜数与答案
for (( i = 0; i < ${#guess[@]}; i++ ))
do
local g=${guess[$i]}
if [[ g -eq ${goal[$i]} ]]
then
#当同一位置的猜数与答案一致时,A加一
((a++))
elif echo ${goal[@]}|grep $g > /dev/null 2>&1
then
#当某一位猜数在答案中存在时,B加一
((b++))
fi
done
#输出线索,当已经完全猜对时,追加输出字母W作为标记
echo "${a}A${b}B $([[ $a -eq 4 ]] && echo "W")"
}
function printBanner()
{
echo "*****************************************************************************"
echo "* GUESS NUMBER *"
echo "*****************************************************************************"
}
function game()
{
local chance=8
local goal=$(generateGoal)
local loseMsg="You Lose. The number is $(echo $goal|tr -d ' ')"
#即便强制退出了,也要告诉玩家,他输了。
trap 'echo;echo $loseMsg;exit' INT
echo "Find the number if you can."
for remain in $(seq $chance -1 1)
do
case $remain in
1)
echo "This is the LAST chance.";;
*)
echo "There are $remain changes.";
esac
until guess=$(readNumber)
do
echo "Input format wrong."
echo "Please input a 4-digit number without same digit."
done
#将线索以数组形式存储
local result=($(generateHint $guess $goal))
echo "My hint: ${result[0]}"
echo "=============="
if [[ ${#result[@]} -gt 1 ]]
then
#当附带有胜利信息时,宣告胜利
echo "You Win!"
break
fi
done
if [[ ${#result[@]} -le 1 ]]
then
echo $loseMsg
fi
trap - INT
}
printBanner
until [[ $exit ]]
do
game
select sel in "Play again?" "Exit"
do
case $sel in
Exit)
exit=1
break;;
*)
break;;
esac
done
done
@limingjie
Copy link

!/bin/bash ?

@limingjie
Copy link

Not working...

$ ./guess.sh


  •                        GUESS NUMBER                                   *
    

    Find the number if you can.
    You Lose. The number is 1460
    1. Play again?
    2. Exit
      #?

@programus
Copy link
Author

fixed. worked on Mac but not linux. seq is different a little.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment