from listener import Listener # This will *probably* never have anything in it... class AbstractGrade(Listener): pass # DDR 6th-8th mix "dance points" grading. This is IMO one of the # fairest grading algorithms and definitely one of the most common. class DancePointsGrade(AbstractGrade): def grade_by_rank(cls, rank): if rank >= 1.00: return "AAA" elif rank >= 0.93: return "AA" elif rank >= 0.80: return "A" elif rank >= 0.65: return "B" elif rank >= 0.45: return "C" elif rank == -2: return "F" elif rank == -1: return "?" else: return "D" grade_by_rank = classmethod(grade_by_rank) def __init__(self): self.score = 0 self.arrow_count = 0 self.hold_count = 0 self.inc = { "V": 2, "P": 2, "G": 1, "B": -4, "M": -8 } def ok_hold(self, pid, curtime, dir, whichone): self.hold_count += 1 self.score += 6 def broke_hold(self, pid, curtime, dir, whichone): self.hold_count += 1 def stepped(self, pid, dir, cur_time, etime, rating, combo): self.arrow_count += 1 self.score += self.inc.get(rating, 0) def rank(self): max_score = float(2 * self.arrow_count + 6 * self.hold_count) if max_score == 0: return 0 else: return (self.score / max_score) def grade(self, failed): if failed == True: return "F" else: return DancePointsGrade.grade_by_rank(self.rank()) # Appropriate for endless mode, it doesn't return E on failure (since # endless mode always ends in a failure). class EndlessGrade(DancePointsGrade): def grade(self, failed): return DancePointsGrade.grade(self, False) grades = [DancePointsGrade, EndlessGrade] grade_opt = [ (0, "Dance Points", ""), (1, "Endless", "Like dance points, but failing doesn't result in an F."), ]