Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- program SnakeGame;
- uses crt;
- const
- DelayDuration = 100;
- TRIESNUM = 128;
- MAXHEIGHT = 40;
- MAXWIDTH = 60;
- type
- Direction = (up, down, left, right, stop);
- segment = ^star;
- star = record CurX, CurY: integer; next: segment; trend: Direction; end;
- AppleStatus = (eated, untouched);
- fruit = record CurX, CurY: integer; status: AppleStatus; end;
- papple = ^fruit;
- borders = record zeroX, endX, zeroY, endY: integer; end;
- procedure DrawBorder(var b: borders);
- var i: integer;
- begin
- TextColor(white);
- for i := 1 to MAXWIDTH do begin GotoXY(i + b.zeroX, b.zeroY); write('_'); end;
- b.endX := i + b.zeroX;
- for i := 1 to MAXHEIGHT do begin GotoXY(b.endX, b.zeroY + i); write('|'); end;
- b.endY := i + b.zeroY - 1;
- for i := 1 to MAXWIDTH do begin GotoXY(b.endX - i, b.endY); write('_'); end;
- for i := 0 to MAXHEIGHT do begin GotoXY(b.zeroX, b.endY - i); write('|'); end;
- GotoXY(1,1);
- end;
- procedure Show(s: segment); begin GotoXY(s^.CurX, s^.CurY); TextColor(Green); write('*'); GotoXY(1,1); end;
- procedure Hide(s: segment); begin GotoXY(s^.CurX, s^.CurY); write(' '); GotoXY(1,1); end;
- procedure Grow(var t: segment);
- var i: integer;
- begin
- for i := 1 to 2 do begin
- new(t^.next); t := t^.next; t^.next := nil;
- end;
- end;
- procedure SelfBite(s: segment);
- var p: segment;
- begin
- p := s^.next;
- while p <> nil do begin
- if (s^.CurX = p^.CurX) and (s^.CurY = p^.CurY) then begin writeln('Bit yourself!'); halt(1); end;
- p := p^.next;
- end;
- end;
- function IsFree(x, y: integer; s: segment): boolean;
- begin
- while s <> nil do begin
- if (s^.CurX = x) and (s^.CurY = y) then exit(false);
- s := s^.next;
- end;
- IsFree := true;
- end;
- procedure PlaceApple(var a: papple; x, y: integer);
- begin
- a^.CurX := x; a^.CurY := y; a^.status := untouched;
- GotoXY(x, y); TextColor(Red); write('@'); GotoXY(1,1);
- end;
- procedure SpawnApple(var a: papple; s: segment; b: borders);
- var x, y, dx, dy, i, pdx, tmpx, tmpy, sign: integer;
- begin
- Randomize; x := random(b.endX - b.zeroX - 2) + b.zeroX + 1;
- y := random(b.endY - b.zeroY - 2) + b.zeroY + 1;
- dx := 0; dy := 0; pdx := 0; sign := -1; i := 1;
- while abs(i) < TRIESNUM do begin
- while abs(dx) <= abs(pdx) do begin dx := dx + i; tmpx := x + dx; tmpy := y + dy;
- if IsFree(tmpx, tmpy, s) then begin PlaceApple(a, tmpx, tmpy); exit; end;
- end;
- while abs(dy) <= abs(dx) do begin dy := dy + i; tmpx := x + dx; tmpy := y + dy;
- if IsFree(tmpx, tmpy, s) then begin PlaceApple(a, tmpx, tmpy); exit; end;
- end;
- x := x + dx; y := y + dy; pdx := dx; i := i * sign; dx := 0; dy := 0;
- end;
- writeln('No space left!'); halt(1);
- end;
- function AteApple(s: segment; a: papple): boolean;
- begin
- AteApple := (s^.CurX = a^.CurX) and (s^.CurY = a^.CurY);
- end;
- procedure MoveBody(s, prev: segment);
- begin
- if s = nil then exit;
- Hide(s); MoveBody(s^.next, s);
- s^.CurX := prev^.CurX; s^.CurY := prev^.CurY; s^.trend := prev^.trend;
- Show(s);
- end;
- procedure CheckBorder(s: segment; b: borders);
- begin
- if (s^.CurX <= b.zeroX) or (s^.CurX >= b.endX) or (s^.CurY <= b.zeroY) or (s^.CurY >= b.endY) then begin
- writeln('Wall hit!'); halt(1);
- end;
- end;
- procedure MoveHead(h, t: segment; a: papple);
- begin
- Hide(h); if h^.next <> nil then MoveBody(h^.next, h);
- case h^.trend of
- left: dec(h^.CurX); right: inc(h^.CurX);
- up: dec(h^.CurY); down: inc(h^.CurY);
- end;
- Show(h);
- end;
- procedure HandleInput(var h: segment; c: char);
- begin
- case c of
- #75: if h^.trend <> right then h^.trend := left;
- #77: if h^.trend <> left then h^.trend := right;
- #72: if h^.trend <> down then h^.trend := up;
- #80: if h^.trend <> up then h^.trend := down;
- ' ': h^.trend := stop;
- end;
- end;
- procedure ShowScore(var s: integer);
- begin
- inc(s); TextColor(white);
- GotoXY(2, ScreenHeight div 2); write('SCORE: ', s);
- GotoXY(1,1);
- end;
- var ch: char; head, tail: segment; apple: papple; box: borders; score: integer;
- begin
- clrscr;
- box.zeroY := (ScreenHeight div 2) - (MAXHEIGHT div 2);
- box.zeroX := (ScreenWidth div 2) - (MAXWIDTH div 2);
- new(head); tail := head; head^.CurX := ScreenWidth div 2; head^.CurY := ScreenHeight div 2;
- head^.trend := stop; head^.next := nil;
- new(apple); apple^.status := eated; apple^.CurX := 0; apple^.CurY := 0;
- score := -1;
- DrawBorder(box); ShowScore(score); Show(head); SpawnApple(apple, head, box);
- while true do begin
- if not KeyPressed then begin
- if head^.trend <> stop then begin
- MoveHead(head, tail, apple);
- CheckBorder(head, box); SelfBite(head);
- if AteApple(head, apple) then begin
- Grow(tail); ShowScore(score); SpawnApple(apple, head, box);
- end;
- end;
- delay(DelayDuration); continue;
- end;
- ch := ReadKey;
- if ch = #0 then HandleInput(head, ReadKey)
- else if ch = #27 then break;
- end;
- clrscr; TextColor(LightGray);
- end.
Advertisement
Add Comment
Please, Sign In to add comment