2009-08-18 38 views
3

我需要創建一個自動生成括號錦標賽網球風格的asp.net頁面。 關於管理數據庫匹配,這不是問題。錦標賽括號算法

問題是括號的動態圖形創建。 用戶將能夠通過2-4 ... 32名玩家創建錦標賽。 而且我不知道豪創建HTML或GDI圖形支架...

回答

8

使用Silverlight,以及電網,可以產生這樣的事情: bracket display http://i32.tinypic.com/30uqywy.jpg

要做到這一點,定義包含網格的常規UserControl。 (這是使用Silverlight 3.0 SDK在VS2008中構建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表格。

+0

非常感謝你! – stighy 2009-08-20 21:37:46

+0

絕妙的回答!我學到了很多。 – neontapir 2012-12-18 20:07:46