Corrected pragma in Board.hs
[tmp/julm/arpeggigon.git] / src / RMCA / GUI / Board.hs
index b65170a91bf33ce2c77fc8c302e04fcbcdfed84c..bde25d3f48a94cde6bf00a1e33f39014bed96b8b 100644 (file)
@@ -1,55 +1,55 @@
-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, ScopedTypeVariables,
-             TypeSynonymInstances #-}
-
-module RMCA.GUI.Board where
-
+{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses,
+             ScopedTypeVariables, TypeSynonymInstances #-}
+
+module RMCA.GUI.Board ( GUICell (..)
+                      , attachGameRules
+                      , initGame
+                      , initBoardRV
+                      , rotateGUICell
+                      , inertCell
+                      , toGUICoords
+                      , fromGUICoords
+                      , validArea
+                      , Player(..)
+                      , actualTile
+                      ) where
+
+import           Control.Arrow
 import           Control.Monad
 import           Data.Array
 import           Data.Array.MArray
-import qualified Data.Bifunctor                   as BF
 import           Data.Board.GameBoardIO
 import           Data.CBMVar
 import           Data.Maybe
-import           Data.Ratio
 import           Data.ReactiveValue
 import           Game.Board.BasicTurnGame
 import           Graphics.UI.Gtk                  hiding (Action)
-import           Graphics.UI.Gtk.Board.BoardLink
-import           Graphics.UI.Gtk.Board.TiledBoard hiding (Board)
+import           Graphics.UI.Gtk.Board.BoardLink  hiding (attachGameRules)
+import           Graphics.UI.Gtk.Board.TiledBoard hiding
+    ( Board
+    , boardOnPieceDragDrop
+    , boardOnPieceDragOver
+    , boardOnPieceDragStart
+    )
 import qualified Graphics.UI.Gtk.Board.TiledBoard as BIO
 import           Paths_RMCA
-import           RMCA.Global.Clock
+import           RMCA.GUI.HelpersRewrite
+import           RMCA.IOClockworks
 import           RMCA.Semantics
 
-import           Debug.Trace
-
-data GUICell = GUICell { cellAction  :: Action
-                       , repeatCount :: Int
-                       , asPh        :: Bool
-                       } deriving(Show)
+newtype GUIBoard = GUIBoard (GameState Int Tile Player GUICell)
 
-newtype GUIBoard = GUIBoard { toGS :: GameState Int Tile Player GUICell }
+-- There are two types of tiles that can be distinguished by setting
+-- two different colors for debugging purposes. A future release might
+-- want to remove that.
+data Tile = TileW | TileB
 
-type IOBoard = BIO.Board Int Tile (Player,GUICell)
-
-data Tile = Tile
-data Player = Player deriving(Show)
 
 rotateGUICell :: GUICell -> GUICell
 rotateGUICell g = g { cellAction = rotateAction $ cellAction g }
   where rotateAction (ChDir b na d) = ChDir b na (nextDir d)
         rotateAction x = x
 
--- Takes a GUI coordinate and give the corresponding coordinate on the
--- internal board
-fromGUICoords :: (Int,Int) -> (Int,Int)
-fromGUICoords (x,y) = (x,(x `mod` 2 - y) `quot` 2)
-
--- Takes coordinates from the point of view of the internal board and
--- translates them to GUI board coordinates.
-toGUICoords :: (Int,Int) -> (Int,Int)
-toGUICoords (x,y) = (x,2*(-y) + x `mod` 2)
-
 tileW :: Int
 tileW = 40
 
@@ -63,56 +63,23 @@ hexW = round d
   where d :: Double
         d = 4 * fromIntegral tileW / 3
 
+{-
 hexH :: Int
 hexH = round d
   where d :: Double
         d = sqrt 3 * fromIntegral hexW / 2
-
-xMax, yMax :: Int
-(xMax,yMax) = BF.second (*2) $ neighbor N nec
-xMin, yMin :: Int
-(xMin,yMin) = BF.second (*2) swc
+-}
 
 boardToTile :: [(Int,Int,Tile)]
-boardToTile = [(x,y,Tile) | (x,y) <- range ( (xMin-1,yMin)
-                                           , (xMax+3,yMax+1))]
-
-defNa :: NoteAttr
-defNa = NoteAttr { naArt = NoAccent
-                 , naDur = 1 % 4
-                 , naOrn = noOrn
-                 }
-
-ctrlPieces :: [(Int,Int,Player,GUICell)]
-ctrlPieces = [(xMax+2,y,Player,GUICell { cellAction = action
-                                       , repeatCount = 1
-                                       , asPh = False
-                                       })
-             | let actions = [ Absorb, Stop defNa
-                             , ChDir False defNa N, ChDir True defNa N
-                             , Split defNa]
-                     -- /!\ It would be nice to find a general formula
-                     -- for placing the control pieces.
-                     , (y,action) <- zip [ yMin+4,yMin+8..] actions]
-
-ctrlCoords :: [(Int,Int)]
-ctrlCoords = map (\(x,y,_,_) -> (x,y)) ctrlPieces
-
-boardToPiece :: [PlayHead] -> Board -> [(Int,Int,Player,GUICell)]
-boardToPiece ph = (++ ctrlPieces) . map placePiece .
-                  filter (onBoard . fst) . assocs
-  where placePiece :: (Pos,Cell) -> (Int,Int,Player,GUICell)
-        placePiece ((x,y),(a,n)) = let c = GUICell { cellAction = a
-                                                   , repeatCount = n
-                                                   , asPh = (x,y) `elem` phPosS
-                                                   }
-                                       (x',y') = toGUICoords (x,y)
-                                   in (x',y',Player,c)
-        phPosS = map phPos ph
-
-validArea :: [(Int,Int)]
-validArea = filter (onBoard . fromGUICoords) $
-            map (\(x,y,_,_) -> (x,y)) $ boardToPiece [] $ makeBoard []
+boardToTile = [(x,y,selTile) | (x,y) <- range ( (xMin-1,yMin)
+                                              , (xMax+3,yMax+1))
+                             , let selTile = if even x && even y
+                                                ||
+                                                odd x && odd y
+                                             then TileW
+                                             else TileB ]
+
+
 
 outGUIBoard :: (Int,Int) -> Bool
 outGUIBoard (xf,yf) = xf < xMin || xf > xMax || yf < yMin || yf > yMax
@@ -135,13 +102,13 @@ instance PlayableGame GUIBoard Int Tile Player GUICell where
   allPos (GUIBoard game)    = boardPos game
   allPieces (GUIBoard game) = boardPieces' game
   moveEnabled _             = True
+
   canMove (GUIBoard game) _ (x,y)
     | Just (_,p) <- getPieceAt game (x,y)
     , GUICell { cellAction = Inert } <- p = False
     | Nothing <- getPieceAt game (x,y) = False
     | otherwise = True
-  canMoveTo _ _ _ fPos = fPos `elem` validArea
-                         || outGUIBoard fPos
+  canMoveTo _ _ _ fPos = fPos `elem` validArea || outGUIBoard fPos
 
   move (GUIBoard game) _ iPos@(_,yi) fPos@(xf,yf)
     | outGUIBoard iPos && outGUIBoard fPos = []
@@ -186,12 +153,15 @@ instance PlayableGame GUIBoard Int Tile Player GUICell where
 initGame :: IO (Game GUIBoard Int Tile Player GUICell)
 initGame = do
   pixbufs <- fileToPixbuf
-  tilePixbuf <- pixbufNew ColorspaceRgb False 8 tileW tileH
-  pixbufFill tilePixbuf 50 50 50 0
+  tilePixbufB <- pixbufNew ColorspaceRgb False 8 tileW tileH
+  tilePixbufW <- pixbufNew ColorspaceRgb False 8 tileW tileH
+  pixbufFill tilePixbufB 50 50 50 0
+  pixbufFill tilePixbufW 50 50 50 0
   let pixPiece :: (Player,GUICell) -> Pixbuf
       pixPiece (_,a) = fromJust $ lookup (actionToFile a) pixbufs
       pixTile :: Tile -> Pixbuf
-      pixTile _ = tilePixbuf
+      pixTile TileW = tilePixbufW
+      pixTile TileB = tilePixbufB
       visualA = VisualGameAspects { tileF = pixTile
                                   , pieceF = pixPiece
                                   , bgColor = (1000,1000,1000)
@@ -202,26 +172,26 @@ initGame = do
 
 -- Initializes a readable RV for the board and an readable-writable RV
 -- for the playheads. Also installs some handlers for pieces modification.
-initBoardRV :: BIO.Board Int Tile (Player,GUICell)
+initBoardRV :: IOTick
+            -> BIO.Board Int Tile (Player,GUICell)
             -> IO ( ReactiveFieldRead IO Board
                   , Array Pos (ReactiveFieldWrite IO GUICell)
                   , ReactiveFieldWrite IO [PlayHead])
-initBoardRV board@BIO.Board { boardPieces = (GameBoard gArray) } = do
+initBoardRV tc board@BIO.Board { boardPieces = (GameBoard gArray) } = do
   -- RV creation
   phMVar <- newCBMVar []
-  notBMVar <- mkClockRV 10
   let getterB :: IO Board
       getterB = do
         (boardArray :: [((Int,Int),Maybe (Player,GUICell))]) <- getAssocs gArray
         let board = makeBoard $
-              map (BF.first fromGUICoords .
-                   BF.second ((\(_,c) -> (cellAction c,repeatCount c)) .
+              map (first fromGUICoords .
+                   second ((\(_,c) -> (cellAction c,repeatCount c)) .
                               fromJust)) $
               filter (isJust . snd) boardArray
         return board
 
       notifierB :: IO () -> IO ()
-      notifierB = reactiveValueOnCanRead notBMVar
+      notifierB = reactiveValueOnCanRead tc
 
       getterP :: IO [PlayHead]
       getterP = readCBMVar phMVar