home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / PASGAMES.ZIP / SNAKE.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1985-10-07  |  7.0 KB  |  318 lines

  1. program snake;
  2.  
  3. const
  4.    playerchar    = 'I';
  5.    snakechar     = 'S';
  6.    moneychar     = '$';
  7.    doorchar      = '#';
  8.  
  9.    upcommand     = 'U';
  10.    downcommand   = 'N';
  11.    leftcommand   = 'H';
  12.    rightcommand  = 'J';
  13.  
  14.    snakelength   =  5;
  15.    height        = 23;
  16.    width         = 39;
  17.    clearscreen   = 26;
  18.    moneyworth    = 25;
  19.  
  20. type
  21.    coordinate = record
  22.       x : integer;
  23.       y : integer;
  24.       end;
  25.    snaketype = array[1..snakelength] of coordinate;
  26.    thing = (playerthing, snakething, moneything, doorthing, emptything, scorething);
  27.  
  28. var
  29.    snake : snaketype;
  30.    player, money, door : coordinate;
  31.    score : integer;
  32.    left, eaten : boolean;
  33.  
  34.    screen : array[0..width] of array[0..height] of thing;
  35.  
  36.    lookslike : array[thing] of char;
  37.  
  38. (*
  39.  * returns a random integer between min and max
  40.  *)
  41.  
  42. function rand(min, max: integer) : integer;
  43.  
  44. begin
  45.    rand := min + random(max-min+1);
  46. end;
  47.  
  48. procedure instructions;
  49.  
  50. var
  51.    answer : char;
  52.  
  53. begin
  54.    write('Do you want instructions? ');
  55.    readln(answer);
  56.    while not (answer in ['y','n','Y','N']) do
  57.       begin
  58.       writeln('Please enter ''Yes'' or ''No''.');
  59.       readln(answer);
  60.       end;
  61.    if (answer = 'y') or (answer = 'Y') then
  62.       begin
  63.       writeln;
  64.       writeln('The object of SNAKE is to get as much money to the door as possible.');
  65.       writeln('The snake tries to prevent you. As you get more money, he tries');
  66.       writeln('more and more successfully. You move up, down, left and right');
  67.       writeln('by typing U, N, H and J respectively. You cannot move diagonally');
  68.       writeln('though the snake can.');
  69.       writeln;
  70.       write('Type return to continue ');
  71.       readln(answer);
  72.       end;
  73. end;
  74.  
  75. (*
  76.  * sets up all the variables
  77.  *)
  78.  
  79. procedure initialize;
  80.  
  81. var
  82.    x, y : integer;
  83.  
  84. begin
  85.    CLRSCR;
  86.    instructions;
  87.    for x := 0 to width do
  88.       for y := 0 to height do
  89.          screen[x][y] := emptything;
  90.    randomize;
  91.    lookslike[snakething] := snakechar;
  92.    lookslike[playerthing] := playerchar;
  93.    lookslike[moneything] := moneychar;
  94.    lookslike[emptything] := ' ';
  95.    lookslike[doorthing] := doorchar;
  96.    left := false;
  97.    eaten := false;
  98.    score := 0;
  99.    for x := 0 to 10 do
  100.       screen[x, 0] := scorething;
  101.    write(chr(clearscreen));
  102. end;
  103.  
  104. (*
  105.  * returns true if the position is valid and empty
  106.  *)
  107.  
  108. function freespot(pos : coordinate) : boolean;
  109.  
  110. begin
  111.    if (pos.x in [0..width]) and (pos.y in [0..height]) then
  112.       freespot := screen[pos.x, pos.y] = emptything
  113.    else freespot := false;
  114. end;
  115.  
  116. (*
  117.  * assigns the coordinates of a position on the screen that is not being used
  118.  *)
  119.  
  120. procedure makespace(var newpos : coordinate; forwhat : thing);
  121.  
  122. begin
  123.    with newpos do
  124.       begin
  125.          repeat
  126.             x := rand(0, width - 1);
  127.             y := rand(0, height - 1);
  128.          until freespot(newpos);
  129.          gotoxy(x, y);
  130.          write(lookslike[forwhat]);
  131.          screen[x, y] := forwhat;
  132.       end;
  133. end;
  134.  
  135. (*
  136.  * placenearby finds a free coordinate adjacent to the argument coordinate
  137.  * and places the thing there.
  138.  *)
  139.  
  140. procedure placenearby(var near, coord : coordinate);
  141.  
  142. var
  143.    deltax, deltay : integer;
  144.  
  145. begin
  146.    repeat
  147.       repeat
  148.          deltax := rand(-1, 1);
  149.          deltay := rand(-1, 1);
  150.       until (deltax <> 0) or (deltay <> 0);
  151.       near.x := coord.x + deltax;
  152.       near.y := coord.y + deltay;
  153.    until (freespot(near) or ((near.x = player.x) and (near.y = player.y)));
  154.    gotoxy(near.x,near.y);
  155.    screen[near.x, near.y] := snakething;
  156.    write(lookslike[snakething]);
  157. end;
  158.  
  159. (*
  160.  * removes whatever is at the coordinates from the terminal screen
  161.  * and the array screen.
  162.  *)
  163.  
  164. procedure remove(pos : coordinate);
  165.  
  166. begin
  167.    gotoxy(pos.x, pos.y);
  168.    write(' ');
  169.    screen[pos.x, pos.y] := emptything;
  170. end;
  171.  
  172. procedure takegold;
  173.  
  174. begin
  175.    score := score + moneyworth;
  176.    gotoxy(0,0);
  177.    write('$',score);
  178.    screen[money.x, money.y] := emptything;
  179.    makespace(money, moneything);
  180. end;
  181.  
  182. (*
  183.  * position all of the items in the game making sure that none of them
  184.  * overlap.
  185.  *)
  186.  
  187. procedure placeobjects;
  188.  
  189. var
  190.    snakebody : integer;
  191.  
  192. begin
  193.    makespace(snake[1], snakething);
  194.    for snakebody := 2 to snakelength do
  195.       placenearby(snake[snakebody], snake[snakebody - 1]);
  196.    makespace(player, playerthing);
  197.    makespace(money, moneything);
  198.    makespace(door, doorthing);
  199. end;
  200.  
  201. (*
  202.  * read the player's move from the keyboard, not input so that the letter
  203.  * will not be echoed and mess up the display.
  204.  *)
  205.  
  206. procedure playermove;
  207.  
  208. var
  209.    command : char;
  210.    oldpos  : coordinate;
  211.  
  212. begin
  213.    oldpos := player;
  214.    read(kbd, command);
  215.    with player do
  216.       begin
  217.       case command of
  218.          upcommand : if y > 0 then y := y - 1;
  219.          downcommand : if y < height then y := y + 1;
  220.          leftcommand : if x > 0 then x := x - 1;
  221.          rightcommand : if x < width then x := x + 1;
  222.       end;
  223.       if screen[x, y] = scorething then
  224.          player := oldpos
  225.       else
  226.          begin
  227.          remove(oldpos);
  228.          if (player.x = money.x) and (player.y = money.y) then
  229.             takegold
  230.          else if (player.x = door.x) and (player.y = door.y) then
  231.             left := true;
  232.          gotoxy(x, y);
  233.          write(playerchar);
  234.          screen[x, y] := playerthing;
  235.          end;
  236.       end;
  237. end;
  238.  
  239. (*
  240.  * used by snakemove to figure out which way is the direction
  241.  * toward the player
  242.  *)
  243.  
  244. function sign(x : integer) : integer;
  245.  
  246. begin
  247.    if x = 0 then
  248.       sign := 0
  249.    else if x > 0 then
  250.       sign := 1
  251.    else
  252.       sign := -1;
  253. end;
  254.  
  255. (*
  256.  * snake moves randomly at first, then it goes more directly toward
  257.  * the player
  258.  *)
  259.  
  260. procedure snakemove;
  261.  
  262. var
  263.    newpos : coordinate;
  264.    bodypart : integer;
  265.  
  266. begin
  267.    if rand(0, score) <= 100 then
  268.       placenearby(newpos, snake[1])
  269.    else
  270.       begin
  271.       newpos.x := snake[1].x + sign(player.x - snake[1].x);
  272.       newpos.y := snake[1].y + sign(player.y - snake[1].y);
  273.       if (screen[newpos.x, newpos.y] = emptything) or
  274.          ((newpos.x = player.x) and (newpos.y = player.y)) then
  275.          begin
  276.          gotoxy(newpos.x, newpos.y);
  277.          write(snakechar);
  278.          screen[newpos.x, newpos.y] := snakething;
  279.          end
  280.       else
  281.          placenearby(newpos, snake[1]);
  282.       end;
  283.    remove(snake[snakelength]);
  284.    if (newpos.x = player.x) and (newpos.y = player.y) then
  285.       eaten := true;
  286.    for bodypart := snakelength downto 2 do
  287.       begin
  288.       snake[bodypart] := snake[bodypart - 1];
  289.       if (snake[bodypart].x = player.x) and (snake[bodypart].y = player.y) then
  290.          eaten := true;
  291.       end;
  292.    snake[1] := newpos;
  293. end;
  294.  
  295.  
  296. begin
  297.    initialize;
  298.    CLRSCR;
  299.    placeobjects;
  300.    repeat
  301.       playermove;
  302.       if not left then
  303.          snakemove;
  304.    until left or eaten;
  305.    gotoxy(0, height);
  306.    writeln;
  307.    if left then
  308.       writeln('You hace escaped with $',score)
  309.    else
  310.       writeln('The snake has eaten you.');
  311. end.
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.