Guest User

Untitled

a guest
Apr 3rd, 2025
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.91 KB | Source Code | 0 0
  1. program SnakeGame;
  2. uses crt;
  3. const
  4. DelayDuration = 100;
  5. TRIESNUM = 128;
  6. MAXHEIGHT = 40;
  7. MAXWIDTH = 60;
  8. type
  9. Direction = (up, down, left, right, stop);
  10. segment = ^star;
  11. star = record CurX, CurY: integer; next: segment; trend: Direction; end;
  12. AppleStatus = (eated, untouched);
  13. fruit = record CurX, CurY: integer; status: AppleStatus; end;
  14. papple = ^fruit;
  15. borders = record zeroX, endX, zeroY, endY: integer; end;
  16.  
  17. procedure DrawBorder(var b: borders);
  18. var i: integer;
  19. begin
  20. TextColor(white);
  21. for i := 1 to MAXWIDTH do begin GotoXY(i + b.zeroX, b.zeroY); write('_'); end;
  22. b.endX := i + b.zeroX;
  23. for i := 1 to MAXHEIGHT do begin GotoXY(b.endX, b.zeroY + i); write('|'); end;
  24. b.endY := i + b.zeroY - 1;
  25. for i := 1 to MAXWIDTH do begin GotoXY(b.endX - i, b.endY); write('_'); end;
  26. for i := 0 to MAXHEIGHT do begin GotoXY(b.zeroX, b.endY - i); write('|'); end;
  27. GotoXY(1,1);
  28. end;
  29.  
  30. procedure Show(s: segment); begin GotoXY(s^.CurX, s^.CurY); TextColor(Green); write('*'); GotoXY(1,1); end;
  31. procedure Hide(s: segment); begin GotoXY(s^.CurX, s^.CurY); write(' '); GotoXY(1,1); end;
  32.  
  33. procedure Grow(var t: segment);
  34. var i: integer;
  35. begin
  36. for i := 1 to 2 do begin
  37. new(t^.next); t := t^.next; t^.next := nil;
  38. end;
  39. end;
  40.  
  41. procedure SelfBite(s: segment);
  42. var p: segment;
  43. begin
  44. p := s^.next;
  45. while p <> nil do begin
  46. if (s^.CurX = p^.CurX) and (s^.CurY = p^.CurY) then begin writeln('Bit yourself!'); halt(1); end;
  47. p := p^.next;
  48. end;
  49. end;
  50.  
  51. function IsFree(x, y: integer; s: segment): boolean;
  52. begin
  53. while s <> nil do begin
  54. if (s^.CurX = x) and (s^.CurY = y) then exit(false);
  55. s := s^.next;
  56. end;
  57. IsFree := true;
  58. end;
  59.  
  60. procedure PlaceApple(var a: papple; x, y: integer);
  61. begin
  62. a^.CurX := x; a^.CurY := y; a^.status := untouched;
  63. GotoXY(x, y); TextColor(Red); write('@'); GotoXY(1,1);
  64. end;
  65.  
  66. procedure SpawnApple(var a: papple; s: segment; b: borders);
  67. var x, y, dx, dy, i, pdx, tmpx, tmpy, sign: integer;
  68. begin
  69. Randomize; x := random(b.endX - b.zeroX - 2) + b.zeroX + 1;
  70. y := random(b.endY - b.zeroY - 2) + b.zeroY + 1;
  71. dx := 0; dy := 0; pdx := 0; sign := -1; i := 1;
  72. while abs(i) < TRIESNUM do begin
  73. while abs(dx) <= abs(pdx) do begin dx := dx + i; tmpx := x + dx; tmpy := y + dy;
  74. if IsFree(tmpx, tmpy, s) then begin PlaceApple(a, tmpx, tmpy); exit; end;
  75. end;
  76. while abs(dy) <= abs(dx) do begin dy := dy + i; tmpx := x + dx; tmpy := y + dy;
  77. if IsFree(tmpx, tmpy, s) then begin PlaceApple(a, tmpx, tmpy); exit; end;
  78. end;
  79. x := x + dx; y := y + dy; pdx := dx; i := i * sign; dx := 0; dy := 0;
  80. end;
  81. writeln('No space left!'); halt(1);
  82. end;
  83.  
  84. function AteApple(s: segment; a: papple): boolean;
  85. begin
  86. AteApple := (s^.CurX = a^.CurX) and (s^.CurY = a^.CurY);
  87. end;
  88.  
  89. procedure MoveBody(s, prev: segment);
  90. begin
  91. if s = nil then exit;
  92. Hide(s); MoveBody(s^.next, s);
  93. s^.CurX := prev^.CurX; s^.CurY := prev^.CurY; s^.trend := prev^.trend;
  94. Show(s);
  95. end;
  96.  
  97. procedure CheckBorder(s: segment; b: borders);
  98. begin
  99. if (s^.CurX <= b.zeroX) or (s^.CurX >= b.endX) or (s^.CurY <= b.zeroY) or (s^.CurY >= b.endY) then begin
  100. writeln('Wall hit!'); halt(1);
  101. end;
  102. end;
  103.  
  104. procedure MoveHead(h, t: segment; a: papple);
  105. begin
  106. Hide(h); if h^.next <> nil then MoveBody(h^.next, h);
  107. case h^.trend of
  108. left: dec(h^.CurX); right: inc(h^.CurX);
  109. up: dec(h^.CurY); down: inc(h^.CurY);
  110. end;
  111. Show(h);
  112. end;
  113.  
  114. procedure HandleInput(var h: segment; c: char);
  115. begin
  116. case c of
  117. #75: if h^.trend <> right then h^.trend := left;
  118. #77: if h^.trend <> left then h^.trend := right;
  119. #72: if h^.trend <> down then h^.trend := up;
  120. #80: if h^.trend <> up then h^.trend := down;
  121. ' ': h^.trend := stop;
  122. end;
  123. end;
  124.  
  125. procedure ShowScore(var s: integer);
  126. begin
  127. inc(s); TextColor(white);
  128. GotoXY(2, ScreenHeight div 2); write('SCORE: ', s);
  129. GotoXY(1,1);
  130. end;
  131.  
  132. var ch: char; head, tail: segment; apple: papple; box: borders; score: integer;
  133. begin
  134. clrscr;
  135. box.zeroY := (ScreenHeight div 2) - (MAXHEIGHT div 2);
  136. box.zeroX := (ScreenWidth div 2) - (MAXWIDTH div 2);
  137. new(head); tail := head; head^.CurX := ScreenWidth div 2; head^.CurY := ScreenHeight div 2;
  138. head^.trend := stop; head^.next := nil;
  139. new(apple); apple^.status := eated; apple^.CurX := 0; apple^.CurY := 0;
  140. score := -1;
  141. DrawBorder(box); ShowScore(score); Show(head); SpawnApple(apple, head, box);
  142. while true do begin
  143. if not KeyPressed then begin
  144. if head^.trend <> stop then begin
  145. MoveHead(head, tail, apple);
  146. CheckBorder(head, box); SelfBite(head);
  147. if AteApple(head, apple) then begin
  148. Grow(tail); ShowScore(score); SpawnApple(apple, head, box);
  149. end;
  150. end;
  151. delay(DelayDuration); continue;
  152. end;
  153. ch := ReadKey;
  154. if ch = #0 then HandleInput(head, ReadKey)
  155. else if ch = #27 then break;
  156. end;
  157. clrscr; TextColor(LightGray);
  158. end.
  159.  
Tags: snakegame
Advertisement
Add Comment
Please, Sign In to add comment