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
)
16 import qualified Data
.Map
as Map
18 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 and [ isBlock p
, idx
> 0
36 , or [ colourFixed
, not $ null $ springsEndAtIdx st idx
] ] ]
38 pieceTypeColouring
:: GameState
-> [PieceIdx
] -> PieceColouring
39 pieceTypeColouring st coloured
= Map
.fromList
40 [ (idx
, col
) |
(idx
, PlacedPiece _ p
) <- enumVec
$ placedPieces st
42 , let col
= if isBlock p
then 1+((connGraphHeight st idx
- 1) `
mod`
5) else 0 ]
45 boardColouring
:: GameState
-> [PieceIdx
] -> PieceColouring
-> PieceColouring
46 boardColouring st coloured lastCol
=
47 fiveColour graph lastCol
50 graph
= Map
.fromList
[ (idx
, nub $ neighbours idx
)
53 neighbours
' idx
(perim idx
) []
54 perim
:: PieceIdx
-> Set
(HexPos
,HexDir
)
56 Set
.fromList
$ nubBy ((==)`on`
fst) [ (pos
', neg dir
)
58 , pos
<- fullFootprint st idx
59 , let pos
' = dir
+^ pos
61 (idx
',_
) <- Map
.lookup pos
' board
64 neighbours
' :: PieceIdx
-> Set
(HexPos
,HexDir
) -> [PieceIdx
] -> [PieceIdx
]
68 let a
= head $ Set
.elems as
69 (path
, ns
') = march idx
(fst a
) a
True
71 (Set
.filter (\(pos
,_
) -> pos `
notElem` path
) as)
73 -- |march around the piece's boundary, returning positions visited and
74 -- neighbouring pieces met (in order)
75 march idx startPos
(pos
,basedir
) init
76 |
not init && pos
== startPos
= ([],[])
79 (idx
',_
) <- Map
.lookup pos board
80 guard $ idx
' `
elem` coloured
83 [ (pos
', rotate
(h
-2) basedir
)
85 , let pos
' = (rotate h basedir
)+^pos
86 , (fst <$> Map
.lookup pos
' board
) /= Just idx
88 (path
,ns
) = case mNext
of
90 Just
next -> march idx startPos
next False
91 in (pos
:path
, (maybeToList mn
)++ns
)