local nhbd=$?
if [ "$nhbd" -eq "$BIRTH" ] # "Живая".
then
return $ALIVE
fi
if [ "$3" = "." -a "$nhbd" -eq "$SURVIVE" ]
then # "Живая" если перед этим была "живая".
return $ALIVE
fi
return $DEAD # По-умолчанию.
}
GetCount () # Подсчет "живых" соседей.
# Необходимо 2 аргумента:
# $1) переменная-массив
# $2) cell номер ячейки
{
local cell_number=$2
local array
local top
local center
local bottom
local r
local row
local i
local t_top
local t_cen
local t_bot
local count=0
local ROW_NHBD=3
array=( `echo "$1"` )
let "top = $cell_number - $COLS - 1" # Номера соседних ячеек.
let "center = $cell_number - 1"
let "bottom = $cell_number + $COLS - 1"
let "r = $cell_number / $ROWS"
for ((i=0; i<$ROW_NHBD; i++)) # Просмотр слева-направо.
do
let "t_top = $top + $i"
let "t_cen = $center + $i"
let "t_bot = $bottom + $i"
let "row = $r" # Пройти по соседям в средней строке.
IsValid $t_cen $row # Координаты корректны?
if [ $? -eq "$TRUE" ]
then
if [ ${array[$t_cen]} = "$ALIVE1" ] # "Живая"?
then # Да!
let "count += 1" # Нарастить счетчик.
fi
fi
let "row = $r - 1" # По верхней строке.
IsValid $t_top $row
if [ $? -eq "$TRUE" ]
then
if [ ${array[$t_top]} = "$ALIVE1" ]
then
let "count += 1"
fi
fi
let "row = $r + 1" # По нижней строке.
IsValid $t_bot $row
if [ $? -eq "$TRUE" ]
then
if [ ${array[$t_bot]} = "$ALIVE1" ]
then
let "count += 1"
fi
fi
done
if [ ${array[$cell_number]} = "$ALIVE1" ]
then
let "count -= 1" # Убедиться, что сама проверяемая ячейка
fi #+ не была подсчитана.
return $count
}
next_gen () # Обновить массив, в котором содержится информация о новом "поколении".
{
local array
local i=0
array=( `echo "$1"` ) # Преобразовать в массив.
while [ "$i" -lt "$cells" ]
do
IsAlive "$1" $i ${array[$i]} # "Живая"?
if [ $? -eq "$ALIVE" ]
then # Если "живая", то
array[$i]=. #+ записать точку.
else
array[$i]="_" # Иначе -- символ подчеркивания
fi #+ (который позднее заменится на пробел).
let "i += 1"
done
# let "generation += 1" # Увеличить счетчик поколений.
# Подготовка переменных, для передачи в функцию "display".
avar=`echo ${array[@]}` # Преобразовать массив в строку.
display "$avar" # Вывести его.
echo; echo
echo "Поколение $generation -- живых особей $alive"
if [ "$alive" -eq 0 ]
then
echo
echo "Преждеверменное завершение: не осталось ни одной живой особи!"
exit $NONE_ALIVE # Нет смысла продолжать
fi #+ если не осталось ни одной живой особи
}
# =========================================================
# main ()
# Загрузить начальное поколение из файла.
initial=( `cat "$startfile" | sed -e '/#/d' | tr -d '\n' |\
sed -e 's/\./\. /g' -e 's/_/_ /g'` )
# Удалить строки, начинающиеся с символа '#' -- комментарии.
# Удалить строки перевода строки и вставить пробелы между элементами.
clear # Очистка экрана.
echo # Заголовок
echo "======================="
echo " $GENERATIONS поколений"
echo " в"
echo " игре \" ЖИЗНЬ\""
echo "======================="
# -------- Вывести первое поколение. --------
Gen0=`echo ${initial[@]}`
display "$Gen0" # Тлько вывод.
echo; echo
echo "Поколение $generation -- живых особей $alive"
# -------------------------------------------
let "generation += 1" # Нарастить счетчик поколений.
echo
# ------- Вывести второе поколение. -------
Cur=`echo ${initial[@]}`
next_gen "$Cur" # Обновить и вывести.
# ------------------------------------------
let "generation += 1" # Нарастить счетчик поколений.
# ------ Основной цикл игры ------
while [ "$generation" -le "$GENERATIONS" ]
do
Cur="$avar"
next_gen "$Cur"
let "generation += 1"
done
# ==============================================================
echo
exit 0
# --------------------------------------------------------------
# Этот сценарий имеет недоработку.
# Граничные ячейки сверху, снизу и сбоков остаются пустыми.
# Упражнение: Доработайте сценарий таким образом, чтобы ,
# + левая и правая стороны как бы "соприкасались",
# + так же и верхняя и нижняя стороны.
Пример A-12. Файл с первым поколением для игры "Жизнь"
# Это файл-пример, содержащий "поколение 0", для сценария "life.sh".
# --------------------------------------------------------------
# Игровое поле имеет размер 10 x 10, точкой обозначается "живая" особь,
#+ символом подчеркивания -- пустая ячейка. Мы не можем использовать пробелы,
#+ для обозначения пустых ячеек, из-за особенностей строения массивов в Bash.
# [Упражнение для читателей: объясните, почему?.]
#
# Строки, начинающиеся с символа '#' считаются комментариями, сценарий их игнорирует.
__.__..___
___._.____
____.___..
_._______.
____._____
..__...___
____._____
___...____
__.._..___
_..___..__
+++
Следующие два сценария предоставил Mark Moraes, из университета в Торонто. См. файл "Moraes-COPYRIGHT", который содержит указание на авторские права.
Пример A-13. behead: Удаление заголовков из электронных писем и новостей
#! /bin/sh
# Удаление заголовков из электронных писем и новостей т.е. до первой
# пустой строки
# Mark Moraes, Университет в Торонто
# ==> Такие комментарии добавлены автором документа.
if [ $# -eq 0 ]; then
# ==> Если входной аргумент не задан (файл), то выводить результат на stdin.
Читать дальше