TournamentWindow.xaml.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Windows;
  7. using System.Windows.Controls;
  8. using System.Windows.Data;
  9. using System.Windows.Documents;
  10. using System.Windows.Input;
  11. using System.Windows.Media;
  12. using System.Windows.Media.Imaging;
  13. using System.Windows.Shapes;
  14. using Курсовой_проект_3._1.UserControls;
  15. using Курсовой_проект_3._1.Windows;
  16. namespace Курсовой_проект_3._1
  17. {
  18. /// <summary>
  19. /// Логика взаимодействия для TournamentWindow.xaml
  20. /// </summary>
  21. public partial class TournamentWindow : Window
  22. {
  23. MyTeamContext _context;
  24. int nowTournamentId;
  25. bool isAccess;
  26. public TournamentWindow(int tournamentId)
  27. {
  28. InitializeComponent();
  29. _context = new MyTeamContext();
  30. nowTournamentId = tournamentId;
  31. isAccess = false;
  32. // Подгрузка краткой информации
  33. Tournaments tournament = _context.Tournaments.Find(nowTournamentId);
  34. // Доступность кнопок
  35. if (App.UserId == tournament.FK_Organizer_Id)
  36. {
  37. AddResultBtn.Visibility = Visibility.Visible;
  38. isAccess = true;
  39. }
  40. if (tournament.Users.Disciplines != null)
  41. {
  42. DiciplineLogoImg.Source = new BitmapImage(new Uri(tournament.Users.Disciplines.IconPath));
  43. DiciplineNameTB.Text = tournament.Users.Disciplines.Name;
  44. }
  45. TournamentNameTB.Text = tournament.Name;
  46. TournamentShortNameTB.Text = tournament.Name;
  47. OrganizerTB.Text = tournament.Users.Nickname;
  48. VenueTB.Text = tournament.Venue;
  49. FormatTB.Text = tournament.TournamentFormats.Name;
  50. PrizeFondTB.Text = Func.ConvertIntToStringMoney(tournament.PrizeFond) + "$";
  51. // Получаем кол-во команд на турнире
  52. int teamCount = _context.Tournaments.Find(nowTournamentId).MaxTeamsCount;
  53. // Создаем сетку на такой размер
  54. MainGrid.Children.Add(GenerateSingleEliminationBracket(teamCount));
  55. // Получаем все матчи турнира
  56. List<TournamentMatch> matchList = new List<TournamentMatch>();
  57. List<Matches> matchesDb = _context.Matches.Where(m => m.FK_Tournament_Id == nowTournamentId).OrderBy(m => m.GameDate).ToList();
  58. int addGameCounter = 0;
  59. foreach (Matches match in matchesDb)
  60. {
  61. matchList.Add(new TournamentMatch(match.FK_FrstTeam_Id.ToString(), match.FK_ScndTeam_Id.ToString(), match.FrstScore.ToString(),
  62. match.ScndScore.ToString(), match.RoundNum, match.FK_WinnerTeam_Id.ToString(), addGameCounter));
  63. addGameCounter++;
  64. }
  65. // Высчитывание размеров сетки
  66. int roundCount = (int)Math.Log(teamCount, 2); // количество раундов
  67. int gridColumnCount = roundCount + roundCount - 1 + 2; // количество колонок в grid
  68. int gridRowCount = teamCount + (teamCount - 2) + 4; // количество строк в grid
  69. int roundCounter = 0;
  70. int gameCounter = 0;
  71. Grid bracketGrid = (Grid)MainGrid.Children[0];
  72. for (int column = 1; column < gridColumnCount; column++)
  73. {
  74. if (column % 2 != 0)
  75. {
  76. roundCounter++;
  77. for (int row = 0; row < gridRowCount; row++)
  78. {
  79. UIElement element = GetElementInGridPosition(column, row, bracketGrid);
  80. if (element is MatchControl)
  81. {
  82. foreach (TournamentMatch match in matchList)
  83. {
  84. if (match.roundNum == roundCounter && match.gameNum == gameCounter)
  85. {
  86. bracketGrid.Children.Remove(GetElementInGridPosition(column, row, bracketGrid));
  87. MatchControl newElement = new MatchControl();
  88. if (isAccess)
  89. {
  90. newElement.MouseDown += MatchControl_Click;
  91. newElement.Cursor = Cursors.Hand;
  92. }
  93. newElement.TeamNameFrst = _context.Teams.Find(Convert.ToInt32(match.teamIdFrst)).Name;
  94. newElement.ScoreFrst = match.ScoreFrst;
  95. newElement.TeamNameScnd = _context.Teams.Find(Convert.ToInt32(match.teamIdScnd)).Name;
  96. newElement.ScoreScnd = match.ScoreScnd;
  97. newElement.RoundNum = roundCounter.ToString();
  98. Grid.SetColumn(newElement, column);
  99. Grid.SetRow(newElement, row);
  100. Grid.SetRowSpan(newElement, 2);
  101. bracketGrid.Children.Add(newElement);
  102. }
  103. }
  104. gameCounter++;
  105. }
  106. }
  107. }
  108. }
  109. // Результаты
  110. List<Achievements> achievementList = _context.Achievements.Where(a => a.FK_Tournament_Id == nowTournamentId).ToList();
  111. List<Result> resultList = new List<Result>();
  112. foreach (Achievements achievement in achievementList)
  113. {
  114. Result result = new Result();
  115. result.Place = achievement.Place;
  116. result.Prize = Func.ConvertIntToStringMoney(achievement.Prize) + " $";
  117. result.TeamName = achievement.Teams.Name;
  118. result.LogoPath = _context.Teams.Find(achievement.FK_Team_Id).LogoPath;
  119. result.CountryIconPath = _context.Teams.Find(achievement.FK_Team_Id).Countries.IconPath;
  120. if (result.Place == "1")
  121. {
  122. result.Place = "";
  123. result.PlacePath = @"C:\Users\nikich4523\source\repos\Курсовой проект 3.1\Курсовой проект 3.1\img\Default\cupGold.png";
  124. }
  125. else if (result.Place == "2")
  126. {
  127. result.Place = "";
  128. result.PlacePath = @"C:\Users\nikich4523\source\repos\Курсовой проект 3.1\Курсовой проект 3.1\img\Default\cupSilver.png";
  129. }
  130. else if (result.Place == "3")
  131. {
  132. result.Place = "";
  133. result.PlacePath = @"C:\Users\nikich4523\source\repos\Курсовой проект 3.1\Курсовой проект 3.1\img\Default\cupBronze.png";
  134. }
  135. resultList.Add(result);
  136. }
  137. ResultLB.ItemsSource = resultList;
  138. }
  139. // Генерирует турнирную сетку SingleElimination (работает со степенями 2ки) - работает не трогай
  140. public Grid GenerateSingleEliminationBracket(int teamCount)
  141. {
  142. Grid grid = new Grid();
  143. grid.Background = Brushes.WhiteSmoke;
  144. grid.ShowGridLines = false;
  145. // Создание Grid'ов ///
  146. // Высчитывание размеров сетки
  147. int roundCount = (int)Math.Log(teamCount, 2); // количество раундов
  148. int gridColumnCount = roundCount + roundCount - 1 + 2; // количество колонок в grid
  149. int gridRowCount = teamCount + (teamCount - 2) + 4; // количество строк в grid
  150. // Добавление колонок
  151. for (int i = 0; i < gridColumnCount; i++)
  152. {
  153. grid.ColumnDefinitions.Add(new ColumnDefinition());
  154. }
  155. // Добавление строк
  156. for (int j = 0; j < gridRowCount; j++)
  157. {
  158. grid.RowDefinitions.Add(new RowDefinition());
  159. }
  160. // Всё остальное
  161. int roundNum = 1; // номер раунда
  162. int skipStart = 2; // сколько пропустить строк с начала
  163. int skipBetween = 2; // сколько пропускать строк между играми
  164. // Наполнение сетки
  165. for (int i = 1; i < gridColumnCount - 1; i++)
  166. {
  167. if (i % 2 != 0) // раунды через одну колонку
  168. {
  169. for (int j = skipStart; j < gridRowCount - 2; j++)
  170. {
  171. MatchControl match = new MatchControl();
  172. if (isAccess)
  173. {
  174. match.MouseDown += MatchControl_Click;
  175. match.Cursor = Cursors.Hand;
  176. match.RoundNum = roundNum.ToString();
  177. }
  178. Grid.SetColumn(match, i);
  179. Grid.SetRow(match, j);
  180. Grid.SetRowSpan(match, 2);
  181. grid.Children.Add(match);
  182. // после каждой игры нужен пропуск (skipBetween) до следующей игры
  183. j += skipBetween + 1;
  184. }
  185. // пересчет значений для следующего раунда
  186. roundNum++;
  187. int gamesInRoundCount = (int)(teamCount / Math.Pow(2, roundNum));
  188. skipStart *= 2;
  189. skipBetween = roundNum == roundCount ? skipStart : (gridRowCount - (skipStart * 2) - (gamesInRoundCount * 2)) / (gamesInRoundCount - 1);
  190. }
  191. }
  192. // соединяющие линии между раундами
  193. int skipStartOrEnd = 4;
  194. for (int i = 2; i < gridColumnCount - 1; i++)
  195. {
  196. if (i % 2 == 0)
  197. {
  198. if (i == 2)
  199. {
  200. for (int j = 4; j < gridRowCount; j++)
  201. {
  202. TextBox linetb1 = new TextBox();
  203. linetb1.BorderBrush = Brushes.Black;
  204. linetb1.IsReadOnly = true;
  205. var bc = new BrushConverter();
  206. linetb1.Background = Brushes.Transparent;
  207. linetb1.BorderThickness = new Thickness(2, 0, 0, 2);
  208. Grid.SetColumn(linetb1, i);
  209. Grid.SetRow(linetb1, j);
  210. grid.Children.Add(linetb1);
  211. TextBox linetb2 = new TextBox();
  212. linetb2.BorderBrush = Brushes.Black;
  213. linetb2.IsReadOnly = true;
  214. linetb2.Background = Brushes.Transparent;
  215. linetb2.BorderThickness = new Thickness(2, 2, 0, 0);
  216. Grid.SetColumn(linetb2, i);
  217. Grid.SetRow(linetb2, j + 1);
  218. grid.Children.Add(linetb2);
  219. j += 7;
  220. }
  221. }
  222. else
  223. {
  224. int drawStatus = 0; // 0 - не рисовать, 1 - leftonly
  225. for (int j = 4; j < gridRowCount - skipStartOrEnd; j++)
  226. {
  227. // тут leftonly
  228. if (drawStatus == 1)
  229. {
  230. // leftonly
  231. TextBox linetb3 = new TextBox();
  232. linetb3.BorderBrush = Brushes.Black;
  233. linetb3.IsReadOnly = true;
  234. var bc = new BrushConverter();
  235. linetb3.Background = Brushes.Transparent;
  236. linetb3.BorderThickness = new Thickness(2, 0, 0, 0);
  237. Grid.SetColumn(linetb3, i);
  238. Grid.SetRow(linetb3, j);
  239. grid.Children.Add(linetb3);
  240. }
  241. // тут проверка
  242. if (GetElementInGridPosition(i - 1, j, grid) is MatchControl)
  243. {
  244. if (drawStatus == 1)
  245. {
  246. grid.Children.Remove(GetElementInGridPosition(i, j, grid));
  247. }
  248. j += 2; // пропуск текущего MatchControl
  249. if (j < gridRowCount - skipStartOrEnd)
  250. {
  251. // leftonly
  252. TextBox linetb3 = new TextBox();
  253. linetb3.BorderBrush = Brushes.Black;
  254. linetb3.IsReadOnly = true;
  255. var bc = new BrushConverter();
  256. linetb3.Background = Brushes.Transparent;
  257. linetb3.BorderThickness = new Thickness(2, 0, 0, 0);
  258. Grid.SetColumn(linetb3, i);
  259. Grid.SetRow(linetb3, j);
  260. grid.Children.Add(linetb3);
  261. }
  262. drawStatus = 1;
  263. }
  264. else if (GetElementInGridPosition(i + 1, j, grid) is MatchControl)
  265. {
  266. var bc = new BrushConverter();
  267. // leftbottom
  268. TextBox linetb1 = new TextBox();
  269. linetb1.BorderBrush = Brushes.Black;
  270. linetb1.IsReadOnly = true;
  271. linetb1.Background = Brushes.Transparent;
  272. linetb1.BorderThickness = new Thickness(2, 0, 0, 2);
  273. Grid.SetColumn(linetb1, i);
  274. Grid.SetRow(linetb1, j);
  275. grid.Children.Add(linetb1);
  276. j++; // переход на следующую строку
  277. // lefttop
  278. TextBox linetb2 = new TextBox();
  279. linetb2.BorderBrush = Brushes.Black;
  280. linetb2.IsReadOnly = true;
  281. linetb2.Background = Brushes.Transparent;
  282. linetb2.BorderThickness = new Thickness(2, 2, 0, 0);
  283. Grid.SetColumn(linetb2, i);
  284. Grid.SetRow(linetb2, j);
  285. grid.Children.Add(linetb2);
  286. }
  287. }
  288. skipStartOrEnd = skipStartOrEnd * 2;
  289. }
  290. }
  291. }
  292. return grid;
  293. }
  294. private UIElement GetElementInGridPosition(int column, int row, Grid RootGrid)
  295. {
  296. foreach (UIElement element in RootGrid.Children)
  297. {
  298. if (Grid.GetColumn(element) == column && Grid.GetRow(element) == row)
  299. return element;
  300. }
  301. return null;
  302. }
  303. private void MatchControl_Click(object sender, RoutedEventArgs e)
  304. {
  305. MatchControl match = (MatchControl)sender;
  306. if(match.TeamNameFrst == "" && match.TeamNameScnd == "")
  307. {
  308. SelectTeamsInMatchWindow wnd = new SelectTeamsInMatchWindow(nowTournamentId, Convert.ToInt32(match.RoundNum));
  309. wnd.ShowDialog();
  310. }
  311. else
  312. {
  313. MatchWindow wnd = new MatchWindow(match, nowTournamentId, Convert.ToInt32(match.RoundNum));
  314. wnd.ShowDialog();
  315. }
  316. }
  317. private void AddResultBtn_Click(object sender, RoutedEventArgs e)
  318. {
  319. ResultAddWindow wnd = new ResultAddWindow(nowTournamentId);
  320. wnd.ShowDialog();
  321. }
  322. private void ResultLB_MouseDoubleClick(object sender, MouseButtonEventArgs e)
  323. {
  324. if (ResultLB.SelectedItem != null)
  325. {
  326. Result result = (Result)ResultLB.SelectedItem;
  327. ResultAddWindow wnd = new ResultAddWindow(result.TeamName, nowTournamentId);
  328. wnd.ShowDialog();
  329. }
  330. }
  331. private void ToMainBtn_Click(object sender, RoutedEventArgs e)
  332. {
  333. ApplicationWindow wnd = new ApplicationWindow();
  334. wnd.Show();
  335. Close();
  336. }
  337. private void ToSearchBtn_Click(object sender, RoutedEventArgs e)
  338. {
  339. SearchWindow wnd = new SearchWindow();
  340. wnd.ShowDialog();
  341. }
  342. private void ToProfileBtn_Click(object sender, RoutedEventArgs e)
  343. {
  344. MainWindow wnd = new MainWindow(App.UserId);
  345. wnd.Show();
  346. Close();
  347. }
  348. }
  349. // Класс, описывающий матч в турнирной сетке
  350. public class TournamentMatch
  351. {
  352. public string teamIdFrst { get; private set; }
  353. public string teamIdScnd { get; private set; }
  354. public string ScoreFrst { get; private set; }
  355. public string ScoreScnd { get; private set; }
  356. public int roundNum { get; private set; }
  357. public int gameNum { get; private set; }
  358. public string teamIdWinner { get; private set; }
  359. public TournamentMatch(string teamIdFrst, string teamIdScnd, string ScoreFrst, string ScoreScnd, int roundNum, string teamIdWinner, int gameNum)
  360. {
  361. this.teamIdFrst = teamIdFrst;
  362. this.teamIdScnd = teamIdScnd;
  363. this.ScoreFrst = ScoreFrst;
  364. this.ScoreScnd = ScoreScnd;
  365. this.roundNum = roundNum;
  366. this.gameNum = gameNum;
  367. this.teamIdWinner = teamIdWinner;
  368. }
  369. }
  370. // Класс, описывающий результат в ResultLB
  371. public class Result
  372. {
  373. public string Place { get; set; }
  374. public string PlacePath { get; set; }
  375. public string LogoPath { get; set; }
  376. public string CountryIconPath { get; set; }
  377. public string TeamName { get; set; }
  378. public string Prize { get; set; }
  379. }
  380. }