# publicclanehin/roguestar

### Subversion checkout URL

You can clone with HTTPS or Subversion.

Fetching contributors…

Cannot retrieve contributors at this time

file 104 lines (96 sloc) 3.42 kb
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 `{-# LANGUAGE OverloadedStrings #-}module Roguestar.Lib.Facing    (Facing(..),     facingToRelative,     facingToRelative7,     stringToFacing,     facingDistance,     isFacing,     faceAt)    whereimport Roguestar.Lib.Positionimport Data.Ordimport Data.Listimport qualified Data.ByteString.Char8 as Bdata Facing = North | NorthEast | East | SouthEast | South | SouthWest | West | NorthWest | Here deriving (Eq,Ord,Enum,Bounded,Read,Show)-- |-- Takes an abbreviation (n,e,sw, etc) and answers a facing.-- The input string must be lower case.-- No form of "Here" is an acceptable input to this function.--stringToFacing :: B.ByteString -> Maybe FacingstringToFacing "n" = Just NorthstringToFacing "ne" = Just NorthEaststringToFacing "e" = Just EaststringToFacing "se" = Just SouthEaststringToFacing "s" = Just SouthstringToFacing "sw" = Just SouthWeststringToFacing "w" = Just WeststringToFacing "nw" = Just NorthWeststringToFacing _ = Nothing-- |-- In relative coordinates, one integral step in the specified direction.--facingToRelative :: Facing -> (Integer,Integer)facingToRelative North = (0,1)facingToRelative NorthEast = (1,1)facingToRelative East = (1,0)facingToRelative SouthEast = (1,-1)facingToRelative South = (0,-1)facingToRelative SouthWest = (-1,-1)facingToRelative West = (-1,0)facingToRelative NorthWest = (-1,1)facingToRelative Here = (0,0)-- |-- In relative coordinates, roughly seven integral steps in the specified direction.--facingToRelative7 :: Facing -> (Integer,Integer)facingToRelative7 North = (0,7)facingToRelative7 NorthEast = (5,5)facingToRelative7 East = (7,0)facingToRelative7 SouthEast = (5,-5)facingToRelative7 South = (0,-7)facingToRelative7 SouthWest = (-5,-5)facingToRelative7 West = (-7,0)facingToRelative7 NorthWest = (-5,5)facingToRelative7 Here = (0,0)-- |-- The distance between two facings, between 0 and 4.--facingDistance :: Facing -> Facing -> IntegerfacingDistance Here _ = 0facingDistance _ Here = 0facingDistance a b = toInteger \$ if enum_distance > 4 then 8 - enum_distance else enum_distance    where enum_distance = abs \$ fromEnum a - fromEnum b-- |-- A test function to detect when one Position + Facing points directly at another Position.--isFacing :: (PositionType a,PositionType b) => (a, Facing) -> b -> BoolisFacing (as,face) bs = or \$ map (\(a,b) -> f face (fromPosition a) (fromPosition b)) \$ positionPairs as bs    where f :: Facing -> (Integer,Integer) -> (Integer,Integer) -> Bool          f North (x,y) (u,v) = x == u && v >= y          f NorthEast (x,y) (u,v) = x - u == y - v && u >= x          f East (x,y) (u,v) = y == v && u >= x          f SouthEast (x,y) (u,v) = x - u == v - y && u >= x          f South (x,y) (u,v) = x == u && v <= y          f SouthWest (x,y) (u,v) = x - u == y - v && u <= x          f West (x,y) (u,v) = y == v && u <= x          f NorthWest (x,y) (u,v) = x - y == v - y && u <= x          f Here xy uv = xy == uv-- |-- Which facing most closely points from the first Position to the second.--faceAt :: Position -> Position -> FacingfaceAt here there = fst \$ minimumBy (comparing snd) \$    map (\x -> let face = Position \$ facingToRelative7 x in                      (x,distanceBetweenSquared there face -                         distanceBetweenSquared here face)) [minBound..maxBound]`
Something went wrong with that request. Please try again.