package Directions is
pragma Pure;
subtype Axis_Direction is Integer range -1..1;
type Direction_Type is
record
x, y : Axis_Direction;
end record;
type Cardinal_Direction is (Left, Right, Up, Down);
type Direction_8 is (D8_Left, D8_Right, D8_Up, D8_Down,
D8_Up_Left, D8_Up_Right, D8_Down_Left, D8_Down_Right);
type Direction_Booleans is array (Cardinal_Direction) of Boolean;
function "+"( l : Direction_Type; r : Cardinal_Direction ) return Direction_Type;
function "-"( l : Direction_Type; r : Cardinal_Direction ) return Direction_Type;
function "and"( l : Direction_Type; r : Cardinal_Direction ) return Boolean;
function To_D8( dir : Direction_Type ) return Direction_8;
pragma Precondition( dir.x /= 0 or else dir.y /= 0 );
function To_D8( dir : Cardinal_Direction ) return Direction_8;
function To_X( dir : Direction_Type ) return Direction_8;
function To_Y( dir : Direction_Type ) return Direction_8;
function To_Y( dir : Direction_Type ) return Cardinal_Direction;
function "not"( db : Direction_Booleans ) return Boolean;
function Opposite( dir : Cardinal_Direction ) return Cardinal_Direction;
function To_Direction( dir : Cardinal_Direction ) return Direction_Type;
Dir_Left : constant Direction_Type;
Dir_Right : constant Direction_Type;
Dir_Up : constant Direction_Type;
Dir_Down : constant Direction_Type;
Dir_Up_Left : constant Direction_Type;
Dir_Up_Right : constant Direction_Type;
Dir_Down_Left : constant Direction_Type;
Dir_Down_Right : constant Direction_Type;
private
Dir_Left : constant Direction_Type := (x => -1, y => 0);
Dir_Right : constant Direction_Type := (x => 1, y => 0);
Dir_Up : constant Direction_Type := (x => 0, y => -1);
Dir_Down : constant Direction_Type := (x => 0, y => 1);
Dir_Up_Left : constant Direction_Type := (x => -1, y => -1);
Dir_Up_Right : constant Direction_Type := (x => 1, y => -1);
Dir_Down_Left : constant Direction_Type := (x => -1, y => 1);
Dir_Down_Right : constant Direction_Type := (x => 1, y => 1);
end Directions;