【问题标题】:Tournament Brackets algorithm锦标赛括号算法
【发布时间】:2009-08-18 14:54:17
【问题描述】:

我需要创建一个自动生成括号锦标赛网球样式的 asp.net 页面。 关于数据库中匹配的管理,这不是问题。

问题是括号的动态图形创建。 用户将能够创建由 2-4...32 名玩家组成的锦标赛。 而且我不知道如何在 html 或 gdi 中创建图形括号...

【问题讨论】:

    标签: asp.net


    【解决方案1】:

    使用 Silverlight 和 Grid,您可以生成如下内容:

    为此,定义一个包含 Grid 的常规 UserControl。 (这是您在 VS2008 中使用 Silverlight 3.0 SDK 构建 silverlight 应用程序时的默认设置。

    然后,在用户控件的构造函数中添加对以下内容的调用:

    private void SetupBracket(int n)
    {
        var black = new SolidColorBrush(Colors.Gray);
        // number of levels, or rounds, in the single-elim tourney
        int levels = (int)Math.Log(n, 2) + 1;
        // number of columns in the Grid.  There's a "connector"
        // column between round n and round n+1.
        int nColumns = levels * 2 - 1;
    
        // add the necessary columns to the grid
        var cdc = LayoutRoot.ColumnDefinitions;
        for (int i = 0; i < nColumns; i++)
        {
            var cd = new ColumnDefinition();
            // the width of the connector is half that of the regular columns
            int width = ((i % 2) == 1) ? 1 : 2;
            cd.Width = new GridLength(width, GridUnitType.Star);
            cdc.Add(cd);
        }
        var rdc = LayoutRoot.RowDefinitions;
    
        // in the grid, there is one row for each player, and 
        // an interleaving row between each pair of players. 
        int totalSlots = 2 * n - 1;
        for (int i = 0; i < totalSlots; i++)
        {
            rdc.Add(new RowDefinition());
        }
    
        // Now we have a grid of the proper geometry.  
        // Next: fill it. 
    
        List<int> slots = new List<int>();
        ImageBrush brush = new ImageBrush();
        brush.ImageSource = new BitmapImage(new Uri("Bridge.png", UriKind.Relative));
    
        // one loop for each level, or "round" in the tourney.  
        for (int j = 0; j < levels; j++)
        {
            // Figure the number of players in the current round.
            // Since we insert the rounds in the reverse order, 
            // think of j as the "number of rounds remaining."
            // Therefore, when j==0, playersThisRound=1.  
            // When j == 1, playersThisRound = 2.  etc.
            int playersThisRound = (int)Math.Pow(2, j);
    
            int x = levels - j;
            int f = (int)Math.Pow(2, x - 1);
    
            for (int i = 0; i < playersThisRound; i++)
            {
                // do this in reverse order.  The innermost round is 
                // inserted first.
                var r = new TextBox();
                r.Background = black;
                if (j == levels - 1)
                    r.Text = "player " + (i + 1).ToString();
                else
                    r.Text = "player ??";
    
                // for j == 0, this is the last column in the grid.
                // for j == levels-1, this is the first column.
                // The grid column is not the same as the current
                // round, because of the columns used for the 
                // interleaved connectors.
                int k = 2 * (x - 1); 
                r.SetValue(Grid.ColumnProperty, k);
    
                int m = (i * 2 + 1) * f - 1;
                r.SetValue(Grid.RowProperty, m);
                LayoutRoot.Children.Add(r);
    
                // are we not on the last round? 
                if (j > 0)
                {
                    slots.Add(m);
                    // Have we just inserted two rows?  Then we need
                    // a connector between these two and the next 
                    // round (the round previously added).
                    if (slots.Count == 2)
                    {
                        string xamlTriangle = "<Path xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' "+
                                              "xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' " +
                                              "Data='M0,0 L 100 50 0 100 Z' Fill='LightBlue' Stretch='Fill'/>";
    
                        Path path = (Path)System.Windows.Markup.XamlReader.Load(xamlTriangle);
    
                        path.SetValue(Grid.ColumnProperty, 2 * (x - 1) + 1);
                        path.SetValue(Grid.RowProperty, slots[0]);
                        path.SetValue(Grid.RowSpanProperty, slots[1] - slots[0] + 1);
                        this.LayoutRoot.Children.Add(path);
                        slots.Clear();
                    }
                }
    
            }
        }
    }
    

    在上面,连接器只是一个等腰三角形,顶点指向右侧。它由 XamlReader.Load() 在字符串上生成。

    我猜你还想美化它,用不同的颜色和字体来设计它。

    您可以将这个 silverlight“用户控件”插入任何 HTML 网页,就像将 Flash 应用程序嵌入到页面中一样。有适用于 IE、Firefox、Opera、Safari 和 Chrome 的 silverlight 插件。

    如果您不想使用 Silverlight,您可以使用类似的方法来构建 HTML 表格。

    【讨论】:

      猜你喜欢
      • 2012-04-03
      • 2011-01-12
      • 1970-01-01
      • 1970-01-01
      • 2012-01-24
      • 2012-04-01
      • 2012-05-17
      • 2014-04-23
      • 1970-01-01
      相关资源
      最近更新 更多