mirror of
https://github.com/yuukiwww/taiko-web.git
synced 2024-10-22 17:05:49 +02:00
Merge pull request #170 from purerosefallen/auto_score
Auto calculate SCOREINIT and SCOREDIFF when missing
This commit is contained in:
commit
6e86292a27
@ -24,6 +24,7 @@ var assets = {
|
|||||||
"canvastest.js",
|
"canvastest.js",
|
||||||
"canvascache.js",
|
"canvascache.js",
|
||||||
"parsetja.js",
|
"parsetja.js",
|
||||||
|
"autoscore.js",
|
||||||
"about.js",
|
"about.js",
|
||||||
"debug.js",
|
"debug.js",
|
||||||
"session.js",
|
"session.js",
|
||||||
|
210
public/src/js/autoscore.js
Normal file
210
public/src/js/autoscore.js
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
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,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if (this.GetMaxCombo() === 0) {
|
||||||
|
this.ScoreDiff = 100;
|
||||||
|
this.ScoreInit = 450;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const target = this.GetTargetScore(difficulty, level);
|
||||||
|
this.Score = 0;
|
||||||
|
this.ScoreDiff = 0;
|
||||||
|
this.ScoreInit = 0;
|
||||||
|
var max_init = this.GetMaxPossibleInit(target);
|
||||||
|
var min_init = 0;
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -12,9 +12,9 @@ class Controller{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(selectedSong.type === "tja"){
|
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{
|
}else{
|
||||||
this.parsedSongData = new ParseOsu(songData, selectedSong.offset)
|
this.parsedSongData = new ParseOsu(songData, selectedSong.difficulty, selectedSong.stars, selectedSong.offset)
|
||||||
}
|
}
|
||||||
this.offset = this.parsedSongData.soundOffset
|
this.offset = this.parsedSongData.soundOffset
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@
|
|||||||
var reader = new FileReader()
|
var reader = new FileReader()
|
||||||
var promise = pageEvents.load(reader).then(event => {
|
var promise = pageEvents.load(reader).then(event => {
|
||||||
var data = event.target.result.replace(/\0/g, "").split("\n")
|
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 = {
|
var songObj = {
|
||||||
id: index + 1,
|
id: index + 1,
|
||||||
type: "tja",
|
type: "tja",
|
||||||
@ -283,7 +283,7 @@
|
|||||||
var reader = new FileReader()
|
var reader = new FileReader()
|
||||||
var promise = pageEvents.load(reader).then(event => {
|
var promise = pageEvents.load(reader).then(event => {
|
||||||
var data = event.target.result.replace(/\0/g, "").split("\n")
|
var data = event.target.result.replace(/\0/g, "").split("\n")
|
||||||
var osu = new ParseOsu(data, 0, true)
|
var osu = new ParseOsu(data, "oni", 0, 0, true);
|
||||||
var dir = file.webkitRelativePath.toLowerCase()
|
var dir = file.webkitRelativePath.toLowerCase()
|
||||||
dir = dir.slice(0, dir.lastIndexOf("/") + 1)
|
dir = dir.slice(0, dir.lastIndexOf("/") + 1)
|
||||||
var songObj = {
|
var songObj = {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
class ParseOsu{
|
class ParseOsu{
|
||||||
constructor(fileContent, offset, metaOnly){
|
constructor(fileContent, difficulty, stars, offset, metaOnly){
|
||||||
this.osu = {
|
this.osu = {
|
||||||
OFFSET: 0,
|
OFFSET: 0,
|
||||||
MSPERBEAT: 1,
|
MSPERBEAT: 1,
|
||||||
@ -52,6 +52,8 @@ class ParseOsu{
|
|||||||
this.metadata = this.parseMetadata()
|
this.metadata = this.parseMetadata()
|
||||||
this.editor = this.parseEditor()
|
this.editor = this.parseEditor()
|
||||||
this.difficulty = this.parseDifficulty()
|
this.difficulty = this.parseDifficulty()
|
||||||
|
this._difficulty = difficulty;
|
||||||
|
this.stars = stars
|
||||||
if(!metaOnly){
|
if(!metaOnly){
|
||||||
this.timingPoints = this.parseTiming()
|
this.timingPoints = this.parseTiming()
|
||||||
this.circles = this.parseCircles()
|
this.circles = this.parseCircles()
|
||||||
@ -354,6 +356,10 @@ class ParseOsu{
|
|||||||
console.warn("Unknown note type found on line " + (i + 1) + ": " + this.data[i])
|
console.warn("Unknown note type found on line " + (i + 1) + ": " + this.data[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.scoremode = 2;
|
||||||
|
var autoscore = new AutoScore(this._difficulty, this.stars, 2, circles);
|
||||||
|
this.scoreinit = autoscore.ScoreInit;
|
||||||
|
this.scorediff = autoscore.ScoreDiff;
|
||||||
return circles
|
return circles
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
class ParseTja{
|
class ParseTja{
|
||||||
constructor(file, difficulty, offset, metaOnly){
|
constructor(file, difficulty, stars, offset, metaOnly){
|
||||||
this.data = []
|
this.data = []
|
||||||
for(let line of file){
|
for(let line of file){
|
||||||
line = line.replace(/\/\/.*/, "").trim()
|
line = line.replace(/\/\/.*/, "").trim()
|
||||||
@ -8,6 +8,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.difficulty = difficulty
|
this.difficulty = difficulty
|
||||||
|
this.stars = stars
|
||||||
this.offset = (offset || 0) * -1000
|
this.offset = (offset || 0) * -1000
|
||||||
this.soundOffset = 0
|
this.soundOffset = 0
|
||||||
this.noteTypes = {
|
this.noteTypes = {
|
||||||
@ -122,11 +123,6 @@
|
|||||||
}
|
}
|
||||||
parseCircles(){
|
parseCircles(){
|
||||||
var meta = this.metadata[this.difficulty]
|
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 ms = (meta.offset || 0) * -1000 + this.offset
|
||||||
var bpm = Math.abs(meta.bpm) || 120
|
var bpm = Math.abs(meta.bpm) || 120
|
||||||
var scroll = 1
|
var scroll = 1
|
||||||
@ -453,6 +449,16 @@
|
|||||||
this.measures.sort((a, b) => a.ms > b.ms ? 1 : -1)
|
this.measures.sort((a, b) => a.ms > b.ms ? 1 : -1)
|
||||||
circles.forEach((circle, i) => circle.id = i + 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, this.stars, this.scoremode, circles);
|
||||||
|
this.scoreinit = autoscore.ScoreInit;
|
||||||
|
this.scorediff = autoscore.ScoreDiff;
|
||||||
|
}
|
||||||
return circles
|
return circles
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -687,7 +687,8 @@ class SongSelect{
|
|||||||
"category": selectedSong.category,
|
"category": selectedSong.category,
|
||||||
"type": selectedSong.type,
|
"type": selectedSong.type,
|
||||||
"offset": selectedSong.offset,
|
"offset": selectedSong.offset,
|
||||||
"songSkin": selectedSong.songSkin
|
"songSkin": selectedSong.songSkin,
|
||||||
|
"stars": selectedSong.stars[difficulty]
|
||||||
}, autoplay, multiplayer, touch)
|
}, autoplay, multiplayer, touch)
|
||||||
}
|
}
|
||||||
toOptions(moveBy){
|
toOptions(moveBy){
|
||||||
|
Loading…
Reference in New Issue
Block a user