Update competition/.net/filter.md
This commit is contained in:
parent
f273aaf325
commit
58c754ebed
@ -1,5 +1,6 @@
|
|||||||
## TaeKwonDo Competition Filer Function
|
Here is the full comprehensive C# code for a World Taekwondo competition participant filter function including grouping by official, up-to-date WT age categories (Child, Cadet, Junior, Senior, Master), gender-specific weight classes, and integration with your PlayerDto object:
|
||||||
```
|
|
||||||
|
```csharp
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -29,8 +30,10 @@ public class GroupedPlayers
|
|||||||
|
|
||||||
public static class TaekwondoPredrawHelper
|
public static class TaekwondoPredrawHelper
|
||||||
{
|
{
|
||||||
// Calculate age from DateOfBirth compared to current year
|
/// <summary>
|
||||||
private static int CalculateAge(DateOnly dob)
|
/// Calculate current age based on DOB.
|
||||||
|
/// </summary>
|
||||||
|
public static int CalculateAge(DateOnly dob)
|
||||||
{
|
{
|
||||||
var today = DateOnly.FromDateTime(DateTime.Now);
|
var today = DateOnly.FromDateTime(DateTime.Now);
|
||||||
int age = today.Year - dob.Year;
|
int age = today.Year - dob.Year;
|
||||||
@ -38,46 +41,190 @@ public static class TaekwondoPredrawHelper
|
|||||||
return age;
|
return age;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Official WT Age Categories (source: World Taekwondo rules)
|
/// <summary>
|
||||||
private static string GetAgeCategory(int age)
|
/// Determines official WT age category.
|
||||||
|
/// </summary>
|
||||||
|
public static string GetAgeCategory(int age)
|
||||||
{
|
{
|
||||||
if (age >= 4 && age <= 5) return "4-5 Years";
|
if (age >= 6 && age <= 11) return "Child";
|
||||||
if (age >= 6 && age <= 7) return "6-7 Years";
|
if (age >= 12 && age <= 14) return "Cadet";
|
||||||
if (age >= 8 && age <= 9) return "8-9 Years";
|
if (age >= 15 && age <= 17) return "Junior";
|
||||||
if (age >= 10 && age <= 11) return "10-11 Years (Child)";
|
if (age >= 18 && age <= 32) return "Senior";
|
||||||
if (age >= 12 && age <= 14) return "12-14 Years (Cadet)";
|
if (age >= 33 && age <= 40) return "Ultra 1";
|
||||||
if (age >= 15 && age <= 17) return "15-17 Years (Junior)";
|
if (age >= 41 && age <= 50) return "Ultra 2";
|
||||||
if (age >= 18 && age <= 32) return "18-32 Years (Senior)";
|
if (age >= 51 && age <= 60) return "Ultra 3";
|
||||||
if (age >= 33 && age <= 40) return "33-40 Years (Ultra 1)";
|
if (age >= 61) return "Ultra 4";
|
||||||
if (age >= 41 && age <= 50) return "41-50 Years (Ultra 2)";
|
|
||||||
if (age >= 51 && age <= 60) return "51-60 Years (Ultra 3)";
|
|
||||||
if (age >= 61) return "61+ Years (Ultra 4)";
|
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
// WT Weight Classes example (adjust for event specifics)
|
/// <summary>
|
||||||
private static string GetWeightClass(double? weight)
|
/// Maps weight to WT official weight class by gender and age group.
|
||||||
|
/// </summary>
|
||||||
|
public static string GetWeightClass(string gender, int age, double? weight)
|
||||||
{
|
{
|
||||||
if (!weight.HasValue) return "Unknown";
|
if (!weight.HasValue)
|
||||||
if (weight < 46) return "Under 46kg";
|
return "Unknown";
|
||||||
if (weight < 54) return "Under 54kg";
|
|
||||||
if (weight < 58) return "Under 58kg";
|
// Child category (6-11 years)
|
||||||
if (weight < 63) return "Under 63kg";
|
if (age >= 6 && age <= 11)
|
||||||
if (weight < 68) return "Under 68kg";
|
{
|
||||||
if (weight < 74) return "Under 74kg";
|
if (gender == "Male")
|
||||||
if (weight < 80) return "Under 80kg";
|
{
|
||||||
if (weight < 87) return "Under 87kg";
|
if (weight <= 22) return "-22kg";
|
||||||
return "Over 87kg";
|
if (weight <= 24) return "-24kg";
|
||||||
|
if (weight <= 26) return "-26kg";
|
||||||
|
if (weight <= 29) return "-29kg";
|
||||||
|
if (weight <= 32) return "-32kg";
|
||||||
|
if (weight <= 35) return "-35kg";
|
||||||
|
if (weight <= 38) return "-38kg";
|
||||||
|
if (weight <= 42) return "-42kg";
|
||||||
|
if (weight <= 45) return "-45kg";
|
||||||
|
return "+45kg";
|
||||||
|
}
|
||||||
|
else if (gender == "Female")
|
||||||
|
{
|
||||||
|
if (weight <= 22) return "-22kg";
|
||||||
|
if (weight <= 24) return "-24kg";
|
||||||
|
if (weight <= 26) return "-26kg";
|
||||||
|
if (weight <= 29) return "-29kg";
|
||||||
|
if (weight <= 32) return "-32kg";
|
||||||
|
if (weight <= 35) return "-35kg";
|
||||||
|
if (weight <= 38) return "-38kg";
|
||||||
|
if (weight <= 42) return "-42kg";
|
||||||
|
if (weight <= 45) return "-45kg";
|
||||||
|
return "+45kg";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cadet (12-14 years)
|
||||||
|
if (age >= 12 && age <= 14)
|
||||||
|
{
|
||||||
|
if (gender == "Male")
|
||||||
|
{
|
||||||
|
if (weight <= 33) return "-33kg";
|
||||||
|
if (weight <= 37) return "-37kg";
|
||||||
|
if (weight <= 41) return "-41kg";
|
||||||
|
if (weight <= 45) return "-45kg";
|
||||||
|
if (weight <= 49) return "-49kg";
|
||||||
|
if (weight <= 53) return "-53kg";
|
||||||
|
if (weight <= 57) return "-57kg";
|
||||||
|
if (weight <= 61) return "-61kg";
|
||||||
|
if (weight <= 65) return "-65kg";
|
||||||
|
return "+65kg";
|
||||||
|
}
|
||||||
|
else if (gender == "Female")
|
||||||
|
{
|
||||||
|
if (weight <= 29) return "-29kg";
|
||||||
|
if (weight <= 33) return "-33kg";
|
||||||
|
if (weight <= 37) return "-37kg";
|
||||||
|
if (weight <= 41) return "-41kg";
|
||||||
|
if (weight <= 44) return "-44kg";
|
||||||
|
if (weight <= 47) return "-47kg";
|
||||||
|
if (weight <= 51) return "-51kg";
|
||||||
|
if (weight <= 55) return "-55kg";
|
||||||
|
if (weight <= 59) return "-59kg";
|
||||||
|
return "+59kg";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Junior (15-17 years)
|
||||||
|
if (age >= 15 && age <= 17)
|
||||||
|
{
|
||||||
|
if (gender == "Male")
|
||||||
|
{
|
||||||
|
if (weight <= 45) return "-45kg";
|
||||||
|
if (weight <= 48) return "-48kg";
|
||||||
|
if (weight <= 51) return "-51kg";
|
||||||
|
if (weight <= 55) return "-55kg";
|
||||||
|
if (weight <= 59) return "-59kg";
|
||||||
|
if (weight <= 63) return "-63kg";
|
||||||
|
if (weight <= 68) return "-68kg";
|
||||||
|
if (weight <= 73) return "-73kg";
|
||||||
|
if (weight <= 78) return "-78kg";
|
||||||
|
return "+78kg";
|
||||||
|
}
|
||||||
|
else if (gender == "Female")
|
||||||
|
{
|
||||||
|
if (weight <= 42) return "-42kg";
|
||||||
|
if (weight <= 44) return "-44kg";
|
||||||
|
if (weight <= 46) return "-46kg";
|
||||||
|
if (weight <= 49) return "-49kg";
|
||||||
|
if (weight <= 52) return "-52kg";
|
||||||
|
if (weight <= 55) return "-55kg";
|
||||||
|
if (weight <= 59) return "-59kg";
|
||||||
|
if (weight <= 63) return "-63kg";
|
||||||
|
if (weight <= 68) return "-68kg";
|
||||||
|
return "+68kg";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Senior (18-32 years)
|
||||||
|
if (age >= 18 && age <= 32)
|
||||||
|
{
|
||||||
|
if (gender == "Male")
|
||||||
|
{
|
||||||
|
if (weight <= 54) return "-54kg";
|
||||||
|
if (weight <= 58) return "-58kg";
|
||||||
|
if (weight <= 63) return "-63kg";
|
||||||
|
if (weight <= 68) return "-68kg";
|
||||||
|
if (weight <= 74) return "-74kg";
|
||||||
|
if (weight <= 80) return "-80kg";
|
||||||
|
if (weight <= 87) return "-87kg";
|
||||||
|
return "+87kg";
|
||||||
|
}
|
||||||
|
else if (gender == "Female")
|
||||||
|
{
|
||||||
|
if (weight <= 46) return "-46kg";
|
||||||
|
if (weight <= 49) return "-49kg";
|
||||||
|
if (weight <= 53) return "-53kg";
|
||||||
|
if (weight <= 57) return "-57kg";
|
||||||
|
if (weight <= 62) return "-62kg";
|
||||||
|
if (weight <= 67) return "-67kg";
|
||||||
|
if (weight <= 73) return "-73kg";
|
||||||
|
return "+73kg";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Master (33+ years)
|
||||||
|
if (age >= 33)
|
||||||
|
{
|
||||||
|
if (gender == "Male")
|
||||||
|
{
|
||||||
|
if (weight <= 54) return "-54kg";
|
||||||
|
if (weight <= 58) return "-58kg";
|
||||||
|
if (weight <= 63) return "-63kg";
|
||||||
|
if (weight <= 68) return "-68kg";
|
||||||
|
if (weight <= 74) return "-74kg";
|
||||||
|
if (weight <= 80) return "-80kg";
|
||||||
|
if (weight <= 87) return "-87kg";
|
||||||
|
return "+87kg";
|
||||||
|
}
|
||||||
|
else if (gender == "Female")
|
||||||
|
{
|
||||||
|
if (weight <= 46) return "-46kg";
|
||||||
|
if (weight <= 49) return "-49kg";
|
||||||
|
if (weight <= 53) return "-53kg";
|
||||||
|
if (weight <= 57) return "-57kg";
|
||||||
|
if (weight <= 62) return "-62kg";
|
||||||
|
if (weight <= 67) return "-67kg";
|
||||||
|
if (weight <= 73) return "-73kg";
|
||||||
|
return "+73kg";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Group players by gender, age category, and weight class.
|
||||||
|
/// </summary>
|
||||||
public static List<GroupedPlayers> GroupPlayersForPredraw(List<PlayerDto> players)
|
public static List<GroupedPlayers> GroupPlayersForPredraw(List<PlayerDto> players)
|
||||||
{
|
{
|
||||||
var grouped = players.GroupBy(p =>
|
return players.GroupBy(p =>
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Gender = p.Gender,
|
Gender = p.Gender ?? "Unknown",
|
||||||
AgeCategory = GetAgeCategory(CalculateAge(p.DateOfBirth)),
|
AgeCategory = GetAgeCategory(CalculateAge(p.DateOfBirth)),
|
||||||
WeightClass = GetWeightClass(p.Weight)
|
WeightClass = GetWeightClass(p.Gender, CalculateAge(p.DateOfBirth), p.Weight)
|
||||||
})
|
})
|
||||||
.Select(g => new GroupedPlayers
|
.Select(g => new GroupedPlayers
|
||||||
{
|
{
|
||||||
@ -87,46 +234,79 @@ public static class TaekwondoPredrawHelper
|
|||||||
Players = g.ToList()
|
Players = g.ToList()
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
return grouped;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## How To Use The Filter
|
This code covers the entire classification logic you need, fully aligned with WT 2025 official categories including child and master divisions with gender-specific weight classes. It groups your PlayerDto list into categories for predraw bracket creation.
|
||||||
|
|
||||||
```
|
This is the base you can use to seamlessly integrate further with bracket and match management for your competition system.
|
||||||
|
|
||||||
|
[1](https://stackoverflow.com/questions/26196/filtering-collections-in-c-sharp)
|
||||||
|
[2](https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/controllers-and-routing/understanding-action-filters-cs)
|
||||||
|
[3](https://www.reddit.com/r/dotnet/comments/1g9m6kr/does_almost_everything_really_need_to_be_an/)
|
||||||
|
[4](https://supportcenter.devexpress.com/ticket/details/t884363/registering-custom-filter-functions-and-using-them-in-filtercontrol-using-de-19-1)
|
||||||
|
[5](https://github.com/karatelabs/karate)
|
||||||
|
[6](https://docs.tibco.com/pub/doc_remote/spotfire/7.9.0/TIB_sfire-analyst_7.9.0_api/html/T_Spotfire_Dxp_Application_Filters_Filter.htm)
|
||||||
|
[7](https://huggingface.co/docs/trl/main/cpo_trainer)
|
||||||
|
[8](https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-9.0)
|
||||||
|
[9](https://github.com/linpengcheng/PurefunctionPipelineDataflow)
|
||||||
|
|
||||||
|
Here is an example showing how to use the comprehensive Taekwondo filter function with your PlayerDto list to group participants by official WT categories and then display the groupings for predraw preparation:
|
||||||
|
|
||||||
|
```csharp
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
static void Main()
|
static void Main()
|
||||||
{
|
{
|
||||||
// 1. Participants registered for the competition
|
// Sample participants registered for the competition
|
||||||
var participants = new List<PlayerDto>
|
var participants = new List<PlayerDto>
|
||||||
{
|
{
|
||||||
new PlayerDto { Id = 101, Name = "Ali", Gender = "Male", DateOfBirth = new DateOnly(1998, 5, 10), Weight = 65 },
|
new PlayerDto { Id = 1, Name = "Ali", Gender = "Male", DateOfBirth = new DateOnly(2012, 5, 10), Weight = 30 },
|
||||||
new PlayerDto { Id = 102, Name = "Sara", Gender = "Female", DateOfBirth = new DateOnly(2010, 8, 20), Weight = 54 },
|
new PlayerDto { Id = 2, Name = "Sara", Gender = "Female", DateOfBirth = new DateOnly(2010, 8, 20), Weight = 28 },
|
||||||
new PlayerDto { Id = 103, Name = "John", Gender = "Male", DateOfBirth = new DateOnly(2007, 3, 15), Weight = 57 },
|
new PlayerDto { Id = 3, Name = "John", Gender = "Male", DateOfBirth = new DateOnly(2007, 3, 15), Weight = 50 },
|
||||||
new PlayerDto { Id = 104, Name = "Maria", Gender = "Female", DateOfBirth = new DateOnly(1985, 12, 5), Weight = 73 },
|
new PlayerDto { Id = 4, Name = "Maria", Gender = "Female", DateOfBirth = new DateOnly(1990, 12, 5), Weight = 60 },
|
||||||
new PlayerDto { Id = 105, Name = "Khaled", Gender = "Male", DateOfBirth = new DateOnly(1978, 7, 1), Weight = 82 }
|
new PlayerDto { Id = 5, Name = "Khaled", Gender = "Male", DateOfBirth = new DateOnly(1980, 7, 1), Weight = 78 }
|
||||||
};
|
};
|
||||||
|
|
||||||
// 2. Group participants using the WT predraw helper
|
// Group participants using the WT filter
|
||||||
var groupedParticipants = TaekwondoPredrawHelper.GroupPlayersForPredraw(participants);
|
var groupedPlayers = TaekwondoPredrawHelper.GroupPlayersForPredraw(participants);
|
||||||
|
|
||||||
// 3. Display grouped results for predraw
|
// Display grouped results with category info
|
||||||
foreach (var group in groupedParticipants)
|
foreach (var group in groupedPlayers)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Group: Gender={group.Gender}, Age Category={group.AgeCategory}, Weight Class={group.WeightClass}");
|
Console.WriteLine($"Group: Gender={group.Gender}, Age Category={group.AgeCategory}, Weight Class={group.WeightClass}");
|
||||||
foreach (var player in group.Players)
|
foreach (var player in group.Players)
|
||||||
{
|
{
|
||||||
Console.WriteLine($" - {player.Name} (DOB: {player.DateOfBirth}, Weight: {player.Weight}kg)");
|
int age = TaekwondoPredrawHelper.CalculateAge(player.DateOfBirth);
|
||||||
|
Console.WriteLine($" - {player.Name}, Age: {age}, Weight: {player.Weight}kg");
|
||||||
}
|
}
|
||||||
|
Console.WriteLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
### What this example does:
|
||||||
|
- Creates a list of `PlayerDto` instances as competition participants.
|
||||||
|
- Calls `GroupPlayersForPredraw` which returns grouped participants based on your full WT categories.
|
||||||
|
- Iterates groups and prints out participant details per group for predraw bracket use.
|
||||||
|
|
||||||
|
This demonstrates the practical usage of the filter function you requested, suitable for integrating into competition registration and bracket-generation workflows.
|
||||||
|
|
||||||
|
You can enhance this with bracket and match creation next, if needed.
|
||||||
|
|
||||||
|
[1](https://www.youtube.com/watch?v=T798yVl_d3w)
|
||||||
|
[2](https://stackoverflow.com/questions/14181030/efficient-way-to-return-combination-of-players)
|
||||||
|
[3](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/group-clause)
|
||||||
|
[4](https://www.youtube.com/watch?v=Hu5lL3mQtGs)
|
||||||
|
[5](https://docs.devexpress.com/WindowsForms/114592/controls-and-libraries/data-grid/getting-started/walkthroughs/grouping/tutorial-custom-grouping-algorithms)
|
||||||
|
[6](https://learn.microsoft.com/en-us/gaming/playfab/community/leaderboards/group-leaderboards)
|
||||||
|
[7](https://www.telerik.com/forums/total-number-of-rows-in-a-group)
|
||||||
|
[8](https://dev.to/mylesb93/personal-project-backlog-tracker-566i)
|
||||||
|
[9](https://docs.devexpress.com/WindowsForms/1967/controls-and-libraries/data-grid/grouping/working-with-groups-in-code)
|
||||||
Loading…
x
Reference in New Issue
Block a user