// Package getrank allows retrieval of the rank of a score on // an osu! beatmap (rank as in one of SSH, SS, SH, S, A, B, C, D) package getrank import ( "gopkg.in/thehowl/go-osuapi.v1" ) const silver = osuapi.ModFlashlight | osuapi.ModHidden // GetRank retrieves a rank of a score with the passed arguments. func GetRank(gameMode osuapi.Mode, mods osuapi.Mods, acc float64, c300, c100, c50, cmiss int) string { total := c300 + c100 + c50 + cmiss switch gameMode { case osuapi.ModeOsu: var ( c300f = float64(c300) totalf = float64(total) perc300 = c300f / totalf ) switch { case acc == 100: return s(true, mods) case perc300 > 0.90 && float64(c50)/totalf < 0.1 && cmiss == 0: return s(false, mods) case (perc300 > 0.80 && cmiss == 0) || (perc300 > 0.90): return "a" case (perc300 > 0.70 && cmiss == 0) || (perc300 > 0.80): return "b" case perc300 > 0.60: return "c" } return "d" case osuapi.ModeTaiko: switch { case acc == 100: return s(true, mods) case acc >= 95: return s(false, mods) case acc >= 90: return "a" case acc >= 80: return "b" // untested case acc >= 70: return "c" } return "d" case osuapi.ModeCatchTheBeat: if acc == 100 { if mods&silver > 0 { return "sshd" } return "ss" } if acc >= 98.01 && acc <= 99.99 { if mods&silver > 0 { return "shd" } return "s" } if acc >= 94.01 && acc <= 98.00 { return "a" } if acc >= 90.01 && acc <= 94.00 { return "b" } if acc >= 85.01 && acc <= 90.00 { return "c" } return "d" case osuapi.ModeOsuMania: switch { case acc == 100: if mods&silver > 0 { return "sshd" } return "ss" case acc > 95: if mods&silver > 0 { return "shd" } return "s" case acc > 90: return "a" case acc > 80: return "b" case acc > 70: return "c" } return "d" } return "a" } func s(s2 bool, h osuapi.Mods) string { a := "s" if s2 { a += "s" } if h&silver > 0 { a += "h" } return a }