როგორ გამოითვლება TAC-ის რეიტინგი
რეიტინგი აფასებს წევრის (და მუდმივი მოთამაშრეების წყვილის) თამაშის დონეს დაფიქსირებული შედეგების საფუძველზე. ამ გვერდზე განმარტება ჯერ ზოგადად არის მოცემული, ხოლო შემდეგ — დეტალურად, დეველოპერებისთვის.
ზოგადად გასაგები
რა არის TAC-ის რეიტინგი?
რეიტინგი არის რიცხვი, რომელიც აჩვენებს, რამდენად ძლიერად თამაშობს მოთამაშე TAC-ს — მსგავსად ჭადრაკის Elo-სისტემისა, ოღონდ უფრო თანამედროვე მეთოდით. ის ითვლება მხოლოდ იმ თამაშების საფუძველზე, რომლებიც აპლიკაციაშია რეგისტრირებული. ქულებს ხელით არავინ ანაწილებს.
არსებობს რეიტინგის ორი სახე: ინდივიდუალური რეიტინგი თითოეული წევრისთვის და გუნდური რეიტინგი მოთამაშეთა ფიქსირებული წყვილისთვის (ორი წევრი, რომლებიც ერთად თამაშობენ).
როდის ჩნდება რეიტინგი?
რეიტინგი ითვლება მხოლოდ მაშინ, როდესაც ორივე მხარეს სულ მცირე ერთი რეალური წევრი თამაშობს. სტუმრები (მოთამაშეები წევრობის ანგარიშის გარეშე) არ ითვლებიან. შესაბამისად, თუ ერთი წევრი თამაშობს მხოლოდ სტუმრებთან ერთად ან სტუმრების წინააღმდეგ, შედარება არ ხდება და რეიტინგი არ ითვლება. გუნდური რეიტინგისთვის საჭიროა, რომ ერთ მხარეს ორი წევრი ითამაშოს სტუმრების გარეშე.
როგორ იცვლება რეიტინგი?
ყოველი რეიტინგული პარტიის შემდეგ რეიტინგი კორექტირდება. ძლიერ მოწინააღმდეგეზე გამარჯვებისას ის საგრძნობლად იზრდება; სუსტესთან წაგების შემთხვევაში კი — უფრო მეტად კლებულობს. ბევრად სუსტ მოწინააღმდეგეზე გამარჯვება თითქმის არაფერს ცვლის, რადგან ასეთი შედეგი მოსალოდნელი იყო.
რეიტინგს თან ახლავს გაურკვევლობაც: თავიდან სისტემამ შენს შესახებ ცოტა რამ იცის, ამიტომ შენი რეიტინგი შეიძლება ჯერ კიდევ მკვეთრად შეიცვალოს. რაც მეტს ითამაშებ, მით უფრო ზუსტი და სტაბილური გახდება შეფასება.
დროებითი რეიტინგი
სანამ წევრს 10 რეიტინგის თამაშზე ნაკლები ექნება, რეიტინგი დროებითად ითვლება — ის ჯერ არ არის საკმარისად ზუსტი სამართლიანი შედარებისთვის.
სხვადასხვა ლიდერების ცხრილი
რეიტინგი რამდენიმე კატეგორიისთვის ცალკვევილად ითვლება, რათა შედარება სამართლიანი იყოს:
- გლობალური — ყველა კლუბის მასშტაბით.
- კლუბი — მხოლოდ კლუბის ფარგლებში ჩატარებული თამაშები.
- შეხვედრა — მხოლოდ ერთი კონკრეტული შეხვედრის/ტურნირის პარტიები.
- სეზონი — მხოლოდ კლუბის სეზონის პერიოდში ჩატარებული თამაშები.
უმოქმედობა
ვინც დიდხანს არ თამაშობს, მისი შეფასება დროთა განმავლობაში უფრო გაურკვეველი ხდება. თავად რეიტინგი (სავარაუდო ძალა) უცვლელი რჩება — მხოლოდ სიზუსტე მცირდება, სანამ მოთამაშე კვლავ არ ითამაშებს.
ტექნიკური აღწერა (დეველოპერებისთვის)
მოდელი და საწყისი მნიშვნელობები
რეიტინგი ეფუძნება OpenSkill-ს (ბაიესის Weng-Lin-ის მეთოდი Plackett-Luce-ის მოდელით). რეფერენს-იმპლემენტაცია მუშაობს Java-ზე, ბიბლიოთეკის com.pocketcombats:openskill გამოყენებით; თავად მეთოდი ენისგან დამოუკიდებელია და სრულად აღწერილია ქვემოთ.
თითოეული რეიტინგი წარმოადგენს ნორმალურ განაწილებას საშუალო მნიშვნელობით μ (სავარაუდო ძალა) და სტანდარტული გადახრით σ (გაურკვევლობა). საწყისი მნიშვნელობები ახალი სუბიექტისთვის:
μ₀ = 25.0 σ₀ = 25 / 3 ≈ 8.3333
გამოჩენილი შედარებადი მნიშვნელობა არის კონსერვატიული ორდინალი — ძალა მინუს უსაფრთხოების კორექტირება გაურკვევლობისთვის:
ordinal = μ − Z · σ (Z = 3)
პარტიის პარამეტრებისთვის გამოიყენება ბიბლიოთეკის (Weng-Lin) სტანდარტული მნიშვნელობები, გადაწერის გარეშე: β = σ₀ / 2 ≈ 4.167 (სიძლიერისა და დღიური ფორმის დისპერსია) და τ = σ₀ / 100 ≈ 0.083 (ადიტიური დინამიკური ტერმინი, რომელიც ყოველი განახლების წინ ოდნავ ზრდის σ-ს, რათა რეიტინგი დინამიკური დარჩეს).
თამაშის შეფასება
თამაში შედგება ორი მხარისგან (გუნდი A და გუნდი B). თითოეული მხარის რეიტინგი გუნდის რეიტინგად აგრეგირდება მათი მოთამაშეების ინდივიდუალური რეიტინგების საფუძველზე (μ-ების ჯამი ან σ²-ების ჯამი, DefaultTeamRatingAggregator). შედეგზე დაყრდნობით განისაზღვრება რანგები:
- გამარჯვებულის მხარე: რანგი
1, წაგებულის მხარე: რანგი2. - ფრე: ორივე მხარეს რანგი
1.
ამ რანგების საფუძველზე, Plackett-Luce-ის მოდელი ანახლებს თითოეულ ჩართულ სუბიექტს: ძალა μ იცვლება რეალური შედეგის მიმართულებით, ხოლო გაურკვევლობა σ მცირდება ყოველი დამატებითი თამაშისას. კორექტირების სიდიდე დამოკიდებულია მოსალოდნელ და რეალურ შედეგებს შორის სხვაობასა და მიმდინარე გაურკვევლობაზე.
A მხარის გამარჯვების ალბათობა B მხარესთან მიმართებაში (პროგნოზირებისთვის/მეჩმაკინგისთვის) გამოითვლება გუნდების აგრეგირებული მნიშვნელობების საფუძველზე, ნორმალური განაწილების კუმულაციური ფუნქციის Φ მეშვეობით:
P(A > B) = Φ( (μ_A − μ_B) / √(σ_A² + σ_B² + β²) )
ორი პროექცია: ინდივიდუალური და წყვილი
ყოველი პარტია ორ დამოუკიდებელ პროექციაში შეფასდება:
- ინდივიდუალური — სუბიექტი არის წევრის ID. საჭიროებს სულ მცირე ერთ რეალურ წევრს ორივე მხარეს.
- წყვილი (გუნდი) — სუბიექტი არის წევრთა წყვილი. სრული მხარე (2 რეალური წევრი) ქმნის წყვილს; მხარე სტუმრით არ ქმნის წყვილს.
გუნდების განაწილება შეგროვებული მონაცემების საფუძველზე: result_player.team არის A ან B; გამარჯვებული მითითებულია result.winner_team-ში (თუ ეს ველი ცარიელია, თამაში ფრედ ითვლება). წევრის ID-ის არმქონე მოთამაშეები (სტუმრები) რეიტინგის დათვლისას ამოღებულები არიან. თუ მხარე მხოლოდ სტუმრებისგან შედგება, ის თავად არ შეფასდება, თუმცა გვევლინება როგორც სტანდარტული მეტოქე (სუბიექტი საწყისი მნიშვნელობებით), რათა მეორე მხარეს სრულად შეეძლოს რეიტინგის დათვლა. თამაშები, რომლებსაც გააჩნიათ exclude_from_rating, სრულად გამოტოვებულია.
პარტიციები და ქრონოლოგიური განმეორება
პარტიცია არის ტუპლე (scope, scopeRefId). არსებობს ოთხი სკოუპი: GLOBAL (მითითების გარეშე), CLUB (clubId), EVENT (eventId), SEASON (seasonId). თითოეული პარტიცია დამოუკიდებლად ითვლება — ერთი თამაში ერთდროულად რამდენიმე პარტიციაში აისახება.
რეიტინგები თანმიმდევრობაზე დამოკიდებული და გადაჯაჭვულია (თამაშის შედეგი დამოკიდებულია მანამდე არსებულ რეიტინგებზე). ამიტომ, ისინი არ ითვლება ინკრემენტულად, არამედ ყალიბდება თამაშების ქრონოლოგიური განმეორებით პრტიციის ფარგლებში. თითოეული თამაშის Snapshot-ისტორია (μ/σ თითოეული თამაშის წინ და შემდეგ) წარმოადგენს ჭეშმარიტების წყაროს; მატერიალიზებული ცხრილები member_rating / team_rating ინახავენ მხოლოდ მიმდინარე მდგომარეობას სწრაფი წვდომისთვის.
- სრული რეკონსტრუქცია: პარტიციის ყველა თამაში საწყისი მნიშვნელობებიდან ხელახლა გადაითვლება.
- ნაწილობრივი განმეორება გარკვეული დროიდან: მდგომარეობა ჩაიტვირთება ცვლილების მდემდე არსებული ბოლო სნეპშოტიდან (Seeding) და იქიდან ხელახლა განხორციელდება თამაში — ამ დროიდან არსებული სნეპშოტები წინასწარ იშლება.
მატერიალიზებული მნიშვნელობები სუბიექტზე
გამეორების შემდეგ, თითოეული სუბიექტისთვის მიმდინარე ჩანაწერი თავიდან ჩაიწერება:
| ველი | მნიშვნელობა |
|---|---|
| mu, sigma | მნიშვნელობები ბოლო პარტიის შემდეგ |
| ordinal | mu − 3 · sigma (კონსერვატორული) |
| ordinalPrevious | რანგი ბოლო თამაშის წინ (ტრენდის ისრისთვის) |
| peakOrdinal / peakAt | ყველა დროის საუკეთესო პოზიცია და დრო |
| gamesCount | პარტიციაში რეიტინგისთვის დათვლილი თამაშების რაოდენობა |
| provisional | მართალია, სანამ gamesCount < 10 |
| lastGameAt | ბოლო რეიტინგის თამაშის თარიღი |
რეიტინგის კლება უმოქმედობის გამო
ყოველდღიური პროცესი (სტანდარტულად: 04:00 საათი) ზრდის არააქტიური რეიტინგების გაურკვევლობას. ყველა იმ რეიტინგისთვის, რომლის ბოლო თამაში 30 დღეზე მეტი ხნის წინ იყო, მოქმედებს შემდეგი:
σ ← min(σ + 0.05, 8.3333) ordinal ← μ − 3 · σ
- თითოეული პარტიისას σ იზრდება
0.05-ით, მაქსიმალური ზღვარიაσ_max = 8.3333(= საწყისი მნიშვნელობა σ₀). - მხოლოდ ზედა ზღვარზე დაბალი რეიტინგები განახლდება (Batch-UPDATE ბრძანება).
- EVENT-ის მასშტაბი რეიტინგის კლებისგან გამონაკლისია (ტურნირი განსაზღვრულ პერიოდს წარმოადგენს).
დამუშავება (ასინქრონული, საბოლოო)
გამოთვლა არასოდეს სრულდება შედეგის შენახვასთან ერთად (inline), არამედ დაგვიანებით (eventual): შედეგის ცვლილება, కమిტის შემდეგ (AFTER_COMMIT), შესაბამის პარტიციებს ამნიშვნელებს როგორც „dirty“ (ამით ისინი ემატება გადათვლის რიგში). ერთი ვორკერი რიგს სერიულად ამუშავებს და თითოეულ შესაბამის პარტიციას ცვლილების მომენტიდან თავიდან გადის. ამგვარად, დაკავშირებული რეიტინგები რჩება კონსისტენტური შენახვის პროცესის დაბლოკვის გარეშე.
შედეგების ცვლილება ყოველთვის ეხება: გლობალურ რეიტინგს, თამაშის კლუბს, ღონისძიებას (ძველს და ახალს, თუ გადაიდო), ასევე ყველა სეზონს, რომლის პერიოდიც მოიცავს თამაშის დროს.