{-# LANGUAGE GeneralizedNewtypeDeriving, StandaloneDeriving, 
 FlexibleInstances, EmptyDataDecls, TypeSynonymInstances #-}

module Types where

import Data.Ix
import Data.Monoid

instance Num a => Num (a,a) where
    a + b = (fst a + fst b, snd a + snd b)
    a - b = (fst a - fst b, snd a - snd b)
    a * b = (fst a * fst b, snd a * snd b)
    negate (a,b) = (negate a, negate b)
    abs (a,b) = (abs a, abs b)
    signum (a,b) = (signum a, signum b)
    fromInteger n = (fromInteger n, fromInteger n)
instance Monoid Int where
    mempty = 0
    mappend = (+)
    mconcat = sum
instance Monoid Double where
    mempty = 0.0
    mappend = (+)
    mconcat = sum

newtype Location = Loc (Int,Int) deriving (Eq,Ord,Ix,Show,Monoid,Num)
newtype Direction = Dir (Double,Double) deriving (Eq,Show,Monoid,Num)

type Coord = (Int,Int)

data Board = Board { trolls  :: [Location]
                   , dwarves :: [Location]
                   } deriving (Eq,Show)

type Situation = (Location, [Location], [Location])
type Strategy = Situation -> Direction

(<+>) :: Strategy -> Strategy -> Strategy
s1 <+> s2 = \x -> s1 x + s2 x
(<*>) :: Double -> Strategy -> Strategy
n <*> s = scale n . s

scale n (Dir (a,b)) = Dir (n*a,n*b)

