1 -- This file is part of Intricacy
2 -- Copyright (C) 2013 Martin Bays <mbays@sdf.org>
4 -- This program is free software: you can redistribute it and/or modify
5 -- it under the terms of version 3 of the GNU General Public License as
6 -- published by the Free Software Foundation, or any later version.
8 -- You should have received a copy of the GNU General Public License
9 -- along with this program. If not, see http://www.gnu.org/licenses/.
11 module BoardColouring
where
13 import Control
.Applicative
15 import Data
.Function
(on
)
18 import qualified Data
.Map
as Map
21 import qualified Data
.Set
as Set
29 type PieceColouring
= Map PieceIdx
Int
31 colouredPieces
:: Bool -> GameState
-> [PieceIdx
]
32 colouredPieces colourFixed st
= [ idx |
33 (idx
, PlacedPiece _ p
) <- enumVec
$ placedPieces st
35 isBlock p
&& (idx
> 0) && colourFixed ||
not (null $ springsEndAtIdx st idx
) ]
37 pieceTypeColouring
:: GameState
-> [PieceIdx
] -> PieceColouring
38 pieceTypeColouring st coloured
= Map
.fromList
39 [ (idx
, col
) |
(idx
, PlacedPiece _ p
) <- enumVec
$ placedPieces st
41 , let col
= if isBlock p
then 1+((connGraphHeight st idx
- 1) `
mod`
5) else 0 ]
44 boardColouring
:: GameState
-> [PieceIdx
] -> PieceColouring
-> PieceColouring
45 boardColouring st coloured
= fiveColour graph
48 graph
= Map
.fromList
[ (idx
, nub $ neighbours idx
)
51 neighbours
' idx
(perim idx
) []
52 perim
:: PieceIdx
-> Set
(HexPos
,HexDir
)
54 Set
.fromList
$ nubBy ((==)`on`
fst) [ (pos
', neg dir
)
56 , pos
<- fullFootprint st idx
57 , let pos
' = dir
+^ pos
59 (idx
',_
) <- Map
.lookup pos
' board
62 neighbours
' :: PieceIdx
-> Set
(HexPos
,HexDir
) -> [PieceIdx
] -> [PieceIdx
]
66 let a
= head $ Set
.elems as
67 (path
, ns
') = march idx
(fst a
) a
True
69 (Set
.filter (\(pos
,_
) -> pos `
notElem` path
) as)
71 -- |march around the piece's boundary, returning positions visited and
72 -- neighbouring pieces met (in order)
73 march idx startPos
(pos
,basedir
) init
74 |
not init && pos
== startPos
= ([],[])
77 (idx
',_
) <- Map
.lookup pos board
78 guard $ idx
' `
elem` coloured
81 [ (pos
', rotate
(h
-2) basedir
)
83 , let pos
' = rotate h basedir
+^pos
84 , (fst <$> Map
.lookup pos
' board
) /= Just idx
86 (path
,ns
) = case mNext
of
88 Just
next -> march idx startPos
next False
89 in (pos
:path
, maybeToList mn
++ns
)