--- Cartas poker (Valor,Palo)

--- donde Treboles = 1, Corazones = 2, Picas = 3, Diamantes = 4.
       -- Valor = Valor_real, J = 11, Q = 12, K = 13, A = 14
import Backtr


type Carta = (Int,Int)

-- tipos para backtraking
type TParcial  = ([Carta], [Carta]) -- (mano,mazo)
type TSolucion = [Carta]



-- Te hace todas las cartas de la baraja.
baraja :: [Carta]
baraja = [(x,y) | x <- [2..14], y <- [1..4]]

aux :: [Carta]
aux = [(x,y) | x <- [2..2], y <- [1..8]]
----------------------------------------------------------------------
-- si la longitud es 5 ya tengo la mano.
esSolucion :: TParcial -> Bool
esSolucion par = length (fst par) == 5


-----------------------------------------------------------------------
convertir :: TParcial -> TSolucion
convertir par = fst par


-----------------------------------------------------------------------
-- da como resultado todas las posibilidades de cojer una carta mas del mazo a la mano.
ampliar :: TParcial -> [TParcial]
ampliar (mano,mazo) = ampliarAux 1 mazo mano

-- resultado de la inmersion de ampliar
ampliarAux :: Int -> [Carta] -> [Carta] -> [TParcial]
ampliarAux carta mazo mano | carta <= length mazo = (insert (elemPos carta mazo) mano, drop carta mazo):(ampliarAux (carta + 1) mazo mano)
                           | otherwise = []
--ampliarAux carta mazo mano | carta <= length mazo = (insert (elemPos carta mazo) mano, delete (elemPos carta mazo) mazo):(ampliarAux (carta + 1) mazo mano)


-- da la carta de la posicion. La posicion tiene que ser uno o superior
-- y como mucho la longitud del mazo.
elemPos :: Int -> [a] -> a
elemPos pos list = head (drop (pos-1) list)

-- borra el elemento de la lista (si no se repite el elemento).
delete :: Eq a => a -> [a] -> [a]
delete elem [] = []
delete elem (p:r) | p == elem = r
                  | otherwise = p:(delete elem r)

insert :: Ord a => a -> [a] -> [a]
insert elem [] = [elem]
insert elem (p:r) | elem <= p = (elem:p:r)
                  | otherwise = p:(insert elem r)


--------------------------FUNCIONES PARA QUE OCUPE MENOS ESPACIO----------------------------------
codify:: Carta -> Char
codify (val,pal) = toEnum (val*8+pal)

decodify:: Char -> Carta
decodify char = divMod (fromEnum char) 8 


--codifyList :: [Carta] -> [Char]
--codifyList cartas = map codify cartas


-------------------------------------------------------------------------
--Te devuelve todas las formas que hay de cojer 5 cartas de baraja.
todasManos :: [Carta] -> [[Char]]
todasManos mazo = map (map codify) (backtr esSolucion convertir ampliar (\x -> True) ([], baraja))


isRepeated :: Eq a => [a] -> Bool
isRepeated [] = False
isRepeated (p:r) = (any (\x -> x == p) r) || isRepeated r

main = do
       print ( isRepeated(todasManos baraja))

