Програмний код гри "Змійка" на мові Pascal

Про матеріал
Приклад викона ння не над скаладного завдання гри змійка на мові програмування Паскаль.
Перегляд файлу

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

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

 

Program MSnake;

  Uses Crt, Graph;

  Type

    TElem = ^TStek;

    TStek = record

      X : integer;      { координаты по X }

      Y : integer;      { координаты по Y }

      Num : Word;       { номер элемента }

      Next : TElem;     { следующий элемент змейки }

      Prev : TElem;     { предыдущий элемент змейки }

    End;

     TDir = 1..4;        { 4 вида направления движения }

    TSnake = object

      First : TElem;    { первый элемент змейки }

      Last : TElem;     { последний элемент змйки }

      Direction : TDir; { направление змейки }

      Length : Word;    { длина змейки }

      Color : Word;     { цвет змеи }

      Esize : Word;     { размер эдиничного элемента }

      Asize : Word;     { размер яблока }

      pSn : pointer;    { для хранения в дим. памяти }

      pA : pointer;     { для хранения изоб. яблока в памяти }

      aX,aY : word;     { координаты яблока }

      AMaxX : word;     { максимум по горинзотали }

      AMAxY : word;     { максимум по вертикале }

       constructor Create(sDirection : TDir;

                         sLength : Word;

                         sX, sY : Word;

                         sColor : Word);

      { процедура создания змеи }

      destructor Destroy;

      { процедура уничтожения змеи }

       {procedure Release;}

      { процедура, выводящая всю змею на массив (чтобы знать, }

      { где расположена змея, вдруг будем вставлять алгоритм  }

      { поиска пути или еще, что-то) }

 

      function  CorrectCoord: boolean;

      { ф-ция для проверки корректности кординат яблока }

       procedure DrawApple;

      { процедура рисует яблоко на поле }

       procedure NewApple;

      { процедура создает новое яблоко}

       function EatApple : boolean;

      { ф-ция для проверки не сьела ли яблоко змея }

       function Snack : boolean;

      { ф-ция проверяет не укулила ли она себя }

       procedure Draw;

      { процедура прорисовки всей змейки }

       procedure DrawElement(Elem : TElem);

      { процедура отрисовывает определенный элемент змеи }

       procedure Clear;

      { процедура стирает змею }

       procedure ClearElement(Elem : TElem);

      { процедура стирает определенный элемент змеи }

       procedure Move(newX,newY : integer);

      { двигает все элементы змейки на место предыдущего, }

      { а первыый на новый координаты можно с помощью этой процедуры }

      { двинуть змейку вообще в какое-нибудь случайное место, }

      { а все элементы потом "телепортируются" туда }

      procedure Add;

      { добавляет к змейке элемент (последний) }

      procedure Remove;

      { уничтожает элемент змейки (последний) }

       {function GetByNumber(Num : Word) : TElem;}

      { находить элемент по номеру }

 {  function GetByCoord(X,Y : Word) : TElem;   }

      { находит элемент по координатам}

       { Вдруг понадобится найти элемент с определенным номером }

      { или расположением }

       procedure SetDirection(sDirection : TDir);

      { устанавливает направление змейки }

    End;

   constructor TSnake.Create(sDirection : TDir;

                            sLength : Word;

                            sX,sY : Word;

                            sColor : Word);

    Var

      i : integer;

      Beg,Tek,Tek2 : TElem;

    Begin

      If sDirection = 3 Then Direction := 1

      Else Direction := sDirection;

      Length := sLength;

      Color := sColor;

       First := nil;

      Last := nil;

       { делаем проверку на правильное введение координат }

      { проверяем, что не вышле за пределы экрана }

      If (sX < 1) or (sX > AMaxX) or (sY < 1) or (sY > AMaxY) or ((sX+sLength)>AMaxX)

        Then Begin

          OutTextXY(0,0,'Error Creating Snake');

          Exit;

        End;

       If sLength = 0 Then

        Begin

          OutTextXY(0,0,'Error Creating Snake');

          Exit;

        End;

      New(Beg);    { создаем первый элемент змейки }

       Beg^.X := sX + sLength*14;{ координата X - координаты конца + длина }

      Beg^.Y := sY;             { по Y все координаты одинаковый }

      Beg^.Num := 1;            { номер естественно первый }

      Beg^.Next := nil;         { следующего элемента пока нет }

      Beg^.Prev := nil;         { предыдущего тоже }

       first := beg;             { запомнили первый элемент змейки }

                                { с этого момента в змейке есть первый элемент}

 

      Tek := beg;               { текущий элемент - первый }

      If (sLength - 1) < 1 Then { если длина 1, тогда ВСЕ }

        exit;

       For i := 1 to (sLength-1) do

        Begin

          New(Tek2);            { создаем новый элемент }

           Tek2^.X := Tek^.X - 14;{ располагаем новый элемент левее }

          Tek2^.Y := Tek^.Y;    { по оси Y все находятся одинаково }

          Tek2^.Next := nil;    { следующий элемент должен быть тот, }

                                { который мы до этого создали }

          Tek2^.Prev := nil;    { предыдущего пока не существует }

           Tek2^.Num := Tek^.Num + 1; { прибавляем номер }

           Tek^.Next := Tek2;    { предыдущий ставим существование следующего }

          Tek := Tek2;          { текущий - вновь созданный }

          Last := Tek2;         { последний созданный элемент - это и есть последний}

        End;

       { рисуем единичный элемент и сохраняем его в памяти }

      SetFillStyle(WideDotFill,15);

      PieSlice(sX,sY,0,360,10);

      Esize := ImageSize(sX-10,sY-10,sX+10,sY+10);

      GetMem(pSn,Esize);

      GetImage(sX-10,sY-10,sX+10,sY+10,pSn^);

      PutImage(sX-10,sY-10,pSn^,XorPut);

       { яблоко }

      Repeat

        aX := {random(AMaxX-10)+10}50;

        aY := {random(AMaxY-10)+10}50;

      Until CorrectCoord;

       SetFillStyle(SolidFill,10);

      PieSlice(aX,aY,0,360,3);

      Asize := ImageSize(aX-3,aY-3,aX+3,aY+3);

      GetMem(pA,Asize);

      GetImage(aX-3,aY-3,aX+3,aY+3,pA^);

    End;

   destructor TSnake.Destroy;

    Var

      Tek,Tek2 : TElem;

    Begin

      Tek := First;

      If Tek = nil Then Exit;   { вдруг змеи нет }

       While Tek^.Next <> nil do

        Begin

          Tek2 := Tek^.Next;

          Dispose(Tek2);        { уничтожаем }

          Tek := Tek2;

        End;

      FreeMem(pSn,Esize);        { освобождаем память }

      FreeMem(pA,Asize);

    End;

   function TSnake.CorrectCoord: boolean;

    Var Tek : TElem;

    Begin

      Tek := First;

      If Tek=nil then Exit;

       While Tek^.Next<>nil do

        Begin

          If (Tek^.X = aX) and (Tek^.Y = aY) Then

            Begin

              CorrectCoord := false;

              Exit;

            End;

          Tek := Tek^.Next;

        End;

       CorrectCoord := true;

    End;

   procedure TSnake.DrawApple;

     Begin

       PutImage(aX-3,aY-3,pA^,XorPut);

     End;

   procedure TSnake.NewApple;

    Begin

      Repeat

        aX := random(AMaxX-10)+10;

        aY := random(AMaxY-10)+10;

      Until CorrectCoord;

    End;

   function TSnake.EatApple : boolean;

    Begin

      If (First^.X in [aX-8..aX+8]) and (First^.Y in [aY-8..aY+8]) Then

        Begin

          EatApple := true;

          Exit;

        End;

       EatApple := false;

    End;

   function TSnake.Snack : boolean;

    Var

      x,y : word;

      Tek : TElem;

    Begin

      x := First^.X; y := First^.Y;

       Tek := First^.Next;

      While Tek <> nil do

        Begin

          If (x = Tek^.X) and (y = Tek^.Y) Then

            Begin

              Snack := true;

              exit;

            End;

          Tek := Tek^.Next;

        End;

       Snack := false;

    End;

   procedure TSnake.DrawElement(Elem:TElem);

    Begin

      PutImage(Elem^.X-10,Elem^.Y-10,pSn^,NormalPut);

    End;

   procedure TSnake.Draw;

    Var Tek:TElem;

    Begin

      Tek:=First;

      If Tek=nil Then Exit;

      DrawElement(Tek);

      While Tek^.Next<>nil do

        Begin

          Tek:= Tek^.Next;

          DrawElement(Tek);

        End;

    End;

   procedure TSnake.ClearElement(Elem:TElem);

    Begin

      PutImage(Elem^.X-10,Elem^.Y-10,pSn^,XorPut);

    End;

   procedure TSnake.Clear;

    Var Tek:TElem;

    Begin

      Tek:=First;

      If Tek=nil Then Exit;

      ClearElement(Tek);

      While Tek^.Next<>nil do

        Begin

          Tek:= Tek^.Next;

          ClearElement(Tek);

        End;

    End;

   procedure TSnake.Move(newX,NewY:integer);

    Var Tek,TEk2 : TElem;

    Begin

      If First=nil Then Exit;

      tek := First;

       If newX>AMaxX Then newX:=1;

      If newX<1 Then newX:=AMaxX;

      If newY>AMaxY Then newY:=1;

      If newY<1 Then newY:=AMaxY;

       While Tek^.Prev <> nil do

        Begin

          Tek2 := Tek^.Next;

          Tek^.X := Tek2^.X;

          Tek^.Y := Tek2^.Y;

          Tek := tek2;

        End;

       First^.X := newX;

      First^.Y := NewY;

       {ClearDevice;}

      If EatApple Then

        Begin

          Add;

          NewApple; DrawApple;

        End;

    End;

   procedure TSnake.SetDirection(sDirection:TDir);

    Begin

      If (sDirection=1) and (Direction=3) Then exit;

      If (sDirection=3) and (Direction=1) Then exit;

      If (sDirection=2) and (Direction=4) Then exit;

      If (sDirection=4) and (Direction=2) Then exit;

       Direction := sDirection;

    End;

   procedure TSnake.Add;

    Var Tek : TElem;

    Begin

      new(Tek);

      Tek^.X := 0;              { координаты можно ставить любые, }

      Tek^.Y := 0;              { все равно при движении все восстановится как надо }

      Tek^.Next := nil;

      Tek^.Prev := Last;

      Tek^.Num := Last^.Num+1;

      Last^.Next := tek;

       Inc(length);

       Last := Tek;

     End;

   procedure TSnake.Remove;

    Var Tek : TElem;

    Begin

      If Last=First Then Exit;

       Tek := Last;

      Last := Tek^.Prev;

      Last^.Next := nil;

      Dispose(Tek);

       Inc(length,-1);

    End;

   Var

   ch : char;

   Snake : TSnake;

   procedure GraphInterface;

    Var

      Driver, Mode, Error : integer;

    Begin

      Driver := Detect;

      InitGraph(Driver,Mode,'BGI\');

      Error := GraphResult;

      If Error <> GrOk Then

        Begin

          Writeln(GraphErrorMsg(Error));

          Readkey;

          Halt(Error);

        End;

    End;

 BEGIN

  ClrScr;

    GraphInterface;

    Snake.AMaxX := GetMaxX; Snake.AMaxY := GetMaxY;

    Snake.Create(1,5,15,15,0);

    Snake.Draw;

    Repeat

      If not Keypressed Then

        Begin

          Snake.Clear;

          Case Snake.Direction of

            1 : Snake.Move(Snake.First^.X+14,Snake.First^.Y);

            2 : Snake.Move(Snake.First^.X,Snake.First^.Y+14);

            3 : Snake.Move(Snake.First^.X-14,Snake.First^.Y);

            4 : Snake.Move(Snake.First^.X,Snake.First^.Y-14);

          End;

          Snake.Draw;

        End

      Else

        Begin

          ch := Readkey;

          If ch=#0 Then ch := Readkey;

          Case ch of

            #72 : Snake.SetDirection(4);  { вверх }

            #77 : Snake.SetDirection(1);  { вправо }

            #75 : Snake.SetDirection(3);  { влево }

            #80 : Snake.SetDirection(2);  { вниз}

            #32 : Snake.Remove;

            #13 : Snake.Add;

            #27 : Exit;

          End;

        End;

      Delay(500);

    until false;

    Snake.destroy;

  Readkey;

END.

 

doc
До підручника
Інформатика (рівень стандарту) 10 клас (Морзе Н.В., Вембер В.П., Кузьмінська О.Г.)
Додано
20 вересня 2019
Переглядів
1348
Оцінка розробки
Відгуки відсутні
Безкоштовний сертифікат
про публікацію авторської розробки
Щоб отримати, додайте розробку

Додати розробку