206 lines
3.2 KiB
Bash
Executable file
206 lines
3.2 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
clear() {
|
|
printf '\x1b\x5b\x48\x1b\x5b\x32\x4a'
|
|
}
|
|
|
|
red() {
|
|
if (( $# )); then
|
|
local red=$'\x1b\x5b\x33\x31\x6d'
|
|
local rst=$'\x1b\x28\x42\x1b\x5b\x6d'
|
|
printf %s%s%s "$red" "$1" "$rst"
|
|
fi
|
|
}
|
|
|
|
render() {
|
|
local pce=${pcs[$pos-1]}
|
|
|
|
if [[ $pce = " " ]]; then
|
|
pcs[$pos-1]=$(red "*")
|
|
else
|
|
pcs[$pos-1]=$(red "$pce")
|
|
fi
|
|
|
|
clear
|
|
printf "%s\n" "${brd[0]}"
|
|
printf "${brd[1]}\n" "${pcs[@]:0:3}"
|
|
printf "%s\n" "${brd[2]}"
|
|
printf "%s\n" "${brd[0]}"
|
|
printf "${brd[1]}\n" "${pcs[@]:3:3}"
|
|
printf "%s\n" "${brd[2]}"
|
|
printf "%s\n" "${brd[0]}"
|
|
printf "${brd[1]}\n" "${pcs[@]:6:3}"
|
|
printf "%s\n" "${brd[0]}"
|
|
|
|
pcs[$pos-1]=$pce
|
|
}
|
|
|
|
place() {
|
|
if (( $# )); then
|
|
local chr=$1 plc=$2 row win col
|
|
pcs[$plc]=$chr
|
|
|
|
for (( row = 0; row < 7; row += 3 )); do
|
|
if [[ ${pcs[*]:$row:3} = @(x x x|o o o) ]]; then
|
|
win=${pcs[$row]}
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [[ -z $win ]]; then
|
|
for col in {0..2}; do
|
|
if [[ ${pcs[$col]}${pcs[$col+3]}${pcs[$col+6]} = @(xxx|ooo) ]]; then
|
|
win=${pcs[$col]}
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if [[ -z $win ]]; then
|
|
if [[ ${pcs[0]}${pcs[4]}${pcs[8]} = @(xxx|ooo) ]]; then
|
|
win=${pcs[0]}
|
|
elif [[ ${pcs[2]}${pcs[4]}${pcs[6]} = @(xxx|ooo) ]]; then
|
|
win=${pcs[2]}
|
|
fi
|
|
fi
|
|
|
|
(( pld += 1 ))
|
|
|
|
if [[ -n $win ]]; then
|
|
case $win in
|
|
x)
|
|
res=1
|
|
;;
|
|
o)
|
|
res=2
|
|
esac
|
|
elif (( pld == 9 )); then
|
|
res=3
|
|
else
|
|
res=0
|
|
fi
|
|
|
|
return "$res"
|
|
fi
|
|
|
|
return 4
|
|
}
|
|
|
|
win=0 pld=0 pos=1
|
|
|
|
pcs=(
|
|
" " " " " "
|
|
" " " " " "
|
|
" " " " " "
|
|
)
|
|
|
|
brd=(
|
|
' | |'
|
|
' %s | %s | %s'
|
|
'___|___|___'
|
|
)
|
|
|
|
while ! (( win )); do
|
|
render
|
|
|
|
while true; do
|
|
read -rsn 1 key
|
|
dir=
|
|
|
|
case $key in
|
|
"")
|
|
if [[ ${pcs[$pos-1]} = " " ]]; then
|
|
break
|
|
fi
|
|
;;
|
|
$'\x1b')
|
|
read -rsn 2 arrow
|
|
|
|
case $arrow in
|
|
$'\x4f\x41'|$'\x5b\x41')
|
|
dir=up
|
|
;;
|
|
$'\x4f\x42'|$'\x5b\x42')
|
|
dir=down
|
|
;;
|
|
$'\x4f\x43'|$'\x5b\x43')
|
|
dir=right
|
|
;;
|
|
$'\x4f\x44'|$'\x5b\x44')
|
|
dir=left
|
|
;;
|
|
esac
|
|
;;
|
|
w|W)
|
|
dir=up
|
|
;;
|
|
s|S)
|
|
dir=down
|
|
;;
|
|
d|D)
|
|
dir=right
|
|
;;
|
|
a|A)
|
|
dir=left
|
|
;;
|
|
esac
|
|
|
|
if [[ -n $dir ]]; then
|
|
case $dir in
|
|
up)
|
|
if (( pos > 3 )); then
|
|
(( pos -= 3 ))
|
|
fi
|
|
;;
|
|
down)
|
|
if (( pos < 7 )); then
|
|
(( pos += 3 ))
|
|
fi
|
|
;;
|
|
right)
|
|
if (( pos % 3 )); then
|
|
(( pos += 1 ))
|
|
fi
|
|
;;
|
|
left)
|
|
if (( (pos % 3) != 1 )); then
|
|
(( pos -= 1 ))
|
|
fi
|
|
esac
|
|
fi
|
|
|
|
render
|
|
done
|
|
|
|
place x "$(( pos - 1 ))"
|
|
|
|
if ! (( res )); then
|
|
unu=( )
|
|
|
|
for (( cnt = 0; cnt < 9; ++cnt )); do
|
|
if [[ ${pcs[$cnt]} = " " ]]; then
|
|
unu+=( "$cnt" )
|
|
fi
|
|
done
|
|
|
|
ops=$(( RANDOM % ${#unu[@]} ))
|
|
place o "${unu[$ops]}"
|
|
fi
|
|
|
|
if (( $res )); then
|
|
render
|
|
|
|
case $res in
|
|
1)
|
|
printf 'x wins\n'
|
|
;;
|
|
2)
|
|
printf 'o wins\n'
|
|
;;
|
|
3)
|
|
printf 'tie game\n'
|
|
esac
|
|
|
|
exit
|
|
fi
|
|
done
|