/// <summary>
        /// Performs the conversion
        /// </summary>
        /// <returns>SGF game tree</returns>
        public SgfGameTree Convert()
        {
            var rootGameTree       = ProcessNode(_gameTree.GameTreeRoot);
            var rootProperties     = GetRootProperties();
            var gameInfoProperties = GetGameInfoProperties();

            //modify the root node
            var firstNode           = rootGameTree.Sequence.First();
            var newSequenceNodeList = new List <SgfNode>();

            //check if the first node has a move (mixing move and root properties is not recommended)
            if (firstNode["B"] != null || firstNode["W"] != null)
            {
                //create a new first node
                var newNode = new SgfNode(rootProperties.Union(gameInfoProperties));
                newSequenceNodeList.Add(newNode);
                newSequenceNodeList.AddRange(rootGameTree.Sequence);
            }
            else
            {
                //modify first node
                var newNode = new SgfNode(rootProperties.Union(gameInfoProperties).Union(firstNode.Properties.Values));
                newSequenceNodeList.Add(newNode);
                for (int i = 1; i < rootGameTree.Sequence.Count(); i++)
                {
                    newSequenceNodeList.Add(rootGameTree.Sequence.Nodes[i]);
                }
            }

            return(new SgfGameTree(new SgfSequence(newSequenceNodeList), rootGameTree.Children));
        }
예제 #2
0
 public void SgfNodeWithRepeatingPropertiesThrowsException()
 {
     var node = new SgfNode(new SgfProperty[]
     {
         new SgfProperty("FF", new [] { SgfNumberValue.Parse("4"), }),
         new SgfProperty("FF", new [] { SgfNumberValue.Parse("4") }),
     });
 }
예제 #3
0
        /// <summary>
        /// Serializes a SGF node
        /// </summary>
        /// <param name="node">Node</param>
        /// <returns>Serialized node</returns>
        private string SerializeNode(SgfNode node)
        {
            StringBuilder builder = new StringBuilder();

            builder.Append(';');
            foreach (var property in node)
            {
                builder.Append(SerializeProperty(property));
            }

            return(builder.ToString());
        }
예제 #4
0
        public void ValidSgfNodeWithPropertiesCanBeCreated()
        {
            var node = new SgfNode(new []
            {
                new SgfProperty("FF", new [] { SgfNumberValue.Parse("4") }),
                new SgfProperty("C", new [] { SgfTextValue.Parse("Test") })
            });

            Assert.AreEqual(2, node.Count());
            Assert.AreEqual("FF", node["FF"].Identifier);
            Assert.AreEqual(4, node["FF"].Value <int>());
            Assert.AreEqual("C", node["C"].Identifier);
            Assert.AreEqual("Test", node["C"].Value <string>());
        }
예제 #5
0
        /// <summary>
        /// Parses a SGF sequence
        /// </summary>
        /// <param name="input">Input</param>
        /// <param name="inputPosition">Current input position</param>
        /// <returns>SGF sequence</returns>
        private SgfSequence ParseSequence(string input, ref int inputPosition)
        {
            if (input[inputPosition] != ';')
            {
                throw new SgfParseException($"No sequence found on input position {inputPosition}");
            }

            List <SgfNode> nodes = new List <SgfNode>();

            while (inputPosition < input.Length && input[inputPosition] == ';')
            {
                SgfNode node = ParseNode(input, ref inputPosition);
                nodes.Add(node);
                SkipInputWhitespace(input, ref inputPosition);
            }
            return(new SgfSequence(nodes));
        }
예제 #6
0
        public void SgfNodeWithEmptyPropertiesCanBeCreatedSuccessfully()
        {
            var node = new SgfNode(new SgfProperty[0]);

            Assert.AreEqual(0, node.Count());
        }
예제 #7
0
        /// <summary>
        /// Parses and fills markup properties
        /// </summary>
        /// <param name="sourceNode">Source SGF node</param>
        /// <param name="targetNode">Target game tree node</param>
        /// <param name="boardSize">Board size</param>
        private void ParseAndFillMarkupProperties(SgfNode sourceNode, GameTreeNode targetNode, GameBoardSize boardSize)
        {
            // Needs to handle:
            string arrow    = "AR"; // AR - Arrow
            string circle   = "CR"; // CR - Circle
            string dimPoint = "DD"; // DD - Dim Point
            string label    = "LB"; // LB - Label
            string line     = "LN"; // LN - Line
            string cross    = "MA"; // MA - Mark With X
            string selected = "SL"; // SL - Selected
            string square   = "SQ"; // SQ - Square
            string triangle = "TR"; // TR - Triangle

            if (sourceNode[arrow] != null)
            {
                // Add arrow
                var property         = sourceNode[arrow];
                var arrowDefinitions = property.ComposeValues <SgfPoint, SgfPoint>();

                foreach (var arrowDefinition in arrowDefinitions)
                {
                    var fromPoint = Position.FromSgfPoint(arrowDefinition.Left, boardSize);
                    var toPoint   = Position.FromSgfPoint(arrowDefinition.Right, boardSize);
                    targetNode.Markups.AddMarkup(new Arrow(fromPoint, toPoint));
                }
            }
            if (sourceNode[circle] != null)
            {
                // Add circle
                var property        = sourceNode[circle];
                var pointRectangles = property.SimpleValues <SgfPointRectangle>();

                var positions = GetPositionsFromPointRectangles(pointRectangles, boardSize);
                foreach (var position in positions)
                {
                    targetNode.Markups.AddMarkup(
                        new Circle(position));
                }
            }
            if (sourceNode[dimPoint] != null)
            {
                // Add dim point
                var property        = sourceNode[dimPoint];
                var pointRectangles = property.SimpleValues <SgfPointRectangle>();
                foreach (var rectangle in pointRectangles)
                {
                    var topLeft     = Position.FromSgfPoint(rectangle.UpperLeft, boardSize);
                    var bottomRight = Position.FromSgfPoint(rectangle.LowerRight, boardSize);
                    targetNode.Markups.AddMarkup(new AreaDim(topLeft, bottomRight));
                }
            }
            if (sourceNode[label] != null)
            {
                // Add label
                var property         = sourceNode[label];
                var labelDefinitions = property.ComposeValues <SgfPoint, string>();
                foreach (var labelDefinition in labelDefinitions)
                {
                    targetNode.Markups.AddMarkup(new Label(Position.FromSgfPoint(labelDefinition.Left, boardSize), labelDefinition.Right));
                }
            }
            if (sourceNode[line] != null)
            {
                // Add line
                var property        = sourceNode[line];
                var lineDefinitions = property.ComposeValues <SgfPoint, SgfPoint>();

                foreach (var lineDefinition in lineDefinitions)
                {
                    var startPoint = Position.FromSgfPoint(lineDefinition.Left, boardSize);
                    var endPoint   = Position.FromSgfPoint(lineDefinition.Right, boardSize);
                    targetNode.Markups.AddMarkup(new Line(startPoint, endPoint));
                }
            }
            if (sourceNode[cross] != null)
            {
                // Add cross
                var property        = sourceNode[cross];
                var pointRectangles = property.SimpleValues <SgfPointRectangle>();

                var positions = GetPositionsFromPointRectangles(pointRectangles, boardSize);
                foreach (var position in positions)
                {
                    targetNode.Markups.AddMarkup(
                        new Cross(position));
                }
            }
            if (sourceNode[selected] != null)
            {
                // Add selected
                // TODO  (future work) Vita : implement
            }
            if (sourceNode[square] != null)
            {
                // Add square
                var property        = sourceNode[square];
                var pointRectangles = property.SimpleValues <SgfPointRectangle>();

                var positions = GetPositionsFromPointRectangles(pointRectangles, boardSize);
                foreach (var position in positions)
                {
                    targetNode.Markups.AddMarkup(
                        new Square(position));
                }
            }
            if (sourceNode[triangle] != null)
            {
                // Add triangle
                var property        = sourceNode[triangle];
                var pointRectangles = property.SimpleValues <SgfPointRectangle>();

                var positions = GetPositionsFromPointRectangles(pointRectangles, boardSize);
                foreach (var position in positions)
                {
                    targetNode.Markups.AddMarkup(
                        new Triangle(position));
                }
            }
        }