From 8574ad25800c01a940cda1e1eb579c4a96c643e8 Mon Sep 17 00:00:00 2001 From: purerosefallen <78877@qq.com> Date: Fri, 1 Nov 2019 00:10:53 +0800 Subject: [PATCH 1/6] add auto score --- public/src/js/assets.js | 1 + public/src/js/autoscore.js | 155 +++++++++++++++++++++++++++++++++++ public/src/js/controller.js | 2 +- public/src/js/importsongs.js | 2 +- public/src/js/parseosu.js | 7 +- public/src/js/parsetja.js | 15 ++-- 6 files changed, 174 insertions(+), 8 deletions(-) create mode 100644 public/src/js/autoscore.js 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 } } From f3f57ea1a54cb1d869881c1bf0059d20ac2c49e0 Mon Sep 17 00:00:00 2001 From: purerosefallen <78877@qq.com> Date: Fri, 1 Nov 2019 00:46:54 +0800 Subject: [PATCH 2/6] fix --- public/src/js/parseosu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/src/js/parseosu.js b/public/src/js/parseosu.js index bf5a4a4..2741772 100644 --- a/public/src/js/parseosu.js +++ b/public/src/js/parseosu.js @@ -356,7 +356,7 @@ class ParseOsu{ } } this.scoremode = 2; - var autoscore = new AutoScore(this._difficulty, this.difficulty.overallDifficulty, 2, circles); + var autoscore = new AutoScore(this._difficulty, 0, 2, circles); this.scoreinit = autoscore.ScoreInit; this.scorediff = autoscore.ScoreDiff; return circles From 88fc5dbbb69f2c1cd835b660f339219ebf851616 Mon Sep 17 00:00:00 2001 From: purerosefallen <78877@qq.com> Date: Sat, 2 Nov 2019 00:45:37 +0800 Subject: [PATCH 3/6] improve --- public/src/js/autoscore.js | 78 +++++++++++++++++++++++++++++++------- public/src/js/parseosu.js | 2 +- 2 files changed, 65 insertions(+), 15 deletions(-) diff --git a/public/src/js/autoscore.js b/public/src/js/autoscore.js index 6837651..fc0276d 100644 --- a/public/src/js/autoscore.js +++ b/public/src/js/autoscore.js @@ -63,22 +63,37 @@ class AutoScore { 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; - } + var max_init = this.GetMaxPossibleInit(target); + var min_init = 100; + while (true) { + this.ScoreInit = (max_init + min_init) / 2; + this.ScoreDiff = Math.round(this.ScoreInit / 4); + this.Score = this.TryScore(this.ScoreInit, this.ScoreDiff); + //console.log(min_init, max_init, this.ScoreInit, this.ScoreDiff, this.Score); + if (this.ScoreInit === target) { + this.ScoreInit = Math.floor(this.ScoreInit / 10) * 10; + this.ScoreDiff = Math.round(this.ScoreInit / 4); + this.Score = this.TryScore(this.ScoreInit, this.ScoreDiff); + break; + } else if (this.Score >= target) { + max_init = this.ScoreInit; + } else { + min_init = this.ScoreInit; + } + if (max_init - min_init <= 10) { + this.ScoreInit = Math.floor(this.ScoreInit / 10) * 10; + this.ScoreDiff = Math.round(this.ScoreInit / 4); + this.Score = this.TryScore(this.ScoreInit, this.ScoreDiff); + break; } } + while (this.Score < target) { + this.ScoreInit += 10; + this.ScoreDiff = Math.round(this.ScoreInit / 4); + this.Score = this.TryScore(this.ScoreInit, this.ScoreDiff); + //console.log(this.ScoreInit, this.ScoreDiff, this.Score); + } + //console.log(this.ScoreInit, this.ScoreDiff, this.Score); } IsCommonCircle(circle) { const ty = circle.type; @@ -152,4 +167,39 @@ class AutoScore { } return combo; } + GetMaxPossibleInit(target) { + var basic_score = 0; + if (this.scoremode !== 1) { + const max_combo = this.GetMaxCombo(); + basic_score += Math.floor(max_combo / 100); + } + var combo = 0; + for (var circle of this.circles) { + if (circle.branch && circle.branch.name !== "master") { + continue; + } + var multiplier = circle.gogoTime ? 1.2 : 1; + switch (circle.type) { + case "don": + case "ka": { + combo += (1 * multiplier); + break; + } + case "daiDon": + case "daiKa": { + combo += (2 * multiplier); + break; + } + case "balloon": { + basic_score += (5000 + 300 * circle.requiredHits) * multiplier; + break; + } + default: { + break; + } + } + } + combo = Math.floor(combo); + return Math.ceil((target - basic_score) / combo / 10) * 10; + } } diff --git a/public/src/js/parseosu.js b/public/src/js/parseosu.js index 2741772..b4447b2 100644 --- a/public/src/js/parseosu.js +++ b/public/src/js/parseosu.js @@ -356,7 +356,7 @@ class ParseOsu{ } } this.scoremode = 2; - var autoscore = new AutoScore(this._difficulty, 0, 2, circles); + var autoscore = new AutoScore(this._difficulty, parseInt(this.difficulty.overallDifficulty) * 2, 2, circles); this.scoreinit = autoscore.ScoreInit; this.scorediff = autoscore.ScoreDiff; return circles From cd7015f582144c5c2341501adae8f86485737147 Mon Sep 17 00:00:00 2001 From: purerosefallen <78877@qq.com> Date: Sat, 2 Nov 2019 09:53:05 +0800 Subject: [PATCH 4/6] fix --- public/src/js/autoscore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/src/js/autoscore.js b/public/src/js/autoscore.js index fc0276d..84115cc 100644 --- a/public/src/js/autoscore.js +++ b/public/src/js/autoscore.js @@ -64,7 +64,7 @@ class AutoScore { this.ScoreDiff = 0; this.ScoreInit = 0; var max_init = this.GetMaxPossibleInit(target); - var min_init = 100; + var min_init = 0; while (true) { this.ScoreInit = (max_init + min_init) / 2; this.ScoreDiff = Math.round(this.ScoreInit / 4); From 84377f62b03fc2691c17b940b0a125e0f6628301 Mon Sep 17 00:00:00 2001 From: purerosefallen <78877@qq.com> Date: Sun, 3 Nov 2019 10:40:24 +0800 Subject: [PATCH 5/6] only for safety --- public/src/js/autoscore.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/public/src/js/autoscore.js b/public/src/js/autoscore.js index 84115cc..7345c20 100644 --- a/public/src/js/autoscore.js +++ b/public/src/js/autoscore.js @@ -59,6 +59,11 @@ class AutoScore { 380000, ] } + if (this.GetMaxCombo() === 0) { + this.ScoreDiff = 100; + this.ScoreInit = 450; + return; + } const target = this.GetTargetScore(difficulty, level); this.Score = 0; this.ScoreDiff = 0; From 1bb33597841f6c4548811fa50d3e0e1bc1472b18 Mon Sep 17 00:00:00 2001 From: LoveEevee Date: Mon, 4 Nov 2019 17:20:44 +0300 Subject: [PATCH 6/6] Use stars on song select for score level --- public/src/js/controller.js | 4 ++-- public/src/js/importsongs.js | 4 ++-- public/src/js/parseosu.js | 5 +++-- public/src/js/parsetja.js | 5 +++-- public/src/js/songselect.js | 3 ++- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/public/src/js/controller.js b/public/src/js/controller.js index 3b0852e..6020d2a 100644 --- a/public/src/js/controller.js +++ b/public/src/js/controller.js @@ -12,9 +12,9 @@ class Controller{ } if(selectedSong.type === "tja"){ - this.parsedSongData = new ParseTja(songData, selectedSong.difficulty, selectedSong.offset) + this.parsedSongData = new ParseTja(songData, selectedSong.difficulty, selectedSong.stars, selectedSong.offset) }else{ - this.parsedSongData = new ParseOsu(songData, selectedSong.difficulty, selectedSong.offset) + this.parsedSongData = new ParseOsu(songData, selectedSong.difficulty, selectedSong.stars, selectedSong.offset) } this.offset = this.parsedSongData.soundOffset diff --git a/public/src/js/importsongs.js b/public/src/js/importsongs.js index 288cece..a0b059c 100644 --- a/public/src/js/importsongs.js +++ b/public/src/js/importsongs.js @@ -199,7 +199,7 @@ var reader = new FileReader() var promise = pageEvents.load(reader).then(event => { var data = event.target.result.replace(/\0/g, "").split("\n") - var tja = new ParseTja(data, "oni", 0, true) + var tja = new ParseTja(data, "oni", 0, 0, true) var songObj = { id: index + 1, type: "tja", @@ -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, "oni", 0, true); + var osu = new ParseOsu(data, "oni", 0, 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 b4447b2..0ef70eb 100644 --- a/public/src/js/parseosu.js +++ b/public/src/js/parseosu.js @@ -1,5 +1,5 @@ class ParseOsu{ - constructor(fileContent, difficulty, offset, metaOnly){ + constructor(fileContent, difficulty, stars, offset, metaOnly){ this.osu = { OFFSET: 0, MSPERBEAT: 1, @@ -53,6 +53,7 @@ class ParseOsu{ this.editor = this.parseEditor() this.difficulty = this.parseDifficulty() this._difficulty = difficulty; + this.stars = stars if(!metaOnly){ this.timingPoints = this.parseTiming() this.circles = this.parseCircles() @@ -356,7 +357,7 @@ class ParseOsu{ } } this.scoremode = 2; - var autoscore = new AutoScore(this._difficulty, parseInt(this.difficulty.overallDifficulty) * 2, 2, circles); + var autoscore = new AutoScore(this._difficulty, this.stars, 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 9071ad9..6979c81 100644 --- a/public/src/js/parsetja.js +++ b/public/src/js/parsetja.js @@ -1,5 +1,5 @@ class ParseTja{ - constructor(file, difficulty, offset, metaOnly){ + constructor(file, difficulty, stars, offset, metaOnly){ this.data = [] for(let line of file){ line = line.replace(/\/\/.*/, "").trim() @@ -8,6 +8,7 @@ } } this.difficulty = difficulty + this.stars = stars this.offset = (offset || 0) * -1000 this.soundOffset = 0 this.noteTypes = { @@ -454,7 +455,7 @@ this.scoremode = meta.scoremode || 1; } else { this.scoremode = meta.scoremode || 2; - var autoscore = new AutoScore(this.difficulty, meta.level, this.scoremode, circles); + var autoscore = new AutoScore(this.difficulty, this.stars, this.scoremode, circles); this.scoreinit = autoscore.ScoreInit; this.scorediff = autoscore.ScoreDiff; } diff --git a/public/src/js/songselect.js b/public/src/js/songselect.js index f50dbc1..d02c07f 100644 --- a/public/src/js/songselect.js +++ b/public/src/js/songselect.js @@ -687,7 +687,8 @@ class SongSelect{ "category": selectedSong.category, "type": selectedSong.type, "offset": selectedSong.offset, - "songSkin": selectedSong.songSkin + "songSkin": selectedSong.songSkin, + "stars": selectedSong.stars[difficulty] }, autoplay, multiplayer, touch) } toOptions(moveBy){