Программа очень простая, ии нет. Делал давно, в рамках ознакомления. С оболочкой больше не играю.
###
### file vars.inc
###
EC='\e[36m' # enable color
DC='\e[0m' # disable color
maxdb=4 # максимально допустимое количество дуплей (в игре на 4-х не может быть меньше 2)
maxeq=5 # максимально допустимое количество одинаковых (в игре на 4-х не может быть меньше 3)
dbfish=true # закрывший рыбу дуплем не считается.
dbzerox=true # один дупль пусто считается за 10
bazar=false # игра с базаром
vii=7 # раздается по семь камней
hundred=50 # игра ведется до 101 или до 51
xiii=13 # минимальная несгораемая сумма (забор)
domino=(00 01 02 03 04 05 06 11 12 13 14 15 16 22 23 24 25 26 33 34 35 36 44 45 46 55 56 66)
score=(0 0)
fence=(0 0)
eggs=0
gamer=('user' 'noob' 'fool' 'pro ') # имена игроков
mover='' # чей ход
super='' # ставщик (кто зашел первым)
state='' # состояние игры (NULL - игра, true - игрок закончил, false - рыба)
snake=() # массив камней на столе
played=() # поставленые камни игроков
###
### file msgs.inc
###
msg_mix="Мешаю..."
msg_ihave="У меня"
msg_yhave="У вас"
msg_bemix="Камни будут перемешаны."
msg_qbmix="Перемешать камни? (y/n)"
msg_maxdb=('0 дуплей' '1 дупль' '2 дупля' '3 дупля.' '4 дупля.' '5 дуплей.' '6 дуплей.' '7 дуплей.')
msg_maxeq=('голых.' 'азов.' 'двоек.' 'троек.' 'четверок.' 'пятерок.' 'шестерок.' 'голых.' 'аза.' 'двойки.' 'тройки.' 'четверки.' 'пятерки.' 'шестерки.')
msg_any_key="Нажмите любую клавишу для продолжения..."
msg_try_again="Попробуйте еще раз"
msg_skip="Проехал."
msg_finish="Закончил."
msg_fish="Рыба."
msg_dbfish="Рыба с отходом."
msg_onfence="на заборе."
msg_score="счёт"
msg_fenсe="забор"
msg_eggs="яйца"
msg_total_score="Общий счет:"
###
### file func.inc
###
f_mixer(){
echo "${msg_mix}"
echo '----------'
domino=(00 01 02 03 04 05 06 11 12 13 14 15 16 22 23 24 25 26 33 34 35 36 44 45 46 55 56 66)
for ((k=0; k<80; ++k)); do
for i in ${!domino[@]}; do
r=$((RANDOM % 28))
t=${domino[$i]}
domino[$i]=${domino[$r]}
domino[$r]=${t}
done
done
for ((i=0; i<${#gamer[@]}; ++i)); do # проверка на 5 дуплей
r=0
for ((k=i*vii; k<i*vii+vii; ++k)); do
[[ "${domino[$k]:0:1}" == "${domino[$k]:1:1}" ]] && ((r++))
done
[[ ${r} -gt ${maxdb} ]] && break
done
if [[ "${i}" -lt "${#gamer[@]}" ]]; then
echo "${gamer[$i]}: ${domino[@]:${i}*7:7}"
if [[ "${i}" -ne 0 ]]; then
echo "${msg_ihave} ${msg_maxdb[$r]} ${msg_bemix}"
read -rsn1 -p "${msg_any_key}"
echo -e '\n----------'
f_mixer
return
else
echo -n "${msg_yhave} ${msg_maxdb[$r]} ${msg_qbmix}"
while true; do
read -r -p ":"
case ${REPLY} in
[Yy])
echo '----------'
f_mixer
return
;;
[Nn])
echo '----------'
break
;;
*) echo -n "${msg_try_again}" ;;
esac
done
fi
fi
for ((i=0; i<${#gamer[@]}; ++i)); do # проверка на 6 одинаковых
for (( t=0; t<7; ++t )); do # азы, двойки, тройки итд
r=0
for (( k=i*vii; k<i*vii+vii; ++k)); do
[[ "${domino[k]:0:1}" == "${t}" ]] && ((++r))
if [[ "${domino[k]:0:1}" != "${domino[k]:1:1}" ]]; then
[[ "${domino[k]:1:1}" == "${t}" ]] && ((++r))
fi
done
[[ "${r}" -gt "${maxeq}" ]] && break 2
done
done
if [[ "${i}" -lt "${#gamer[@]}" ]]; then
[[ "${r}" -lt 5 ]] && (( t+=7 )) # локализация
echo "${gamer[i]}: ${domino[@]:i*7:7}"
[[ "${i}" -ne 0 ]] && echo -n "${msg_ihave} " || echo -n "${msg_yhave} "
echo "${r} ${msg_maxeq[t]} ${msg_bemix}"
read -rsn1 -p "${msg_any_key}"
echo -e '\n----------'
f_mixer
return
fi
}
f_0ut(){
echo -e "${gamer[$mover]}: ${snake[@]}"
}
f_round(){
local i
i=${domino[@]:$mover*7:7}
if [[ -z "${i}" ]]; then
echo "${gamer[$mover]}: ${msg_finish}"
state="true"
return
fi
if [[ "${snake[-1]:1:1}" == "${snake[0]:0:1}" ]]; then
for i in ${domino[@]}; do
[[ "${snake[-1]:1:1}" == "${i:0:1}" ]] && return
[[ "${snake[-1]:1:1}" == "${i:1:1}" ]] && return
done
state="false"
if ${dbfish}; then
if [[ "${snake[-1]:0:1}" == "${snake[-1]:1:1}" ]] || [[ "${snake[0]:0:1}" == "${snake[0]:1:1}" ]]; then
for (( i=1; i < ${#gamer[@]}; ++i )); do
if [[ "${played[mover-i]:(-1):1}" == "${snake[-1]:1:1}" ]]; then
(( mover -= i ))
[[ "${mover}" -lt 0 ]] && (( mover += ${#gamer[@]} )) # избавляемся от минуса
break
fi
done
echo "${msg_dbfish}"
return
fi
fi
echo "${msg_fish}"
return
fi
}
f_choice(){
for ((i = 7*mover; i < 7*mover+7; i++)); do
if [[ ${snake[-1]:1:1} == ${domino[$i]:0:1} ]]; then
snake+=( "${EC}${domino[$i]}${DC}" )
played[mover]+=" ${snake[0]:0:1}${domino[$i]}"
f_0ut
snake[-1]="${domino[$i]}"
domino[$i]=''
break
elif [[ ${snake[0]:0:1} == ${domino[$i]:0:1} ]]; then
domino[$i]="${domino[$i]:1:1}${domino[$i]:0:1}"
snake=( "${EC}${domino[$i]}${DC}" "${snake[@]}" )
played[mover]+=" ${snake[-1]:1:1}${domino[$i]}"
f_0ut
snake[0]="${domino[$i]}"
domino[$i]=''
break
elif [[ ${snake[-1]:1:1} == ${domino[$i]:1:1} ]]; then
domino[$i]="${domino[$i]:1:1}${domino[$i]:0:1}"
snake+=( "${EC}${domino[$i]}${DC}" )
played[mover]+=" ${snake[0]:0:1}${domino[$i]}"
f_0ut
snake[-1]="${domino[$i]}"
domino[$i]=''
break
elif [[ ${snake[0]:0:1} == ${domino[$i]:1:1} ]]; then
snake=( "${EC}${domino[$i]}${DC}" "${snake[@]}" )
played[mover]+=" ${snake[-1]:1:1}${domino[$i]}"
f_0ut
snake[0]="${domino[$i]}"
domino[$i]=''
break
fi
done
if [[ ${i} -eq ${mover}*7+7 ]]; then
echo "${gamer[$mover]}: ${msg_skip}"
played[mover]+=" ${snake[0]:0:1}${snake[-1]:1:1}-"
fi
}
###
### file domino.bash
###
#!/bin/bash
. vars.inc
. msgs.inc
. func.inc
echo -en "\ec" # очистка терминала
clear
gamer[0]=${USER}
while true; do
played=()
snake=()
state=''
f_mixer
(( score[0] + score[1] )) || mover=''
case ${mover} in #################################################### первый ход
'')
for i in ${!domino[@]}; do
if [[ ${domino[$i]} == 11 ]]; then
mover=$(( i / 7 ))
break
fi
done
;;
0)
echo -n ${domino[@]:${mover}*7:7}
while true; do
read -r -p ":"
case $REPLY in
[0-6][0-6])
for ((i=0; i<7; i++)); do
if [[ "${REPLY}" == "${domino[$i]}" ]] || [[ "${REPLY:1:1}${REPLY:0:1}" == "${domino[$i]}" ]]; then
domino[$i]="${REPLY}"
break 2
fi
done
;&
*) echo -n "${msg_try_again}" ;;
esac
done
echo '----------'
;;
[1-3]) i=$((RANDOM % 7 + 7 * mover)) ;;
esac
snake+=( "${EC}${domino[$i]}${DC}" )
played[mover]+=" ${domino[$i]}"
f_0ut
snake[-1]="${domino[i]}"
domino[$i]=''
super="${mover}"
while true; do #################################################### игра
(( ++mover ))
for (( ; mover < ${#gamer[@]}; ++mover )); do
f_choice
f_round
[[ "${state}" ]] && break 2
done
mover=0
echo '----------'
echo -n ${domino[@]:mover*vii:vii}
while true; do
read -r -p ':'
case $REPLY in
[0-6][0-6])
for ((i=0; i<vii; i++)); do
if [[ "${REPLY}" == "${domino[$i]}" ]] || [[ "${REPLY:1:1}${REPLY:0:1}" == "${domino[$i]}" ]]; then
if [[ ${snake[-1]:1:1} == ${REPLY:0:1} ]]; then
domino[$i]="${REPLY}"
snake+=( "${EC}${domino[$i]}${DC}" )
played[mover]+=" ${snake[0]:0:1}${domino[$i]}"
echo '----------'
f_0ut
snake[-1]="${domino[$i]}"
domino[$i]=''
break 2
elif [[ ${snake[0]:0:1} == ${REPLY:0:1} ]]; then
domino[$i]="${REPLY:1:1}${REPLY:0:1}"
snake=( "${EC}${domino[$i]}${DC}" "${snake[@]}" )
played[mover]+=" ${snake[-1]:1:1}${domino[$i]}"
echo '----------'
f_0ut
snake[0]="${domino[$i]}"
domino[$i]=''
break 2
elif [[ ${snake[-1]:1:1} == ${REPLY:1:1} ]]; then
domino[$i]="${REPLY:1:1}${REPLY:0:1}"
snake+=( "${EC}${domino[$i]}${DC}" )
played[mover]+=" ${snake[0]:0:1}${domino[$i]}"
echo '----------'
f_0ut
snake[-1]="${domino[$i]}"
domino[$i]=''
break 2
elif [[ ${snake[0]:0:1} == ${REPLY:1:1} ]]; then
domino[$i]="${REPLY}"
snake=( "${EC}${domino[$i]}${DC}" "${snake[@]}" )
played[mover]+=" ${snake[-1]:1:1}${domino[$i]}"
echo '----------'
f_0ut
snake[0]="${domino[$i]}"
domino[$i]=''
break 2
fi
fi
done
;;&
'')
for ((i=0; i<vii; ++i)); do
[[ "${snake[-1]:1:1}" == "${domino[$i]:0:1}" ]] && break
[[ "${snake[0]:0:1}" == "${domino[$i]:0:1}" ]] && break
[[ "${snake[-1]:1:1}" == "${domino[$i]:1:1}" ]] && break
[[ "${snake[0]:0:1}" == "${domino[$i]:1:1}" ]] && break
done
if [[ "${i}" -eq "${vii}" ]]; then
echo '----------'
echo "${gamer[$mover]}: ${msg_skip}"
played[mover]+=" ${snake[0]:0:1}${snake[-1]:1:1}-"
break
fi
;&
*) echo -n "${msg_try_again}" ;;
esac
done
f_round
[[ "${state}" ]] && break
done #################################################### считаем
played=(0 0 0 0) # сначала считаем всех
for ((i=0; i<4; i++)); do
for ((k=0; k<7; k++)); do
played[$i]=$(( ${domino[7*i+k]:0:1} + ${domino[7*i+k]:1:1} + played[i] ))
done
done
if ${dbzerox}; then
for ((i=0; i<4; i++)); do
[[ ${played[i]} -eq 0 ]] && played[$i]=10
done
fi
if ${state}; then # если игрок закончил обнуляем очки
played[mover-0]=0
played[mover-2]=0
else
echo "${gamer[mover]}:" ${domino[@]:7*(mover-0):7} # если рыба, выводим камни
fi
echo "${gamer[mover-2]}:" ${domino[@]:7*(mover-2):7} # выводим всех остальных
echo "${gamer[mover-1]}:" ${domino[@]:7*(mover-1):7}
echo "${gamer[mover-3]}:" ${domino[@]:7*(mover-3):7}
if (( (played[0] + played[2]) == (played[1] + played[3]) )); then
(( eggs+=(played[0] + played[2])*2 ))
continue
fi
(( i = (played[0] + played[2]) > (played[1] + played[3]) ? 0 : 1 )) # индекс пары, набравшей большее кол-во очков
echo -n "${gamer[i]} + ${gamer[i+2]} = " # вывод проигравшей пары
[[ ${score[i]} -ne 0 ]] && echo -n "${score[i]} + " # выводим, если есть, счет
[[ ${fence[i]} -ne 0 ]] && echo -n "${fence[i]} + " # вывод забора, если есть
echo -n "${played[i]} + ${played[i+2]} " # набранные очки
if [[ ${score[i]} -eq 0 ]] && (( (played[i] + played[i+2]) < xiii )); then # если нет записи и набрали меньше xiii
(( fence[i] += played[i] + played[i+2] )) # считаем результат на забор
echo "= ${fence[i]} ${msg_onfence}" # окончательный вывод забора
else # если есть запись или если нет записи и набрали больше 13, то пишем в счет
[[ "${eggs}" -ne 0 ]] && echo -n "+ ${eggs}(${msg_eggs}) " # выводим, если есть, яйца
(( score[i] += played[i] + played[i+2] + fence[i] + eggs )) # считаем результат
echo "= ${score[i]}" # выводим окончательный результат
fence[!i]=0 # и забор противника сгорает
eggs=0
fi
echo "${msg_total_score} ${score[0]} : ${score[1]}"
if [[ ${score[$i]} -gt ${hundred} ]]; then
[[ ${i} -eq 0 ]] && echo "Вы козёл :-)" || echo "Вам просто повезло."
break
fi
echo '----------'
done
exit 0