diff --git a/fowl/game/models.py b/fowl/game/models.py index 39086fa..a246605 100644 --- a/fowl/game/models.py +++ b/fowl/game/models.py @@ -60,12 +60,22 @@ admin.site.register(Event) WIN_TYPES = (('pin', 'pin'), ('DQ', 'DQ'), ('submission', 'submission')) +TITLES = (('wwe', 'WWE'), + ('heavyweight', 'Heavyweight'), + ('ic', 'Intercontinental'), + ('us', 'United States'), + ('tag', 'Tag Team'), + ('diva', 'Divas'), + ) class Match(models.Model): event = models.ForeignKey(Event, related_name='matches') + winner = models.ForeignKey(Star, null=True) win_type = models.CharField(max_length=10, choices=WIN_TYPES) + title_at_stake = models.BooleanField(default=False) - def add_team(self, *members): - mt = MatchTeam.objects.create(match=self) + def add_team(self, *members, **kwargs): + title = kwargs.get('title', None) + mt = MatchTeam.objects.create(match=self, title=title) for member in members: member = Star.objects.get(pk=member) mt.members.add(member) @@ -73,23 +83,77 @@ class Match(models.Model): def record_win(self, star, win_type): self.teams.filter(members__pk=star).update(victorious=True) self.win_type = win_type + self.winner__pk = star self.save() + def points(self): - winners = self.teams.filter(victorious=True) points = {} + winners = self.teams.filter(victorious=True) + if winners: winners = winners[0] - allies = winners.members.count() - 1 - opponents = self.teams.filter(victorious=False).aggregate( - opponents=models.Count('members'))['opponents'] + winner_count = winners.members.count() + losers = [x.mcount for x in self.teams.all().annotate(mcount=models.Count('members'))] + loser_count = sum(losers) + + # figure out base points for winning + # DQ wins are worth 1 point no matter what + if self.win_type == 'DQ': + base_points = 1 + allies = 0 # allies don't matter in a DQ + # rumble is worth participants/2 + elif self.teams.count() > 6: + base_points = self.teams.count() / 2 + allies = 0 # no allies in a rumble + else: + # normal wins are worth 2 + allies = winner_count - 1 + opponents = self.teams.filter(victorious=False).aggregate( + opponents=models.Count('members'))['opponents'] + base_points = max((opponents - allies) * 2, 1) + + # award points to winners for w in winners.members.all(): - points[w.id] = max((opponents - allies)*2, 1) + points[w.id] = base_points + + # if multiple people in this match and this person was credited + # w/ win, give them the bonus points + if allies and w.id == self.winner__pk: + points[w.id] += 1 + if w.id == self.winner__pk and self.win_type == 'submission': + points[w.id] += 1 + + # look over all titles in this match + for t in self.teams.values_list('title', flat=True): + # skip titles we hold or people without titles + if t is None: + continue + # title defense + elif winners.title == t and self.title_at_stake: + if t in ('heavyweight', 'wwe'): + points[w.id] += 5 + else: + points[w.id] += 3 + # beat someone w/ title + elif winners.title != t: + # title win + if self.title_at_stake and self.win_type != 'DQ': + if t in ('heavyweight', 'wwe'): + points[w.id] += 20 + else: + points[w.id] += 10 + elif self.title_at_stake and self.win_type != 'DQ': + for star in self.teams.get(title=t).members.all(): + points[star.id] += 1 + # beat tag champs in tag match w/o tag belt on line + elif t == 'tag' and all(c == 2 for c in losers): + points[w.id] += 2 + # beat champ in non-handicap match w/o belt on line + elif all(c == 1 for c in losers): + points[w.id] += 2 return points - - - def __unicode__(self): return ' vs. '.join(str(t) for t in self.teams.all()) @@ -99,9 +163,12 @@ class MatchTeam(models.Model): members = models.ManyToManyField(Star) match = models.ForeignKey(Match, related_name='teams') victorious = models.BooleanField(default=False) + title = models.CharField(max_length=50, choices=TITLES, null=True) def __unicode__(self): ret = ' & '.join([str(m) for m in self.members.all()]) + if self.title: + ret += ' (c)' if self.victorious: ret += ' (v)' return ret \ No newline at end of file diff --git a/fowl/game/tests.py b/fowl/game/tests.py index f50b91b..8ae1ea2 100644 --- a/fowl/game/tests.py +++ b/fowl/game/tests.py @@ -7,11 +7,165 @@ class MatchTest(TestCase): call_command('loadstars') self.wm29 = Event.objects.create(name='Wrestlemania 29', date='2012-04-01') - def test_basics(self): + def test_display(self): match = Match.objects.create(event=self.wm29) match.add_team('tripleh') match.add_team('undertaker') self.assertEqual(unicode(match), 'Triple H vs. Undertaker') match.record_win('undertaker', 'pin') self.assertEqual(unicode(match), 'Triple H vs. Undertaker (v)') - match.points() \ No newline at end of file + + match = Match.objects.create(event=self.wm29) + match.add_team('cmpunk', title='wwe') + match.add_team('reymysterio') + self.assertEqual(unicode(match), 'CM Punk (c) vs. Rey Mysterio') + match.record_win('cmpunk', 'pin') + self.assertEqual(unicode(match), 'CM Punk (c) (v) vs. Rey Mysterio') + + + def test_scoring(self): + # one on one : 2 points + match = Match.objects.create(event=self.wm29) + match.add_team('tripleh') + match.add_team('undertaker') + match.record_win('undertaker', 'pin') + self.assertEqual(match.points(), {'undertaker': 2}) + + # fatal 4 way: 6 points + match = Match.objects.create(event=self.wm29) + match.add_team('randyorton') + match.add_team('albertodelrio') + match.add_team('sheamus') + match.add_team('chrisjericho') + match.record_win('sheamus', 'pin') + self.assertEqual(match.points(), {'sheamus': 6}) + + # win stacked match: 1 point for team (bonuses can apply) + match = Match.objects.create(event=self.wm29) + match.add_team('santinomarella') + match.add_team('markhenry', 'kane') + match.record_win('markhenry', 'pin') + self.assertEqual(match.points(), {'markhenry': 2, 'kane': 1}) + + # DQ : 1 point + match = Match.objects.create(event=self.wm29) + match.add_team('kane') + match.add_team('undertaker') + match.record_win('undertaker', 'DQ') + self.assertEqual(match.points(), {'undertaker': 1}) + + # submission: +1 + match = Match.objects.create(event=self.wm29) + match.add_team('danielbryan') + match.add_team('cmpunk') + match.record_win('danielbryan', 'submission') + self.assertEqual(match.points(), {'danielbryan': 3}) + + # complicated one, outnumbered + submission + match = Match.objects.create(event=self.wm29) + match.add_team('danielbryan', 'chrisjericho') + match.add_team('cmpunk') + match.record_win('cmpunk', 'submission') + self.assertEqual(match.points(), {'cmpunk': 5}) + + # tag team: 2 points, +1 for the person who made pin + match = Match.objects.create(event=self.wm29) + match.add_team('kofikingston', 'rtruth') + match.add_team('jackswagger', 'dolphziggler') + match.record_win('dolphziggler', 'pin') + self.assertEqual(match.points(), {'jackswagger': 2, + 'dolphziggler': 3}) + # tag team submission: stacks on ziggler + match = Match.objects.create(event=self.wm29) + match.add_team('kofikingston', 'rtruth') + match.add_team('jackswagger', 'dolphziggler') + match.record_win('dolphziggler', 'submission') + self.assertEqual(match.points(), {'jackswagger': 2, + 'dolphziggler': 4}) + # tag team DQ: 1 point each member + match = Match.objects.create(event=self.wm29) + match.add_team('kofikingston', 'rtruth') + match.add_team('jackswagger', 'dolphziggler') + match.record_win('dolphziggler', 'DQ') + self.assertEqual(match.points(), {'jackswagger': 1, + 'dolphziggler': 1}) + + # rumble: participants / 2 + match = Match.objects.create(event=self.wm29) + match.add_team('kofikingston') + match.add_team('rtruth') + match.add_team('themiz') + match.add_team('dolphziggler') + match.add_team('johncena') + match.add_team('jackswagger') + match.add_team('kharma') + match.add_team('kane') + match.add_team('albertodelrio') + match.add_team('christian') + match.record_win('christian', 'pin') + self.assertEqual(match.points(), {'christian': 5}) + + def test_champ_scoring(self): + # champ doesn't get a bonus just for winning + match = Match.objects.create(event=self.wm29) + match.add_team('cmpunk', title='wwe') + match.add_team('reymysterio') + match.record_win('cmpunk', 'pin') + self.assertEqual(match.points(), {'cmpunk': 2}) + + # defending wwe belt is worth +5 + match = Match.objects.create(event=self.wm29, title_at_stake=True) + match.add_team('cmpunk', title='wwe') + match.add_team('reymysterio') + match.record_win('cmpunk', 'pin') + self.assertEqual(match.points(), {'cmpunk': 7}) + + # winning wwe belt + match = Match.objects.create(event=self.wm29, title_at_stake=True) + match.add_team('cmpunk', title='wwe') + match.add_team('reymysterio') + match.record_win('reymysterio', 'pin') + self.assertEqual(match.points(), {'reymysterio': 22}) + + # defending other belt is worth +3 + match = Match.objects.create(event=self.wm29, title_at_stake=True) + match.add_team('christian', title='ic') + match.add_team('codyrhodes') + match.record_win('christian', 'pin') + self.assertEqual(match.points(), {'christian': 5}) + + # winning other belt is worth +3 + match = Match.objects.create(event=self.wm29, title_at_stake=True) + match.add_team('christian', title='ic') + match.add_team('codyrhodes') + match.record_win('codyrhodes', 'pin') + self.assertEqual(match.points(), {'codyrhodes': 12}) + + # title non-defense (DQ/countout) + match = Match.objects.create(event=self.wm29, title_at_stake=True) + match.add_team('christian', title='ic') + match.add_team('codyrhodes') + match.record_win('codyrhodes', 'DQ') + self.assertEqual(match.points(), {'codyrhodes': 1, + 'christian': 1}) + + # +2 bonus for beating a champ in a non-title match + match = Match.objects.create(event=self.wm29) + match.add_team('cmpunk', title='wwe') + match.add_team('reymysterio') + match.record_win('reymysterio', 'pin') + self.assertEqual(match.points(), {'reymysterio': 4}) + + # no bonus in a tag match + match = Match.objects.create(event=self.wm29) + match.add_team('cmpunk', 'christian', title='wwe') + match.add_team('reymysterio', 'codyrhodes') + match.record_win('reymysterio', 'pin') + self.assertEqual(match.points(), {'codyrhodes': 2, 'reymysterio': 3}) + + # ...unless it is the tag title + match = Match.objects.create(event=self.wm29) + match.add_team('cmpunk', 'christian', title='tag') + match.add_team('reymysterio', 'codyrhodes') + match.record_win('reymysterio', 'pin') + self.assertEqual(match.points(), {'codyrhodes': 4, 'reymysterio': 5})