1. -- 
  2. -- Copyright (c) 2012 Kevin Wellwood 
  3. -- All rights reserved. 
  4. -- 
  5. -- This source code is distributed under the Modified BSD License. For terms and 
  6. -- conditions, see license.txt. 
  7. -- 
  8.  
  9. package Directions is 
  10.  
  11.     pragma Pure; 
  12.  
  13.     subtype Axis_Direction is Integer range -1..1; 
  14.  
  15.     -- A record capable of expressing eight directions with x, y axis. It is 
  16.     -- useful because direction arithmetic can be performed on a Direction_Type. 
  17.     type Direction_Type is 
  18.         record 
  19.             x, y : Axis_Direction; 
  20.         end record; 
  21.  
  22.     -- Enumeration of the four cardinal directions. 
  23.     type Cardinal_Direction is (Left, Right, Up, Down); 
  24.  
  25.     -- Enumeration of eight directions at 45 degree angles. 
  26.     type Direction_8 is (D8_Left,    D8_Right,    D8_Up,        D8_Down, 
  27.                          D8_Up_Left, D8_Up_Right, D8_Down_Left, D8_Down_Right); 
  28.  
  29.     -- An array of Booleans indexed by cardinal direction. 
  30.     type Direction_Booleans is array (Cardinal_Direction) of Boolean; 
  31.  
  32.     ---------------------------------------------------------------------------- 
  33.  
  34.     -- Returns a combined direction. If the direction of 'r' is directly 
  35.     -- opposite the matching component of the 'l' direction, then 'r' will 
  36.     -- override the matching component of 'l' in the resultant direction. 
  37.     -- (ex: Dir_Left + Right = Dir_Right) 
  38.     function "+"( l : Direction_Type; r : Cardinal_Direction ) return Direction_Type; 
  39.  
  40.     -- Zeros the component of direction 'l' that matches 'r'. Note that the 
  41.     -- returned direction will have at least one non-zero component because a 
  42.     -- direction with no components is illegal. 
  43.     function "-"( l : Direction_Type; r : Cardinal_Direction ) return Direction_Type; 
  44.  
  45.     -- Returns true if cardinal direction 'r' is a component of direction 'l'. 
  46.     -- Example: "<Up+Right> and Up = True", "<Down+Right> and Up = False" 
  47.     function "and"( l : Direction_Type; r : Cardinal_Direction ) return Boolean; 
  48.  
  49.     -- Converts dir to a Direction_8 type. If dir doesn't have a component in 
  50.     -- any axis then a Constraint_Error is raised. 
  51.     function To_D8( dir : Direction_Type ) return Direction_8; 
  52.     pragma Precondition( dir.x /= 0 or else dir.y /= 0 ); 
  53.  
  54.     -- Converts dir to a Direction_8 type. 
  55.     function To_D8( dir : Cardinal_Direction ) return Direction_8; 
  56.  
  57.     -- Returns only the X component of dir as a Direction_8. If dir doesn't have 
  58.     -- an X component then Left is returned as a default. 
  59.     function To_X( dir : Direction_Type ) return Direction_8; 
  60.  
  61.     -- Returns only the Y component of dir as a Direction_8. If dir doesn't have 
  62.     -- any Y component then Up is returned as a default. 
  63.     function To_Y( dir : Direction_Type ) return Direction_8; 
  64.  
  65.     -- Returns only the Y component of dir as a cardinal direction. If dir 
  66.     -- doesn't have any Y component then Up is returned as a default. 
  67.     function To_Y( dir : Direction_Type ) return Cardinal_Direction; 
  68.  
  69.     -- Returns true if all of the Booleans in the array are False. 
  70.     function "not"( db : Direction_Booleans ) return Boolean; 
  71.  
  72.     -- Returns the opposite of the given direction. 
  73.     function Opposite( dir : Cardinal_Direction ) return Cardinal_Direction; 
  74.  
  75.     -- Converts a Cardinal_Direction to a general Direction_Type. 
  76.     function To_Direction( dir : Cardinal_Direction ) return Direction_Type; 
  77.  
  78.     -- Converts a Direction_8 to a general Direction_Type. 
  79.     function To_Direction( dir : Direction_8 ) return Direction_Type; 
  80.  
  81.     function To_String( dir : Direction_Type ) return String; 
  82.  
  83.     ---------------------------------------------------------------------------- 
  84.  
  85.     Dir_Left       : constant Direction_Type; 
  86.     Dir_Right      : constant Direction_Type; 
  87.     Dir_Up         : constant Direction_Type; 
  88.     Dir_Down       : constant Direction_Type; 
  89.     Dir_Up_Left    : constant Direction_Type; 
  90.     Dir_Up_Right   : constant Direction_Type; 
  91.     Dir_Down_Left  : constant Direction_Type; 
  92.     Dir_Down_Right : constant Direction_Type; 
  93.  
  94. private 
  95.  
  96.     Dir_Left       : constant Direction_Type := (x => -1, y =>  0); 
  97.     Dir_Right      : constant Direction_Type := (x =>  1, y =>  0); 
  98.     Dir_Up         : constant Direction_Type := (x =>  0, y => -1); 
  99.     Dir_Down       : constant Direction_Type := (x =>  0, y =>  1); 
  100.     Dir_Up_Left    : constant Direction_Type := (x => -1, y => -1); 
  101.     Dir_Up_Right   : constant Direction_Type := (x =>  1, y => -1); 
  102.     Dir_Down_Left  : constant Direction_Type := (x => -1, y =>  1); 
  103.     Dir_Down_Right : constant Direction_Type := (x =>  1, y =>  1); 
  104.  
  105. end Directions;