
--
--  Implementation of the Creature.  In this case, it is a worm.
--  Charles Kann, The George Washington University
--

WITH Screen; USE Screen;
WITH Screen_IO; USE Screen_IO;
WITH Random; USE Random;
PACKAGE BODY Creatures IS

    Max_Length : CONSTANT POSITIVE :=6;
    SUBTYPE Length IS POSITIVE RANGE 1..Max_Length;
    TYPE Worm_Definition IS ARRAY(Length) of Coordinate;

--
--  New_Direction finds the new direction for the worm to move
--

    FUNCTION New_Direction RETURN INTEGER IS
        Direction : Integer;
    BEGIN
        Direction := Random.Random_Int(10);
        IF Direction > 5 THEN
            Direction := -1;
    ELSE
        Direction := 1;
        END IF;
        RETURN Direction;
    END New_Direction;

--
--  Move_Worm actually moves the worm 
--

    PROCEDURE Move_Worm( Worm_Position : IN OUT Worm_Definition;
                         Symbol : IN Character ) IS
      Temp: String(1..1) := (1 => Symbol);
    BEGIN

        Terminal.WriteAt( (Worm_Position(Max_Length).x, 
                          Worm_Position(Max_Length).y), " " );

        FOR I in REVERSE 2..Max_Length LOOP
            Worm_Position(I) := Worm_Position(I-1);
            Terminal.WriteAt( (Worm_Position(I).x, Worm_Position(I).y), 
                               Temp );
        END LOOP;

        Worm_Position(1).x := Worm_Position(1).x + New_Direction;
        IF Worm_Position(1).x < Minimum_xy.x THEN
            Worm_Position(1).x := Minimum_xy.x;
        END IF;
        IF Worm_Position(1).x > Maximum_xy.x THEN
            Worm_Position(1).x := Maximum_xy.x;
        END IF;

        Worm_Position(1).y := Worm_Position(1).y + New_Direction;
        IF Worm_Position(1).y < Minimum_xy.y THEN
            Worm_Position(1).y := Minimum_xy.y;
        END IF;
        IF Worm_Position(1).y > Maximum_xy.y THEN
            Worm_Position(1).y := Maximum_xy.y;
        END IF;

        Terminal.WriteAt( (Worm_Position(1).x, Worm_Position(1).y), 
                               Temp );
    END;

--
--  This is the body for the worm task.
--

    TASK BODY Worm IS
        Worm_Position : Worm_Definition;
        My_Symbol : Character;
    BEGIN
        --
    -- Initialize the symbol for the worm, and the position of the
    -- worm to the upper left hand corner.
    --
        ACCEPT Init_Worm( Symbol : IN Character ) DO
            My_Symbol := Symbol;
        END Init_Worm;
        FOR I in Length LOOP
            Worm_Position(I).x := 1;
            Worm_Position(I).y := 1;
        END LOOP;

        LOOP
            Move_Worm( Worm_Position, My_Symbol );
        END LOOP;
    END Worm;
END Creatures;
