never executed always true always false
    1 {-|
    2 Module      : LI11718
    3 Description : Módulo auxiliar para LI1 17/18
    4 
    5 Tipos de dados e funções auxiliares para a realização do projeto de LI1 em 2017/18.
    6 -}
    7 
    8 module LI11718 (
    9     -- * Tipos de dados
   10     -- ** Básicos
   11     Altura,Orientacao(..),Posicao,Ponto,Angulo,Tempo,Velocidade,
   12     -- ** Caminhos
   13     Caminho(..),Passo(..),
   14     -- ** Mapas
   15     Mapa(..),Tabuleiro,Peca(..),Tipo(..),Dimensao,Carro(..),
   16     -- ** Jogo
   17     Jogo(..),Propriedades(..),Acao(..),
   18     -- * Funções auxiliares fornecidas
   19     dimensao, partida, dirInit, altInit, altLava
   20     ) where
   21 
   22 -- | Uma sequência de passos que dá origem a um mapa.
   23 type Caminho = [Passo]
   24 -- | Tipos de passos que podem occorrer num 'Caminho'.
   25 data Passo 
   26   -- | Segue em frente e mantem o nível
   27   = Avanca
   28   -- | Segue em frente e sobe um nível
   29   | Sobe
   30   -- | Segue em frente e desce um nível
   31   | Desce 
   32   -- | Curva à esquerda e mantem o nível
   33   | CurvaEsq
   34   -- | Curva à direita e mantem o nível
   35   | CurvaDir
   36   deriving (Eq,Read,Show)
   37 
   38 -- | Mapa de um jogo, composto por um tabuleiro, uma posição inicial e uma altura inicial.
   39 data Mapa = Mapa (Posicao,Orientacao) Tabuleiro
   40   deriving (Eq,Read,Show)
   41 
   42 -- | O tabuleiro do mapa, representado por uma matriz de 'Peca'.
   43 type Tabuleiro = [[Peca]]
   44 
   45 -- | Uma peça num 'Tabuleiro'. A altura atribuída é sempre a do ponto mais /baixo/ da peça.
   46 data Peca = Peca Tipo Altura
   47   deriving (Eq,Read,Show) 
   48 
   49 -- | Tipos de peças contidos num 'Tabuleiro'.
   50 data Tipo = Rampa Orientacao | Curva Orientacao | Recta | Lava
   51   deriving (Eq,Read,Show)
   52 
   53 -- | Posições num 'Tabuleiro'.
   54 type Posicao  = (Int,Int)
   55 -- | Dimensões de um 'Tabuleiro'.
   56 type Dimensao = (Int,Int)
   57 -- | Altura de uma peça num 'Tabuleiro'.
   58 type Altura = Int 
   59 
   60 -- | Orientações no mapa.
   61 data Orientacao = Norte | Este | Sul | Oeste
   62   deriving (Eq,Read,Show,Enum)
   63 -- | Ponto no mapa.
   64 type Ponto = (Double,Double)
   65 -- | Ângulo em graus.
   66 type Angulo = Double
   67 -- | Períodos de tempo.
   68 type Tempo = Double
   69 -- | Vectores de velocidade.
   70 type Velocidade = Ponto
   71 
   72 {- | 
   73   O estado de um carro dentro de um 'Mapa'.
   74   A direção da velocidade (movimento) /não/ é necessariamente a mesma da direção do carro.
   75 -}
   76 data Carro = Carro
   77     { posicao    :: Ponto      -- ^ a posição atual do carro
   78     , direcao    :: Angulo     -- ^ a direção atual do carro
   79     , velocidade :: Velocidade -- ^ a velocidade atual do carro
   80     }
   81   deriving (Eq,Read,Show)
   82 
   83 {- | Direção inicial na construção de um caminho.
   84 
   85 prop> dirInit == Este
   86 -}
   87 dirInit :: Orientacao
   88 dirInit = Este
   89 
   90 {- | Altura inicial na construção de um caminho.
   91 
   92 prop> altInit == 0
   93 -}
   94 altInit :: Altura
   95 altInit = 0
   96 
   97 {- | Altura da lava.
   98 
   99 prop> altLava == 0
  100 -}
  101 altLava :: Altura
  102 altLava = 0
  103 
  104 {- | Dado um caminho, calcula a dimensão do tabuleiro correspondente.
  105 
  106 >>> dimensao [CurvaDir,CurvaDir,CurvaDir,CurvaDir]
  107 (4,4)
  108 -}
  109 dimensao :: Caminho -> Dimensao
  110 dimensao c = (2+m'+abs m+1,2+n'+abs n+1)
  111   where ((m,m'),(n,n')) = bB ((0,0),(0,0)) (0,0) dirInit c
  112         
  113 {- |
  114 Dado um caminho, calcula a sua posição inicial no tabuleiro correspondente.
  115 
  116 >>> partida [CurvaDir,CurvaDir,CurvaDir,CurvaDir]
  117 (2,1)
  118 -}
  119 partida :: Caminho -> Posicao
  120 partida c = (1+abs m,1+abs n)
  121   where ((m,m'),(n,n')) = bB ((0,0),(0,0)) (0,0) dirInit c
  122 
  123 bB m i _ [] = up m i
  124 bB m i d (s:c) = bB (up m i) (mx i d') d' c
  125   where d' = toEnum (((fromEnum d) + k) `mod` 4)
  126         k | s == CurvaDir = 1
  127           | s == CurvaEsq = (-1)
  128           | otherwise = 0
  129 up ((m,m'),(n,n')) (i,j) = ((min m i, max m' i), (min n j, max n' j))
  130 mx (x,y) d = (x+round (sin a),y-round (cos a))
  131   where a = ((toEnum.fromEnum) d)*(pi/2)
  132 
  133 {- | 
  134   O estado de um jogo dentro, incluindo o mapa e as suas propriedades e o estado dos vários jogadores.
  135   Os campos 'carros', 'nitros' e 'historico' devem ter a mesma dimensão, o número de jogadores.
  136 -}
  137 data Jogo = Jogo 
  138   { mapa        :: Mapa         -- ^ o mapa do percurso
  139   , pista       :: Propriedades -- ^ as propriedades do percurso
  140   , carros      :: [Carro]      -- ^ o estado do carro de cada jogador
  141   , nitros      :: [Tempo]      -- ^ a quantidade de nitro disponível para cada jogador
  142   , historico   :: [[Posicao]]  -- ^ o histórico de posições de cada jogador
  143   }
  144   deriving (Eq,Read,Show)
  145 
  146 -- | As propriedades físicas de um percurso.
  147 data Propriedades = Propriedades 
  148   { k_atrito    :: Double -- ^ o atrito do piso
  149   , k_pneus     :: Double -- ^ o atrito dos pneus 
  150   , k_acel      :: Double -- ^ a intensidade da aceleração
  151   , k_peso      :: Double -- ^ o peso do carro
  152   , k_nitro     :: Double -- ^ a intensidade do nitro
  153   , k_roda      :: Double -- ^ a sensibilidade do guiador
  154   }
  155   deriving (Eq,Read,Show)
  156 
  157 -- | As ações que podem ser tomadas por cada jogador em cada instante.
  158 data Acao = Acao 
  159   { acelerar :: Bool      -- ^ se está a acelerar
  160   , travar   :: Bool      -- ^ se está a travar
  161   , esquerda :: Bool      -- ^ se está a curvar para a esquerda
  162   , direita  :: Bool      -- ^ se está a curvar para a direita
  163   , nitro    :: Maybe Int -- ^ se o nitro está ativo em algum jogador
  164   }
  165   deriving (Eq,Read,Show)