diff --git a/public/src/js/assets.js b/public/src/js/assets.js index e363842..6245548 100644 --- a/public/src/js/assets.js +++ b/public/src/js/assets.js @@ -24,6 +24,7 @@ var assets = { "canvastest.js", "canvascache.js", "parsetja.js", + "autoscore.js", "about.js", "debug.js", "session.js", diff --git a/public/src/js/autoscore.js b/public/src/js/autoscore.js new file mode 100644 index 0000000..6837651 --- /dev/null +++ b/public/src/js/autoscore.js @@ -0,0 +1,155 @@ +class AutoScore { + constructor(difficulty, level, scoremode, circles) { + this.scoremode = scoremode; + this.circles = circles; + this.basic_max_score_list = { + oni: [ + 1200000, + 700000, + 750000, + 800000, + 850000, + 900000, + 950000, + 1000000, + 1050000, + 1100000, + 1200000 + ], + ura: [ + 1200000, + 700000, + 750000, + 800000, + 850000, + 900000, + 950000, + 1000000, + 1050000, + 1100000, + 1200000 + ], + hard: [ + 900000, + 550000, + 600000, + 650000, + 700000, + 750000, + 800000, + 850000, + 900000, + ], + normal: [ + 700000, + 400000, + 450000, + 500000, + 550000, + 600000, + 650000, + 700000, + ], + easy: [ + 380000, + 300000, + 320000, + 340000, + 360000, + 380000, + ] + } + const target = this.GetTargetScore(difficulty, level); + this.Score = 0; + this.ScoreDiff = 0; + this.ScoreInit = 0; + const max_possible_init = Math.ceil(target / this.GetMaxCombo() / 10) * 10; + //console.log(target); + for (var init = 100; init <= max_possible_init; init += 10) { + for (var diff = 10; diff < init; diff++) { + const score = this.TryScore(init, diff); + if (score > target && Math.abs(score - target) < Math.abs(this.Score - target)) { + this.Score = score; + this.ScoreInit = init; + this.ScoreDiff = diff; + //console.log(init, diff, score); + } + if (score > target) { + break; + } + } + } + } + IsCommonCircle(circle) { + const ty = circle.type; + return ty === "don" || ty === "ka" || ty === "daiDon" || ty === "daiKa"; + } + TryScore(init, diff) { + var score = 0; + var combo = 0; + for (var circle of this.circles) { + if (circle.branch && circle.branch.name !== "master") { + continue; + } + if (this.IsCommonCircle(circle)) { + combo++; + if (combo % 100 === 0 && this.scoremode !== 1) { + score += 10000; + } + } + var diff_mul = 0; + var multiplier = circle.gogoTime ? 1.2 : 1; + if (this.scoremode === 1) { + diff_mul = Math.max(0, Math.floor((Math.min(combo, 100) - 1) / 10)); + } else { + if (combo >= 100) { + diff_mul = 8; + } else if (combo >= 50) { + diff_mul = 4; + } else if (combo >= 30) { + diff_mul = 2; + } else if (combo >= 10) { + diff_mul = 1; + } + } + switch (circle.type) { + case "don": + case "ka": { + score += Math.floor((init + diff * diff_mul) * multiplier / 10) * 10; + break; + } + case "daiDon": + case "daiKa": { + score += Math.floor((init + diff * diff_mul) * multiplier / 5) * 10; + break; + } + case "balloon": { + score += (5000 + 300 * circle.requiredHits) * multiplier; + break; + } + default: { + break; + } + } + } + return score; + } + GetTargetScore(difficulty, level) { + //console.log(difficulty, level) + var ret = this.basic_max_score_list[difficulty][level]; + if (!ret) { + ret = this.basic_max_score_list[difficulty][0]; + } + return ret; + } + GetMaxCombo() { + var combo = 0; + for (var circle of this.circles) { + //alert(this.IsCommonCircle(circle)); + if (this.IsCommonCircle(circle) && (!circle.branch || circle.branch.name === "master")) { + combo++; + } + } + return combo; + } +} diff --git a/public/src/js/controller.js b/public/src/js/controller.js index cf253b4..3b0852e 100644 --- a/public/src/js/controller.js +++ b/public/src/js/controller.js @@ -14,7 +14,7 @@ class Controller{ if(selectedSong.type === "tja"){ this.parsedSongData = new ParseTja(songData, selectedSong.difficulty, selectedSong.offset) }else{ - this.parsedSongData = new ParseOsu(songData, selectedSong.offset) + this.parsedSongData = new ParseOsu(songData, selectedSong.difficulty, selectedSong.offset) } this.offset = this.parsedSongData.soundOffset diff --git a/public/src/js/importsongs.js b/public/src/js/importsongs.js index 112b675..288cece 100644 --- a/public/src/js/importsongs.js +++ b/public/src/js/importsongs.js @@ -283,7 +283,7 @@ var reader = new FileReader() var promise = pageEvents.load(reader).then(event => { var data = event.target.result.replace(/\0/g, "").split("\n") - var osu = new ParseOsu(data, 0, true) + var osu = new ParseOsu(data, "oni", 0, true); var dir = file.webkitRelativePath.toLowerCase() dir = dir.slice(0, dir.lastIndexOf("/") + 1) var songObj = { diff --git a/public/src/js/parseosu.js b/public/src/js/parseosu.js index b8d94e2..bf5a4a4 100644 --- a/public/src/js/parseosu.js +++ b/public/src/js/parseosu.js @@ -1,5 +1,5 @@ class ParseOsu{ - constructor(fileContent, offset, metaOnly){ + constructor(fileContent, difficulty, offset, metaOnly){ this.osu = { OFFSET: 0, MSPERBEAT: 1, @@ -52,6 +52,7 @@ class ParseOsu{ this.metadata = this.parseMetadata() this.editor = this.parseEditor() this.difficulty = this.parseDifficulty() + this._difficulty = difficulty; if(!metaOnly){ this.timingPoints = this.parseTiming() this.circles = this.parseCircles() @@ -354,6 +355,10 @@ class ParseOsu{ console.warn("Unknown note type found on line " + (i + 1) + ": " + this.data[i]) } } + this.scoremode = 2; + var autoscore = new AutoScore(this._difficulty, this.difficulty.overallDifficulty, 2, circles); + this.scoreinit = autoscore.ScoreInit; + this.scorediff = autoscore.ScoreDiff; return circles } } diff --git a/public/src/js/parsetja.js b/public/src/js/parsetja.js index 31bc67e..9071ad9 100644 --- a/public/src/js/parsetja.js +++ b/public/src/js/parsetja.js @@ -122,11 +122,6 @@ } parseCircles(){ var meta = this.metadata[this.difficulty] - this.scoreinit = meta.scoreinit; - this.scorediff = meta.scorediff; - if (this.scoreinit && this.scorediff) { - this.scoremode = meta.scoremode || 1; - } var ms = (meta.offset || 0) * -1000 + this.offset var bpm = Math.abs(meta.bpm) || 120 var scroll = 1 @@ -453,6 +448,16 @@ this.measures.sort((a, b) => a.ms > b.ms ? 1 : -1) circles.forEach((circle, i) => circle.id = i + 1) } + this.scoreinit = meta.scoreinit; + this.scorediff = meta.scorediff; + if (this.scoreinit && this.scorediff) { + this.scoremode = meta.scoremode || 1; + } else { + this.scoremode = meta.scoremode || 2; + var autoscore = new AutoScore(this.difficulty, meta.level, this.scoremode, circles); + this.scoreinit = autoscore.ScoreInit; + this.scorediff = autoscore.ScoreDiff; + } return circles } }