never executed always true always false
    1 {-# LANGUAGE PatternGuards #-}
    2 
    3 module Tarefa3_2017li1g183 where
    4 
    5 import LI11718
    6 import Tarefa2_2017li1g183
    7 import Test.QuickCheck.Gen
    8 import Data.List
    9 import Data.Maybe
   10 import Safe
   11 
   12 testesT3 :: [(Tabuleiro,Tempo,Carro)]
   13 testesT3 = unitTests
   14 
   15 randomizeCarro :: Tabuleiro -> Double -> Carro -> Gen Carro
   16 randomizeCarro tab delta c = do
   17     suchThat genC (validaCarro tab)
   18   where
   19     (x,y) = posicao c
   20     genC = do
   21         dx <- choose (0,delta)
   22         dy <- choose (0,delta)
   23         let x' = x + dx
   24         let y' = y + dy
   25         return c { posicao = (x',y') }
   26 
   27 ranksT3 :: [(Tabuleiro,Tempo,Carro)]
   28 ranksT3 = unitTests
   29 
   30 -- Nuno/Hugo's simpler version
   31 -- ranksT3Nuno :: [(Tabuleiro,Tempo,Carro)]
   32 -- ranksT3Nuno = [(tab1,5,carro1)]
   33 --     where
   34 --     tab1 = [[Peca Lava altLava, Peca Lava altLava, Peca Lava altLava, Peca Lava altLava, Peca Lava altLava]
   35 --                           ,[Peca Lava altLava, Peca (Curva Norte) 2,Peca Recta 2,Peca (Curva Este) 2, Peca Lava altLava]
   36 --                           ,[Peca Lava altLava, Peca Recta 2,Peca Lava altLava,Peca Recta 2, Peca Lava altLava]
   37 --                           ,[Peca Lava altLava, Peca (Curva Oeste) 2,Peca Recta 2,Peca (Curva Sul) 2, Peca Lava altLava]
   38 --                           ,[Peca Lava altLava, Peca Lava altLava, Peca Lava altLava, Peca Lava altLava, Peca Lava altLava]
   39 --                           ]
   40 --     carro1 = Carro (3,3) 30 (2,1.5)
   41 
   42 solutionsT3 :: [((Tabuleiro,Tempo,Carro),Maybe Carro)]
   43 solutionsT3 = zip ranksT3 (map aux ranksT3)
   44     where
   45     aux x@(tab,tempo,carro) = movimenta tab tempo carro
   46 
   47 compareT3Solutions :: Double -> Maybe Carro -> Maybe Carro -> Double
   48 compareT3Solutions distance Nothing Nothing = 100
   49 compareT3Solutions distance Nothing (Just y) = 0
   50 compareT3Solutions distance (Just x) Nothing = 0
   51 compareT3Solutions distance (Just x) (Just y) = (pos+dir+vel) / 3
   52     where
   53     pos = if distance == 0 then 100 else (1 - dist (posicao x) (posicao y) / distance) * 100
   54     dir = (1 - (normAngulo (abs (direcao x - direcao y))) / 360) * 100
   55     vel = if distance == 0 then 100 else (1 - dist (velocidade x) (velocidade y) / distance) * 100
   56 
   57 normAngulo x = if x >= 360 then normAngulo (x - 360) else x
   58 
   59 genTempo :: Gen Tempo
   60 genTempo = choose (0,30)
   61 
   62 validaCarro :: Tabuleiro -> Carro -> Bool
   63 validaCarro tab carro = (not $ derrete tab (posicao carro))
   64 
   65 ponto2Pos (i,j) = (round i, round j)
   66 
   67 derrete :: Tabuleiro -> Ponto -> Bool
   68 derrete t p = derrete' tp a
   69   where
   70   (i,j) = ponto2Pos p
   71   a = denorm p (i,j)
   72   Peca tp _ = (atNote "derrete" (atNote "derrete" t j) i)
   73   derrete' :: Tipo -> Ponto -> Bool 
   74   derrete' Lava _ = True
   75   -- hpacheco: mudei para incluir parede
   76   derrete' (Curva Norte) (x,y) = x < (1-y)
   77   derrete' (Curva Este) (x,y) = x > y
   78   derrete' (Curva Sul) (x,y) = x > (1-y)
   79   derrete' (Curva Oeste) (x,y) = x < y
   80   derrete' _ _  = False
   81 
   82 movimenta :: Tabuleiro -> Tempo -> Carro -> Maybe Carro
   83 movimenta m t c = case (colideLocal m v (a,b) i) of
   84                   Nothing -> Nothing
   85                   Just (p',v') -> Just $ c { posicao = p', velocidade = v' }
   86   where a = posicao c
   87         v = velocidade c
   88         b = a .+. (t .*. v)
   89         i = ponto2Pos a
   90 
   91 bounce :: (Double,Double) -> (Double,Double) -> (Double,Double)
   92 bounce (d,a1) (1,a2) = componentsToArrow $ (arrowToComponents (d,a1)) .+. (-x,-y)
   93     where dp = 2 * (arrowToComponents (d,a1) .$. arrowToComponents (1,a2))
   94           (x,y) = dp .*. (arrowToComponents (1,a2))
   95 
   96 colideLocal :: Tabuleiro -> Velocidade -> (Ponto,Ponto) -> Posicao -> Maybe (Ponto,Velocidade)
   97 colideLocal e v ab ij = case colideLocalAcc [] e v ab ij of
   98                           (l,Just v) -> Just (last l,v)
   99                           (_,Nothing) -> Nothing
  100 
  101 colideLocalAcc :: [Ponto] -> Tabuleiro -> Velocidade -> (Ponto,Ponto) -> Posicao -> ([Ponto],Maybe Velocidade)
  102 colideLocalAcc ps m v (a,b) (i,j) | morto = (ps++[a,b],Nothing)
  103                                   | colideInterno = colideLocalAcc (ps++[a]) m iVel iPos (i+1,j)  -- se houverem colisões internas (diagonais), da prioridade e volta a aplicar novo vector
  104                                   | dentroPeca (a,b) (i,j) g = (ps++[a,b],Just v)                    -- caso contrario, se estiver dentro da peça pode parar
  105                                   | colideExterno = colideLocalAcc (ps++[a]) m eVel ePos (i,j)  -- se passar para fora da peça mas houver parede, colide na parede e volta a aplicar novo vector
  106                                   | otherwise = colideLocalAcc (ps++[a]) m v (aPos,b) ij'       -- se passar para fora da peça mas não houver parede, chama na peça seguinte
  107   where (_,g) = componentsToArrow (b.-.a)
  108 
  109         morto = (isJust int && isNothing (fromJust int)) || (colideExterno && not (fromJust $ temParede m (i,j) (fromJust ext)))
  110 
  111         int = colisaoInterna (atNote "colideLocalAcc" (atNote "colideLocalAcc" m j) i) (i,j) (a,b)                            
  112         colideInterno = isJust int && isJust (fromJust int) && colisaoRelevante (a,b) (fromJust (fromJust int))
  113         (iPos,iVel) = inv v (a,b) (fromJust int) 
  114 
  115         ext = atravessaOnde (i,j) (a,b)    
  116         colideExterno = isJust ext && (isJust . temParede m (i,j)) (fromJust ext)
  117         (ePos,eVel) = inv v (a,b) (Just (norm (fst (fromJust ext)) (i,j),snd (fromJust ext)))
  118 
  119         (aPos,aVel) = (norm (fst (fromJust ext)) (i,j), snd (fromJust ext))
  120         ij' = atravessa aVel (i,j)  
  121 
  122 
  123 norm (x,y) (i,j) = (x+toEnum i,y+toEnum j)
  124 denorm (x,y) (i,j) = (x-toEnum i,y-toEnum j)
  125 
  126 -- dada uma velocidade e um deslocamento, inverte ambos dada uma colisão
  127 inv :: Velocidade -> (Ponto,Ponto) -> Maybe (Ponto,Double) -> ((Ponto,Ponto),Velocidade)
  128 inv v ab Nothing = (ab,v)
  129 inv v ab (Just (c,g)) = ((c,d),arrowToComponents (vd,v'))
  130   where (_,d,v') = inverte ab c g
  131         (vd,_) = componentsToArrow v
  132 
  133 inverte :: (Ponto,Ponto) -> Ponto -> Double -> (Ponto,Ponto,Double)
  134 inverte (a,b) c g = (c,d,v')
  135   where (z,v') = bounce (componentsToArrow (b .-. c)) (1,g)
  136         d = c .+. arrowToComponents (z,v')
  137 
  138 -- dada uma peça e um segmento (relativo à peça), detecta colisoes e devolve angulo da normal
  139 -- colisões internas apenas acontecem em diagonais e no maximo uma
  140 colisaoInterna :: Peca -> Posicao -> (Ponto,Ponto) -> Maybe (Maybe (Ponto,Double))
  141 colisaoInterna (Peca (Curva d) al) ij (a,b) | d == Norte || d == Sul = f (intersecta ab ((1,0),(0,1))) (135 + dlt)
  142                                             | otherwise = f (intersecta ab ((0,0),(1,1))) (45 + dlt)
  143   where f :: Maybe Ponto -> Double -> Maybe (Maybe (Ponto,Double))
  144         f Nothing _ = Nothing
  145         f (Just a) b | al < altLava = Just $ Just (norm a ij,b)
  146                      | otherwise = Just Nothing
  147         dlt = if d == Norte || d == Este then 180 else 0
  148         ab = (denorm a ij, denorm b ij)
  149 colisaoInterna _ _ _ = Nothing
  150 
  151 -- se o movimento mantem-se dentro da peça
  152 dentroPeca :: (Ponto,Ponto) -> Posicao -> Double -> Bool
  153 dentroPeca (a,b) (i,j) g = belongs b
  154   where belongs (x,y) = (x == toEnum i+1 || floor x == i) && (floor y == j || y == toEnum j+1)
  155 
  156 -- dado um segmento (relativo à peça), calcula pontos de interceção e angulos das normais
  157 -- entre 0 e 2 no caso extremo (segmento que começa em cima da linha e atravessa outra)
  158 atravessaOnde :: Posicao -> (Ponto,Ponto) -> Maybe (Ponto, Double)
  159 atravessaOnde ij (x,y) | null rel = Nothing
  160                        | length rel == 1 = Just (head rel)
  161                        | otherwise = Just (last rel) --error $ "Duas travessias: "++(show rel)
  162   where rel = filter (colisaoRelevante (x,y)) $ normalize $ zip is [0,270,90,180]
  163         is = [intersecta xy ((i,i),(toEnum j,toEnum $ (j+1)`mod`2)) | i <- [0,1], j <- [0,1]]
  164         normalize = catMaybes . map (\(a,b) -> if (isJust a) then Just (fromJust a,b) else Nothing)
  165         xy = (denorm x ij, denorm y ij)
  166 
  167 -- para uma peça e uma aresta, testa se vai haver colisão
  168 temParede :: Tabuleiro -> Posicao -> (Ponto,Double) -> Maybe Bool
  169 temParede m (i,j) c | t == Lava = Just (a1 < altLava)
  170                     | snd c == 270 && (t == Curva Sul || t == Curva Oeste) = Just (a1 < altLava)
  171                     | snd c == 180 && (t == Curva Norte || t == Curva Oeste) = Just (a1 < altLava)
  172                     | snd c == 90 && (t == Curva Norte || t == Curva Este) = Just (a1 < altLava)
  173                     | snd c == 0 && (t == Curva Sul || t == Curva Este) = Just (a1 < altLava)
  174                     | middle && mwall t0 (fst c) && aa > aa' = Just True
  175                     | middle && mfall t0 (fst c) && aa < aa' = Just False                    
  176                     | a2 > a1 = Just True
  177                     | a2 < a1 = Just False
  178                     | otherwise = Nothing
  179   where (i',j') = atravessa (snd c) (i,j)
  180         Peca t aa = atNote "temParede" (atNote "temParede" m j') i'
  181         Peca t0 aa' = atNote "temParede" (atNote "temParede" m j) i
  182         isR (Rampa _) = True
  183         isR _ = False
  184         (a1,a2) = normAlturas (atNote "temParede" (atNote "temParede" m j) i) (atNote "temParede" (atNote "temParede" m j') i')
  185         middle = case t of (Rampa x) -> t0 == (Rampa (toEnum (((fromEnum x) + 2) `mod` 4))) && (abs $ aa-aa') == 1
  186                            otherwise -> False
  187         mwall (Rampa Oeste) (x,y) = x >= 0.5
  188         mwall (Rampa Este) (x,y) = x <= 0.5
  189         mwall (Rampa Norte) (x,y) = y >= 0.5
  190         mwall (Rampa Sul) (x,y) = y <= 0.5
  191         mfall r p = not $ mwall r p
  192         
  193 normAlturas :: Peca -> Peca -> (Altura,Altura)
  194 normAlturas (Peca (Rampa _) a1) p@(Peca _ a2) | a2 > a1 = normAlturas (Peca Recta (a1+1)) p
  195                                               | otherwise = normAlturas (Peca Recta a1) p
  196 normAlturas p@(Peca _ a1) (Peca (Rampa _) a2) | a2 < a1 = normAlturas p (Peca Recta (a2+1))
  197                                               | otherwise = normAlturas p (Peca Recta a2)
  198 normAlturas (Peca _ a1) (Peca _ a2) = (a1,a2)
  199  
  200 -- dado o angulo de travessia, da a nova posiçao
  201 atravessa :: Double -> Posicao -> Posicao
  202 atravessa 270 (i,j) = (i,j-1)
  203 atravessa 90  (i,j) = (i,j+1)
  204 atravessa 0   (i,j) = (i-1,j)
  205 atravessa 180 (i,j) = (i+1,j)
  206 
  207 -- dado o deslocamento e o ponto de colisão com o angulo da normal, testa de é relevante
  208 -- é relevante se a diferença de angulos > 90º
  209 colisaoRelevante :: (Ponto,Ponto) -> (Ponto,Double) -> Bool
  210 colisaoRelevante ((a1,a2),(b1,b2)) ((x,y),a) = diff > 90 && diff < 270 
  211   where (_,a') = componentsToArrow (b1-a1,b2-a2)
  212         diff = f (a-a')
  213         f x | x < 0 = f (x+360)
  214             | x > 360 = f (x-360)
  215             | otherwise = x
  216 
  217 
  218 -- geometry
  219 
  220 -- copiado do Gloss para Double
  221 intersecta :: (Ponto,Ponto) -> (Ponto,Ponto) -> Maybe Ponto
  222 intersecta (p1,p2) (p3,p4) | Just p0 <- intersectaL p1 p2 p3 p4
  223                            , t12   <- closestPontoOnL p1 p2 p0
  224                            , t23   <- closestPontoOnL p3 p4 p0
  225                            , t12 >= 0 && t12 <= 1
  226                            , t23 >= 0 && t23 <= 1
  227                            = Just p0
  228                            | otherwise
  229                            = Nothing
  230 
  231 -- copiado do Gloss para Double
  232 intersectaL :: Ponto -> Ponto -> Ponto -> Ponto -> Maybe Ponto
  233 intersectaL (x1, y1) (x2, y2) (x3, y3) (x4, y4)
  234  = let  dx12  = x1 - x2
  235         dx34  = x3 - x4
  236         dy12  = y1 - y2
  237         dy34  = y3 - y4
  238   
  239         den = dx12 * dy34  - dy12 * dx34
  240 
  241     in if den == 0
  242        then Nothing
  243        else let det12 = x1*y2 - y1*x2 
  244                 det34 = x3*y4 - y3*x4 
  245                 numx  = det12 * dx34 - dx12 * det34
  246                 numy  = det12 * dy34 - dy12 * det34
  247             in Just (numx / den, numy / den)
  248 
  249 -- copiado do Gloss para Double
  250 closestPontoOnL :: Ponto -> Ponto -> Ponto -> Double
  251 closestPontoOnL p1 p2 p3 = (p3 .-. p1) .$. (p2 .-. p1) / (p2 .-. p1) .$. (p2 .-. p1)
  252 
  253 (.*.) :: Double -> (Double,Double) -> (Double,Double)
  254 (.*.) x (a,b) = ((x*a),(x*b))
  255        
  256 (.+.) :: (Double,Double) -> (Double,Double) -> (Double,Double)
  257 (.+.) (x,y) (a,b) = ((x+a),(y+b))
  258 
  259 (.-.) :: (Double,Double) -> (Double,Double) -> (Double,Double)
  260 (.-.) (x,y) (a,b) = ((x-a),(y-b))
  261 
  262 -- the dot product between two (Double,Double)s
  263 (.$.) :: (Double,Double) -> (Double,Double) -> Double
  264 (.$.) (d1,a1) (d2,a2) = (x1*x2) + (y1*y2)
  265     where (x1,y1) = (d1,a1)
  266           (x2,y2) = (d2,a2)
  267 
  268 radians th = th * (pi/180)
  269 degrees th = th * (180/pi)
  270 
  271 arrowToComponents :: (Double,Double) -> Ponto
  272 arrowToComponents (v,th) = (getX v th,getY v th)
  273     where getX v th = v * cos (radians (th))
  274           getY v th = v * sin (radians (-th))
  275 
  276 componentsToArrow :: Ponto -> (Double,Double)
  277 componentsToArrow (x,0) | x >= 0 = (x,0)
  278 componentsToArrow (x,0) | x < 0 = (abs x,180)
  279 componentsToArrow (0,y) | y >= 0 = (y,-90)
  280 componentsToArrow (0,y) | y < 0 = (abs y,90)
  281 componentsToArrow (x,y) = (hyp,dir angle)
  282     where
  283     dir o = case (x >= 0, y >= 0) of
  284                 (True,True) -> -o
  285                 (True,False) -> o
  286                 (False,False) -> 180 - o
  287                 (False,True) -> 180 + o
  288     hyp = sqrt ((abs x)^2 + (abs y)^2)
  289     angle = degrees $ atan (abs y / abs x)
  290 
  291 dist :: Ponto -> Ponto -> Double
  292 dist (x1,y1) (x2,y2) = sqrt ((x2-x1)^2+(y2-y1)^2)
  293 
  294 
  295 --------------
  296 
  297 testeMapa =
  298   [[Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0
  299                ,Peca Lava 0,Peca Lava 0,Peca Lava 0]
  300   ,[Peca Lava 0,Peca (Curva Norte) 0,Peca (Rampa Este) 0,Peca Recta 1,Peca (Rampa Oeste) 0,Peca Recta 0,Peca Recta 0,Peca (Rampa Oeste) (-1),Peca Recta (-1)
  301                ,Peca (Rampa Este) (-1),Peca (Rampa Este) 0,Peca (Rampa Oeste) 0,Peca (Rampa Oeste) (-1),Peca (Curva Este) (-1),Peca Lava 0]
  302   ,[Peca Lava 0,Peca (Curva Oeste) 0,Peca (Rampa Este) 0,Peca (Rampa Oeste) 0,Peca (Rampa Este) 0,Peca Recta 1,Peca (Rampa Oeste) 0,Peca (Rampa Oeste) (-1)
  303                ,Peca Recta (-1),Peca (Rampa Oeste) (-2),Peca (Rampa Oeste) (-3),Peca (Rampa Este) (-3),Peca (Rampa Este) (-2),Peca (Curva Sul) (-1),Peca Lava 0]
  304   ,[Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0
  305                ,Peca Lava 0,Peca Lava 0,Peca Lava 0]]
  306 --   00011110000009999001100999  
  307 -- ..//>>[]<<[][]<<[]>>>><<<<\\..
  308 -- ..\\>><<>>[]<<<<[]<<<<>>>>//..
  309 --   00011001111009999887788999
  310 
  311 testeCurvas =
  312   [[Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0]
  313   ,[Peca Lava 0,Peca (Curva Norte) 0,Peca (Rampa Oeste) (-1),Peca (Curva Este) (-1),Peca Lava 0,Peca (Curva Norte) 0,Peca (Curva Este) 0
  314                ,Peca Lava 0,Peca (Curva Norte) 1,Peca (Curva Este) 1,Peca Lava 0]
  315   ,[Peca Lava 0,Peca (Rampa Sul) 0,Peca Lava 0,Peca (Curva Oeste) (-1),Peca (Rampa Este) (-1),Peca (Curva Sul) 0,Peca (Curva Oeste) 0
  316                ,Peca (Rampa Este) 0,Peca (Curva Sul) 1,Peca Recta 1,Peca Lava 0]
  317   ,[Peca Lava 0,Peca (Curva Oeste) 1,Peca (Rampa Oeste) 0,Peca Recta 0,Peca (Rampa Oeste) (-1),Peca Recta (-1),Peca (Rampa Este) (-1)
  318                ,Peca (Rampa Este) 0,Peca Recta 1,Peca (Curva Sul) 1,Peca Lava 0]
  319   ,[Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0,Peca Lava 0]]
  320 
  321 -- ..//<<\\..//\\..//\\..
  322 -- ..\/..\\>>//\\>>//[]..
  323 -- ..\\<<[]<<[]>>>>[]//..
  324 
  325 unitTests :: [(Tabuleiro,Tempo,Carro)]
  326 unitTests = [
  327   --- apenas um passo recursivo
  328   -- rectas: passa percurso
  329     (testeMapa , 1.2, Carro (5.5,1.5) 0 (0.9,0.1))
  330   -- rectas: cai adjacente
  331   , (testeMapa , 1.2, Carro (5.5,2.5) 0 (0.1,-0.9))
  332   -- rectas: passa adjacente
  333   , (testeMapa , 1.2, Carro (8.5,1.5) 0 (0.1,0.9))
  334   -- rectas: choca adjacente
  335   , (testeMapa , 1.2, Carro (5.5,1.5) 0 (0.1,0.9))
  336   -- rectas: cai lava
  337   , (testeMapa , 1.2, Carro (3.5,1.5) 0 (0.1,-0.9))
  338   -- rectas: passa lava (mesma altura)
  339   , (testeMapa , 1.2, Carro (5.5,1.5) 0 (0.1,-0.9))
  340   -- rectas: choca lava
  341   , (testeMapa , 1.2, Carro (8.5,1.5) 0 (0.1,-0.9))
  342   -- curva: choca lava
  343   , (testeMapa , 1.2, Carro (13.4,1.5) 0 (0.3,-0.1))
  344   -- curva: cai lava (mesma altura)
  345   , (testeMapa , 1.2, Carro (1.6,1.5) 0 (-0.3,-0.1))
  346 
  347   -- recta->curva: cai
  348   , (testeCurvas , 1.2, Carro (8.5,3.5) 0 (0.1,-0.9))
  349   -- recta->curva: lava
  350   , (testeCurvas , 1.2, Carro (5.5,3.5) 0 (0.1,-0.9))
  351   -- recta->curva: choca
  352   , (testeCurvas , 1.2, Carro (3.5,3.5) 0 (0.1,-0.9))
  353 
  354   --- dois+ passos recursivos
  355   -- rectas: passa percurso 2
  356   , (testeMapa , 1.2, Carro (3.6,1.5) 0 (-1.6,0.1))  
  357   -- rectas: passa percurso 3
  358   , (testeMapa , 1.2, Carro (4.6,1.5) 0 (-2.6,0.1))  
  359   -- curvas: cai lava (mesma altura) 3
  360   , (testeMapa , 1.2, Carro (3.6,1.5) 0 (-2.6,0.1))  
  361   -- rectas: adjacente + cai lava (mesma altura) 10 
  362   , (testeMapa , 5.5, Carro (12.5,1.2) 0 (-2.1,0.1))
  363   -- rectas: adjacente + choca lava 2 
  364   , (testeMapa , 1.2, Carro (8.5,1.5) 0 (0.1,1.9))
  365   -- rectas: choca lava + adjacente 2 
  366   , (testeMapa , 1.2, Carro (8.5,2.5) 0 (0.1,1.9))
  367   -- rectas: choca lava + adjacente + choca lava 3 
  368   , (testeMapa , 1.2, Carro (8.5,2.5) 0 (0.1,2.3))
  369   -- rectas: choca lava + adjacente + choca lava + adjacente 4 
  370   , (testeMapa , 1.2, Carro (8.5,2.5) 0 (0.1,3.3))
  371   -- rectas: choca adjacente + cai lava (mesma altura) 2
  372   , (testeMapa , 1.2, Carro (5.5,1.5) 0 (0.1,1.9))
  373   -- curvas: adjacente + choca lava 3
  374   , (testeMapa , 1.2, Carro (11.6,1.5) 0 (2.1,0.1))
  375   -- curva: adjacente + cai lava 2
  376   , (testeMapa , 1.2, Carro (1.6,2.5) 0 (-0.1,-1.1))
  377   -- curva: choca lava 2
  378   , (testeMapa , 1.2, Carro (12.5,1.5) 0 (2.8,-0.1))
  379   -- curva: cai 2 (passa a lava) -- @nmm nao percebo a particularidade deste teste!
  380   , (testeMapa , 1.2, Carro (1.6,2.5) 0 (-0.3,-0.1))
  381 
  382   ----- PLANO NOVO (cai se queda >= 1, choca se degrau >= 1, passa se diff. entre 1 e -1)
  383   -- rampas: cai 
  384   , (testeMapa , 1.2, Carro (10.5,1.5) 0 (-0.1,0.9))
  385   -- rampas: choca 
  386   , (testeMapa , 1.2, Carro (10.5,2.5) 0 (0.1,-0.9))
  387   -- rampas: passa (igual)
  388   , (testeMapa , 1.2, Carro (2.5,1.5) 0 (0.1,0.9))
  389   -- rampas x2: passa (um pouco maior)
  390   , (testeMapa , 1.2, Carro (4.5,1.5) 0 (0.1,0.9))
  391   -- rampas x2: passa (um pouco menor)
  392   , (testeMapa , 1.2, Carro (4.5,1.5) 0 (-0.1,0.9))
  393   ---- casos difíceis (sobe/desce Bom Jesus)!
  394   -- rampas: choca (tricky)
  395   , (testeMapa , 1.2, Carro (9.5,2.5) 0 (0.1,-0.9))
  396   -- rampas: não choca (tricky)
  397   , (testeMapa , 1.2, Carro (9.5,2.5) 0 (-0.1,-0.9))
  398   -- rampas: passa (tricky)
  399   , (testeMapa , 1.2, Carro (9.5,1.5) 0 (0.1,0.9))
  400   -- rampas: não passa (tricky)
  401   , (testeMapa , 1.2, Carro (9.5,1.5) 0 (-0.1,0.9))
  402   -- rampas: choca rés-vés (tricky x2)
  403   , (testeMapa , 1.2, Carro (9.5,2.5) 0 (0,-0.9))
  404   -- rampas: choca lava
  405   , (testeMapa , 1.2, Carro (9.5,2.5) 0 (0.1,0.9))
  406   -- rampas: cai lava
  407   , (testeMapa , 1.2, Carro (9.5,1.5) 0 (0.1,-0.9))
  408   ------
  409   
  410   ----- PLANO ANTIGO (cai se altura maior, choca se menor, passa se igual)
  411   -- -- rampas: cai 
  412   -- , (testeMapa , 1.2, Carro (6.5,2.5) 0 (0.1,-0.9)) -- oracle: (6.6,1.4), got Noth
  413   -- -- rampas: passa
  414   -- , (testeMapa , 1.2, Carro (2.5,1.5) 0 (0.1,0.9))
  415   -- -- rampas: choca
  416   -- , (testeMapa , 1.2, Carro (3.5,2.5) 0 (0.1,-0.9)) -- oracle: (_.1.5), got (_,2.6)
  417   -- -- rampas x2: choca
  418   -- , (testeMapa , 1.2, Carro (4.5,1.5) 0 (0.1,0.9))  -- oracle (_.2.5), got (_,1.4)
  419   -- -- rampas x2: cai
  420   -- , (testeMapa , 1.2, Carro (4.5,1.5) 0 (-0.1,0.9)) -- oracle (4.4,2.6), got Noth
  421   -- -- rampas x2: bónus - passa?
  422   -- , (testeMapa , 1.2, Carro (4.5,1.5) 0 (0,0.9))
  423   -------------
  424   ]
  425 
  426 
  427