Искусство программирования на языке сценариев командной оболочки
Шрифт:
then
if [ -e "$1" ] # Проверка наличия файла.
then
startfile="$1"
fi
fi
ALIVE1=.
DEAD1=_
# Представление "живых" особей и пустых ячеек в файле с "поколением 0".
# Этот сценарий работает с игровым полем 10 x 10 grid (может быть увеличено,
#+ но большое игровое поле будет обрабатываться очень медленно).
ROWS=10
COLS=10
GENERATIONS=10 # Максимальное
NONE_ALIVE=80 # Код завершения на случай,
#+ если не осталось ни одной "живой" особи.
TRUE=0
FALSE=1
ALIVE=0
DEAD=1
avar= # Текущее поколение.
generation=0 # Инициализация счетчика поколений.
# =================================================================
let "cells = $ROWS * $COLS"
# Количество ячеек на игровом поле.
declare -a initial # Массивы ячеек.
declare -a current
display
{
alive=0 # Количество "живых" особей.
# Изначально -- ноль.
declare -a arr
arr=( `echo "$1"` ) # Преобразовать аргумент в массив.
element_count=${#arr[*]}
local i
local rowcheck
for ((i=0; i<$element_count; i++))
do
# Символ перевода строки -- в конец каждой строки.
let "rowcheck = $i % ROWS"
if [ "$rowcheck" -eq 0 ]
then
echo # Перевод строки.
echo -n " " # Выравнивание.
fi
cell=${arr[i]}
if [ "$cell" = . ]
then
let "alive += 1"
fi
echo -n "$cell" | sed -e 's/_/ /g'
# Вывести массив, по пути заменяя символы подчеркивания на пробелы.
done
return
}
IsValid # Проверка корректности координат ячейки.
{
if [ -z "$1" -o -z "$2" ] # Проверка наличия входных аргументов.
then
return $FALSE
fi
local row
local lower_limit=0 # Запрет на отрицательные координаты.
local upper_limit
local left
local right
let "upper_limit = $ROWS * $COLS - 1" # Номер последней ячейки на игровом поле.
if [ "$1" -lt "$lower_limit" -o "$1" -gt "$upper_limit" ]
then
return $FALSE # Выход за границы массива.
fi
row=$2
let "left = $row * $ROWS" #
let "right = $left + $COLS - 1" # Правая граница.
if [ "$1" -lt "$left" -o "$1" -gt "$right" ]
then
return $FALSE # Выхол за нижнюю строку.
fi
return $TRUE # Координаты корректны.
}
IsAlive # Проверка наличия "живой" особи в ячейке.
# Принимает массив и номер ячейки в качестве входных аргументов.
{
GetCount "$1" $2 # Подсчитать кол-во "живых" соседей.
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" ]