1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
Uses crt; var x, y, vx, vy, xap, yap, speed, i, score, go: integer; sim, snake,sim2: char; loose, begintext, wait: boolean; procedure zone; var i: integer; begin textcolor(lightcyan); for i := 1 To 80 Do write('*'); gotoxy(1, 2); for i := 1 To 24 Do writeln('*'); gotoxy(2, 25); for i := 1 To 79 Do write('*'); for i := 2 To 24 Do begin gotoxy(80, i); write('*'); end; textcolor(white); end; procedure notplay; var sim: char; begin while keypressed Do begin sim := readkey; case sim Of 'd','a','w','s','в','ф','ц','ы','D','A','W','S','В','Ф','Ц','Ы': begin vx := 0; vy := -1; end; End; end; end; begin speed := 120; snake := '0'; wait := true; SetWindowSize(80, 25); TextBackGround(black); clrscr; begintext := true; while begintext = true Do begin textColor(red); writeln('WARNING, NOT EXPAND THE WINDOW ,FOR CONVENIENCE!'); textcolor(green); writeln('To control use "wasd"'); textcolor(white); delay(2000); notplay; TextBackGround(green); begintext := false; end; clrscr; zone; x := 40; y := 25 Div 2; vy := -1; xap := random(79) + 2; yap := random(23) + 2; gotoxy(xap, yap); textcolor(red); write('+'); textcolor(white); gotoxy(1, 1); score := 0; textcolor(yellow); write('Score: ', score, ' '); textcolor(white); while (x >= 1) Or (x <= 80) Or (y >= 1) Or (y <= 24) Do begin gotoxy(x, y); textcolor(black); write(snake); textcolor(white); while wait = true do begin textcolor(red); gotoxy(39, 25); write(333); delay(1000); gotoxy(39, 25); write(222); delay(1000); gotoxy(39, 25); write(111); delay(1000); gotoxy(39, 25); write('GO!'); delay(500); gotoxy(39, 25); textcolor(lightcyan); write('***'); textcolor(white); notplay; wait := false; end; delay(speed); if keypressed Then begin sim := readkey; if ((sim2='d') or (sim2='D') or (sim2='в') or (sim2='В')) and ((sim='a') or (sim='A') or (sim='ф') or (sim='Ф')) then sim:='d'; if ((sim2='a') or (sim2='A') or (sim2='ф') or (sim2='Ф')) and ((sim='d') or (sim='D') or (sim='в') or (sim='В')) then sim:='a'; if ((sim2='w') or (sim2='W') or (sim2='ц') or (sim2='Ц')) and ((sim='s') or (sim='S') or (sim='ы') or (sim='Ы')) then sim:='w'; if ((sim2='s') or (sim2='S') or (sim2='ы') or (sim2='Ы')) and ((sim='w') or (sim='W') or (sim='ц') or (sim='Ц')) then sim:='s'; sim2:=sim; case sim Of 'd','D','в','В': begin vx := 1; vy := 0 end; 'a','A','ф','Ф': begin vx := -1; vy := 0 end; 'w','W','ц','Ц': begin vy := -1; vx := 0 end; 's','S','ы','Ы': begin vy := 1; vx := 0 end; End; end; gotoxy(x, y); write(' '); inc(x, vx); inc(y, vy); if ((x < 2) Or (x > 79) Or (y < 2) Or (y > 24)) Then begin loose := true; while loose = true Do begin if (x >= 71) then begin gotoxy(x - 9, y); textcolor(red); Write('You Lose!'); textcolor(white); end else begin textcolor(red); write('You Lose!'); textcolor(white); end; delay(5000); notplay; wait := true; loose := false; end; clrscr; zone; gotoxy(1, 1); score := 0; textcolor(yellow); write('Score: ', score, ' '); textcolor(white); if (vx = -1) And (vy = 0) Then begin vx := 0; vy := -1 end; if (vy = 1) And (vx = 0) Then begin vx := 0; vy := -1 end; if (vy = -1) And (vx = 0) Then begin vx := 0; vy := -1 end; if (vx = 1) And (vy = 0) Then begin vx := 0; vy := -1; end; x := 40; y := 25 Div 2; gotoxy(x, y); textcolor(black); writeln(snake); textcolor(white); xap := random(79) + 2; yap := random(23) + 2; gotoxy(xap, yap); textcolor(red); write('+'); textcolor(white); while wait = true do begin textcolor(red); gotoxy(39, 25); write(222); delay(1000); gotoxy(39, 25); write(111); delay(1000); gotoxy(39, 25); write('GO!'); delay(500); gotoxy(39, 25); textcolor(lightcyan); write('***'); textcolor(white); notplay; wait := false; end; end; if (x = xap) And (y = yap) Then begin xap := random(79) + 2; yap := random(23) + 2; gotoxy(xap, yap); textcolor(red); write('+'); textcolor(white); gotoxy(1, 1); score := score + 1; textcolor(yellow); write('Score: ', score, ' '); textcolor(white); end; end; end. |
На чтение 5 мин. Опубликовано 03.03.2021
Такая игра, как «Змейка», известна многим, не только детям, но и взрослым. В том случае, если человек знает хотя бы минимальные основы программирования посредством использования языка Паскаль, есть возможность написать её самостоятельно.
Змейка представляет собой игру, в которой по экрану полоска осуществляет перемещение. Изменять направление, в котором она будет двигаться, можно посредством использования клавиш влево, вправо, вниз и вверх. Ключевая цель игры заключается в том, что передвигающаяся змейка не должна столкнуться с «врагами», «препятствиями» и при этом собрать все возможные бонусы.
В процессе столкновениями с бонусом змейка будет автоматически увеличиваться. В том случае, если столкновение произойдет с препятствиями, то игра автоматически заканчивается и ее можно начинать с самого начала.
Решение задачи по созданию «Змейки» в Паскале
Рассматривая сам процесс написания кода программы к игре «Змейка», можно сказать, что для тех, кто только начинает заниматься программированием, задача достаточно сложная. Здесь даже можно остановиться на том варианте, когда по экрану будет перемещаться обыкновенная полоска, которую можно будет посредством клавиатуры перемещать в нужном направлении.
Ниже можно ознакомиться с вариантом кода для игры «Змейка». Но особенность этот варианта будет заключаться в том, что по площади экрана будет попросту перемещаться курсом посредством использования клавиш влево, вправо, вверх и вниз.
Как только он выйдет за границы, игра будет автоматически заканчиваться. При этом границы, за которые не может выйти курсор, в обязательном порядке должны быть прописаны в цикле while. Рассматривая ниже приведенный вариант, стоит обратить внимание на то, что у змейки будет полностью отсутствовать хвост.
Вариант реализации игры «Змейка» на языке программирования Паскаль будет выглядеть следующим образом:
В модуле graph также можно предложить следующую модель реализации этой игры на Паскале. Будет выглядеть она следующим образом:
Детальное описание разработки
Написание программы происходит в специальной среде программирования под наименованием TurboPascal. Именно в ней будет создано специальное контекстное меню, которое возникнет перед игроком в самом начале игрового процесса.
В этом меню каждый пользователь сможет найти подсказки по тому, как можно будет осуществлять процесс управления змейкой в процессе игры. На поле будет находиться змейка, которую нужно будет перемещать и бонусы, которые нужно будет собирать для ее дальнейшего перемещения.
Как только будет осуществлен процесс запуска программы, будут выполнены следующие действия:
- первоначально появится контекстное меню, в котором будет отображена специальная справка о том, каким образом можно будет осуществлять процесс управления змейкой;
- после этого игроку предлагается приступить к выполнению игрового процесса;
- после подтверждения перед игроком откроется специальное игровое поле зеленого цвета, где в точках с произвольными координатами будет появляться еда и бонусы, а также появиться змейка, которая сразу же начнет процесс движения в правую сторону.
Процесс управления змейкой можно реализовать посредством применения следующих клавиш:
- d – вправо;
- a – влево;
- s – вниз;
- w – вверх.
Хранение каждой из координат составляющих частей змейки будет происходить в специальной матрице. После того, как будет происходить процесс нажатия одной из клавиш, эти значения будут автоматически меняться и повторно сохраняться в матрице, а змейка при этом будет осуществлять свое передвижение.
В том случае, если координаты начала змейки и еды будут между собой совпадать, координаты, в которых находится еда и бонусы, будут автоматически меняться. При поедании змейкой еды или же бонусов ее длина будет автоматически изменяться на один сегмент.
Стоит обратить внимание на то, что на каждом из этапов змейка будет осуществлять проверку на то, не столкнулась ли змейка с препятствием. В том случае, если это все-таки произойдет, игровой процесс заканчивается, а игрок видит перед собой сообщение о проигрыше и возможность осуществить игру повторно в том случае, если он желает.
Если же игроку удастся собрать абсолютно все бонусы и всю еду до того момента, пока змейка достигнет максимально возможной длины, перед ним появится сообщение о том, что он выиграл. Поэтому, если кто-то думает, что игра «Змейка» является бесконечной, на самом деле это не так. В процессе написания игры указывается предельное значение длины змейки.
Рассматривая функциональное описание, стоит обратить внимание на то, что для точки есть необходимость выбрать тип данных spoint=record. Максимальная длина змейки будет выступать в качестве константы и здесь программист должен самостоятельно выбрать предельное значение. Если же рассматривать переменные, то среди них можно выделить следующие:
- координаты размещения еды и бонусов;
- длина змейки;
- координаты расположения головы змейки;
- координаты размещения отдельных частей тела змейки;
- флаг, отвечающий за конец игрового процесса;
- вектор, по которому будет происходить перемещение змейки.
Поэтому, чтобы реализовать такую игру, как «Змейка» посредством использования языка программирования Паскаль, можно сказать, что выполнить этот процесс вполне возможно. Но при этом у человека, который начинает изучать язык программирования, должны быть хотя бы минимальные знания в реализации этого процесса. В других случаях понадобиться большое количество сил и времени для того, чтобы без подготовки выполнить написание код программы к известной и популярной игре под наименованием «Змейка».
Uses graphABC,ABCObjects; var snake_lenght:integer{1}; i,xhead,yhead,z,appleX,appleY,t:integer; head:CircleABC; snake:array[1..4] of CircleABC; apple:circleABC; score:TextABC; destructor Destroy; procedure keyDown(key:integer); begin if(key=vk_Right) then z:=1; if(key=vk_Left) then z:=2; if(key=vk_Up) then z:=3; if(key=vk_Down) then z:=4; end; begin snake_lenght:=1; for i:=0 to 6 do begin line(0,i*80,windowWidth,i*80); end; for i:=0 to 8 do begin line(i*80,0,i*80,windowHeight); end; xhead :=3*80-40; yhead:=2*80-40; appleX:=6*80-40; appleY:=3*80-40; apple:= CircleABC.Create(appleX,appleY,40,clRed); head :=CircleABC.Create(xhead,yhead,40,clBlue); for i:=1 to snake_lenght do begin snake [i]:=CircleABC.Create(xhead,yhead+80*i,40,clBlue); end; score := TextABC.Create(5,0,80,'0',clGreen); while(true) do begin onKeyDown :=keyDown; if(z<>0)then begin for i:= snake_lenght downto 2 do begin snake[i].MoveTo(snake[i-1].Position.X,snake[i-1].Position.Y); end; snake[1].MoveTo(xhead-40,yhead-40); end; if(z = 1) then xhead := xhead + 80 else if (z = 2) then xhead := xhead - 80 else if (z = 3) then yhead := yhead - 80 else if (z = 4) then yhead := yhead + 80; if(xhead > windowWidth) then xhead := 40; if(xhead < 0) then xhead := windowWidth - 40; if(yhead > windowHeight) then yhead := 40; if(yhead < 0) then yhead := windowHeight - 40; if((xHead = appleX) and (yHead = appleY)) then begin if snake_lenght<4 then begin snake_lenght:=snake_lenght+1; snake [snake_lenght]:=CircleABC.Create(snake[snake_lenght-1].Position.X,snake[snake_lenght-1].Position.Y,40,clBlue);end; appleX := random(1,8)*80 - 40; appleY := random(1,6)*80 - 40; apple.MoveTo(appleX-40,appleY - 40); score.Text := ((score.Text).ToInteger + 1).ToString(); end; head.MoveTo(xhead-40,yhead-40); sleep(500) end; end.
Exe Download
Code Download
uses crt;
const arenaSize=20; //The size of the arena
startingSpeed=120; //The starting speed(smaller=faster)
startingSize=18; //The starting size of the snake
snakeColor=10; //The snake color
foodColor=14; //The food color
wallColor=9; //The wall color
var xfood,yfood,count,size,cycle,i,last,first,score,negativePoints,food:integer;
keyCheck,sizeChange,foodNotOnSnake:boolean;
direction,d2:string;
speed:real;
Snake:array [1..2, 1..4000] of integer;
ch:char;
label start,lose;
begin
start:
begin
clrscr;
randomize;
size:=startingSize+1;
first:=size-1;
speed:=startingSpeed;
last:=0;
score:=0;
food:=0;
negativePoints:=0;
for count:=size downto 1 do
begin
snake[1,count]:=count+1;
snake[2,count]:=2;
end;
direction:=’right’;
repeat
FoodNotOnSnake:=true;
xfood:=random(arenaSize+8)+2;
yfood:=random(arenaSize-2)+2;
for i:=1 to first do
for count:=first to size+1 do
if ((xfood=snake[1,count])and(yfood=snake[2,count]))or((xfood=snake[1,i])and(yfood=snake[2,i])) then
foodNotOnSnake:=false;
until foodNotOnSNake;
xfood:=random(arenaSize+8)+2;
yfood:=random(arenaSize-2)+2;
textcolor(wallColor);
gotoxy(1,1);
write(#201);
gotoxy(arenaSize+10,1);
write(#187);
gotoxy(1,arenaSize);
write(#200);
gotoxy(arenaSize+10,arenaSize);
write(#188);
for i:=2 to arenaSize+9 do
begin
gotoxy(i,1);
write(#205);
gotoxy(i,arenaSize);
write(#205);
end;
for i:=2 to arenaSize-1 do
begin
gotoxy(1,i);
write(#186);
gotoxy(arenaSize+10,i);
write(#186);
end;
textcolor(white);
while (true) do
begin
speed:=speed-0.01;
textcolor(foodColor);
gotoxy(xfood,yfood);
write(‘@’);
textcolor(white);
for count:=1 to size do
begin
textcolor(snakeColor);
gotoxy(snake[1,count],snake[2,count]);
if count=first+1 then
begin
case direction of
‘up’:write(#30);
‘down’:write(#31);
‘left’:write(#17);
‘right’:write(#16);
end;
end
else
write(#249);
textcolor(white);
end;
gotoxy(1,1);
for i:=1 to first-1 do
for count:=first+1 to size-1 do
if ((snake[1,first]=snake[1,count])and(snake[2,first]=snake[2,count]))or((snake[1,first]=snake[1,i])and(snake[2,first]=snake[2,i])) then
goto lose;
sizeChange:=false;
if (xfood=snake[1,first])and(yfood=snake[2,first]) then
begin
size:=size+1;
snake[1,size]:=snake[1,last];
snake[2,size]:=snake[2,last];
sizeChange:=true;
inc(food);
speed:=speed-1;
repeat
FoodNotOnSnake:=true;
xfood:=random(arenaSize+8)+2;
yfood:=random(arenaSize-2)+2;
for i:=1 to first-1 do
for count:=first+1 to size+1 do
if ((xfood=snake[1,count])and(yfood=snake[2,count]))or((xfood=snake[1,i])and(yfood=snake[2,i])) then
foodNotOnSnake:=false;
until foodNotOnSNake;
end
else inc(negativePoints);
begin
if last=size then
last:=1
else
inc(last);
end;
if sizeChange then
begin
if first=size-1 then
first:=1
else
inc(first);
end
else
begin
if first=size then
first:=1
else
inc(first);
end;
gotoxy(snake[1,last],snake[2,last]);
write(‘ ‘);
if (snake[1,first]<2)or(snake[2,first]<2)or(snake[1,first]>=arenaSize+10)or(snake[2,first]>=arenaSize) then
goto lose;
if keypressed then
begin
ch:=readkey;
if ch=’p’ then
ch:=readkey;
if ch=#0 then
begin
ch:=readkey;
case ch of
#72:if direction<>’down’ then
direction:=’up’;
#80:if direction<>’up’ then
direction:=’down’;
#75:if direction<>’right’ then
direction:=’left’;
#77:if direction<>’left’ then
direction:=’right’;
end;
end
else
if ch=#27 then
exit;
end;
if direction=’left’ then
begin
snake[1,last]:=snake[1,first]-1;
snake[2,last]:=snake[2,first];
end;
if direction=’right’ then
begin
snake[1,last]:=snake[1,first]+1;
snake[2,last]:=snake[2,first];
end;
if direction=’up’ then
begin
snake[1,last]:=snake[1,first];
snake[2,last]:=snake[2,first]-1;
end;
if direction=’down’ then
begin
snake[1,last]:=snake[1,first];
snake[2,last]:=snake[2,first]+1;
end;
score:=food*100-negativePoints;
if score<0 then
score:=0;
gotoxy(5,arenaSize+1);
write(‘Eaten food:’,food);
delay(round(speed));
end;
end;
lose:
begin
textcolor(12);
gotoxy(arenaSize+11,1);
writeln(‘You lose!Your score is:’,score);
gotoxy(arenaSize+11,2);
write(‘Press any key to play again or Esc to quit…’);
repeat
ch:=readkey;
if ch=#13 then
goto start;
until ch=#27;
end;
end.
К оглавлению | Назад | Вперёд
Все программы, код которых выложен здесь, являются работоспособными. Ниже приведены возможные варианты реализации игр «Крестики-нолики» и «Змейка» на PascalABC.Net 3.0.
Крестики-нолики[править]
Описание алгоритма |
---|
|
Управление:
- Левая кнопка мыши — установить крестик/нолик.
uses GraphABC; const N = 2; Z = '0'; K = 'X'; Size = 200; Border = 1; Sx = 1200; Sy = 70; var Matrix: array [0..N, 0..N] of char; Player1: boolean; procedure Draw(); procedure DrawZ(i, j: integer); begin SetPenColor(clCyan); SetPenWidth(4); var size2 := Size div 2; DrawCircle((i + 1) * Size - size2, (j + 1) * Size - size2, Round(size2 * 0.7)); end; procedure DrawK(i, j: integer); procedure RLine(x, y, x1, y1: real):=Line(Round(x), Round(y), Round(x1), Round(y1)); begin SetPenColor(clPink); SetPenWidth(4); var size2 := Size div 2 * 0.3; var cx1 := i * Size + size2; var cy1 := j * Size + size2; var cx2 := (i + 1) * Size - size2; var cy2 := (j + 1) * Size - size2; RLine(cx1, cy1, cx2, cy2); RLine(cx1, cy2, cx2, cy1); end; begin ClearWindow(clBlack); if Player1 then SetWindowCaption('Ходит первый игрок') else SetWindowCaption('Ходит второй игрок'); for var i := 0 to N do for var j := 0 to N do begin SetPenColor(clLightBlue); SetPenWidth(1); DrawRectangle(i * Size + Border, j * Size + Border, (i + 1) * Size - Border, (j + 1) * Size - Border); if Matrix[i, j] = Z then DrawZ(i, j) else if Matrix[i, j] = K then DrawK(i, j); end; Redraw(); end; function Won(c: char): boolean; var count: byte; begin Result := false; for var i := 0 to N do begin count := 0; for var j := 0 to N do if Matrix[i, j] = c then Inc(count); if count = 3 then Result := true; end; if not Result then begin for var i := 0 to N do begin count := 0; for var j := 0 to N do if Matrix[j, i] = c then Inc(count); if count = 3 then Result := true; end; if not Result then begin count := 0; for var i := 0 to N do if Matrix[i, i] = c then Inc(count); if count = 3 then Result := true; if not Result then begin count := 0; for var i := 0 to N do if Matrix[N - i, i] = c then Inc(count); if count = 3 then Result := true; end; end; end; end; function IsFull(): boolean; begin Result := true; for var i := 0 to N do for var j := 0 to N do if (Matrix[i, j] <> Z) and (Matrix[i, j] <> K) then begin Result := false; break; end; end; procedure MouseDown(x, y, mb: integer); procedure ShowWinner(s: string; c: Color); begin SetWindowCaption('Результат игры'); Sleep(2000); SetWindowSize(Sx, Sy); CenterWindow(); ClearWindow(clBlack); SetFontSize(16); SetFontStyle(fsBold); SetFontColor(c); DrawTextCentered(0, 0, Sx, Sy, s); Redraw(); Sleep(2000); Halt(); end; begin var i := x div Size; var j := y div Size; if (Matrix[i, j] <> Z) and (Matrix[i, j] <> K) then begin if Player1 then Matrix[i, j] := Z else Matrix[i, j] := K; Draw(); var winnerExists := Won(Z) or Won(K); if winnerExists then if Player1 then ShowWinner('Игрок первый победил!', clLightBlue) else ShowWinner('Игрок второй победил!', clLightBlue); if IsFull() and not winnerExists then ShowWinner('Ничья!', clOrange); Player1 := not Player1; end; end; begin var Size2 := Size * 3; SetWindowIsFixedSize(true); SetWindowSize(Size2, Size2); CenterWindow(); LockDrawing(); Player1 := true; Draw(); OnMouseDown := MouseDown; end.
Змейка[править]
==Упрощенный вариант== (просто змейка которой можно управлять)
Описание алгоритма |
---|
|
Управление:
- W — вверх.
- S — вниз.
- A — влево.
- D — вправо.
uses GraphABC; const Size = 20; var Snake: List<Point>; procedure Draw(); begin ClearWindow(); Polyline(Snake.ToArray()); var c := Snake.Count - 1; Circle(Snake[c].X, Snake[c].Y, 5); Redraw(); end; procedure KeyDown(Key: integer); begin var c := Snake.Count - 2; case Key of VK_Left: begin Snake.RemoveAt(0); Snake.Add(new Point(Snake[c].X - Size, Snake[c].Y)); end; VK_Right: begin Snake.RemoveAt(0); Snake.Add(new Point(Snake[c].X + Size, Snake[c].Y)); end; VK_Up: begin Snake.RemoveAt(0); Snake.Add(new Point(Snake[c].X, Snake[c].Y - Size)); end; VK_Down: begin Snake.RemoveAt(0); Snake.Add(new Point(Snake[c].X, Snake[c].Y + Size)); end; end; Draw(); end; begin LockDrawing(); SetSmoothingOff(); Snake := new List<Point>(); for var x := 1 to 30 do Snake.Add(new Point(x * Size, Size)); Draw(); OnKeyDown := KeyDown; end.
Возрастающая последовательность[править]
uses GraphABC, ABCObjects; const Border = 100; var Obj: CircleABC; DX, DY: integer; Move: boolean; Numbers: TCircles; function IsEqual(L2: TCircles): boolean; begin Result := true; for var i := 0 to L2.Count - 1 do if Numbers[i].Number <> L2[i].Number then begin Result := false; break; end; end; procedure MouseUp(x, y, mb: integer); procedure MouseMove(x, y, mb: integer); begin if mb = 1 then if not Move then begin for var i := 0 to Numbers.Count - 1 do if Numbers[i].PtInside(x, y) then begin DX := x - Numbers[i].Position.X; DY := y - Numbers[i].Position.Y; Obj := Numbers[i]; Move := true; break; end; end else Obj.Position := new Point(x - Dx, y - Dy); end; begin var W := Window.Width - 2 * Border; var H := Window.Height - 2 * Border; Numbers := new TCircles(); for var i := 0 to 6 do end Numbers.Add(new CircleABC(Border + Random(W), Border + Random(H), 30, clRandom())); Numbers.Last().Number := i; Move := false; OnMouseMove := MouseMove; OnMouseUp := MouseUp; end.
59 |
|
Программирование на языке Pascal |
Практикум: Разработка приложения «Змейка»
В этом параграфе мы используем массивы для разработки приложения, в котором пользователь может управлять местоположением «змейки» на экране.
Тело змейки будет состоять из каких-либо символов, перемещаемых вслед за ведущим символом – головой змеи.
При перемещении, нам, по сути дела, потребуется изменять координату только головы змеи – все остальные части тела будут лишь «перебираться» на предыдущие положения впередистоящих звеньев.
Движение влево |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
||||||
7 |
||||||
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
Таким образом, алгоритм движения змейки будет заключаться в следующем:
1.Вычислить новые координаты головы змеи (на нашем рисунке – это нулевой элемент) по следующему правилу:
—Если была нажата кнопка «ВВЕРХ», то вычитаем из вертикальной координаты Y единицу. Координата X остается прежней.
—Если была нажата кнопка «ВНИЗ», то прибавляем к вертикальной координате Y единицу. Координата X также остается без изменений.
—Если была нажата кнопка «ВЛЕВО», то вычитаем единицу из координаты X.
—Если была нажата кнопка «ВПРАВО» то прибавляем единицу к координате X.
2.Переместить первое звено на место предыдущего нулевого звена, второе звено – на место предыдущего первого и т.д.
Отлавливать нажатие клавиш управления курсором мы будем при помощи процедуры
ReadKey из модуля Crt.
Координаты X и Y будем хранить в двух различных массивах. Длина змейки будет
определяться количеством элементов в этих массивах.
Uses Crt;
Const
SNAKE_LEN=6;
Type
TSnakeCoords=Array[0..SNAKE_LEN] Of Byte;
Var
X, Y : TSnakeCoords; c : Char;
i : Integer;
NewX, NewY : Integer;
Begin
{первоночальное положение змейки – левый верхний угол}
For i:=0 To SNAKE_LEN Do
Begin
59
60 |
|
Программирование на языке Pascal |
X[i]:=i+1;
Y[i]:=1;
End;
{Основной цикл – до тех пор пока не нажмут Esc}
Repeat
ClrScr;
{Вывод на экран змейки}
For i:=0 To SNAKE_LEN Do
Begin
GotoXY(X[i], Y[i]); Write(‘*’);
End;
c:=ReadKey;
If c=#0 Then c:=ReadKey;
{Получаем местоположение головы змейки}
NewX:=X[0];
NewY:=Y[0];
{На их основе вычисляем новые координаты}
Case C Of
#72: NewY:=NewY-1;
#80: NewY:=NewY+1;
#75: NewX:=NewX-1;
#77: NewX:=NewX+1;
End;
{Перебрасываем звенья на положения впередистоящих участков}
For i:=SNAKE_LEN DownTo 1 Do
Begin
X[i]:=X[i-1];
Y[i]:=Y[i-1];
End;
{Записываем новые координаты головы змеи}
X[0]:=NewX;
Y[0]:=NewY; Until c=#27;
End.
60
61 |
|
Программирование на языке Pascal |
Модуль 5. Строки и многомерные массивы
Представление строк в Pascal
Мы уже сталкивались с типом данных, способным хранить один символ. Это тип данных Char. Но в прикладных задачах часто приходится иметь дело не с одним символом, а с целыми словами и предложениями (вспомним хотя бы текстовый редактор). Можно,
конечно, работать со строками, объявив массив символов, например, так:
Const
String_Len=100;
Type
StringType=Array[1..StringLen] Of Char;
Var
MyString: StringType;
Но такой подход зачастую неудобен, поскольку требует непосредственного написания всех процедур манипулирования со строками (копирование строчек, поиск подстроки, извлечение подстроки и т.д.). Поэтому был введен специальный тип данных для работы со строками: String. По сути дела, строковый тип данных – это тот же массив символов, однако для него предусмотрены специальные процедуры и функции, облегчающие разработку программ.
Максимальная длина строки для типа данных String ограничена 255-ю символами. Это ограничение было снято в реализации языка Object Pascal, используемой в среде Delphi. Все символы строки нумеруются от 1 до длины строки. В нулевом символе хранится символ, с кодом, равным длине строки. Так, например, если строка содержит 32 символа, то нулевой символ будет пробелом (‘ ‘), так как его код равен 32.
В остальном, использование переменных строкового типа ничем не отличается от
использования тех переменных, которые мы использовали ранее. Приведем пример:
Var
UserName : String;
Begin
WriteLn(‘Введите ваше имя’); ReadLn(UserName);
WriteLn(‘Рады приветствовать, ‘, UserName);
End.
Эта программа просит ввести пользователя его имя, и затем просто выводит приветственное сообщение, содержащее обращение по имени к пользователю.
Операции над строками
Для строковых переменных определены операции присваивания (для нее используется уже знакомый нам оператор ‘:= ‘), сравнения (‘=‘ – равенство, ‘<‘ – меньше, ‘>‘ – больше, ‘<=‘ – меньше или равно, ‘>=‘ – больше или равно) и конкатенации – объединения строк. Для конкатенации используется символ «+», который, несмотря на то, что используется для сложения, не подразумевает независимость результат от мест «слагаемых»-строчек.
Действительно, если у нас есть две строки
S1:=’Маша’; S2:=’ ела кашу.’;
то в результате конкатенации S1+S2 мы получим строчку «Маша ела кашу», а поменяв «слагаемые» местами – « ела кашу.Маша».
Сравнение строк происходит следующим образом: если одна из сравниваемых строк имеет большую длину, то она считается больше той, что меньше по длине. Если длины строк одинаковы, то происходит посимвольное сравнение – знак неравенства будет
61
62 |
|
Программирование на языке Pascal |
совпадать со знаком неравенства несовпадающих символов. При этом символ в нижнем регистре считается больше соответствующего символа в верхнем регистре (например, ‘m‘>‘M‘). Общее же правило при сравнении символов такое: среди двух сравниваемых символов тот из них считается больше, чей код является больше. Приведем примеры сравнения строк
Строка 1 |
Строка 2 |
Результат сравнения |
‘Pascal‘ |
‘pascal‘ |
‘pascal‘>‘Pascal‘ |
‘Turbo Pascal‘ |
‘Pascal‘ |
‘Turbo Pascal‘>‘Pascal‘ |
‘abcdef‘ |
‘acdeff‘ |
‘abcdef‘<‘acdeff‘ |
Для того, чтобы узнать длину строки, хранящейся в переменной строкового типа, можно использовать два подхода:
1.Вычислить код символа, находящегося на нулевой позиции, например
Var S: String;
L: Byte;
Begin
WriteLn(‘Введите строку’);
ReadLn(S);
L:=Ord(S[0]);
WriteLn(‘Вы ввели строку, длиной ‘, L);
End.
В этом примере мы использовали функцию Ord для получения кода нулевого символа строки S[0].
2.Использовать функцию Length.
Var S: String;
L: Byte;
Begin
WriteLn(‘Введите строку’);
ReadLn(S);
L:=Length(S);
WriteLn(‘Вы ввели строку, длиной ‘, L);
End.
Аналогично первому способу определения длины строки, можно узнать какой символ находится на определенной позиции – для этого достаточно рассматривать строковую переменную как массив символов. Как правило, этим пользуются, когда необходимо «пробежаться» по всем символам строки для реализации различных алгоритмов над текстами (например, шифрования, когда нужно каждый символ или последовательность заменить другим символом).
Попробуем применить полученные знания для подсчета количества гласных и согласных символов в строке, состоящей из букв английского алфавита.
Для этой цели нам потребуется в введенной строке проверить каждый символ на принадлежность множеству гласных или согласных символов. Символы строки будем перебирать в цикле при помощи параметра, изменяющегося от 1 до длины строки. Поскольку при проверке строк регистр символов важен, то, чтобы нам отдельно не проверять на равенство верхнему и нижнему регистру символов, приведем проверяемые символы к верхнему регистру при помощи функции UpCase (она не работает для
62
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
- #
- #
- #
- #
- #
- #
- #
- #
- #
- #
- #