{-|
Module      : Labs2026
Description : Definições base do jogo.
Copyright   : Henrique Faria <d14410@di.uminho.pt>
              Emanuel Rodrigues <d14960@di.uminho.pt>
              Nelson Estevão <d12733@di.uminho.pt>
              Olga Pacheco <omp@di.uminho.pt>
              Sérgio Alves <sfa@di.uminho.pt>
              Xavier Pinho <d12736@di.uminho.pt>

Tipos de dados e funções auxiliares para a realização do projeto de LI1\/LP1 em 2026\/27.

O projeto é uma versão simplificada do jogo /Motherload/: uma escavadora explora
um mundo visto de lado, recolhe minérios, e vende-os à superfície.
-}
module Labs2026
  ( -- * Tipos de dados

    -- ** Básicos
    Combustivel
  , Creditos
  , Dimensao
  , Direcao (..)
  , Nivel
  , Peso
  , Posicao
  , Semente
  , Ticks

    -- ** Mapas
  , Matriz
  , Mapa
  , Bloco (..)
  , TipoMinerio (..)

    -- ** Entidades
  , Escavadora (..)
  , Edificio (..)
  , TipoEdificio (..)
  , Objeto (..)
  , Melhoria (..)
  , Loja

    -- ** Jogo
  , Jogo (..)
  , Jogada (..)

    -- * Constantes do jogo

    -- ** Minérios
  , valorMinerio
  , pesoMinerio

    -- ** Escavação e movimento
  , durezaBloco
  , custoEscavacao
  , custoMovimento
  , custoVoo

    -- ** Dano
  , danoLava
  , alturaQuedaSegura
  , danoQueda

    -- ** Edifícios
  , precoCombustivel
  , precoReparacao

    -- ** Dinamite
  , duracaoDinamite
  , raioDinamite
  , danoDinamite

    -- * Funções auxiliares
  , geraAleatorios
  ) where

import Data.Maybe (fromMaybe)
import System.Random (mkStdGen, randoms)

import Tarefa0_geral (Dimensao, Direcao (..), Matriz, Posicao)

-- * Tipos de dados

-- ** Básicos

-- | Unidade de tempo do jogo. Por tick a escavadora desloca-se, no máximo, um bloco.
type Ticks = Int

-- | Moeda do jogo.
type Creditos = Int

-- | Unidades de combustível.
type Combustivel = Int

-- | Peso de minérios na carga.
type Peso = Int

-- | Nível da broca \/ dureza de um bloco.
type Nivel = Int

-- | Valor inicial que determina a sequência de números pseudo-aleatórios.
type Semente = Int

-- ** Mapas

-- | Minérios, por ordem crescente de valor.
data TipoMinerio = Ferro | Bronze | Prata | Ouro | Platina | Diamante
  deriving (TipoMinerio -> TipoMinerio -> Bool
(TipoMinerio -> TipoMinerio -> Bool)
-> (TipoMinerio -> TipoMinerio -> Bool) -> Eq TipoMinerio
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TipoMinerio -> TipoMinerio -> Bool
== :: TipoMinerio -> TipoMinerio -> Bool
$c/= :: TipoMinerio -> TipoMinerio -> Bool
/= :: TipoMinerio -> TipoMinerio -> Bool
Eq, Eq TipoMinerio
Eq TipoMinerio =>
(TipoMinerio -> TipoMinerio -> Ordering)
-> (TipoMinerio -> TipoMinerio -> Bool)
-> (TipoMinerio -> TipoMinerio -> Bool)
-> (TipoMinerio -> TipoMinerio -> Bool)
-> (TipoMinerio -> TipoMinerio -> Bool)
-> (TipoMinerio -> TipoMinerio -> TipoMinerio)
-> (TipoMinerio -> TipoMinerio -> TipoMinerio)
-> Ord TipoMinerio
TipoMinerio -> TipoMinerio -> Bool
TipoMinerio -> TipoMinerio -> Ordering
TipoMinerio -> TipoMinerio -> TipoMinerio
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: TipoMinerio -> TipoMinerio -> Ordering
compare :: TipoMinerio -> TipoMinerio -> Ordering
$c< :: TipoMinerio -> TipoMinerio -> Bool
< :: TipoMinerio -> TipoMinerio -> Bool
$c<= :: TipoMinerio -> TipoMinerio -> Bool
<= :: TipoMinerio -> TipoMinerio -> Bool
$c> :: TipoMinerio -> TipoMinerio -> Bool
> :: TipoMinerio -> TipoMinerio -> Bool
$c>= :: TipoMinerio -> TipoMinerio -> Bool
>= :: TipoMinerio -> TipoMinerio -> Bool
$cmax :: TipoMinerio -> TipoMinerio -> TipoMinerio
max :: TipoMinerio -> TipoMinerio -> TipoMinerio
$cmin :: TipoMinerio -> TipoMinerio -> TipoMinerio
min :: TipoMinerio -> TipoMinerio -> TipoMinerio
Ord, Int -> TipoMinerio -> ShowS
[TipoMinerio] -> ShowS
TipoMinerio -> String
(Int -> TipoMinerio -> ShowS)
-> (TipoMinerio -> String)
-> ([TipoMinerio] -> ShowS)
-> Show TipoMinerio
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TipoMinerio -> ShowS
showsPrec :: Int -> TipoMinerio -> ShowS
$cshow :: TipoMinerio -> String
show :: TipoMinerio -> String
$cshowList :: [TipoMinerio] -> ShowS
showList :: [TipoMinerio] -> ShowS
Show, ReadPrec [TipoMinerio]
ReadPrec TipoMinerio
Int -> ReadS TipoMinerio
ReadS [TipoMinerio]
(Int -> ReadS TipoMinerio)
-> ReadS [TipoMinerio]
-> ReadPrec TipoMinerio
-> ReadPrec [TipoMinerio]
-> Read TipoMinerio
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS TipoMinerio
readsPrec :: Int -> ReadS TipoMinerio
$creadList :: ReadS [TipoMinerio]
readList :: ReadS [TipoMinerio]
$creadPrec :: ReadPrec TipoMinerio
readPrec :: ReadPrec TipoMinerio
$creadListPrec :: ReadPrec [TipoMinerio]
readListPrec :: ReadPrec [TipoMinerio]
Read, Int -> TipoMinerio
TipoMinerio -> Int
TipoMinerio -> [TipoMinerio]
TipoMinerio -> TipoMinerio
TipoMinerio -> TipoMinerio -> [TipoMinerio]
TipoMinerio -> TipoMinerio -> TipoMinerio -> [TipoMinerio]
(TipoMinerio -> TipoMinerio)
-> (TipoMinerio -> TipoMinerio)
-> (Int -> TipoMinerio)
-> (TipoMinerio -> Int)
-> (TipoMinerio -> [TipoMinerio])
-> (TipoMinerio -> TipoMinerio -> [TipoMinerio])
-> (TipoMinerio -> TipoMinerio -> [TipoMinerio])
-> (TipoMinerio -> TipoMinerio -> TipoMinerio -> [TipoMinerio])
-> Enum TipoMinerio
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: TipoMinerio -> TipoMinerio
succ :: TipoMinerio -> TipoMinerio
$cpred :: TipoMinerio -> TipoMinerio
pred :: TipoMinerio -> TipoMinerio
$ctoEnum :: Int -> TipoMinerio
toEnum :: Int -> TipoMinerio
$cfromEnum :: TipoMinerio -> Int
fromEnum :: TipoMinerio -> Int
$cenumFrom :: TipoMinerio -> [TipoMinerio]
enumFrom :: TipoMinerio -> [TipoMinerio]
$cenumFromThen :: TipoMinerio -> TipoMinerio -> [TipoMinerio]
enumFromThen :: TipoMinerio -> TipoMinerio -> [TipoMinerio]
$cenumFromTo :: TipoMinerio -> TipoMinerio -> [TipoMinerio]
enumFromTo :: TipoMinerio -> TipoMinerio -> [TipoMinerio]
$cenumFromThenTo :: TipoMinerio -> TipoMinerio -> TipoMinerio -> [TipoMinerio]
enumFromThenTo :: TipoMinerio -> TipoMinerio -> TipoMinerio -> [TipoMinerio]
Enum, TipoMinerio
TipoMinerio -> TipoMinerio -> Bounded TipoMinerio
forall a. a -> a -> Bounded a
$cminBound :: TipoMinerio
minBound :: TipoMinerio
$cmaxBound :: TipoMinerio
maxBound :: TipoMinerio
Bounded)

-- | Bloco do mundo.
data Bloco
  = -- | Espaço livre (céu ou túnel). A escavadora só ocupa blocos de ar.
    Ar
  | -- | Escavável, sem valor.
    Terra
  | -- | Inescavável.
    Rocha
  | -- | Escavável; ao ser escavado o minério passa para a carga da escavadora.
    Minerio TipoMinerio
  | -- | Escavável, mas causa 'danoLava' à escavadora quando escavado.
    Lava
  deriving (Bloco -> Bloco -> Bool
(Bloco -> Bloco -> Bool) -> (Bloco -> Bloco -> Bool) -> Eq Bloco
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Bloco -> Bloco -> Bool
== :: Bloco -> Bloco -> Bool
$c/= :: Bloco -> Bloco -> Bool
/= :: Bloco -> Bloco -> Bool
Eq, Eq Bloco
Eq Bloco =>
(Bloco -> Bloco -> Ordering)
-> (Bloco -> Bloco -> Bool)
-> (Bloco -> Bloco -> Bool)
-> (Bloco -> Bloco -> Bool)
-> (Bloco -> Bloco -> Bool)
-> (Bloco -> Bloco -> Bloco)
-> (Bloco -> Bloco -> Bloco)
-> Ord Bloco
Bloco -> Bloco -> Bool
Bloco -> Bloco -> Ordering
Bloco -> Bloco -> Bloco
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Bloco -> Bloco -> Ordering
compare :: Bloco -> Bloco -> Ordering
$c< :: Bloco -> Bloco -> Bool
< :: Bloco -> Bloco -> Bool
$c<= :: Bloco -> Bloco -> Bool
<= :: Bloco -> Bloco -> Bool
$c> :: Bloco -> Bloco -> Bool
> :: Bloco -> Bloco -> Bool
$c>= :: Bloco -> Bloco -> Bool
>= :: Bloco -> Bloco -> Bool
$cmax :: Bloco -> Bloco -> Bloco
max :: Bloco -> Bloco -> Bloco
$cmin :: Bloco -> Bloco -> Bloco
min :: Bloco -> Bloco -> Bloco
Ord, Int -> Bloco -> ShowS
[Bloco] -> ShowS
Bloco -> String
(Int -> Bloco -> ShowS)
-> (Bloco -> String) -> ([Bloco] -> ShowS) -> Show Bloco
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Bloco -> ShowS
showsPrec :: Int -> Bloco -> ShowS
$cshow :: Bloco -> String
show :: Bloco -> String
$cshowList :: [Bloco] -> ShowS
showList :: [Bloco] -> ShowS
Show, ReadPrec [Bloco]
ReadPrec Bloco
Int -> ReadS Bloco
ReadS [Bloco]
(Int -> ReadS Bloco)
-> ReadS [Bloco]
-> ReadPrec Bloco
-> ReadPrec [Bloco]
-> Read Bloco
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Bloco
readsPrec :: Int -> ReadS Bloco
$creadList :: ReadS [Bloco]
readList :: ReadS [Bloco]
$creadPrec :: ReadPrec Bloco
readPrec :: ReadPrec Bloco
$creadListPrec :: ReadPrec [Bloco]
readListPrec :: ReadPrec [Bloco]
Read)

-- | Mapa retangular de blocos, ou seja, uma 'Matriz' de 'Bloco's.
-- A linha 0 é a superfície e é toda 'Ar'.
type Mapa = Matriz Bloco

-- ** Entidades

-- | Escavadora controlada pelo jogador.
data Escavadora = Escavadora
  { -- | Posição no mapa (bloco de 'Ar').
    Escavadora -> Posicao
posicaoEscavadora :: Posicao
  , -- | Direção do último movimento bem sucedido (para desenhar).
    Escavadora -> Direcao
direcaoEscavadora :: Direcao
  , -- | Combustível atual, entre 0 e 'depositoEscavadora'.
    Escavadora -> Int
combustivelEscavadora :: Combustivel
  , -- | Capacidade do depósito.
    Escavadora -> Int
depositoEscavadora :: Combustivel
  , -- | Vida atual, entre 0 e 'vidaMaximaEscavadora'.
    Escavadora -> Int
vidaEscavadora :: Int
  , -- | Vida máxima.
    Escavadora -> Int
vidaMaximaEscavadora :: Int
  , -- | Dureza máxima de bloco que a broca consegue escavar.
    Escavadora -> Int
brocaEscavadora :: Nivel
  , -- | Minérios transportados.
    Escavadora -> [TipoMinerio]
cargaEscavadora :: [TipoMinerio]
  , -- | Peso máximo transportável.
    Escavadora -> Int
capacidadeEscavadora :: Peso
  , -- | Blocos caídos consecutivamente (para dano de queda).
    Escavadora -> Int
quedaEscavadora :: Int
  , -- | Propulsores ligados (suspendem a gravidade).
    Escavadora -> Bool
voandoEscavadora :: Bool
  , -- | Dinamites no inventário.
    Escavadora -> Int
dinamitesEscavadora :: Int
  }
  deriving (Escavadora -> Escavadora -> Bool
(Escavadora -> Escavadora -> Bool)
-> (Escavadora -> Escavadora -> Bool) -> Eq Escavadora
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Escavadora -> Escavadora -> Bool
== :: Escavadora -> Escavadora -> Bool
$c/= :: Escavadora -> Escavadora -> Bool
/= :: Escavadora -> Escavadora -> Bool
Eq, Eq Escavadora
Eq Escavadora =>
(Escavadora -> Escavadora -> Ordering)
-> (Escavadora -> Escavadora -> Bool)
-> (Escavadora -> Escavadora -> Bool)
-> (Escavadora -> Escavadora -> Bool)
-> (Escavadora -> Escavadora -> Bool)
-> (Escavadora -> Escavadora -> Escavadora)
-> (Escavadora -> Escavadora -> Escavadora)
-> Ord Escavadora
Escavadora -> Escavadora -> Bool
Escavadora -> Escavadora -> Ordering
Escavadora -> Escavadora -> Escavadora
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Escavadora -> Escavadora -> Ordering
compare :: Escavadora -> Escavadora -> Ordering
$c< :: Escavadora -> Escavadora -> Bool
< :: Escavadora -> Escavadora -> Bool
$c<= :: Escavadora -> Escavadora -> Bool
<= :: Escavadora -> Escavadora -> Bool
$c> :: Escavadora -> Escavadora -> Bool
> :: Escavadora -> Escavadora -> Bool
$c>= :: Escavadora -> Escavadora -> Bool
>= :: Escavadora -> Escavadora -> Bool
$cmax :: Escavadora -> Escavadora -> Escavadora
max :: Escavadora -> Escavadora -> Escavadora
$cmin :: Escavadora -> Escavadora -> Escavadora
min :: Escavadora -> Escavadora -> Escavadora
Ord, Int -> Escavadora -> ShowS
[Escavadora] -> ShowS
Escavadora -> String
(Int -> Escavadora -> ShowS)
-> (Escavadora -> String)
-> ([Escavadora] -> ShowS)
-> Show Escavadora
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Escavadora -> ShowS
showsPrec :: Int -> Escavadora -> ShowS
$cshow :: Escavadora -> String
show :: Escavadora -> String
$cshowList :: [Escavadora] -> ShowS
showList :: [Escavadora] -> ShowS
Show, ReadPrec [Escavadora]
ReadPrec Escavadora
Int -> ReadS Escavadora
ReadS [Escavadora]
(Int -> ReadS Escavadora)
-> ReadS [Escavadora]
-> ReadPrec Escavadora
-> ReadPrec [Escavadora]
-> Read Escavadora
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Escavadora
readsPrec :: Int -> ReadS Escavadora
$creadList :: ReadS [Escavadora]
readList :: ReadS [Escavadora]
$creadPrec :: ReadPrec Escavadora
readPrec :: ReadPrec Escavadora
$creadListPrec :: ReadPrec [Escavadora]
readListPrec :: ReadPrec [Escavadora]
Read)

-- | Tipo de edifício à superfície.
data TipoEdificio
  = -- | Abastecer combustível.
    Posto
  | -- | Vender a carga.
    Refinaria
  | -- | Reparar a escavadora e comprar melhorias.
    Oficina
  deriving (TipoEdificio -> TipoEdificio -> Bool
(TipoEdificio -> TipoEdificio -> Bool)
-> (TipoEdificio -> TipoEdificio -> Bool) -> Eq TipoEdificio
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TipoEdificio -> TipoEdificio -> Bool
== :: TipoEdificio -> TipoEdificio -> Bool
$c/= :: TipoEdificio -> TipoEdificio -> Bool
/= :: TipoEdificio -> TipoEdificio -> Bool
Eq, Eq TipoEdificio
Eq TipoEdificio =>
(TipoEdificio -> TipoEdificio -> Ordering)
-> (TipoEdificio -> TipoEdificio -> Bool)
-> (TipoEdificio -> TipoEdificio -> Bool)
-> (TipoEdificio -> TipoEdificio -> Bool)
-> (TipoEdificio -> TipoEdificio -> Bool)
-> (TipoEdificio -> TipoEdificio -> TipoEdificio)
-> (TipoEdificio -> TipoEdificio -> TipoEdificio)
-> Ord TipoEdificio
TipoEdificio -> TipoEdificio -> Bool
TipoEdificio -> TipoEdificio -> Ordering
TipoEdificio -> TipoEdificio -> TipoEdificio
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: TipoEdificio -> TipoEdificio -> Ordering
compare :: TipoEdificio -> TipoEdificio -> Ordering
$c< :: TipoEdificio -> TipoEdificio -> Bool
< :: TipoEdificio -> TipoEdificio -> Bool
$c<= :: TipoEdificio -> TipoEdificio -> Bool
<= :: TipoEdificio -> TipoEdificio -> Bool
$c> :: TipoEdificio -> TipoEdificio -> Bool
> :: TipoEdificio -> TipoEdificio -> Bool
$c>= :: TipoEdificio -> TipoEdificio -> Bool
>= :: TipoEdificio -> TipoEdificio -> Bool
$cmax :: TipoEdificio -> TipoEdificio -> TipoEdificio
max :: TipoEdificio -> TipoEdificio -> TipoEdificio
$cmin :: TipoEdificio -> TipoEdificio -> TipoEdificio
min :: TipoEdificio -> TipoEdificio -> TipoEdificio
Ord, Int -> TipoEdificio -> ShowS
[TipoEdificio] -> ShowS
TipoEdificio -> String
(Int -> TipoEdificio -> ShowS)
-> (TipoEdificio -> String)
-> ([TipoEdificio] -> ShowS)
-> Show TipoEdificio
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TipoEdificio -> ShowS
showsPrec :: Int -> TipoEdificio -> ShowS
$cshow :: TipoEdificio -> String
show :: TipoEdificio -> String
$cshowList :: [TipoEdificio] -> ShowS
showList :: [TipoEdificio] -> ShowS
Show, ReadPrec [TipoEdificio]
ReadPrec TipoEdificio
Int -> ReadS TipoEdificio
ReadS [TipoEdificio]
(Int -> ReadS TipoEdificio)
-> ReadS [TipoEdificio]
-> ReadPrec TipoEdificio
-> ReadPrec [TipoEdificio]
-> Read TipoEdificio
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS TipoEdificio
readsPrec :: Int -> ReadS TipoEdificio
$creadList :: ReadS [TipoEdificio]
readList :: ReadS [TipoEdificio]
$creadPrec :: ReadPrec TipoEdificio
readPrec :: ReadPrec TipoEdificio
$creadListPrec :: ReadPrec [TipoEdificio]
readListPrec :: ReadPrec [TipoEdificio]
Read, Int -> TipoEdificio
TipoEdificio -> Int
TipoEdificio -> [TipoEdificio]
TipoEdificio -> TipoEdificio
TipoEdificio -> TipoEdificio -> [TipoEdificio]
TipoEdificio -> TipoEdificio -> TipoEdificio -> [TipoEdificio]
(TipoEdificio -> TipoEdificio)
-> (TipoEdificio -> TipoEdificio)
-> (Int -> TipoEdificio)
-> (TipoEdificio -> Int)
-> (TipoEdificio -> [TipoEdificio])
-> (TipoEdificio -> TipoEdificio -> [TipoEdificio])
-> (TipoEdificio -> TipoEdificio -> [TipoEdificio])
-> (TipoEdificio -> TipoEdificio -> TipoEdificio -> [TipoEdificio])
-> Enum TipoEdificio
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: TipoEdificio -> TipoEdificio
succ :: TipoEdificio -> TipoEdificio
$cpred :: TipoEdificio -> TipoEdificio
pred :: TipoEdificio -> TipoEdificio
$ctoEnum :: Int -> TipoEdificio
toEnum :: Int -> TipoEdificio
$cfromEnum :: TipoEdificio -> Int
fromEnum :: TipoEdificio -> Int
$cenumFrom :: TipoEdificio -> [TipoEdificio]
enumFrom :: TipoEdificio -> [TipoEdificio]
$cenumFromThen :: TipoEdificio -> TipoEdificio -> [TipoEdificio]
enumFromThen :: TipoEdificio -> TipoEdificio -> [TipoEdificio]
$cenumFromTo :: TipoEdificio -> TipoEdificio -> [TipoEdificio]
enumFromTo :: TipoEdificio -> TipoEdificio -> [TipoEdificio]
$cenumFromThenTo :: TipoEdificio -> TipoEdificio -> TipoEdificio -> [TipoEdificio]
enumFromThenTo :: TipoEdificio -> TipoEdificio -> TipoEdificio -> [TipoEdificio]
Enum, TipoEdificio
TipoEdificio -> TipoEdificio -> Bounded TipoEdificio
forall a. a -> a -> Bounded a
$cminBound :: TipoEdificio
minBound :: TipoEdificio
$cmaxBound :: TipoEdificio
maxBound :: TipoEdificio
Bounded)

-- | Edifício à superfície (linha 0).
data Edificio = Edificio
  { -- | Que serviço o edifício presta.
    Edificio -> TipoEdificio
tipoEdificio :: TipoEdificio
  , -- | Posição do edifício, sempre na linha 0.
    Edificio -> Posicao
posicaoEdificio :: Posicao
  }
  deriving (Edificio -> Edificio -> Bool
(Edificio -> Edificio -> Bool)
-> (Edificio -> Edificio -> Bool) -> Eq Edificio
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Edificio -> Edificio -> Bool
== :: Edificio -> Edificio -> Bool
$c/= :: Edificio -> Edificio -> Bool
/= :: Edificio -> Edificio -> Bool
Eq, Eq Edificio
Eq Edificio =>
(Edificio -> Edificio -> Ordering)
-> (Edificio -> Edificio -> Bool)
-> (Edificio -> Edificio -> Bool)
-> (Edificio -> Edificio -> Bool)
-> (Edificio -> Edificio -> Bool)
-> (Edificio -> Edificio -> Edificio)
-> (Edificio -> Edificio -> Edificio)
-> Ord Edificio
Edificio -> Edificio -> Bool
Edificio -> Edificio -> Ordering
Edificio -> Edificio -> Edificio
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Edificio -> Edificio -> Ordering
compare :: Edificio -> Edificio -> Ordering
$c< :: Edificio -> Edificio -> Bool
< :: Edificio -> Edificio -> Bool
$c<= :: Edificio -> Edificio -> Bool
<= :: Edificio -> Edificio -> Bool
$c> :: Edificio -> Edificio -> Bool
> :: Edificio -> Edificio -> Bool
$c>= :: Edificio -> Edificio -> Bool
>= :: Edificio -> Edificio -> Bool
$cmax :: Edificio -> Edificio -> Edificio
max :: Edificio -> Edificio -> Edificio
$cmin :: Edificio -> Edificio -> Edificio
min :: Edificio -> Edificio -> Edificio
Ord, Int -> Edificio -> ShowS
[Edificio] -> ShowS
Edificio -> String
(Int -> Edificio -> ShowS)
-> (Edificio -> String) -> ([Edificio] -> ShowS) -> Show Edificio
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Edificio -> ShowS
showsPrec :: Int -> Edificio -> ShowS
$cshow :: Edificio -> String
show :: Edificio -> String
$cshowList :: [Edificio] -> ShowS
showList :: [Edificio] -> ShowS
Show, ReadPrec [Edificio]
ReadPrec Edificio
Int -> ReadS Edificio
ReadS [Edificio]
(Int -> ReadS Edificio)
-> ReadS [Edificio]
-> ReadPrec Edificio
-> ReadPrec [Edificio]
-> Read Edificio
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Edificio
readsPrec :: Int -> ReadS Edificio
$creadList :: ReadS [Edificio]
readList :: ReadS [Edificio]
$creadPrec :: ReadPrec Edificio
readPrec :: ReadPrec Edificio
$creadListPrec :: ReadPrec [Edificio]
readListPrec :: ReadPrec [Edificio]
Read)

-- | Objeto colocado no mapa.
data Objeto = Dinamite
  { -- | Posição da dinamite.
    Objeto -> Posicao
posicaoDinamite :: Posicao
  , -- | Ticks até explodir. Em cada tick o temporizador é decrementado e a dinamite explode
    -- quando chega a 0.
    Objeto -> Int
tempoDinamite :: Ticks
  }
  deriving (Objeto -> Objeto -> Bool
(Objeto -> Objeto -> Bool)
-> (Objeto -> Objeto -> Bool) -> Eq Objeto
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Objeto -> Objeto -> Bool
== :: Objeto -> Objeto -> Bool
$c/= :: Objeto -> Objeto -> Bool
/= :: Objeto -> Objeto -> Bool
Eq, Eq Objeto
Eq Objeto =>
(Objeto -> Objeto -> Ordering)
-> (Objeto -> Objeto -> Bool)
-> (Objeto -> Objeto -> Bool)
-> (Objeto -> Objeto -> Bool)
-> (Objeto -> Objeto -> Bool)
-> (Objeto -> Objeto -> Objeto)
-> (Objeto -> Objeto -> Objeto)
-> Ord Objeto
Objeto -> Objeto -> Bool
Objeto -> Objeto -> Ordering
Objeto -> Objeto -> Objeto
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Objeto -> Objeto -> Ordering
compare :: Objeto -> Objeto -> Ordering
$c< :: Objeto -> Objeto -> Bool
< :: Objeto -> Objeto -> Bool
$c<= :: Objeto -> Objeto -> Bool
<= :: Objeto -> Objeto -> Bool
$c> :: Objeto -> Objeto -> Bool
> :: Objeto -> Objeto -> Bool
$c>= :: Objeto -> Objeto -> Bool
>= :: Objeto -> Objeto -> Bool
$cmax :: Objeto -> Objeto -> Objeto
max :: Objeto -> Objeto -> Objeto
$cmin :: Objeto -> Objeto -> Objeto
min :: Objeto -> Objeto -> Objeto
Ord, Int -> Objeto -> ShowS
[Objeto] -> ShowS
Objeto -> String
(Int -> Objeto -> ShowS)
-> (Objeto -> String) -> ([Objeto] -> ShowS) -> Show Objeto
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Objeto -> ShowS
showsPrec :: Int -> Objeto -> ShowS
$cshow :: Objeto -> String
show :: Objeto -> String
$cshowList :: [Objeto] -> ShowS
showList :: [Objeto] -> ShowS
Show, ReadPrec [Objeto]
ReadPrec Objeto
Int -> ReadS Objeto
ReadS [Objeto]
(Int -> ReadS Objeto)
-> ReadS [Objeto]
-> ReadPrec Objeto
-> ReadPrec [Objeto]
-> Read Objeto
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Objeto
readsPrec :: Int -> ReadS Objeto
$creadList :: ReadS [Objeto]
readList :: ReadS [Objeto]
$creadPrec :: ReadPrec Objeto
readPrec :: ReadPrec Objeto
$creadListPrec :: ReadPrec [Objeto]
readListPrec :: ReadPrec [Objeto]
Read)

-- | Melhoria comprável na 'Oficina'. Os valores são absolutos (a nova capacidade), exceto
-- 'Dinamites', que é somada ao inventário.
data Melhoria
  = -- | Novo 'depositoEscavadora'.
    Deposito Combustivel
  | -- | Novo 'vidaMaximaEscavadora'.
    Vida Int
  | -- | Novo 'brocaEscavadora'.
    Broca Nivel
  | -- | Nova 'capacidadeEscavadora'.
    Carga Peso
  | -- | Acrescenta dinamites ao inventário.
    Dinamites Int
  deriving (Melhoria -> Melhoria -> Bool
(Melhoria -> Melhoria -> Bool)
-> (Melhoria -> Melhoria -> Bool) -> Eq Melhoria
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Melhoria -> Melhoria -> Bool
== :: Melhoria -> Melhoria -> Bool
$c/= :: Melhoria -> Melhoria -> Bool
/= :: Melhoria -> Melhoria -> Bool
Eq, Eq Melhoria
Eq Melhoria =>
(Melhoria -> Melhoria -> Ordering)
-> (Melhoria -> Melhoria -> Bool)
-> (Melhoria -> Melhoria -> Bool)
-> (Melhoria -> Melhoria -> Bool)
-> (Melhoria -> Melhoria -> Bool)
-> (Melhoria -> Melhoria -> Melhoria)
-> (Melhoria -> Melhoria -> Melhoria)
-> Ord Melhoria
Melhoria -> Melhoria -> Bool
Melhoria -> Melhoria -> Ordering
Melhoria -> Melhoria -> Melhoria
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Melhoria -> Melhoria -> Ordering
compare :: Melhoria -> Melhoria -> Ordering
$c< :: Melhoria -> Melhoria -> Bool
< :: Melhoria -> Melhoria -> Bool
$c<= :: Melhoria -> Melhoria -> Bool
<= :: Melhoria -> Melhoria -> Bool
$c> :: Melhoria -> Melhoria -> Bool
> :: Melhoria -> Melhoria -> Bool
$c>= :: Melhoria -> Melhoria -> Bool
>= :: Melhoria -> Melhoria -> Bool
$cmax :: Melhoria -> Melhoria -> Melhoria
max :: Melhoria -> Melhoria -> Melhoria
$cmin :: Melhoria -> Melhoria -> Melhoria
min :: Melhoria -> Melhoria -> Melhoria
Ord, Int -> Melhoria -> ShowS
[Melhoria] -> ShowS
Melhoria -> String
(Int -> Melhoria -> ShowS)
-> (Melhoria -> String) -> ([Melhoria] -> ShowS) -> Show Melhoria
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Melhoria -> ShowS
showsPrec :: Int -> Melhoria -> ShowS
$cshow :: Melhoria -> String
show :: Melhoria -> String
$cshowList :: [Melhoria] -> ShowS
showList :: [Melhoria] -> ShowS
Show, ReadPrec [Melhoria]
ReadPrec Melhoria
Int -> ReadS Melhoria
ReadS [Melhoria]
(Int -> ReadS Melhoria)
-> ReadS [Melhoria]
-> ReadPrec Melhoria
-> ReadPrec [Melhoria]
-> Read Melhoria
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Melhoria
readsPrec :: Int -> ReadS Melhoria
$creadList :: ReadS [Melhoria]
readList :: ReadS [Melhoria]
$creadPrec :: ReadPrec Melhoria
readPrec :: ReadPrec Melhoria
$creadListPrec :: ReadPrec [Melhoria]
readListPrec :: ReadPrec [Melhoria]
Read)

-- | Loja de melhorias com o respetivo preço. O stock é infinito: comprar não altera a loja.
type Loja = [(Creditos, Melhoria)]

-- ** Jogo

-- | Estado completo do jogo.
data Jogo = Jogo
  { -- | O mapa atual.
    Jogo -> Mapa
mapaJogo :: Mapa
  , -- | A escavadora do jogador.
    Jogo -> Escavadora
escavadoraJogo :: Escavadora
  , -- | Edifícios à superfície.
    Jogo -> [Edificio]
edificiosJogo :: [Edificio]
  , -- | Objetos no mapa.
    Jogo -> [Objeto]
objetosJogo :: [Objeto]
  , -- | Créditos do jogador.
    Jogo -> Int
creditosJogo :: Creditos
  , -- | Melhorias à venda.
    Jogo -> Loja
lojaJogo :: Loja
  }
  deriving (Jogo -> Jogo -> Bool
(Jogo -> Jogo -> Bool) -> (Jogo -> Jogo -> Bool) -> Eq Jogo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Jogo -> Jogo -> Bool
== :: Jogo -> Jogo -> Bool
$c/= :: Jogo -> Jogo -> Bool
/= :: Jogo -> Jogo -> Bool
Eq, Eq Jogo
Eq Jogo =>
(Jogo -> Jogo -> Ordering)
-> (Jogo -> Jogo -> Bool)
-> (Jogo -> Jogo -> Bool)
-> (Jogo -> Jogo -> Bool)
-> (Jogo -> Jogo -> Bool)
-> (Jogo -> Jogo -> Jogo)
-> (Jogo -> Jogo -> Jogo)
-> Ord Jogo
Jogo -> Jogo -> Bool
Jogo -> Jogo -> Ordering
Jogo -> Jogo -> Jogo
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Jogo -> Jogo -> Ordering
compare :: Jogo -> Jogo -> Ordering
$c< :: Jogo -> Jogo -> Bool
< :: Jogo -> Jogo -> Bool
$c<= :: Jogo -> Jogo -> Bool
<= :: Jogo -> Jogo -> Bool
$c> :: Jogo -> Jogo -> Bool
> :: Jogo -> Jogo -> Bool
$c>= :: Jogo -> Jogo -> Bool
>= :: Jogo -> Jogo -> Bool
$cmax :: Jogo -> Jogo -> Jogo
max :: Jogo -> Jogo -> Jogo
$cmin :: Jogo -> Jogo -> Jogo
min :: Jogo -> Jogo -> Jogo
Ord, Int -> Jogo -> ShowS
[Jogo] -> ShowS
Jogo -> String
(Int -> Jogo -> ShowS)
-> (Jogo -> String) -> ([Jogo] -> ShowS) -> Show Jogo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Jogo -> ShowS
showsPrec :: Int -> Jogo -> ShowS
$cshow :: Jogo -> String
show :: Jogo -> String
$cshowList :: [Jogo] -> ShowS
showList :: [Jogo] -> ShowS
Show, ReadPrec [Jogo]
ReadPrec Jogo
Int -> ReadS Jogo
ReadS [Jogo]
(Int -> ReadS Jogo)
-> ReadS [Jogo] -> ReadPrec Jogo -> ReadPrec [Jogo] -> Read Jogo
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Jogo
readsPrec :: Int -> ReadS Jogo
$creadList :: ReadS [Jogo]
readList :: ReadS [Jogo]
$creadPrec :: ReadPrec Jogo
readPrec :: ReadPrec Jogo
$creadListPrec :: ReadPrec [Jogo]
readListPrec :: ReadPrec [Jogo]
Read)

-- | Ações do jogador.
data Jogada
  = -- | Ausência de ação que desliga propulsores ativos.
    Parado
  | -- | Deslocar-se ('Ar'), voar ('Cima') ou escavar (bloco escavável, só quando apoiado).
    Move Direcao
  | -- | Na 'Refinaria': vende toda a carga.
    Vende
  | -- | No 'Posto': enche o depósito, limitado pelos créditos.
    Abastece
  | -- | Na 'Oficina': repara a escavadora, limitado pelos créditos.
    Repara
  | -- | Na 'Oficina': compra a melhoria com este índice na 'Loja'.
    Compra Int
  | -- | Coloca uma dinamite na posição atual.
    LargaDinamite
  deriving (Jogada -> Jogada -> Bool
(Jogada -> Jogada -> Bool)
-> (Jogada -> Jogada -> Bool) -> Eq Jogada
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Jogada -> Jogada -> Bool
== :: Jogada -> Jogada -> Bool
$c/= :: Jogada -> Jogada -> Bool
/= :: Jogada -> Jogada -> Bool
Eq, Eq Jogada
Eq Jogada =>
(Jogada -> Jogada -> Ordering)
-> (Jogada -> Jogada -> Bool)
-> (Jogada -> Jogada -> Bool)
-> (Jogada -> Jogada -> Bool)
-> (Jogada -> Jogada -> Bool)
-> (Jogada -> Jogada -> Jogada)
-> (Jogada -> Jogada -> Jogada)
-> Ord Jogada
Jogada -> Jogada -> Bool
Jogada -> Jogada -> Ordering
Jogada -> Jogada -> Jogada
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Jogada -> Jogada -> Ordering
compare :: Jogada -> Jogada -> Ordering
$c< :: Jogada -> Jogada -> Bool
< :: Jogada -> Jogada -> Bool
$c<= :: Jogada -> Jogada -> Bool
<= :: Jogada -> Jogada -> Bool
$c> :: Jogada -> Jogada -> Bool
> :: Jogada -> Jogada -> Bool
$c>= :: Jogada -> Jogada -> Bool
>= :: Jogada -> Jogada -> Bool
$cmax :: Jogada -> Jogada -> Jogada
max :: Jogada -> Jogada -> Jogada
$cmin :: Jogada -> Jogada -> Jogada
min :: Jogada -> Jogada -> Jogada
Ord, Int -> Jogada -> ShowS
[Jogada] -> ShowS
Jogada -> String
(Int -> Jogada -> ShowS)
-> (Jogada -> String) -> ([Jogada] -> ShowS) -> Show Jogada
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Jogada -> ShowS
showsPrec :: Int -> Jogada -> ShowS
$cshow :: Jogada -> String
show :: Jogada -> String
$cshowList :: [Jogada] -> ShowS
showList :: [Jogada] -> ShowS
Show, ReadPrec [Jogada]
ReadPrec Jogada
Int -> ReadS Jogada
ReadS [Jogada]
(Int -> ReadS Jogada)
-> ReadS [Jogada]
-> ReadPrec Jogada
-> ReadPrec [Jogada]
-> Read Jogada
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Jogada
readsPrec :: Int -> ReadS Jogada
$creadList :: ReadS [Jogada]
readList :: ReadS [Jogada]
$creadPrec :: ReadPrec Jogada
readPrec :: ReadPrec Jogada
$creadListPrec :: ReadPrec [Jogada]
readListPrec :: ReadPrec [Jogada]
Read)

-- * Constantes do jogo

-- ** Minérios

-- | Valor de venda de uma unidade de cada minério, na 'Refinaria'.
--
-- Cada minério vale cerca de duas vezes e meia o anterior, e o mesmo salto separa cada nível da
-- broca: o valor de uma viagem cresce com a profundidade a que se consegue chegar.
--
-- +------------+-------+
-- | Minério    | Valor |
-- +============+=======+
-- | 'Ferro'    |    25 |
-- +------------+-------+
-- | 'Bronze'   |    60 |
-- +------------+-------+
-- | 'Prata'    |   150 |
-- +------------+-------+
-- | 'Ouro'     |   400 |
-- +------------+-------+
-- | 'Platina'  |  1000 |
-- +------------+-------+
-- | 'Diamante' |  2500 |
-- +------------+-------+
valorMinerio :: TipoMinerio -> Creditos
valorMinerio :: TipoMinerio -> Int
valorMinerio TipoMinerio
Ferro = Int
25
valorMinerio TipoMinerio
Bronze = Int
60
valorMinerio TipoMinerio
Prata = Int
150
valorMinerio TipoMinerio
Ouro = Int
400
valorMinerio TipoMinerio
Platina = Int
1000
valorMinerio TipoMinerio
Diamante = Int
2500

-- | Peso de uma unidade de cada minério na carga da escavadora.
--
-- __NB:__ o 'Diamante' é o mais valioso /e/ o mais leve; a 'Platina' obriga a escolher.
pesoMinerio :: TipoMinerio -> Peso
pesoMinerio :: TipoMinerio -> Int
pesoMinerio TipoMinerio
Ferro = Int
2
pesoMinerio TipoMinerio
Bronze = Int
2
pesoMinerio TipoMinerio
Prata = Int
3
pesoMinerio TipoMinerio
Ouro = Int
4
pesoMinerio TipoMinerio
Platina = Int
5
pesoMinerio TipoMinerio
Diamante = Int
1

-- ** Escavação e movimento

-- | Dureza de um bloco, ou seja, o nível mínimo de 'brocaEscavadora' que o consegue escavar.
--
-- Devolve @Nothing@ para os blocos que não são escaváveis: 'Ar' (não há nada para escavar) e
-- 'Rocha' (inescavável a qualquer nível).
durezaBloco :: Bloco -> Maybe Nivel
durezaBloco :: Bloco -> Maybe Int
durezaBloco Bloco
Ar = Maybe Int
forall a. Maybe a
Nothing
durezaBloco Bloco
Rocha = Maybe Int
forall a. Maybe a
Nothing
durezaBloco Bloco
Terra = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1
durezaBloco Bloco
Lava = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1
durezaBloco (Minerio TipoMinerio
Ferro) = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1
durezaBloco (Minerio TipoMinerio
Bronze) = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1
durezaBloco (Minerio TipoMinerio
Prata) = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
2
durezaBloco (Minerio TipoMinerio
Ouro) = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
2
durezaBloco (Minerio TipoMinerio
Platina) = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
3
durezaBloco (Minerio TipoMinerio
Diamante) = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
3

-- | Combustível gasto a escavar um bloco: a sua 'durezaBloco'.
--
-- >>> custoEscavacao Terra
-- 1
-- >>> custoEscavacao Rocha
-- 0
custoEscavacao :: Bloco -> Combustivel
custoEscavacao :: Bloco -> Int
custoEscavacao Bloco
b = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
0 (Bloco -> Maybe Int
durezaBloco Bloco
b)

-- | Combustível gasto a deslocar-se um bloco na horizontal.
custoMovimento :: Combustivel
custoMovimento :: Int
custoMovimento = Int
1

-- | Combustível gasto a subir um bloco com os propulsores.
custoVoo :: Combustivel
custoVoo :: Int
custoVoo = Int
2

-- ** Dano

-- | Vida perdida ao escavar um bloco de 'Lava'.
danoLava :: Int
danoLava :: Int
danoLava = Int
30

-- | Número de blocos que a escavadora pode cair sem sofrer dano.
alturaQuedaSegura :: Int
alturaQuedaSegura :: Int
alturaQuedaSegura = Int
2

-- | Vida perdida por cada bloco caído acima da 'alturaQuedaSegura'.
danoQueda :: Int
danoQueda :: Int
danoQueda = Int
10

-- ** Edifícios

-- | Créditos por unidade de combustível, no 'Posto'.
precoCombustivel :: Creditos
precoCombustivel :: Int
precoCombustivel = Int
1

-- | Créditos por ponto de vida reparado, na 'Oficina'.
precoReparacao :: Creditos
precoReparacao :: Int
precoReparacao = Int
2

-- ** Dinamite

-- | Ticks entre largar uma dinamite e a sua explosão.
duracaoDinamite :: Ticks
duracaoDinamite :: Int
duracaoDinamite = Int
3

-- | Raio da explosão de uma dinamite, em blocos (distância de Chebyshev).
raioDinamite :: Int
raioDinamite :: Int
raioDinamite = Int
1

-- | Vida perdida numa explosão que apanhe a escavadora.
danoDinamite :: Int
danoDinamite :: Int
danoDinamite = Int
40

-- * Funções auxiliares

{-| Função que gera uma lista de números aleatórios a partir de uma 'Semente'.

== Exemplos

>>> geraAleatorios 2627 3
[7884690122452951765,-2301222553746467507,2230926884526872602]
-}
geraAleatorios :: Semente -> Int -> [Int]
geraAleatorios :: Int -> Int -> [Int]
geraAleatorios Int
s Int
c = Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
c ([Int] -> [Int]) -> [Int] -> [Int]
forall a b. (a -> b) -> a -> b
$ StdGen -> [Int]
forall g. RandomGen g => g -> [Int]
forall a g. (Random a, RandomGen g) => g -> [a]
randoms (Int -> StdGen
mkStdGen Int
s)