-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A monadic take on a 2,500-year-old board game - library. -- -- Goatee is a Go library and game editor, written in Haskell. It -- provides a GUI for recording, studying, and editing game records. -- Underneath this is a portable library for manipulating SGF files to -- build UIs and tools. Goatee aims to be full-featured by supporting all -- of the SGF spec and allowing for full and easy customization of the -- game records you create. -- -- This package is the shared library. @package goatee @version 0.2.0 -- | Common definitions for a renderer that supports failure. module Game.Goatee.Lib.Renderer -- | A monad for accumulating string output with the possibility of -- failure. type Render = WriterT String (Either String) -- | Returns either the rendered result on the right, or a message -- describing a failure on the left. runRender :: Render a -> Either String String -- | Wraps a renderer in an exception handler that, when the renderer or -- something it calls fails, will add context about this renderer's -- invocation to the failure message. rendererOf :: Show a => String -> (a -> Render ()) -> a -> Render () -- | Base-10 arbitrary-precision floating-point numbers. module Game.Goatee.Common.Bigfloat -- | A base-10, infinite-precision, floating-point number. Implemented as -- an infinite-precision significand together with an exponent, such that -- the numeric value is equal to significand f * (10 ^ -- exponent f). The exponent is a limited-precision -- Int, because some operations may break if the exponent is -- larger (specifically show and toDouble). This shouldn't -- be an issue for Goatee. -- -- These values form an integral domain. -- -- The Show instance always outputs in decimal notation, never -- scientific notation. Examples: -- --
--   300   (never trailing .0 if there's no fractional part)
--   0.1   (never redundant trailing or leading zeros)
--   
-- -- Similarly, the Read instance accepts numbers matching the regex -- -?\d+(\.\d+)?(e-?\d+)?. Scientific exponent notation is -- supported for reading, for ease of converting Doubles to -- Bigfloats. data Bigfloat -- | encode significand exponent creates a Bigfloat value -- whose numeric value is significand * (10 ^ exponent). encode :: Integer -> Int -> Bigfloat significand :: Bigfloat -> Integer exponent :: Bigfloat -> Int -- | Converts a Double to a Bigfloat (with as much precision -- as the Double Show instance provides). fromDouble :: Double -> Bigfloat -- | Converts a Bigfloat to a Double, lossily. toDouble :: Bigfloat -> Double instance Read Bigfloat instance Show Bigfloat instance Num Bigfloat instance Ord Bigfloat instance Eq Bigfloat -- | Common utilities used throughout the project. module Game.Goatee.Common -- | Drops the element at an index from a list. If the index is out of -- bounds then the list is returned unmodified. listDeleteAt :: Int -> [a] -> [a] -- | Inserts the element into the list before the given position. If the -- position is less than 0 or greater than the length of the list, then -- the index is clamped to this range. listInsertAt :: Int -> a -> [a] -> [a] -- | listReplace old new list replaces all occurrences of -- old with new in list. listReplace :: Eq a => a -> a -> [a] -> [a] -- | Modifies the element at a specific index in a list. listUpdate :: Show a => (a -> a) -> Int -> [a] -> [a] -- | If any item is a Left, then the list of Lefts is -- returned, otherwise the list of Rights is returned. andEithers :: [Either a b] -> Either [a] [b] -- | for is flip map. for :: [a] -> (a -> b) -> [b] -- | Transforms both values in a homogeneous tuple. mapTuple :: (a -> b) -> (a, a) -> (b, b) -- | Executes the monadic function if a Maybe contains a value. whenMaybe :: Monad m => Maybe a -> (a -> m ()) -> m () -- | Finds the first tuple whose first element is true, and returns its -- second element. If all of the first values are false, then the first -- argument to cond is returned instead. cond :: a -> [(Bool, a)] -> a -- | A function form of if that takes its test last. if' :: a -> a -> Bool -> a -- | and in a monad. Executes the actions in the list in order. If -- any action returns false then the remaining actions are skipped and -- the result is false. Otherwise all actions returned true, and the -- result is true. An empty list returns true. andM :: Monad m => [m Bool] -> m Bool -- | forM_ that also passes in the index of each element. forIndexM_ :: Monad m => [a] -> (Int -> a -> m ()) -> m () -- | whileM test body repeatedly evaluates test until it -- returns false. Every time test returns true, body is -- executed once. whileM :: Monad m => m Bool -> m () -> m () -- | whileM' test body repeatedly evaluates test until it -- returns Nothing. Every time it returns a Just, that -- value is passed to body and the result is executed. whileM' :: Monad m => m (Maybe a) -> (a -> m ()) -> m () -- | doWhileM init body repeatedly calls body with -- init. As long as body returns a Right -- value, it is re-executed with the returned value. When it returns a -- Left value, the loop stops and the value is returned. doWhileM :: Monad m => a -> (a -> m (Either b a)) -> m b -- | Constants and data types for property values used in SGF game trees. module Game.Goatee.Lib.Types -- | The FF versions supported by Goatee. Currently only 4. supportedFormatVersions :: [Int] -- | The default SGF version to use when FF[] is not specified in -- a root node. -- -- This value is actually INCORRECT: SGF defines it to be 1, but because -- we don't support version 1 yet, for the sake of ignoring this issue -- (for now!) in tests, we fix the default to be 4. defaultFormatVersion :: Int -- | SGF supports multiple game types. This list contains the game types -- that Goatee supports, which is only Go (1). supportedGameTypes :: [Int] -- | The default size of the board. The FF[4] SGF spec says that the -- default Go board is 19x19 square. boardSizeDefault :: Int -- | The minimum board size allowed by FF[4], 1. boardSizeMin :: Int -- | The maximum board size allowed by FF[4], 52. boardSizeMax :: Int -- | A coordinate on a Go board. (0, 0) refers to the upper-left -- corner of the board. The first component is the horizontal position; -- the second component is the vertical position. type Coord = (Int, Int) -- | A structure for compact representation of a list of coordinates. -- Contains a list of individual points, as well as a list of rectangles -- of points denoted by an ordered pair of the upper-left point and the -- lower-right point. The union of the single points and points contained -- within rectangles make up all of the points a CoordList -- represents. There is no rule saying that adjacent points have to be -- grouped into rectangles; it's perfectly valid (although possibly -- inefficient) to never use rectangles. -- -- For any CoordList, all of the following hold: -- --
    --
  1. Any point may be specified at most once, either in the singles -- list or in a single rectangle.
  2. --
  3. For a rectangle ((x0,y0), (x1,y1)), x0 <= x1 -- and y0 <= y1 and (x0,y0) /= (x1,y1) (otherwise -- the point belongs in the singles list).
  4. --
data CoordList -- | Returns the single points in a CoordList. coordListSingles :: CoordList -> [Coord] -- | Returns the rectangles in a CoordList. coordListRects :: CoordList -> [(Coord, Coord)] -- | Constructs a CoordList containing a single point. coord1 :: Coord -> CoordList -- | Constructs a CoordList containing the given single points. For -- rectangle detection, use buildCoordList. coords :: [Coord] -> CoordList -- | Constructs a CoordList containing the given single points and -- rectangles. coords' :: [Coord] -> [(Coord, Coord)] -> CoordList -- | A CoordList that contains no points. emptyCoordList :: CoordList -- | Converts a compact CoordList to a list of coordinates. expandCoordList :: CoordList -> [Coord] -- | Constructs a CoordList from a list of Coords, doing some -- not-completely-stupid rectangle detection. The order of data in the -- result is unspecified. buildCoordList :: [Coord] -> CoordList -- | starLines width height returns Just a list of -- row/column indices that have star points on a board of the given size, -- or Nothing if the board size does not have star points defined. starLines :: Int -> Int -> Maybe [Int] -- | isStarPoint width height x y determines whether (x, -- y) is a known star point on a board of the given width and -- height. isStarPoint :: Int -> Int -> Int -> Int -> Bool -- | handicapStones width height handicap returns a list of points -- where handicap stones should be placed for the given handicap, if -- handicap points are defined for the given board size, otherwise -- Nothing. handicapStones :: Int -> Int -> Int -> Maybe [Coord] -- | A class for SGF data types that are coercable to and from strings. -- -- The construction of an SGF value with stringToSgf may process -- the input, such that the resulting stringlike value does not represent -- the same string as the input. In other words, the following does *not* -- necessarily hold: -- --
--   sgfToString . stringToSgf = id   (does not necessarily hold!)
--   
-- -- The following does hold, however, for a single stringlike type: -- --
--   stringToSgf . sgfToString = id
--   
-- -- The String instance is defined with sgfToString = -- stringToSgf = id. For other types, the string returned by -- sgfToString is in a raw, user-editable format: characters that -- need to be escaped in serialized SGF aren't escaped, but the returned -- value is otherwise similar to SGF format. class Stringlike a sgfToString :: Stringlike a => a -> String stringToSgf :: Stringlike a => String -> a -- | Converts between Stringlike types via a string. -- --
--   convertStringlike = stringToSgf . sgfToString
--   
convertStringlike :: (Stringlike a, Stringlike b) => a -> b -- | An SGF text value. data Text -- | Converts an SGF Text to a string. fromText :: Text -> String -- | Converts a string to an SGF Text. toText :: String -> Text -- | An SGF SimpleText value. data SimpleText -- | Converts an SGF SimpleText to a string. fromSimpleText :: SimpleText -> String -- | Converts a string to an SGF SimpleText, replacing all -- whitespaces (including newlines) with spaces. toSimpleText :: String -> SimpleText -- | The value type for an UnknownProperty. Currently represented -- as a string. data UnknownPropertyValue -- | Returns the string contained within the UnknownProperty this -- value is from. fromUnknownPropertyValue :: UnknownPropertyValue -> String -- | Constructs a value for a UnknownProperty. toUnknownPropertyValue :: String -> UnknownPropertyValue -- | An SGF real value is a decimal number of unspecified precision. type RealValue = Bigfloat -- | An SGF double value: either 1 or 2, nothing else. data DoubleValue Double1 :: DoubleValue Double2 :: DoubleValue -- | Stone color: black or white. data Color Black :: Color White :: Color -- | Returns the logical negation of a stone color, yang for yin and yin -- for yang. cnot :: Color -> Color -- | SGF flags that control how move variations are to be presented while -- displaying the game. data VariationMode VariationMode :: VariationModeSource -> Bool -> VariationMode -- | Which moves to display as variations. variationModeSource :: VariationMode -> VariationModeSource -- | Whether to overlay variations on the board. variationModeBoardMarkup :: VariationMode -> Bool -- | An enumeration that describes which variations are shown. data VariationModeSource -- | Show children of the current move. ShowChildVariations :: VariationModeSource -- | Show alternatives to the current move. ShowCurrentVariations :: VariationModeSource -- | The default variation mode as defined by the SGF spec is -- VariationMode ShowChildVariations True. defaultVariationMode :: VariationMode -- | Parses a numeric variation mode, returning nothing if the number is -- invalid. toVariationMode :: Int -> Maybe VariationMode -- | Returns the integer value for a variation mode. fromVariationMode :: VariationMode -> Int -- | A list of arrows, each specified as (startCoord, endCoord). type ArrowList = [(Coord, Coord)] -- | A list of lines, each specified as (startCoord, endCoord). type LineList = [(Coord, Coord)] -- | A list of labels, each specified with a string and a coordinate about -- which to center the string. type LabelList = [(Coord, SimpleText)] -- | The markings that SGF supports annotating coordinates with. data Mark MarkCircle :: Mark MarkSquare :: Mark MarkTriangle :: Mark MarkX :: Mark MarkSelected :: Mark data GameResult GameResultWin :: Color -> WinReason -> GameResult GameResultDraw :: GameResult GameResultVoid :: GameResult GameResultUnknown :: GameResult GameResultOther :: SimpleText -> GameResult data WinReason WinByScore :: RealValue -> WinReason WinByResignation :: WinReason WinByTime :: WinReason WinByForfeit :: WinReason -- | A ruleset used for a Go game. Can be one of the rulesets defined by -- the SGF specification, or a custom string. data Ruleset KnownRuleset :: RulesetType -> Ruleset UnknownRuleset :: String -> Ruleset -- | The rulesets defined by the SGF specification, for use with -- Ruleset. data RulesetType RulesetAga :: RulesetType RulesetIng :: RulesetType RulesetJapanese :: RulesetType RulesetNewZealand :: RulesetType -- | Returns the string representation for a ruleset. fromRuleset :: Ruleset -> String -- | Parses a string representation of a ruleset. toRuleset :: String -> Ruleset instance Show CoordList instance Eq Text instance Show Text instance Eq SimpleText instance Show SimpleText instance Eq UnknownPropertyValue instance Show UnknownPropertyValue instance Eq DoubleValue instance Show DoubleValue instance Eq Color instance Show Color instance Bounded VariationModeSource instance Enum VariationModeSource instance Eq VariationModeSource instance Show VariationModeSource instance Eq VariationMode instance Show VariationMode instance Bounded Mark instance Enum Mark instance Eq Mark instance Show Mark instance Eq WinReason instance Show WinReason instance Eq GameResult instance Show GameResult instance Bounded RulesetType instance Enum RulesetType instance Eq RulesetType instance Show RulesetType instance Eq Ruleset instance Show Ruleset instance Stringlike Ruleset instance Stringlike GameResult instance Stringlike UnknownPropertyValue instance Stringlike SimpleText instance Stringlike Text instance Stringlike String instance Eq CoordList -- | Parsers of property values. -- -- Import Game.Goatee.Lib.Property rather than importing this -- module. module Game.Goatee.Lib.Property.Parser colorParser :: Parser Color coordElistParser :: Parser CoordList coordListParser :: Parser CoordList coordPairListParser :: Parser [(Coord, Coord)] doubleParser :: Parser DoubleValue gameResultParser :: Parser GameResult labelListParser :: Parser [(Coord, SimpleText)] moveParser :: Parser (Maybe Coord) noneParser :: Parser () integralParser :: (Integral a, Read a) => Parser a realParser :: Parser RealValue rulesetParser :: Parser Ruleset simpleTextPairParser :: Parser (SimpleText, SimpleText) -- | A parser for SGF SimpleText property values. simpleTextParser :: Parser SimpleText sizeParser :: Parser (Int, Int) textParser :: Parser Text unknownPropertyParser :: Parser UnknownPropertyValue variationModeParser :: Parser VariationMode compose :: Parser a -> Parser b -> Parser (a, b) line :: Parser Int simpleText :: Bool -> Parser SimpleText -- | A parser for SGF text property values. Its argument should be true if -- the text is inside of a composed property value, so ':' -- should terminate the value in addition to ']'. text :: Bool -> Parser String instance Monoid CoordListMonoid -- | Structures and functions for working with SGF node properties. module Game.Goatee.Lib.Property data PropertyValueType a pvtParser :: PropertyValueType a -> Parser a pvtRenderer :: PropertyValueType a -> a -> Render () pvtRendererPretty :: PropertyValueType a -> a -> Render () -- | Properties of Goatee the application. module Game.Goatee.App -- | A string containing the name of this application, "Goatee". applicationName :: String -- | A user-presentable copyright message. applicationCopyright :: String -- | The home page for Goatee on the web. applicationWebsite :: String -- | A list of contributors to Goatee. applicationAuthors :: [String] -- | SGF data structures modelling the hierarchical game tree. module Game.Goatee.Lib.Tree -- | An SGF collection of game trees. data Collection Collection :: [Node] -> Collection collectionTrees :: Collection -> [Node] -- | See NodeWithDeepEquality. newtype CollectionWithDeepEquality CollectionWithDeepEquality :: Collection -> CollectionWithDeepEquality collectionWithDeepEquality :: CollectionWithDeepEquality -> Collection -- | An SGF game tree node. Unlike in the SGF spec, we represent a game -- tree with nodes uniformly, rather than having the separation between -- sequences and nodes. data Node Node :: [Property] -> [Node] -> Node nodeProperties :: Node -> [Property] nodeChildren :: Node -> [Node] -- | A wrapper around Node with an Eq instance that considers -- two nodes equal iff they contain the same properties (not necessarily -- in the same order), and if they contain children (in the same order) -- whose nodes are recursively equal. -- -- This instance is not on Node directly because it is not the -- only obvious sense of equality (only comparing properties would be -- another one), and it's also potentially expensive. newtype NodeWithDeepEquality NodeWithDeepEquality :: Node -> NodeWithDeepEquality nodeWithDeepEquality :: NodeWithDeepEquality -> Node -- | A node with no properties and no children. emptyNode :: Node -- | Returns a fresh root Node with AP set to Goatee and -- optionally with a board size set via SZ. rootNode :: Maybe (Int, Int) -> Node -- | Searches for a matching property in a node's property list. findProperty :: Descriptor a => a -> Node -> Maybe Property -- | Searches for a matching property in a property list. findProperty' :: Descriptor a => a -> [Property] -> Maybe Property -- | Retrieves the value of a property in a node's property list. findPropertyValue :: ValuedDescriptor a v => a -> Node -> Maybe v -- | Retrieves the value of a property in a property list. findPropertyValue' :: ValuedDescriptor a v => a -> [Property] -> Maybe v -- | Appends a property to a node's property list. addProperty :: Property -> Node -> Node -- | addChild child parent appends a child node to a node's child -- list. addChild :: Node -> Node -> Node -- | addChildAt index child parent inserts a child node into a -- node's child list at the given index, shifting all nodes at or after -- the given index to the right. If the position is less than 0 or -- greater than the length of the list, then the index is clamped to this -- range. addChildAt :: Int -> Node -> Node -> Node -- | deleteChildAt index node deletes the child at the given index -- from the node. If the index is invalid, node is returned. deleteChildAt :: Int -> Node -> Node -- | Returns a list of validation errors for the current node, an empty -- list if no errors are detected. validateNode :: Bool -> Bool -> Node -> [String] instance Show Node instance Show Collection instance Show CollectionWithDeepEquality instance Eq NodeWithDeepEquality instance Eq CollectionWithDeepEquality -- | Data structures that wrap and provide a higher-level interface to the -- SGF game tree, including a zipper that navigates the tree and provides -- the current board state. module Game.Goatee.Lib.Board -- | Properties that are specified in the root nodes of game trees. data RootInfo RootInfo :: Int -> Int -> VariationMode -> RootInfo rootInfoWidth :: RootInfo -> Int rootInfoHeight :: RootInfo -> Int rootInfoVariationMode :: RootInfo -> VariationMode -- | Properties that are specified in game info nodes. data GameInfo GameInfo :: RootInfo -> Maybe SimpleText -> Maybe SimpleText -> Maybe SimpleText -> Maybe SimpleText -> Maybe SimpleText -> Maybe SimpleText -> Maybe Ruleset -> Maybe RealValue -> Maybe SimpleText -> Maybe GameResult -> Maybe SimpleText -> Maybe Text -> Maybe SimpleText -> Maybe SimpleText -> Maybe SimpleText -> Maybe SimpleText -> Maybe SimpleText -> Maybe SimpleText -> Maybe SimpleText -> Maybe SimpleText -> Maybe SimpleText -> GameInfo gameInfoRootInfo :: GameInfo -> RootInfo gameInfoBlackName :: GameInfo -> Maybe SimpleText gameInfoBlackTeamName :: GameInfo -> Maybe SimpleText gameInfoBlackRank :: GameInfo -> Maybe SimpleText gameInfoWhiteName :: GameInfo -> Maybe SimpleText gameInfoWhiteTeamName :: GameInfo -> Maybe SimpleText gameInfoWhiteRank :: GameInfo -> Maybe SimpleText gameInfoRuleset :: GameInfo -> Maybe Ruleset gameInfoBasicTimeSeconds :: GameInfo -> Maybe RealValue gameInfoOvertime :: GameInfo -> Maybe SimpleText gameInfoResult :: GameInfo -> Maybe GameResult gameInfoGameName :: GameInfo -> Maybe SimpleText gameInfoGameComment :: GameInfo -> Maybe Text gameInfoOpeningComment :: GameInfo -> Maybe SimpleText gameInfoEvent :: GameInfo -> Maybe SimpleText gameInfoRound :: GameInfo -> Maybe SimpleText gameInfoPlace :: GameInfo -> Maybe SimpleText gameInfoDatesPlayed :: GameInfo -> Maybe SimpleText gameInfoSource :: GameInfo -> Maybe SimpleText gameInfoCopyright :: GameInfo -> Maybe SimpleText gameInfoAnnotatorName :: GameInfo -> Maybe SimpleText gameInfoEntererName :: GameInfo -> Maybe SimpleText -- | Builds a GameInfo with the given RootInfo and no extra -- data. emptyGameInfo :: RootInfo -> GameInfo -- | Returns whether a node contains any game info properties. internalIsGameInfoNode :: Node -> Bool -- | Converts a GameInfo into a list of Propertys that can be -- used to reconstruct the GameInfo. gameInfoToProperties :: GameInfo -> [Property] -- | An object that corresponds to a node in some game tree, and represents -- the state of the game at that node, including board position, player -- turn and captures, and also board annotations. data BoardState BoardState :: [[CoordState]] -> Bool -> Bool -> ArrowList -> LineList -> LabelList -> Integer -> Color -> Int -> Int -> GameInfo -> BoardState -- | The state of individual points on the board. Stored in row-major -- order. Point (x, y) can be accessed via !! y !! x -- (but prefer boardCoordState). boardCoordStates :: BoardState -> [[CoordState]] -- | Whether any of the board's CoordStates are invisible. This is -- an optimization to make it more efficient to set the board to all -- visible. boardHasInvisible :: BoardState -> Bool -- | Whether any of the board's CoordStates are dimmed. This is an -- optimization to make it more efficient to clear all dimming from the -- board. boardHasDimmed :: BoardState -> Bool boardArrows :: BoardState -> ArrowList boardLines :: BoardState -> LineList boardLabels :: BoardState -> LabelList boardMoveNumber :: BoardState -> Integer boardPlayerTurn :: BoardState -> Color boardBlackCaptures :: BoardState -> Int boardWhiteCaptures :: BoardState -> Int boardGameInfo :: BoardState -> GameInfo -- | Returns the width of the board, in stones. boardWidth :: BoardState -> Int -- | Returns the height of the board, in stones. boardHeight :: BoardState -> Int -- | Used by BoardState to represent the state of a single point on -- the board. Records whether a stone is present, as well as annotations -- and visibility properties. data CoordState CoordState :: Bool -> Maybe Color -> Maybe Mark -> Bool -> Bool -> CoordState -- | Whether this point is a star point. coordStar :: CoordState -> Bool coordStone :: CoordState -> Maybe Color coordMark :: CoordState -> Maybe Mark coordVisible :: CoordState -> Bool coordDimmed :: CoordState -> Bool rootBoardState :: Node -> BoardState -- | Returns the CoordState for a coordinate on a board. boardCoordState :: Coord -> BoardState -> CoordState -- | Maps a function over each CoordState in a BoardState, -- returning a list-of-lists with the function's values. The function is -- called like fn y x coordState. mapBoardCoords :: (Int -> Int -> CoordState -> a) -> BoardState -> [[a]] -- | Returns whether it is legal to place a stone of the given color at a -- point on a board. Accepts out-of-bound coordinates and returns false. isValidMove :: BoardState -> Color -> Coord -> Bool -- | Returns whether it is legal for the current player to place a stone at -- a point on a board. Accepts out-of-bound coordinates and returns -- false. isCurrentValidMove :: BoardState -> Coord -> Bool -- | A pointer to a node in a game tree that also holds information about -- the current state of the game at that node. data Cursor Cursor :: Maybe Cursor -> Int -> Node -> BoardState -> Cursor -- | The cursor for the node above this cursor's node in the game tree. The -- node of the parent cursor is the parent of the cursor's node. -- -- This is Nothing iff the cursor's node has no parent. cursorParent :: Cursor -> Maybe Cursor -- | The index of this cursor's node in its parent's child list. When the -- cursor's node has no parent, the value in this field is not specified. cursorChildIndex :: Cursor -> Int -- | The game tree node about which the cursor stores information. cursorNode :: Cursor -> Node -- | The complete board state for the current node. cursorBoard :: Cursor -> BoardState -- | Returns a cursor for a root node. rootCursor :: Node -> Cursor cursorRoot :: Cursor -> Cursor cursorChild :: Cursor -> Int -> Cursor cursorChildren :: Cursor -> [Cursor] cursorChildCount :: Cursor -> Int cursorChildPlayingAt :: Maybe Coord -> Cursor -> Maybe Cursor -- | This is simply nodeProperties . cursorNode. cursorProperties :: Cursor -> [Property] cursorModifyNode :: (Node -> Node) -> Cursor -> Cursor -- | Returns the variations to display for a cursor. The returned list -- contains the location and color of B and W properties in -- variation nodes. Variation nodes are either children of the current -- node, or siblings of the current node, depending on the variation mode -- source. cursorVariations :: VariationModeSource -> Cursor -> [(Coord, Color)] moveToProperty :: Color -> Maybe Coord -> Property instance Eq RootInfo instance Show RootInfo instance Show GameInfo instance Show ApplyMoveParams instance Show ApplyMoveGroup instance Show Cursor instance Show CoordState instance Show BoardState -- | A monad for working with game trees. module Game.Goatee.Lib.Monad -- | A monad (transformer) for navigating and mutating Cursors, and -- remembering previous locations. See GoT and GoM. -- -- The monad supports handlers for events raised during actions it takes, -- such as navigating through the tree and modifying nodes. class (Functor go, Applicative go, Monad go) => MonadGo go where getCoordState coord = liftM (boardCoordState coord . cursorBoard) getCursor getProperties = liftM cursorProperties getCursor getPropertyValue descriptor = liftM (liftM $ propertyValue descriptor) $ getProperty descriptor putProperty property = modifyProperty (propertyInfo property) $ const $ Just property deleteProperty descriptor = modifyProperty descriptor $ const Nothing modifyPropertyValue descriptor fn = modifyProperty descriptor $ \ old -> propertyBuilder descriptor <$> fn (propertyValue descriptor <$> old) modifyPropertyString descriptor fn = modifyPropertyValue descriptor $ \ value -> case fn (maybe "" sgfToString value) of { "" -> Nothing str -> let sgf = stringToSgf str in if null $ sgfToString sgf then Nothing else Just sgf } modifyPropertyCoords descriptor fn = modifyPropertyValue descriptor $ \ value -> case fn $ maybe [] expandCoordList value of { [] -> Nothing coords -> Just $ buildCoordList coords } getMark = liftM coordMark . getCoordState modifyMark fn coord = do { maybeOldMark <- getMark coord; case (maybeOldMark, fn maybeOldMark) of { (Just oldMark, Nothing) -> remove oldMark (Nothing, Just newMark) -> add newMark (Just oldMark, Just newMark) | oldMark /= newMark -> remove oldMark >> add newMark (Just _, Just _) -> return () (Nothing, Nothing) -> return () } } where remove mark = modifyPropertyCoords (markProperty mark) (delete coord) add mark = modifyPropertyCoords (markProperty mark) (coord :) addChild node = do { childCount <- liftM (length . cursorChildren) getCursor; addChildAt childCount node } on0 event handler = on event $ eventHandlerFromAction event handler getCursor :: MonadGo go => go Cursor getCoordState :: MonadGo go => Coord -> go CoordState goUp :: MonadGo go => go () goDown :: MonadGo go => Int -> go () goToRoot :: MonadGo go => go () goToGameInfoNode :: MonadGo go => Bool -> go Bool pushPosition :: MonadGo go => go () popPosition :: MonadGo go => go () dropPosition :: MonadGo go => go () getProperties :: MonadGo go => go [Property] modifyProperties :: MonadGo go => ([Property] -> go [Property]) -> go () getProperty :: (MonadGo go, Descriptor d) => d -> go (Maybe Property) getPropertyValue :: (MonadGo go, ValuedDescriptor d v) => d -> go (Maybe v) putProperty :: MonadGo go => Property -> go () deleteProperty :: (MonadGo go, Descriptor d) => d -> go () modifyProperty :: (MonadGo go, Descriptor d) => d -> (Maybe Property -> Maybe Property) -> go () modifyPropertyValue :: (MonadGo go, ValuedDescriptor d v) => d -> (Maybe v -> Maybe v) -> go () modifyPropertyString :: (MonadGo go, Stringlike s, ValuedDescriptor d s) => d -> (String -> String) -> go () modifyPropertyCoords :: (MonadGo go, ValuedDescriptor d CoordList) => d -> ([Coord] -> [Coord]) -> go () modifyGameInfo :: MonadGo go => (GameInfo -> GameInfo) -> go GameInfo modifyVariationMode :: MonadGo go => (VariationMode -> VariationMode) -> go () getMark :: MonadGo go => Coord -> go (Maybe Mark) modifyMark :: MonadGo go => (Maybe Mark -> Maybe Mark) -> Coord -> go () addChild :: MonadGo go => Node -> go () addChildAt :: MonadGo go => Int -> Node -> go () deleteChildAt :: MonadGo go => Int -> go NodeDeleteResult on :: MonadGo go => Event go h -> h -> go () on0 :: MonadGo go => Event go h -> go () -> go () -- | The standard monad transformer for MonadGo. data GoT m a -- | The standard monad for MonadGo. type GoM = GoT Identity -- | Executes a Go monad transformer on a cursor, returning in the -- underlying monad a tuple that contains the resulting value and the -- final cursor. runGoT :: Monad m => GoT m a -> Cursor -> m (a, Cursor) -- | Runs a Go monad on a cursor. See runGoT. runGo :: GoM a -> Cursor -> (a, Cursor) -- | Executes a Go monad transformer on a cursor, returning in the -- underlying monad the value in the transformer. evalGoT :: Monad m => GoT m a -> Cursor -> m a -- | Runs a Go monad on a cursor and returns the value in the monad. evalGo :: GoM a -> Cursor -> a -- | Executes a Go monad transformer on a cursor, returning in the -- underlying monad the final cursor. execGoT :: Monad m => GoT m a -> Cursor -> m Cursor -- | Runs a Go monad on a cursor and returns the final cursor. execGo :: GoM a -> Cursor -> Cursor -- | A single step along a game tree. Either up or down. data Step -- | Represents a step up from a child with the given index. GoUp :: Int -> Step -- | Represents a step down to the child with the given index. GoDown :: Int -> Step -- | The result of deleting a node. data NodeDeleteResult -- | The node was deleted successfully. NodeDeleteOk :: NodeDeleteResult -- | The node couldn't be deleted, because an invalid index was given. NodeDeleteBadIndex :: NodeDeleteResult -- | The node couldn't be deleted, because it is on the path stack. NodeDeleteOnPathStack :: NodeDeleteResult -- | A type of event in a Go monad that can be handled by executing an -- action. go is the type of the Go monad. h is the -- handler type, a function that takes some arguments relating to the -- event and returns an action in the Go monad. The arguments to the -- handler are usually things that would be difficult to recover from the -- state of the monad alone, for example the Step associated with -- a navigationEvent. -- -- The Eq, Ord, and Show instances use events' -- names, via eventName. data Event go h -- | An existential type for any event in a particular Go monad. Like -- Event, the Eq, Ord, and Show instances use -- events' names, via eventName. data AnyEvent go AnyEvent :: (Event go h) -> AnyEvent go eventName :: Event go h -> String -- | Fires all of the handlers for the given event, using the given -- function to create a Go action from each of the handlers (normally -- themselves functions that create Go actions, if they're not just Go -- actions directly, depending on the event). fire :: Monad m => Event (GoT m) h -> (h -> GoT m ()) -> GoT m () eventHandlerFromAction :: Event go h -> go () -> h -- | An event corresponding to a child node being added to the current -- node. childAddedEvent :: Event go (ChildAddedHandler go) -- | A handler for childAddedEvents. Called with the index of the -- child added to the current node. type ChildAddedHandler go = Int -> go () -- | An event corresponding to the deletion of one of the current node's -- children. childDeletedEvent :: Event go (ChildDeletedHandler go) -- | A handler for childDeletedEvents. It is called with a cursor at -- the child that was deleted (this cursor is now out of date). type ChildDeletedHandler go = Cursor -> go () -- | An event that is fired when the current game info changes, either by -- navigating past a node with game info properties, or by modifying the -- current game info properties. gameInfoChangedEvent :: Event go (GameInfoChangedHandler go) -- | A handler for gameInfoChangedEvents. It is called with the old -- game info then the new game info. type GameInfoChangedHandler go = GameInfo -> GameInfo -> go () -- | An event that is fired when a single step up or down in a game tree is -- made. navigationEvent :: Event go (NavigationHandler go) -- | A handler for navigationEvents. -- -- A navigation handler may navigate further, but beware infinite -- recursion. A navigation handler must end on the same node on which it -- started. type NavigationHandler go = Step -> go () -- | An event corresponding to a modification to the properties list of the -- current node. propertiesModifiedEvent :: Event go (PropertiesModifiedHandler go) -- | A handler for propertiesModifiedEvents. It is called with the -- old property list then the new property list. type PropertiesModifiedHandler go = [Property] -> [Property] -> go () -- | An event corresponding to a change in the active VariationMode. -- This can happen when modifying the ST property, and also when -- navigating between collections (as they have different root nodes). variationModeChangedEvent :: Event go (VariationModeChangedHandler go) -- | A handler for variationModeChangedEvents. It is called with the -- old variation mode then the new variation mode. type VariationModeChangedHandler go = VariationMode -> VariationMode -> go () instance Eq Step instance Show Step instance Bounded NodeDeleteResult instance Enum NodeDeleteResult instance Eq NodeDeleteResult instance Show NodeDeleteResult instance Show (AnyEvent go) instance Ord (AnyEvent go) instance Eq (AnyEvent go) instance Show (Event go h) instance Ord (Event go h) instance Eq (Event go h) instance Monad m => MonadGo (GoT m) instance MonadWriter w m => MonadWriter w (GoT m) instance MonadState s m => MonadState s (GoT m) instance MonadIO m => MonadIO (GoT m) instance MonadTrans GoT instance Monad m => Monad (GoT m) instance Monad m => Applicative (GoT m) instance Monad m => Functor (GoT m) -- | A parser for reading SGF files. module Game.Goatee.Lib.Parser -- | Parses a string in SGF format. Returns an error string if parsing -- fails. parseString :: String -> Either String Collection -- | Parses a file in SGF format. Returns an error string if parsing fails. parseFile :: String -> IO (Either String Collection) -- | Parses a node as part of an existing game tree, from textual SGF -- "GameTree" syntax. The RootInfo is needed to supply necessary -- information from the existing game tree. parseSubtree :: RootInfo -> String -> Either String Node propertyParser :: Parser Property -- | Functions for serializing SGF trees. module Game.Goatee.Lib.Renderer.Tree -- | Renders an SGF Collection to a string. renderCollection :: Collection -> Render () -- | Recursively renders an SGF GameTree (as defined in the spec) rooted at -- the given node. renderGameTree :: Node -> Render () renderProperty :: Property -> Render ()