Snake: Difference between revisions

9,476 bytes added ,  2 years ago
no edit summary
No edit summary
Line 13:
The game ends when the snake attempts to eat himself.
<br><br>
 
=={{header|Ada}}==
<lang Ada>
-- This code is a basic implementation of snake in Ada using the command prompt
-- feel free to improve it!
 
-- Snake.ads
with Ada.Containers; use Ada.Containers;
with Ada.Containers.Vectors;
 
package Snake is
-- copy from 2048 game (
-- Keyboard management
type directions is (Up, Down, Right, Left, Quit, Restart, Invalid);
-- Redefining this standard procedure as function to allow Get_Keystroke as an expression function
function Get_Immediate return Character;
 
Arrow_Prefix : constant Character := Character'Val(224); -- works for windows
 
function Get_Keystroke return directions;
-- )
-- The container for game data
type gameBoard is array (Natural range <>, Natural range <>) of Character;
-- Initilize the board
procedure init;
-- Run the game
procedure run;
-- Displaying the board
procedure Display_Board;
-- Clear the board from content
procedure ClearBoard;
-- coordinates data structure
type coord is tagged record
X,Y : Integer;
end record;
 
-- list of coordinate (one coordinate for each body part of the snake)
package snakeBody is new Ada.Containers.Vectors (Natural, coord);
use snakeBody;
-- update snake's part depending on the snakeDirection and checking colicion (with borders and snak's part)
function moveSnake return Boolean;
-- generate food if it was eaten
procedure generateFood;
-- Add snake and food to the board
procedure addDataToBoard;
-- generate random integer between 1 and upperBound to generate random food position
function getRandomInteger(upperBound : Integer) return Integer;
private
width, height : Positive := 10;
board : gameBoard := (0 .. (width+1) => (0 .. (height+1) => ' '));
snake : Vector := (1,1) & (2,1) & (3,1);
snakeDirection : directions := Right;
food : coord := (5,5);
 
end Snake;
 
 
-- Snake.adb
 
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Discrete_Random;
 
package body Snake is
-----------------------------------------------------------------------------
-- Redefining this standard procedure as function to allow Get_Keystroke as an expression function (copy from 2048 game)
function Get_Immediate return Character is
begin
return Answer : Character do Ada.Text_IO.Get_Immediate(Answer);
end return;
end Get_Immediate;
 
-----------------------------------------------------------------------------
-- (copy from 2048 game)
function Get_Keystroke return directions is
(case Get_Immediate is
when 'Q' | 'q' => Quit,
when 'R' | 'r' => Restart,
when 'W' | 'w' => Left,
when 'A' | 'a' => Up,
when 'S' | 's' => Down,
when 'D' | 'd' => Right,
-- Windows terminal
when Arrow_Prefix => (case Character'Pos(Get_Immediate) is
when 72 => Up,
when 75 => Left,
when 77 => Right,
when 80 => Down,
when others => Invalid),
-- Unix escape sequences
when ASCII.ESC => (case Get_Immediate is
when '[' => (case Get_Immediate is
when 'A' => Up,
when 'B' => Down,
when 'C' => Right,
when 'D' => Left,
when others => Invalid),
when others => Invalid),
when others => Invalid);
-----------------------------------------------------------------------------
procedure init is
begin
for Row in 0 .. width+1 loop
for Column in 0 .. height+1 loop
if Row = 0 or Row = width+1 then
board(Row,Column) := '#';
-- Insert(board(Row,0), Column, '#');
else
if Column = 0 or Column = height+1 then
board(Row,Column) := '#';
-- Insert(board, board(Row, Column), "#");
else
board(Row,Column) := ' ';
-- Insert(board, board(Row, Column), " ");
end if;
end if;
end loop;
end loop;
end;
 
-----------------------------------------------------------------------------
procedure run is
task T;
task body T is
begin
loop
snakeDirection := Get_Keystroke;
end loop;
end T;
begin
init;
loop
exit when snakeDirection = Quit;
if moveSnake = False then
Put_Line("GAME OVER!!!");
Put_Line("Your score is:" & Length(snake)'Image);
exit;
end if;
Display_Board;
delay 0.7;
end loop;
end run;
-----------------------------------------------------------------------------
procedure Display_Board is
begin
for Row in 0 .. width+1 loop
for Column in 0 .. height+1 loop
Put(board(Row, Column));
end loop;
New_Line;
end loop;
end Display_Board;
-----------------------------------------------------------------------------
procedure ClearBoard is
begin
for Row in 1 .. width loop
for Column in 1 .. height loop
board(Row, Column) := ' ';
end loop;
end loop;
end ClearBoard;
-----------------------------------------------------------------------------
function moveSnake return Boolean is
colision : Boolean := False;
headCoord : coord := Snake.First_Element;
addSnakePart : Boolean := False;
begin
case snakeDirection is
when Up => headCoord.X := headCoord.X - 1;
when Down => headCoord.X := headCoord.X + 1;
when Right => headCoord.Y := headCoord.Y + 1;
when Left => headCoord.Y := headCoord.Y - 1;
when others => null;
end case;
if headCoord.Y = height+1 then
return False;
end if;
if headCoord.Y = 0 then
return False;
end if;
if headCoord.X = width+1 then
return False;
end if;
if headCoord.X = 0 then
return False;
end if;
for index in snake.Iterate loop
if headCoord = snake(To_Index(index)) then
return False;
end if;
end loop;
 
snake.Prepend(headCoord);
if headCoord /= food then
snake.Delete_Last;
else
food := (0,0);
generateFood;
end if;
addDataToBoard;
 
return True;
end moveSnake;
-----------------------------------------------------------------------------
procedure generateFood is
begin
if food.X = 0 or food.Y = 0 then
food := (getRandomInteger(width), getRandomInteger(height));
end if;
end generateFood;
-----------------------------------------------------------------------------
procedure addDataToBoard is
begin
ClearBoard;
board(food.X, food.Y) := '*';
for index in snake.Iterate loop
board(snake(To_Index(index)).X, snake(To_Index(index)).Y) := 'o';
end loop;
end addDataToBoard;
 
-----------------------------------------------------------------------------
function getRandomInteger(upperBound : Integer) return Integer is
 
subtype Random_Range is Integer range 1 .. upperBound;
 
package R is new
Ada.Numerics.Discrete_Random (Random_Range);
use R;
 
G : Generator;
begin
Reset (G);
return Random (G);
end getRandomInteger;
 
end Snake;
 
 
-- main.adb
 
with Snake;
 
procedure Main is
begin
Snake.run;
end;
</lang>
 
{{out}}
<pre>
############
# #
# #
# ooo #
# o #
# o #
# o #
# o #
# o #
# * #
# #
############
</pre>
 
 
Anonymous user