Минимальный уровень:
Для получения зачета по теме «Объектно-ориентированное программирование» необходимо выполнить следующие задания:
Набрать, отладить и проверить работу программы «Аквариум»;
Модифицировать программу, добавив метод движения для рыб;
«Поселить» в аквариуме созданный вами объект, придумать его свойства и методы, а также взаимодействие с рыбами.
Максимальный уровень:
Для получения зачета на этом уровне вам необходимо самостоятельно решить одну из предложенных задач, используя описание объектов и принципы ООП.
Задачи:
Решить задачу «Аквариум» в графическом режиме, используя следующие рекомендации для развития задачи и изменения законов обитания рыб:
определить объект «аквариумная рыбка», имеющий свойства (координаты, скорость движения, размер, цвет, направление движения) и методы Init (устанавливает значения полей и рисует рыбу на экране методом Draw), Draw (рисует рыбу в виде уголка с острием в точке с координатами (x, y) и направленного острием по ходу движения), Look (проверяет несколько точек на линии движения рыбы. Если хоть одна точка отличается по цвету от воды, возвращаются ее цвет и расстояние до рыбы), Run (перемещает рыбу в текущем направлении на расстояние, зависящее от скорости. Иногда случайным образом меняет направление движения рыбы. Если рыба видит препятствие, направление движения меняется, пока препятствие не исчезнет из поля зрения рыбы).
объединить «съедобных» рыб и «хищников» в две стаи. Позвольте пользователю пополнять стаи, вводя рыб с клавиатуры.
позволить «хищникам» поедать «съедобных» рыб как только они их увидят или догонят (на ваше усмотрение).
Составить программу для игры в шашки. Шашка каждого цвета выступает в качестве отдельного объекта. Характеристики шашки – цвет и позиция на доске. Методы – перемещение. Не забудьте о таких объектах, как «дамки».
Волчий остров (Ван Тассел Д. Стиль, разработка, эффективность, отладка и испытание программ. М.: Мир, 1981.)
Волчий остров размером 20 * 20 заселен дикими кроликами, волками и волчицами. Имеется по несколько представителей каждого вида. Кролики довольно глупы: в каждый момент времени они с одинаковой вероятностью 1/9 передвигаются в один из восьми соседних квадратов (за исключением участков, ограниченных береговой линией) или просто сидят неподвижно. Каждый кролик с вероятностью 0.2 превращается в двух кроликов. Каждая волчица передвигается случайным образом, пока в одном из соседних восьми квадратов не окажется кролик, за которым она охотится. Если волчица и кролик оказываются в одном квадрате, волчица съедает кролика и получает одно "очко". В противном случае она теряет 0.1 "очка". Волки и волчицы с нулевым количеством очков умирают.
В начальный момент времени все волки и волчицы имеют 1 очко. Волк ведет себя подобно волчице до тех пор, пока в соседних квадратах не исчезнут все кролики; тогда если волчица находится в одном из восьми близлежащих квадратов, волк гонится за ней. Если волк и волчица окажутся в одном квадрате и там нет кролика, которого нужно съесть, они производят потомство случайного пола.
Запрограммируйте предполагаемую экологическую модель, понаблюдайте за изменением популяции в течение некоторого периода времени.
Задача об инфекции стригущего лишая (Ван Тассел Д. Стиль, разработка, эффективность, отладка и испытание программ. М.: Мир, 1981.)
Промоделируйте процесс распространения инфекции стригущего лишая по участку кожи размером n * n (n — нечетное) клеток. Предполагается, что исходной зараженной клеткой кожи является центральная. В каждый интервал времени пораженная инфекцией клетка может с вероятностью 0,5 заразить любую из соседних здоровых клеток. По прошествии шести единиц времени зараженная клетка становится невосприимчивой к инфекции, возникший иммунитет действует в течение последующих четырех единиц времени, а затем клетка оказывается здоровой. В ходе моделирования описанного процесса выдавать текущее состояние моделируемого участка кожи в каждом интервале времени, отмечая зараженные, невосприимчивые к инфекции и здоровые клетки.
Игра "Две лисы и 20 кур"
На поле указанной формы (см. рисунок ниже) находятся две лисы и 20 кур. Куры могут перемещаться на один шаг вверх, влево или вправо, но не назад и не по диагонали. Лисы также могут перемещаться только на один шаг, но также и вверх — как вниз, влево и вправо. Лиса может съесть курицу — как в игре в шашки: если в горизонтальном или вертикальном направлении за курицей на один шаг следует свободное поле, то лиса перепрыгивает через курицу и берет ее. Лисы всегда обязаны есть и, когда у них есть выбор, — они обязаны осуществлять наиболее длинное поедание. Если два приема пищи имеют одинаковую длину, осуществляется один из них — по выбору лисы.
Составить программу, которая играет за лис. Игрок перемещает кур. Партнеры играют по очереди, причем куры начинают. Они выигрывают партию, если девяти из них удается занять 9 полей, образующих верхний квадрат игры.
Начальное положение кур и лис изображено на рисунке.
-
Л
Л
К
К
К
К
К
К
К
К
К
К
К
К
К
К
К
К
К
К
К
К
Лисы выигрывают, если им удается съесть 12 кур, так как тогда оставшихся кур недостаточно, чтобы занять 9 верхних полей.
Морской бой
Составить программу, позволяющую играть в морской бой игроку с компьютером. Программа должна позволять расставлять корабли на поле 10 * 10, контролировать правильность их расстановки, делать противникам поочередно ходы и выдавать соответствующие информационные сообщения. Когда в качестве одного из игроков выступает компьютер, программа должна анализировать предыдущие ходы и следующий делать на основе проведенного анализа.
Пример решения задачи с использованием объектов
Рассмотрим пример решения следующей задачи:
в аквариуме находится N рыбок. К ним помещается «хищник». «Хищник» может съесть рыбку, находящуюся от него на самом близком расстоянии.
Наша задача заключается в размещении рыбок в аквариуме случайным образом. Случайным образом к ним помещается «хищник». Необходимо выделить и удалить с экрана ту рыбку, которая оказалась от «хищника» на ближайшем расстоянии.
Задание 1.
Начнем с описания объекта «рыба». Этот объект должен иметь свойства (поля): координаты, цвет, название; методы: вывода на экран Drow, инициализации Init, т.е. установки координат, цвета и изображения на экране с помощью метода Drow.
Такое описание объекта «рыба» в программе будет выглядеть следующим образом:
type
tfish=object
x,y,col:byte; {свойства объекта: x,y – координаты, col – цвет}
name:char; {свойство объекта – название}
procedure drow(x1,y1:byte; s:char); {метод объекта, изображающий его на экране}
procedure init; {метод, инициализирующий объект}
end;
Замечание: решение задачи будем выполнять в текстовом режиме.
После описания объектного типа для примера и контроля введем один экземпляр данного типа:
Var f: tfish;
Заметим сразу, что этот экземпляр объектного типа мы используем для проверки описания методов объектного типа «рыба», чтобы проверить правильность установки текстового режима, выбора цвета и т.д.
Далее в тексте программы в разделе описания процедур и функций следует описание методов объектного типа «рыба»:
procedure tfish.drow;
begin
GoToXY(x1,y1); {устанавливаем курсор на позицию с координатами x1, y1}
write(s); {«рыбу» изобразим символом }
delay(100); {поставим задержку на 100 миллисекунд для того, чтобы, когда будем выводить на экран много рыб, они появлялись постепенно}
end;
procedure tfish.init;
begin
x:=random(80); {случайным образом задаем значение столбца от 1 до 80}
y:=random(25); {случайным образом задаем значение строки от 1 до 25}
col:=random(15); {случайным образом задаем цвет от 0 до 15}
TextColor(col); {устанавливаем цвет выводимой буквы}
Name:=chr(random(100)) {случайным образом задаем название «рыбы» как символ, соответствующий коду от 1 до 100}
drow(x,y,name); {обращаемся к методу, изображающему «рыбу» на экране}
end;
А сейчас напишем вспомогательную процедуру, «заполняющую аквариум водой», эта процедура не имеет отношения к объектно-ориентированному программированию, но для решения нашей задачи может пригодиться, хотя бы просто для красоты.
procedure fon;
var
i,j,k:byte;
begin
TextColor(Blue); {установим цвет выводимых символов, совпадающий с цветом фона}
for j:=24 downto 1 do
begin
for i:=40 downto 1 do
begin
k:=80-i+1;
GotoXY(i,j);
write(chr(219)); {выводим символ, соответствующий коду 219 – прямоугольник}
GotoXY(k,j);
write(chr(219)); {выводим символ, соответствующий коду 219 – прямоугольник}
delay(12); {эта процедура позволяет устанавливать время задержки в миллисекундах}
end;
end;
end;
После всех предварительно проделанных действий мы можем написать программу, в которой определим объектный тип «рыба» с его свойствами и методами, «заведем» одну из «рыб», «заполним аквариум водой» и поместим туда одну нашу «рыбку»:
program fish;
uses crt; {для использования процедур работы в текстовом режиме необходимо подключить специальный модуль CRT}
type
tfish=object {описание объектного типа «рыба»}
x,y,col:byte; name:char
procedure drow(x1,y1:byte; s:char);
procedure init;
end;
var
f:tfish;
procedure tfish.drow;
begin
GoToXY(x1,y1);
write(s);
delay(100)
end;
procedure tfish.init; {метод, инициализирующий объект «рыба»}
begin
x:=random(80);
y:=random(25);
col:=random(15);
TextColor(col);
Name:=chr(random(100));
drow(x,y,name);
end;
procedure fon; {«заполнение аквариума водой»}
var
i,j,k:byte;
begin
TextColor(Blue);
for j:=24 downto 1 do
begin
for i:=40 downto 1 do
begin
k:=80-i+1;
GotoXY(i,j);
write(chr(219));
GotoXY(k,j);
write(chr(219));
delay(12);
end;
end;
end;
begin {начало основной программы}
clrscr; {очищаем экран}
randomize; {активизируем функцию генерации случайных чисел}
TextMode(CO80); {устанавливаем текстовый режим цветной, 80*25}
TextBackGround(Blue); {устанавливаем синий цвет фона}
fon; {«заполняем аквариум водой»}
f.init; {«размещаем рыбку в аквариуме», используя метод инициализации объекта «рыба»}
readln;
end.
Задание 2.
Настало время описать объектный тип «съедобных (для хищника) рыб», назовем этих рыб «карп». Причем объектный тип «карп» является потомком объектного типа «рыба», т.е. наследует его структуру и поведение. Нам понадобится новый метод, назовем его kill, удаляющий с экрана тех «карпов», которых съест «хищник». А также перекроем родительский одноименный метод init, т.к. для «карпов» этот метод будет выполняться особым для них («карпов») образом.
Описание объектного типа «карп»:
……{раздел описания типов}
tkarp=object(tfish) {в скобках указывается имя родительского типа}
{свойства (координаты, цвет и название) автоматически наследуются от родительского типа}
{метод drow автоматически наследуется от родительского типа}
procedure kill; {новый метод, удаляющий «карпов» с экрана}
procedure init; {перекрываем метод родительского объекта}
end;
Далее по программе, в разделе описания процедур и функций, описываем методы объектного типа «карп»:
procedure tkarp.init;
begin
x:=random(80);
y:=random(25);
col:=14; {зафиксируем цвет «карпов» – желтый}
TextColor(col);
name:='K'; {зафиксируем символ, которым на экране будут обозначаться «карпы»}
drow(x,y,name); {с помощью метода объектного типа «карп» выведем на экран в позиции с координатами x,y, заданной случайным образом, желтую букву К}
end;
procedure tkarp.kill;
begin
name:=chr(219);{заменяем символ ‘K’ на прямоугольник}
Col:=Blue; {заменяем желтый цвет на цвет фона}
TextColor(col);
Drow(x,y,name) {перерисовываем объект заново, при этом синий прямоугольник сливается с цветом фона}
End;
После описания объектного типа «карп» можно определить количество N экземпляров данного типа и задать массив из N элементов типа «карп»:
……..{раздел описания переменных}
k: array [1..100] of tkarp;
n,i: integer;
Итак, мы завершили описание объектного типа «карп» и приступаем к описанию объектного типа «хищник», назовем его «акула». Объектный тип «акула» является потомком объектного типа «рыба», и, следовательно, наследует все его свойства и методы. Перекроем родительский одноименный метод init, т.к. для «акул» этот метод будет выполняться особым для них («акул») образом.
Описание объектного типа «акула»:
takula=object(tfish)
procedure init;
end;
Далее по программе, в разделе описания процедур и функций, описываем методы объектного типа «акула»:
procedure takula.init;
begin
x:=random(80);
y:=random(25);
col:=5; {определим цвет изображения «акулы» – малиновый}
TextColor(col+128); {устанавливаем цвет выводимого символа и добавляем эффект мерцания}
name:='A'; {«акула» на экране будет изображаться символом ‘A’}
drow(x,y,name);
end;
В разделе описания переменных следует определить экземпляр типа «акула»:
…….{раздел описания переменных}
a: takula;
А теперь объединим все необходимые фрагменты в программу, которая только заполняет аквариум «карпами» и помещает туда же «акулу». В этой программе «карпам» еще ничего не угрожает.
program fish;
uses crt;
type
tfish=object
x,y,col:byte;
name:char;
procedure drow(x1,y1:byte; s:char);
procedure init;
end;
tkarp=object(tfish)
procedure init;
procedure kill;
end;
takula=object(tfish)
procedure init;
end;
var
a:takula;
k:array[1..100] of tkarp;
n,i:integer;
procedure tfish.drow;
begin
GoToXY(x1,y1);
write(s);
end;
procedure tfish.init;
begin
x:=random(80);
y:=random(25);
col:=random(15);
TextColor(col);
Name:=chr(random(100));
drow(x,y,name);
end;
{вспомогательная процедура заполнения аквариума водой}
procedure fon;
var
i,j,k:byte;
begin
TextColor(Blue);
for j:=24 downto 1 do
begin
for i:=40 downto 1 do
begin
k:=80-i+1;
GotoXY(i,j);
write(chr(219));
GotoXY(k,j);
write(chr(219));
delay(12);
end;
end;
end;
procedure tkarp.init;
begin
x:=random(80);
y:=random(25);
col:=14;
TextColor(col);
name:='K';
drow(x,y,name);
end;
procedure tkarp.kill;
begin
name:=chr(219);
Col:=Blue;
TextColor(col);
Drow(x,y,name)
End;
procedure takula.init;
begin
x:=random(80);
y:=random(25);
col:=5;
TextColor(col+128);
name:='A';
drow(x,y,name);
end;
{начало основной программы}
begin
write(‘Задайте число карпов в аквариуме: ‘);
readln(n);
clrscr;
randomize;
TextMode(CO80);
TextBackGround(Blue);
fon;
for i:=1 to n do
k[i].init; {в цикле последовательно размещаем «карпов» на экране}
a.init; {размещаем «акулу»}
readln;
TextMode(BW80); {возвращаем экрану черно-белый режим 80*25}
end.
Задание 3.
Мы проделали основную часть работы. Что еще осталось сделать? Теперь нам нужно среди всех «карпов» определить самого близкого к «акуле» и «съесть» его. В этой части решения задачи уже нет элементов объектно-ориентированного программирования, кроме обращения к методу tkarp.kill, задача свелась к поиску минимального элемента в массиве. Эту часть программы вы можете написать самостоятельно.
Задание 4.
Все остальные задания, начиная с этого, предлагаются вам для самостоятельной работы. Для начала попробуйте наделить «акулу» новым методом – способностью перемещаться. Для этого вам нужно придать приращение координатам и перерисовать «акулу» на новом месте. А там снова найти самого близкого «карпа» и «съесть» его.
Поместите в аквариум не одну, а несколько «акул». Позвольте каждой из них «съедать» самого близкого к ней «карпа».
Дайте возможность перемещаться не только «акулам», но и «карпам».
Перенесите решение задачи из текстового в графический режим, создайте объект «аквариум», в котором и живут «рыбы», напишите для этого объекта методы: init, включающий графический режим, заполняющий «аквариум» водой, скалами, рыбами; done, выключающий графический режим. Придумайте продолжение и развитие нашей задачи, и, может быть, скоро вы будете иметь на своем компьютере свой аквариум.