so i have been stuck with this issue for 3 weeks now and i couldn\'t for the life of me figure it out. what im trying to do is to get this kind of output/presentation using tabl
Here's my attempt. I have tested the code for 2, 3, and 4 Round Tournaments. The outputs for a 2-Round and 3-Round tournament are shown here:


I have used the same model that you provided to define a Match. I have added a Tournament class to generate test data.
Match.cs - The class containing the models
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace tournament
{
public class Match
{
public int id { get; set; }
public int teamid1 { get; set; }
public int teamid2 { get; set; }
public int roundnumber { get; set; }
public int winner { get; set; }
public Match(int id, int teamid1, int teamid2, int roundnumber, int winner)
{
this.id = id;
this.teamid1 = teamid1;
this.teamid2 = teamid2;
this.roundnumber = roundnumber;
this.winner = winner;
}
}
public class Tournament
{
public SortedList> TournamentRoundMatches { get; private set; }
public Match ThirdPlaceMatch { get; private set; }
public Tournament(int rounds)
{
this.TournamentRoundMatches = new SortedList>();
this.GenerateTournamentResults(rounds);
if (rounds > 1)
{
this.GenerateThirdPlaceResult(rounds);
}
}
public void AddMatch(Match m)
{
if (this.TournamentRoundMatches.ContainsKey(m.roundnumber))
{
if (!this.TournamentRoundMatches[m.roundnumber].ContainsKey(m.id))
{
this.TournamentRoundMatches[m.roundnumber].Add(m.id, m);
}
}
else
{
this.TournamentRoundMatches.Add(m.roundnumber, new SortedList());
this.TournamentRoundMatches[m.roundnumber].Add(m.id, m);
}
}
private void GenerateTournamentResults(int rounds)
{
Random WinnerRandomizer = new Random();
for (int round = 1, match_id = 1; round <= rounds; round++)
{
int matches_in_round = 1 << (rounds - round);
for (int round_match = 1; round_match <= matches_in_round; round_match++, match_id++)
{
int team1_id;
int team2_id;
int winner;
if (round == 1)
{
team1_id = (match_id * 2) - 1;
team2_id = (match_id * 2);
}
else
{
int match1 = (match_id - (matches_in_round * 2) + (round_match - 1));
int match2 = match1 + 1;
team1_id = this.TournamentRoundMatches[round - 1][match1].winner;
team2_id = this.TournamentRoundMatches[round - 1][match2].winner;
}
winner = (WinnerRandomizer.Next(1, 3) == 1) ? team1_id : team2_id;
this.AddMatch(new Match(match_id, team1_id, team2_id, round, winner));
}
}
}
private void GenerateThirdPlaceResult(int rounds)
{
Random WinnerRandomizer = new Random();
int semifinal_matchid1 = this.TournamentRoundMatches[rounds - 1].Keys.ElementAt(0);
int semifinal_matchid2 = this.TournamentRoundMatches[rounds - 1].Keys.ElementAt(1);
Match semifinal_1 = this.TournamentRoundMatches[rounds - 1][semifinal_matchid1];
Match semifinal_2 = this.TournamentRoundMatches[rounds - 1][semifinal_matchid2];
int semifinal_loser1 = (semifinal_1.winner == semifinal_1.teamid1) ? semifinal_1.teamid2 : semifinal_1.teamid1;
int semifinal_loser2 = (semifinal_2.winner == semifinal_2.teamid1) ? semifinal_2.teamid2 : semifinal_2.teamid1;
int third_place_winner = (WinnerRandomizer.Next(1, 3) == 1) ? semifinal_loser1 : semifinal_loser2;
this.ThirdPlaceMatch = new Match((1 << rounds) + 1, semifinal_loser1, semifinal_loser2, 1, third_place_winner);
}
}
}
I have generated the raw HTML dynamically using the static method Program.cs - The static Program class that initializes test data and generates the HTML UPDATE Explanation of Parameters Used to Generate the HTML Table As you can see, the As you've noticed, I am iterating over the columns one row at a time. That seems most natural considering that HTML tables are also constructed that way, i.e. create row, add cells ... create row, add cels ... and so on.GenerateHTMLResultsTable. This was done using only without any need for
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace tournament
{
class Program
{
static string GenerateHTMLResultsTable(Tournament tournament)
{
int match_white_span;
int match_span;
int position_in_match_span;
int column_stagger_offset;
int effective_row;
int col_match_num;
int cumulative_matches;
int effective_match_id;
int rounds = tournament.TournamentRoundMatches.Count;
int teams = 1 << rounds;
int max_rows = teams << 1;
StringBuilder HTMLTable = new StringBuilder();
HTMLTable.AppendLine("");
HTMLTable.AppendLine("Tournament Results
");
HTMLTable.AppendLine("");
for (int row = 0; row <= max_rows; row++)
{
cumulative_matches = 0;
HTMLTable.AppendLine("
");
HTMLTable.AppendLine("");
for (int col = 1; col <= rounds + 1; col++)
{
match_span = 1 << (col + 1);
match_white_span = (1 << col) - 1;
column_stagger_offset = match_white_span >> 1;
if (row == 0)
{
if (col <= rounds)
{
HTMLTable.AppendLine(" ");
}
HTMLTable.AppendLine("Round " + col + " ");
}
else
{
HTMLTable.AppendLine(" Winner ");
}
}
else if (row == 1)
{
HTMLTable.AppendLine(" ");
}
else
{
effective_row = row + column_stagger_offset;
if (col <= rounds)
{
position_in_match_span = effective_row % match_span;
position_in_match_span = (position_in_match_span == 0) ? match_span : position_in_match_span;
col_match_num = (effective_row / match_span) + ((position_in_match_span < match_span) ? 1 : 0);
effective_match_id = cumulative_matches + col_match_num;
if ((position_in_match_span == 1) && (effective_row % match_span == position_in_match_span))
{
HTMLTable.AppendLine(" ");
}
else if ((position_in_match_span == (match_span >> 1)) && (effective_row % match_span == position_in_match_span))
{
HTMLTable.AppendLine(" Team " + tournament.TournamentRoundMatches[col][effective_match_id].teamid1 + " ");
}
else if ((position_in_match_span == ((match_span >> 1) + 1)) && (effective_row % match_span == position_in_match_span))
{
HTMLTable.AppendLine(" VS ");
}
else if ((position_in_match_span == match_span) && (effective_row % match_span == 0))
{
HTMLTable.AppendLine(" Team " + tournament.TournamentRoundMatches[col][effective_match_id].teamid2 + " ");
}
}
else
{
if (row == column_stagger_offset + 2)
{
HTMLTable.AppendLine(" Team " + tournament.TournamentRoundMatches[rounds][cumulative_matches].winner + " ");
}
else if (row == column_stagger_offset + 3)
{
HTMLTable.AppendLine(" ");
}
}
}
if (col <= rounds)
{
cumulative_matches += tournament.TournamentRoundMatches[col].Count;
}
}
HTMLTable.AppendLine(" Third Place Results
");
HTMLTable.AppendLine("");
HTMLTable.AppendLine("
");
return HTMLTable.ToString();
}
static void Main(string[] args)
{
Tournament Test3RoundTournament = new Tournament(3);
Tournament Test2RoundTournament = new Tournament(2);
File.WriteAllText(@"C:\Tournament\results.html", GenerateHTMLResultsTable(Test2RoundTournament));
File.WriteAllText(@"C:\Tournament\results.html", GenerateHTMLResultsTable(Test3RoundTournament));
Console.ReadLine();
}
}
}
");
HTMLTable.AppendLine(" ");
HTMLTable.AppendLine(" Round 1 ");
HTMLTable.AppendLine(" Third Place ");
HTMLTable.AppendLine(" ");
HTMLTable.AppendLine(" ");
HTMLTable.AppendLine(" ");
HTMLTable.AppendLine(" ");
HTMLTable.AppendLine(" ");
HTMLTable.AppendLine(" ");
HTMLTable.AppendLine(" Team " + tournament.ThirdPlaceMatch.teamid1 + " ");
HTMLTable.AppendLine(" ");
HTMLTable.AppendLine(" ");
HTMLTable.AppendLine(" VS ");
HTMLTable.AppendLine(" Team " + tournament.ThirdPlaceMatch.winner + " ");
HTMLTable.AppendLine(" ");
HTMLTable.AppendLine(" ");
HTMLTable.AppendLine("Team " + tournament.ThirdPlaceMatch.teamid2 + " ");
HTMLTable.AppendLine(" ");
HTMLTable.AppendLine("

column_stagger_offset is the amount by which each column is shifted up to align them the way they are supposed to. The effective_row is essentially where the particular table cell would have been had there been no vertical shift. Knowing the effective_row and the position_in_match_span helps determine what needs to be shown in that particuar cell (blank, team1, team2, or vs.).