never executed always true always false
    1 {-# LANGUAGE PatternGuards #-}
    2 
    3 module Tarefa4_2017li1g183 where
    4 
    5 import LI11718
    6 import Tarefa3_2017li1g183
    7 import Tarefa1_2017li1g183
    8 import Test.QuickCheck.Gen
    9 import Data.List
   10 import Data.Maybe
   11 --import Safe
   12 --import Debug.Trace
   13 
   14 testesT4 :: [(Tempo,Jogo,Acao)]
   15 testesT4 = [(0.2,jogoT { carros = ((head $ carros jogoT) { velocidade = (1,0)}) : tail (carros jogoT) },Acao True False True False (Just 0))
   16            ,(0.2,jogoT { carros = ((head $ carros jogoT) { velocidade = (3,-1)}) : tail (carros jogoT) },Acao True False False True (Just 0))
   17            ,(0.2,jogoT { carros = ((head $ carros jogoT) { velocidade = (0,0)}) : tail (carros jogoT) },Acao False True True False Nothing)
   18            ,(0.4,jogoT { carros = ((head $ carros jogoT) { velocidade = (1,0)}) : tail (carros jogoT) },Acao True False True False (Just 0))]
   19 
   20 jogoT = jogoInicial $ constroi [Avanca,Avanca,CurvaDir,CurvaDir,Avanca,Avanca,CurvaDir,CurvaDir]
   21 
   22 
   23 njogadores = 1
   24 qntnitro = 5
   25 
   26 jogoInicial :: Mapa -> Jogo
   27 jogoInicial m@(Mapa p t) = Jogo { mapa      = m 
   28                                 , pista     = standard
   29                                 , carros    = map (carroInicial t (fst p)) [0..njogadores-1]
   30                                 , nitros    = replicate njogadores qntnitro
   31                                 , historico = replicate njogadores [(fst p)]
   32                                 }
   33 
   34 carroInicial :: Tabuleiro -> Posicao -> Int -> Carro
   35 carroInicial t (a,b) i = Carro { posicao    = centroPeca tp (a,b)
   36                                , direcao    = 0
   37                                , velocidade = (0,0)
   38                                }
   39     where  (Peca tp _) = (t!!b!!a)
   40 
   41 
   42 centroPeca :: Tipo -> Posicao -> Ponto
   43 centroPeca (Curva Norte) (a,b) = (toEnum a+0.7,toEnum b+0.7)
   44 centroPeca (Curva Este) (a,b) = (toEnum a+0.3,toEnum b+0.7)
   45 centroPeca (Curva Sul) (a,b) = (toEnum a+0.3,toEnum b+0.3)
   46 centroPeca (Curva Oeste) (a,b) = (toEnum a+0.7,toEnum b+0.3)
   47 centroPeca _ (a,b) = (toEnum a+0.5,toEnum b+0.5)
   48 
   49 standard = Propriedades (1.5) 1 4 2 15 90
   50 
   51 
   52 atualiza :: Tempo -> Jogo -> Int -> Acao -> Jogo
   53 atualiza t e j a = lancaNitros t j e e' a
   54   where e' = e { carros = cs', historico = hs' }
   55         Mapa _ m = (mapa e)
   56         c' = moveCarro t e (carros e!!j,a)
   57         h' = atualizaHistorico (carros e!!j) (historico e!!j)
   58         cs' = (take j (carros e))++(c':drop (j+1) (carros e))
   59         hs' = (take j (historico e))++(h':drop (j+1) (historico e))
   60 
   61 moveCarro :: Tempo -> Jogo -> (Carro,Acao) -> Carro
   62 moveCarro t e (c,a) = rodaCarro t e (andaCarro t e (c,a) ,a)
   63 
   64 rodaCarro :: Tempo -> Jogo -> (Carro,Acao) -> Carro
   65 rodaCarro t e (c,a) | direita a && not (esquerda a) = c { direcao = direcao c - (t*k_roda (pista e))}
   66                     | esquerda a && not (direita a) = c { direcao = direcao c + (t*k_roda (pista e))}
   67                     | otherwise = c
   68 
   69 atualizaHistorico :: Carro -> [Posicao] -> [Posicao]
   70 atualizaHistorico c [] = [(floor (fst (posicao c)), floor (snd (posicao c)))]
   71 atualizaHistorico c (h:hs) = hs'
   72   where (i,j) = (floor (fst (posicao c)), floor (snd (posicao c)))
   73         hs' | h == (i,j) = (h:hs)
   74             | otherwise = (i,j):h:hs
   75 
   76 lancaNitros :: Tempo -> Int -> Jogo -> Jogo -> Acao -> Jogo
   77 lancaNitros _ _ e0 e (Acao _ _ _ _ Nothing) = e
   78 lancaNitros t i e0 e (Acao _ _ _ _ (Just j)) | (nitros e)!!i == 0 = e
   79                                           | otherwise = e { carros = cs', nitros = ns' }
   80   where tNitro = min t (max 0 ((nitros e)!!i))
   81         ns' = (take i (nitros e))++(n':drop (i+1) (nitros e))
   82         cs' = (take j (carros e))++(c':drop (j+1) (carros e))
   83         n' = max 0 (((nitros e)!!i)-tNitro)
   84         c = (carros e)!!j
   85         c0 = (carros e0)!!j
   86         c' = c { velocidade = (velocidade c) .+. (tNitro .*. (nitroVec (pista e) c0)) }
   87 
   88 andaCarro :: Tempo -> Jogo -> (Carro,Acao) -> Carro
   89 andaCarro t e (c,a) = c { velocidade = v' }
   90   where v' = (velocidade c) .+. (t .*. ((accelVec ps (c,a)) .+. (dragVec ps c) .+. (driftVec ps c) .+. (gravityVec ps p c)))
   91         ps = pista e
   92         Mapa _ m = mapa e
   93         (i,j) = (floor (fst (posicao c)), floor (snd (posicao c)))
   94         p = m!!j!!i
   95 
   96 accelVec :: Propriedades -> (Carro,Acao) -> Velocidade
   97 accelVec ps (c,a) | acelerar a && not (travar a) = arrowToComponents (k_acel ps,direcao c)
   98                   | travar a && not (acelerar a) = arrowToComponents (k_acel ps,direcao c + 180)
   99                   | otherwise = (0,0)
  100 
  101 dragVec :: Propriedades -> Carro -> Velocidade
  102 dragVec ps c = arrowToComponents (v*k_atrito ps,a + 180) 
  103   where (v,a) = componentsToArrow (velocidade c)
  104 
  105 driftVec :: Propriedades -> Carro -> Velocidade
  106 driftVec ps c = arrowToComponents (driftCoef,driftAngle)
  107   where (v,a) = componentsToArrow $ velocidade c
  108         d = direcao c
  109         driftAngle = if (sin (radians (a-d))) > 0
  110                      then d-90 -- going right 
  111                      else d+90 -- going left
  112         driftCoef = v * k_pneus ps * abs (sin (radians (a-d)))
  113     
  114 nitroVec :: Propriedades -> Carro -> Velocidade
  115 nitroVec ps c = arrowToComponents (k_nitro ps,direcao c)
  116 
  117 gravityVec :: Propriedades -> Peca -> Carro -> Velocidade
  118 gravityVec ps (Peca (Rampa Sul) _)   c = arrowToComponents (k_peso ps, 90)
  119 gravityVec ps (Peca (Rampa Norte) _) c = arrowToComponents (k_peso ps, 270)
  120 gravityVec ps (Peca (Rampa Oeste) _) c = arrowToComponents (k_peso ps, 0)
  121 gravityVec ps (Peca (Rampa Este) _)  c = arrowToComponents (k_peso ps, 180)
  122 gravityVec ps _                      c = (0,0)