-
Notifications
You must be signed in to change notification settings - Fork 0
/
score_analyzer.py
147 lines (134 loc) · 5.9 KB
/
score_analyzer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import sqlite3
import csv
from io import StringIO
import pandas
import datetime
def combo_multiplier(note, total):
if note >= total * 9 // 10:
return 2
elif note >= total * 8 // 10:
return 1.7
elif note >= total * 7 // 10:
return 1.5
elif note >= total // 2:
return 1.4
elif note >= total // 4:
return 1.3
elif note >= total // 10:
return 1.2
elif note >= total // 20:
return 1.1
else:
return 1
def active(time, period, uptime, last_note):
return time >= period and time % period < uptime and time // period * period <= last_note - 3
def is_flick(note):
return note.status == 1 or note.status == 2
def is_slide(note):
return note.type == 3
long_end = [False] * 5
def is_long(note):
pos = int(note.finishPos) - 1
if note.type == 2:
long_end[pos] = not long_end[pos]
return True
elif is_flick(note) and long_end[pos]:
long_end[pos] = False
return True
else:
return False
master_con = sqlite3.connect('chihiro/data/db/master.db')
cur = master_con.cursor()
diff_id = [4, 5, 101]
diff_names = {4: "MASTER", 5: "MASTER+", 101: "LEGACY"}
types = {1: "Cu", 2: "Co", 3: "Pa", 4: "All"}
req = cur.execute( 'SELECT ld.id, music_data.name, live_detail.difficulty_type, live_detail.level_vocal, ld.type '
'FROM music_data '
'INNER JOIN live_data AS ld '
'ON ld.music_data_id = music_data.id '
'INNER JOIN live_detail '
'ON ld.id = live_detail.live_data_id '
'AND live_detail.difficulty_type IN (' + ', '.join(map(str,diff_id)) + ') '
'WHERE ( NOT EXISTS ('
'SELECT other.id '
'FROM live_data AS other, music_data md1, music_data md2 '
'WHERE other.id < ld.id '
'AND other.difficulty_5 <> 0 '
'AND other.music_data_id = md1.id '
'AND ld.music_data_id = md2.id '
'AND md1.name = md2.name))')
now = datetime.datetime.now()
print(now.strftime('%Y%m%d-%H%M%S'))
#data = pandas.DataFrame(index = ['Song Name', 'Notes'])
data = []
timers = [[3, 4], [4.5, 7], [6, 9], [7.5, 11], [9, 13], [4.5, 6], [6, 7], [7.5, 9], [9, 11], [7.5, 12]]
act_timers = [[6, 7], [7.5, 9], [9, 11]]
note_types = ['long', 'flick', 'slide']
verifier = {'long': is_long, 'flick': is_flick, 'slide': is_slide}
with open('level_data.csv', 'w', encoding = 'utf-8') as fp:
myfile = csv.writer(fp)
for level_data in req:
song_id = level_data[0]
song_name = level_data[1]
diff_type = level_data[2]
diff = level_data[3]
song_type = level_data[4]
if song_id >= 1000:
continue
score_db = 'chihiro/data/musicscores/musicscores_m{:03d}.db'.format(song_id)
score_con = sqlite3.connect(score_db)
score_cur = score_con.cursor()
print(song_id, diff_type)
score_name = 'musicscores/m{:03d}/{}_{}.csv'.format(song_id, song_id, diff_type)
try:
score_req = score_cur.execute("SELECT data FROM blobs WHERE name = ?", (score_name,))
score = None
for s in score_req:
enc_score = s[0]
score = enc_score.decode('utf-8')
score_ifile = StringIO(score)
score_data = pandas.read_csv(score_ifile)
if song_id == 1:
print(score_data)
note_count = score_data.shape[0] - 3
song_data = {'Song Name': song_name, 'Song id': song_id, 'Notes': note_count, 'Difficulty': diff_names[diff_type], 'Type': types[song_type], 'Level': diff}
skill_uptime = [0] * len(timers)
act_skill_uptime = {}
for type in note_types:
act_skill_uptime[type] = [0] * len(act_timers)
# Problematic loop?
skip_notes = 0
last_note = 0
for i in range(score_data.shape[0]):
note = score_data.iloc[score_data.shape[0]-1-i]
#print('Note:', note)
if note['type'] <= 3:
last_note = note['sec']
break
for note in score_data.itertuples():
if note.type <= 3:
for idx, timer in enumerate(timers):
if active(note.sec, timer[1], timer[0], last_note):
skill_uptime[idx] += combo_multiplier(note.id - skip_notes, note_count)
for type in note_types:
if verifier[type](note):
for idx, timer in enumerate(act_timers):
if active(note.sec, timer[1], timer[0], last_note):
act_skill_uptime[type][idx] += combo_multiplier(note.id - skip_notes, note_count)
else:
skip_notes += 1
if note.type == 100:
note_count = int(note.status)
song_data['Notes'] = note_count
for index, timer in enumerate(timers):
song_data['{}/{}s'.format(timer[0], timer[1])] = skill_uptime[index] / note_count / 1.41
for type in note_types:
for index, timer in enumerate(act_timers):
song_data['{}/{}s {}'.format(timer[0], timer[1], type)] = act_skill_uptime[type][index] / note_count / 1.41
data.append(song_data)
except sqlite3.OperationalError:
print('File ' + str(song_id) + ' not found')
processed_data = pandas.DataFrame(data)
now = datetime.datetime.now()
print(now.strftime('%Y%m%d-%H%M%S'))
processed_data.to_excel('output/level_data' + now.strftime('%Y%m%d-%H%M%S') + '.xlsx')