feat(db): recommend charts based on score

This commit is contained in:
283375 2023-09-18 20:41:57 +08:00
parent bed9e14368
commit ec9926993c
Signed by: 283375
SSH Key Fingerprint: SHA256:UcX0qg6ZOSDOeieKPGokA5h7soykG61nz2uxuQgVLSk
2 changed files with 52 additions and 1 deletions

View File

@ -1,2 +1,13 @@
from .b30 import calculate_b30, get_b30_calculated_list from .b30 import calculate_b30, get_b30_calculated_list
from .score import calculate_play_rating, calculate_score_range, calculate_shiny_pure from .score import (
calculate_constants_from_play_rating,
calculate_play_rating,
calculate_score_modifier,
calculate_score_range,
calculate_shiny_pure,
)
from .world_step import (
calculate_play_rating_from_step,
calculate_step,
calculate_step_original,
)

View File

@ -1,9 +1,11 @@
import logging import logging
import math
from typing import Iterable, List, Optional, Type, Union from typing import Iterable, List, Optional, Type, Union
from sqlalchemy import Engine, func, inspect, select from sqlalchemy import Engine, func, inspect, select
from sqlalchemy.orm import DeclarativeBase, InstrumentedAttribute, sessionmaker from sqlalchemy.orm import DeclarativeBase, InstrumentedAttribute, sessionmaker
from .calculate import calculate_score_modifier
from .external.arcsong.arcsong_json import ArcSongJsonBuilder from .external.arcsong.arcsong_json import ArcSongJsonBuilder
from .external.exports import ScoreExport, exporters from .external.exports import ScoreExport, exporters
from .models.config import * from .models.config import *
@ -227,6 +229,12 @@ class Database(metaclass=Singleton):
results = list(session.scalars(stmt)) results = list(session.scalars(stmt))
return results return results
def get_charts_by_constant(self, constant: int):
stmt = select(Chart).where(Chart.constant == constant)
with self.sessionmaker() as session:
results = list(session.scalars(stmt))
return results
def get_chart(self, song_id: str, rating_class: int): def get_chart(self, song_id: str, rating_class: int):
stmt = select(Chart).where( stmt = select(Chart).where(
(Chart.song_id == song_id) & (Chart.rating_class == rating_class) (Chart.song_id == song_id) & (Chart.rating_class == rating_class)
@ -275,6 +283,38 @@ class Database(metaclass=Singleton):
session.delete(score) session.delete(score)
session.commit() session.commit()
def recommend_charts(self, play_result: float):
base_constant = math.ceil(play_result * 10)
results = []
results_id = []
with self.sessionmaker() as session:
for constant in range(base_constant - 20, base_constant + 1):
# from Pure Memory(EX+) to AA
score_modifier = (play_result * 10 - constant) / 10
if score_modifier >= 2.0:
min_score = 10000000
elif score_modifier >= 1.0:
min_score = 200000 * (score_modifier - 1) + 9800000
else:
min_score = 300000 * score_modifier + 9500000
min_score = int(min_score)
charts = self.get_charts_by_constant(constant)
for chart in charts:
score_best_stmt = select(ScoreBest).where(
(ScoreBest.song_id == chart.song_id)
& (ScoreBest.rating_class == chart.rating_class)
& (ScoreBest.score >= min_score)
)
if session.scalar(score_best_stmt):
chart_id = f"{chart.song_id},{chart.rating_class}"
if chart_id not in results_id:
results.append(chart)
results_id.append(chart_id)
return results
# endregion # endregion
def get_b30(self): def get_b30(self):