Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Самоучитель игры на Паскале. АВС и немного Турбо

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
1 Мб
Скачать
SetPenColor(clBlue); SetPenWidth(5);
Line( 100,100, 300,300);
А вот таксо стилем: SetPenColor(clBlue); SetPenStyle(psDashDot); Line( 100,100, 300,300);
А если вот так? SetPenColor(clBlue); SetPenWidth(5); SetPenStyle(psDashDot); Line( 100,100, 300,300);
Занудства ради – стиль линии учитывается, только если линия тонкая. Если линия толстая – без баловства, только сплошная. И ещё о цвете. Зелёный прямоугольник – освоили. Зелёный эллипс – освоили. А зелёный треугольник? С треугольником сложнее. Зато, освоив треугольник, освоим и вс
ов вообще. Знакомьтесь – FloodFill. Возвращаемся к когда-то
угл нарисованному нами треугольнику (мы ведь его нарисовали, правда?):
SetPenColor(clGreen); Line(100,100, 300,100); Line(300,100, 100,200); Line(100,200, 100,100);
А теперь:
FloodFill( 105,105, clGreen);
FloodFill закрашивает (заливает) всё, начиная с заданной точки (первые два параметра – (105,105)) пока не встретит границу заданного цвета (третий параметр - clGreen). Каким цветом красить? Тоже clGreen. Цвет
ицы и цвет заливки совпадают – всё зелёненькое/
гран
ё остальное, сколь угодно многоугольное и без
61
А что будет, если промахнёмся и не попадём в треугольник? А он, FloodFill, всё равно будет красить, пока не встретит зелёную границу, только не внутри границы, а снаружи. Попробуйте, напишите вместо (105,105) что-то вроде (5,5)
Полезная вещь – метод опорной точки
Вернёмся к нашему старому квадрату:
Line(100,100, 200,100); Line(200,100, 200,200); Line(200,200, 100,200); Line(100,200, 100,100);
Это квадрат с ле злой заказчик и передумал – ле Трудолюбиво переписываем:
Line(120,130, 220,130); Line(220,130, 220,230); Line(220,230, 120,230); Line(120,230, 120,130);
Понравилось? Дурацкий вопрос. Пересчитали без ошибок? Ну, повезло, значит. А по умному нельзя? Можно. Объявляем две переменные, которые будут олицетворять левый верхний угол:
var
x0,y0 : integer;
Дальше так:
x0:=100; y0:=100; Line(x0,y0, x0+100,y0);
вым верхним углом в точке (100,100). А теперь пришёл
вый верхний угол теперь в точке (120,130).
62
Line(x0+100,y0, x0+100,y0+100); Line(x0+100,y0+100, x0,y0+100); Line(x0,y0+100, x0,y0);
Теперь при возникновении злобного заказчика достаточно поменять две первые строки на следующий текст:
x0:=120; y0:=130;
и получаем желаемое (заказчиком). Всем медитировать три минуты! Если кого-то посетила мысль, не завести ли ещё одну переменную, например A, и не присвоить ли ей значение стороны квадрата – 100, поздравляю. Мысль очень правильная. Развивать здесь пока не будем, и оставим в качестве самостоятельного упражнения. После освоения процедур ме
тодика эта станет ещё привлекате
льнее и заблещет новыми красками. А называется это счастье “Метод опорной точки”.
TP. В чём разница
Разница большая, тоскливая и печальная. Зато. Зато по сути последняя, дальше всё будет практически одинаково, разница между Паскалям сглаживается и пропадает. Ну почти. Ну или она
, разница, будет
и
исключительно в пользу TP. Вы, конечно, заметили, что основные расхождения между реализациями языка возникают в тот момент, когда дело доходит до вывода на экран – неважно, текстового или графического. А реализации самих языков почти одинаковы.
Вот так выглядит стандартная графическая программа в TP
program Gr; uses Graph;
var
63
driver, mode : integer;
begin
driver:=VGA; mode:=VGAHi; InitGraph( driver, mode, ‘c:\bpascal\bgi’);
{ а вот тут что-нибудь потом нарисуем}
Readln; CloseGraph; end.
То, что до комментария – обязательная часть, то, что после комментария, тоже. Оцените унылый Readln почти в конце. То, что он не в конце, а только почти, это очень важно. Подумайте. Особое внимание вот этой строке:
InitGraph( driver, mode, ‘c:\bpascal\bgi’);.
А точнее, тому, чт Строка эта может бы Наш Паскаль. Процедуры рисования отличаются, но совсем немного. Отличаются, как именами, так и, кое-где, параметрами. Но не сильно. Вы справитесь. Вместо (справа ABC, слева Turbo):
Рисование
PutPixel SetPixel Bar Rectangle
Задание параметров: SetColor SetPenColor SetFillStyle SetBrushColor SetLineStyle SetPenStyle
Текст выводится процедурами: SetTextStyle
о в кавычках - ‘c:\bpascal\bgi’.
ть другой в зависимости от места, куда установили
64
OutTextXY
Названия шрифтов в первой процедуре свои, не совпадающие с Windows и задаются без кавычек (это константы языка). Впрочем, вместо них можно писать номера шрифтов, от нуля до четырех, или даже больше – в зависимости от версии.
Цвета называются почти одинаково, но без префикса cl, то есть Blue, он и есть Blue, а не clBlue.
Зато FloodFill в TP гораздо интереснее, увлекательнее и непредсказуемей. Дело в том, что цвет (и, дополнительно, стиль закраски) задаются оператором SetFillStyle, который предшествует нашему FloodFill. А в нём самом задаётся цвет границы, плюс к этому есть и дополнительный параметр, указывающий, как этот цвет понимать. Попробуйте, удовольствие гарантировано.
А в остальном вы сами разберётесь.
65
Глава 5, сложная.
Циклы и массивы
Просто массив
Три вещи, которые надо постичь программисту – переменные, массивы и указатели. То есть, конечно, надо постичь ещё очень много и других понятий, но эти, выделяясь, лежат на одной линии. Что сложного в переменной? Что у переменной есть имя и есть значение. С массивами и указателями та же проблема, только на другом уровн массивами, без этого никак. Без указателей, по правде гово но многие программисты как-то обходятся. Сначала массив объявим:
var a : array[1..5] of integer;
Объявлен одномерный массив из пяти целых элементов. Элементы массива имеют индексы от одного до пяти. Кажется, я уже говорил, что присутствие в программе числа, отличного от ну вредительством, а допустивший это программист подвергается экзекуции. Остаюсь при этом же мнении, но с пятеркой разберём пусть будет. А теперь что-нибудь с массивом сделаем. Для наглядности приведём всю программу полностью.
program Arr; uses
Crt;
var a : array[1..5] of integer; begin
a[1]:=2; a[2]:=1; a[4]:=a[1]+a[2]; Writeln(‘a[1]=’,a[1]); Writeln(‘a[2]=’,a[2]);
Writeln(‘a[4]=’,a[4]);
66
е. Сейчас займёмся
ря, тоже никак,
ля или единицы, является
ся попозже, а пока
end.
В нашем массиве под одним именем A скрываются пять целых переменных – A первое, A второе и так далее. Какая от этого польза – будет понятно чуть позже, а пока разберёмся в том, что написали. Вначале первому элементу массива присваивается значение два. Номер элемента массива называется индексом массива. Индекс массива указывается в квадратных скобках пос бо
льшинстве случаев сопровождается индексом. В остальном оператор присваивания выглядит совершенно как обычно. Далее второму элементу массива точно так же присваивается значение один. В чем здесь трудность – у некоторых изучающих программирование? В том, что у массива в целом есть имя, а у элемента массива есть индекс и значение. Пустяк, а некоторым даётся трудно.
ёртому элементу массива пр
Четв только чтобы убедиться, что к элементам массива можно обращаться и в правой части оператора присваивания. Дальше мы выводим на экран значения первого, второго и четвертого элементов массива – тех, которым что-то присвоили. Что будет, если вывести значение третьего элемента? То же самое, что будет, если
таться вывести значение переменной, которой ничего не присвоили –
попы скорее всего, ноль, или, возможно, какой-то мусор. И ещё. Пусть у нас N объявлена как целая переменная. Тогда можно написать вот так:
n:=3; a[n]:=10;
Как ни странно, это очень, очень важно. Почему возможность использ ясно через один раздел. А какая вообще польза от массивов? Да пожалуй, что и никакой, если использовать их без циклов. Но всё же – массивы совершенно необходимы для хранения и обработки большого количества однотипных данных. Важны оба условия: большое количество и однотипность. Массив из дву подозрение, что что-то не так. Однотипность означает, что если в первом элементе массива хранится температура, то в следующих девяноста девяти элементах будет она же. Если в первом элементе температура, а во
ования переменно
й в качестве индекса массива так важна, станет
ле имени массива. Имя массива в
исваиваем сумму первого и второго –
х элементов вызывает
сильное
67
втором давление, то программисту надо вежливо выкрутить руки и нежно спрашивать, слышал ли он о существовании записей. Где-то так.
Просто цикл
С массивами без циклов мы уже ознакомились, а теперь – циклы без массивов, предмет гораздо более осмысленный. Вот такая программа:
program Cycle; uses
Crt; var i : integer;
begin
for i:=1 to 5 do
Writeln(‘Au!!!’); end.
ускаем программу на выполнение и видим
Зап
Au! Au! Au! Au! Au!
А теперь разбираемся, что же мы напрограммировали и что полу результате. Цифра пять в программе и пять выведенных на экран строчек наводят на мысль, что между ними есть какая-то связь. Действительно, если мы заменим 5 на 10, то выведенных на экран строк тож теперь немного понаучнее. I – переменная цикла. Она должна быть объявлена как целая. for i:=1 to 5 do – оператор цикла. То, чт называют телом цикла. Тело цикла выполняется по одному разу для каждого значения переменной цикла от первого(1 у нас) до последнего(5)
о следует за словом do, обычно
е станет десять. А
чили в
68
в нашем случае пять раз. После каждого выполнения значение
переменной цикла возрастает на единицу. Одно выполнение цикла по научному называется итерация. Про переменную цикла говорят, что она управляет циклом. Сначала не совсем понятно, зачем вообще нужна переменная цикла и начальное и конечное значения – если мы в нашей программе напишем вот так - for i:=11 to 15 do выполнится те же пять раз. Причина в том, что в нашей программе переменная цикла в теле цикла не используется. Это редкий случай, обычно она там присутствует.
По причинам исторического характера, переменным цикла принято давать такие имена: I. J, K, L, M, N. Это если имя короткое, в
енности из одной буквы. Также впол
особ относительно осмысленные – NumberOfLine, к примеру.
Напишем вот такой цикл:
for i:=1 to 5 do Writeln(i);
На экране после выполнения программы получим:
1 2 3 4 5
А если мы снова поменяем начальное и конечное значение:
for i:=11 to 15 do Writeln(i);
то результат будет соответственно
11
то получим абсолютно тот же резу
не допустимы имена длинные и
льтат, цикл
69
12 13 14
15.
В целом понятно, не правда ли? И на всякий случай. Цикл может выполняться ровно один раз. Вот так:
for i:=11 to 11 do Writeln(i);
А может вообще ни разу:
for i:=15 to 11 do Writeln(i);
Ещё немного теории и немного практики. Тело цикла у нас состоит ровно из одного оператора. А если нужно больше, на
пример, опять покрас
ить текст в зелёный цвет? Всё то же
самое, что и для условного оператора:
for i:=1 to 5 do begin TextColor(clGreen); Writeln(‘Au!!!’); end;
Разумеется, точно так же между begin и end может находиться только один оператор.
При каждом выполнении цикла значение переменной цикла возрастает и ровно на единицу. Так и только так. Это не потому, что изобретатели Паскаля по-другому не смогли, это из-за того, что они по-другому не захотели. По своей вредности они считали, что для целей образования переменная цикла должна только возрастать и только на единицу. А циклы, в которых эт переменная цикла убывала на единицу, то можно, но надо специально попросить. Цикл в этом случае пишется слегка по-другому: for i:=5 downto 1 do.
о не так – неправильные циклы. Всё же, одно п
ослабление они сделали. Если очень надо, чтобы
Теперь обещанная практика. Задачи, которые будут преследовать Вас всю Вашу программистскую жизнь.
70
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]