Esempio n. 1
0
        /// <summary>
        /// Generates all immediate children of the specified node
        /// WARNING: this method is not thread-safe, run it in parallel only
        /// for nodes in non-overlapping subtrees
        /// </summary>
        public void GenerateAllChildren(AnalysisNode parent, uint depth,
            bool is_restore_missing_positions = true)
        {
            Debug.Assert(parent != null && parent.Position != null);
            Debug.Assert(depth > 0);

            // Check if all moves were generated for the parent node
            // If not, clear the list of children and re-generate them all
            if (parent.IsSomeChildrenErased)
            {
                parent.SetChildrenList(null);
            }

            if (parent.Children == null)
            {
                parent.InitChildrenList();
                // TODO - conside memory pooling for the list of moves
                var moves = new List<Move>(64);
                MovesGenerator.GenerateMoves(parent.Position, moves);
                var player_to_move = parent.Position.PlayerToMove;
                bool is_parent_in_check = parent.Position.IsInCheck;
                foreach (var m in moves)
                {
                    var child_position = parent.Position.PlayMove(m);
                    // Last check if the move is a legal move
                    // Didn't do it earlier, as we need resulting position
                    // for this
                    if (!PositionValidator.IsMyMovePutsMyKingInCheck(
                        player_to_move, m, child_position, is_parent_in_check))
                    {
                        parent.Children.Add(new AnalysisNode(parent, child_position,
                            m));
                        Interlocked.Increment(ref m_node_count);
                    }
                }
                // Let the position to know whether there are legal moves
                parent.Position.HasLegalMoves = !parent.IsLeaf;
            }
            else if (is_restore_missing_positions)
            {
                foreach (var node in parent.Children)
                {
                    if (node.Position == null)
                    {
                        // Position object was destroyed to free the memory
                        // Re-create it now
                        node.RecreatePosition();
                    }
                }
            }

            // Indicate that all children are generated and present in the collection
            // Unless we have generated the moves having some restrictions imposed
            parent.IsSomeChildrenErased = false;

            // Generate next levels of child nodes recursively
            if (depth > 1)
            {
                foreach (var node in parent.Children)
                {
                    GenerateAllChildren(node, depth - 1, is_restore_missing_positions);
                }
            }

            if (ReferenceEquals(parent, Root))
            {
                m_listener.RootChildrenGenerated(Root.Children);
            }
        }