public void AddSecondaryParent(EliminationNode secondaryParent) { if(secondaryParent != null && !this.secondaryParents.Contains(secondaryParent)) { this.secondaryParents.Add(secondaryParent); } }
public PassThroughDecider(EliminationNode node) { if (node == null) { throw new ArgumentNullException("node"); } this.node = node; }
public ContinuationDecider(EliminationNode nodeA, EliminationNode nodeB) { if (nodeA == null) { throw new ArgumentNullException("nodeA"); } if (nodeB == null) { throw new ArgumentNullException("nodeB"); } this.nodeA = nodeA; this.nodeB = nodeB; }
public StayDecider(EliminationNode previousWinnerNode, EliminationNode stayNode) { if (previousWinnerNode == null) { throw new ArgumentNullException("previousWinnerNode"); } if (stayNode == null) { throw new ArgumentNullException("stayNode"); } this.previousWinnerNode = previousWinnerNode; this.stayNode = stayNode; }
public ContinuationDecider(EliminationNode nodeA, EliminationNode nodeB) { this.nodeA = nodeA ?? throw new ArgumentNullException(nameof(nodeA)); this.nodeB = nodeB ?? throw new ArgumentNullException(nameof(nodeB)); }
protected void RenderTree(IGraphics g, TournamentNameTable names, float x, float y, float textHeight, EliminationNode nodeA, EliminationNode nodeB) { var m = this.MeasureTree(g, names, textHeight, nodeA, nodeB); var mA = nodeA == null ? null : nodeA.Measure(g, names, textHeight); var mB = nodeB == null ? null : nodeB.Measure(g, names, textHeight); if (mA == null && mB == null) { return; } else if (mA != null && mB != null) { // Preline g.DrawLine( BracketPen, new PointF( x + (m.Width - BracketPreIndent), y + m.CenterLine), new PointF( x + m.Width, y + m.CenterLine)); // V-Line g.DrawLine( BracketPen, new PointF( x + (m.Width - BracketPreIndent), y + mA.CenterLine), new PointF( x + (m.Width - BracketPreIndent), y + mA.Height + BracketVSpacing + mB.CenterLine)); // Post-Line-A g.DrawLine( BracketPen, new PointF( x + (m.Width - BracketPreIndent - BracketPostIndent), y + mA.CenterLine), new PointF( x + (m.Width - BracketPreIndent), y + mA.CenterLine)); // Post-Line-B g.DrawLine( BracketPen, new PointF( x + (m.Width - BracketPreIndent - BracketPostIndent), y + mA.Height + BracketVSpacing + mB.CenterLine), new PointF( x + (m.Width - BracketPreIndent), y + mA.Height + BracketVSpacing + mB.CenterLine)); nodeA.Render(g, names, x + (m.Width - (mA.Width + BracketPreIndent + BracketPostIndent)), y, textHeight); nodeB.Render(g, names, x + (m.Width - (mB.Width + BracketPreIndent + BracketPostIndent)), y + mA.Height + BracketVSpacing, textHeight); } else if (mA != null) { // TODO: Render Lines? nodeA.Render(g, names, x, y, textHeight); } else { // TODO: Render Lines? nodeB.Render(g, names, x, y, textHeight); } }
protected NodeMeasurement MeasureTree(IGraphics g, TournamentNameTable names, float textHeight, EliminationNode nodeA, EliminationNode nodeB) { var mA = nodeA == null ? null : nodeA.Measure(g, names, textHeight); var mB = nodeB == null ? null : nodeB.Measure(g, names, textHeight); if (mA == null && mB == null) { return null; } else if (mA != null && mB != null) { return new NodeMeasurement( Math.Max(mA.Width, mB.Width) + BracketPreIndent + BracketPostIndent, mA.Height + mB.Height + BracketVSpacing, (mA.CenterLine + (mA.Height + BracketVSpacing + mB.CenterLine)) / 2); } else if (mA != null) { return new NodeMeasurement( mA.Width + BracketPreIndent + BracketPostIndent, mA.Height, mA.CenterLine); } else { return new NodeMeasurement( mB.Width + BracketPreIndent + BracketPostIndent, mB.Height, mB.CenterLine); } }
public StayDecider(EliminationNode previousWinnerNode, EliminationNode stayNode) { this.PreviousWinnerNode = previousWinnerNode ?? throw new ArgumentNullException(nameof(previousWinnerNode)); this.StayNode = stayNode ?? throw new ArgumentNullException(nameof(stayNode)); }
private EliminationNode MakeSiblings(EliminationNode nodeA, EliminationNode nodeB) { var oldParent = nodeA.PrimaryParent as ContinuationDecider; var newDecider = new ContinuationDecider(nodeA, nodeB); var newNode = new WinnerNode(newDecider); newDecider.PrimaryParent = newNode; nodeA.PrimaryParent = nodeB.PrimaryParent = newDecider; newNode.PrimaryParent = oldParent; if (oldParent != null) { if (oldParent.ChildA == nodeA) { oldParent.ChildA = newNode; } else if (oldParent.ChildB == nodeA) { oldParent.ChildB = newNode; } } return newNode; }
private static void LockByes(EliminationNode rootNode) { var deciders = rootNode.FindDeciders(d => d.IsDecided && !d.Locked).ToList(); foreach (var d in deciders) { d.Lock(); } }
public void Reset() { this.loadedTeams = null; this.loadedRootNode = null; this.state = PairingsGeneratorState.NotInitialized; }
public void LoadState(IEnumerable<TournamentTeam> teams, IList<TournamentRound> rounds) { if (teams == null) { throw new ArgumentNullException("teams"); } if (rounds == null) { throw new ArgumentNullException("rounds"); } if (rounds.Where(r => r.Pairings.Where(p => p.TeamScores.Count > 2).Any()).Any()) { throw new InvalidTournamentStateException("At least one pairing had more than two teams competing. This is invalid in a single elimination tournament."); } var rootNode = BuildTree(teams); bool byesLocked = false; foreach (var round in rounds) { foreach (var pairing in round.Pairings) { // TODO: We must sort the byes to the top. if (pairing.TeamScores.Count == 0) { continue; } tryagainwithbyeslocked: bool success = rootNode.ApplyPairing(pairing); if (!success) { var teamScoreA = pairing.TeamScores[0]; var teamScoreB = pairing.TeamScores.Count > 1 ? pairing.TeamScores[1] : null; if (teamScoreA == null) { teamScoreA = teamScoreB; teamScoreB = null; } if (teamScoreA == null) continue; var teamA = teamScoreA != null ? teamScoreA.Team : null; var teamB = teamScoreB != null ? teamScoreB.Team : null; var scoreA = teamScoreA != null ? teamScoreA.Score : null; var scoreB = teamScoreB != null ? teamScoreB.Score : null; var nodesA = teamA == null ? null : rootNode.FindDeciders(d => d.IsDecided && !d.Locked && d.GetWinner() != null && d.GetWinner().TeamId == teamA.TeamId); var nodesB = teamB == null ? null : rootNode.FindDeciders(d => d.IsDecided && !d.Locked && d.GetWinner() != null && d.GetWinner().TeamId == teamB.TeamId); if (nodesA == null || nodesA.Count() == 0 || nodesB == null || nodesB.Count() == 0) { if (!byesLocked) { byesLocked = true; LockByes(rootNode); goto tryagainwithbyeslocked; } throw new InvalidTournamentStateException("There was at least one pairing that could not be matched: The requested team was not available to play."); } if (nodesA.Count() > 1 || nodesB.Count() > 1) { if (!byesLocked) { byesLocked = true; LockByes(rootNode); goto tryagainwithbyeslocked; } throw new InvalidTournamentStateException("There was at least one pairing that could not be matched: The requested team was not able to be decided unambiguously."); } var deciderA = nodesA.Single(); var deciderB = nodesB.Single(); var parentDecider = deciderA.PrimaryParent.PrimaryParent as ContinuationDecider; if (parentDecider == null) { parentDecider = deciderB.PrimaryParent.PrimaryParent as ContinuationDecider; if (parentDecider == null) { if (!byesLocked) { byesLocked = true; LockByes(rootNode); goto tryagainwithbyeslocked; } throw new InvalidTournamentStateException("There was at least one pairing that could not be matched: The requested pairing was not compatible with the state of the tournament."); } } if (parentDecider.ChildA.Decider == deciderA || parentDecider.ChildA.Decider == deciderB) { if (parentDecider.ChildA.Decider == deciderA) { SwapDeciders(parentDecider.ChildB.Decider, deciderB); } else { SwapDeciders(parentDecider.ChildB.Decider, deciderA); } } else { if (parentDecider.ChildB.Decider == deciderA) { SwapDeciders(parentDecider.ChildA.Decider, deciderB); } else { SwapDeciders(parentDecider.ChildA.Decider, deciderA); } } success = rootNode.ApplyPairing(pairing); if (!success) { if (!byesLocked) { byesLocked = true; LockByes(rootNode); goto tryagainwithbyeslocked; } throw new InvalidTournamentStateException("A swap was performed to match the tournament to the actual state, but applying the pairing failed."); } } } } this.loadedRootNode = rootNode; this.loadedTeams = new List<TournamentTeam>(teams); this.state = PairingsGeneratorState.Initialized; }
protected NodeMeasurement MeasureTree(IGraphics g, TournamentNameTable names, float textHeight, EliminationNode nodeA, EliminationNode nodeB) { var mA = nodeA?.Measure(g, names, textHeight); var mB = nodeB?.Measure(g, names, textHeight); if (mA == null && mB == null) { return(null); } else if (mA != null && mB != null) { return(new NodeMeasurement( Math.Max(mA.Width, mB.Width) + BracketPreIndent + BracketPostIndent, mA.Height + mB.Height + BracketVSpacing, (mA.CenterLine + (mA.Height + BracketVSpacing + mB.CenterLine)) / 2)); } else if (mA != null) { return(new NodeMeasurement( mA.Width + BracketPreIndent + BracketPostIndent, mA.Height, mA.CenterLine)); } else { return(new NodeMeasurement( mB.Width + BracketPreIndent + BracketPostIndent, mB.Height, mB.CenterLine)); } }
public void SwapChildren() { var tempNode = this.nodeA; this.nodeA = this.nodeB; this.nodeB = tempNode; }
protected void RenderTree(IGraphics g, TournamentNameTable names, float x, float y, float textHeight, EliminationNode nodeA, EliminationNode nodeB) { var m = this.MeasureTree(g, names, textHeight, nodeA, nodeB); var mA = nodeA?.Measure(g, names, textHeight); var mB = nodeB?.Measure(g, names, textHeight); if (mA == null && mB == null) { return; } else if (mA != null && mB != null) { // Preline g.DrawLine( BracketPen, new PointF( x + (m.Width - BracketPreIndent), y + m.CenterLine), new PointF( x + m.Width, y + m.CenterLine)); // V-Line g.DrawLine( BracketPen, new PointF( x + (m.Width - BracketPreIndent), y + mA.CenterLine), new PointF( x + (m.Width - BracketPreIndent), y + mA.Height + BracketVSpacing + mB.CenterLine)); // Post-Line-A g.DrawLine( BracketPen, new PointF( x + (m.Width - BracketPreIndent - BracketPostIndent), y + mA.CenterLine), new PointF( x + (m.Width - BracketPreIndent), y + mA.CenterLine)); // Post-Line-B g.DrawLine( BracketPen, new PointF( x + (m.Width - BracketPreIndent - BracketPostIndent), y + mA.Height + BracketVSpacing + mB.CenterLine), new PointF( x + (m.Width - BracketPreIndent), y + mA.Height + BracketVSpacing + mB.CenterLine)); nodeA.Render(g, names, x + (m.Width - (mA.Width + BracketPreIndent + BracketPostIndent)), y, textHeight); nodeB.Render(g, names, x + (m.Width - (mB.Width + BracketPreIndent + BracketPostIndent)), y + mA.Height + BracketVSpacing, textHeight); } else if (mA != null) { // TODO: Render Lines? nodeA.Render(g, names, x, y, textHeight); } else { // TODO: Render Lines? nodeB.Render(g, names, x, y, textHeight); } }
public void LoadState(IEnumerable <User> teams, IList <TournamentRound> rounds) { if (teams == null) { throw new ArgumentNullException("teams"); } if (rounds == null) { throw new ArgumentNullException("rounds"); } if (rounds.Where(r => r.Pairings.Where(p => p.TeamScores.Count > 2).Any()).Any()) { throw new InvalidTournamentStateException("At least one pairing had more than two teams competing. This is invalid in a single elimination tournament."); } var rootNode = BuildTree(teams); bool byesLocked = false; foreach (var round in rounds) { foreach (var pairing in round.Pairings) { // TODO: We must sort the byes to the top. if (pairing.TeamScores.Count == 0) { continue; } tryagainwithbyeslocked: bool success = rootNode.ApplyPairing(pairing); if (!success) { var teamScoreA = pairing.TeamScores[0]; var teamScoreB = pairing.TeamScores.Count > 1 ? pairing.TeamScores[1] : null; if (teamScoreA == null) { teamScoreA = teamScoreB; teamScoreB = null; } if (teamScoreA == null) { continue; } var teamA = teamScoreA != null ? teamScoreA.Team : null; var teamB = teamScoreB != null ? teamScoreB.Team : null; var scoreA = teamScoreA != null ? teamScoreA.Score : null; var scoreB = teamScoreB != null ? teamScoreB.Score : null; var nodesA = teamA == null ? null : rootNode.FindDeciders(d => d.IsDecided && !d.Locked && d.GetWinner() != null && d.GetWinner().Id == teamA.Id); var nodesB = teamB == null ? null : rootNode.FindDeciders(d => d.IsDecided && !d.Locked && d.GetWinner() != null && d.GetWinner().Id == teamB.Id); if (nodesA == null || nodesA.Count() == 0 || nodesB == null || nodesB.Count() == 0) { if (!byesLocked) { byesLocked = true; LockByes(rootNode); goto tryagainwithbyeslocked; } throw new InvalidTournamentStateException("There was at least one pairing that could not be matched: The requested team was not available to play."); } if (nodesA.Count() > 1 || nodesB.Count() > 1) { if (!byesLocked) { byesLocked = true; LockByes(rootNode); goto tryagainwithbyeslocked; } throw new InvalidTournamentStateException("There was at least one pairing that could not be matched: The requested team was not able to be decided unambiguously."); } var deciderA = nodesA.Single(); var deciderB = nodesB.Single(); var parentDecider = deciderA.PrimaryParent.PrimaryParent as ContinuationDecider; if (parentDecider == null) { parentDecider = deciderB.PrimaryParent.PrimaryParent as ContinuationDecider; if (parentDecider == null) { if (!byesLocked) { byesLocked = true; LockByes(rootNode); goto tryagainwithbyeslocked; } throw new InvalidTournamentStateException("There was at least one pairing that could not be matched: The requested pairing was not compatible with the state of the tournament."); } } if (parentDecider.ChildA.Decider == deciderA || parentDecider.ChildA.Decider == deciderB) { if (parentDecider.ChildA.Decider == deciderA) { SwapDeciders(parentDecider.ChildB.Decider, deciderB); } else { SwapDeciders(parentDecider.ChildB.Decider, deciderA); } } else { if (parentDecider.ChildB.Decider == deciderA) { SwapDeciders(parentDecider.ChildA.Decider, deciderB); } else { SwapDeciders(parentDecider.ChildA.Decider, deciderA); } } success = rootNode.ApplyPairing(pairing); if (!success) { if (!byesLocked) { byesLocked = true; LockByes(rootNode); goto tryagainwithbyeslocked; } throw new InvalidTournamentStateException("A swap was performed to match the tournament to the actual state, but applying the pairing failed."); } } } } this.loadedRootNode = rootNode; this.loadedTeams = new List <User>(teams); this.state = PairingsGeneratorState.Initialized; }
/// <summary> /// Initializes a new instance of the <see cref="PassThroughDecider"/> class. /// </summary> /// <param name="passThroughNode">The node whose winner will be passed through.</param> public PassThroughDecider(EliminationNode passThroughNode) { this.PassThroughNode = passThroughNode ?? throw new ArgumentNullException(nameof(passThroughNode)); }