Spaces:
Runtime error
Runtime error
Upload 5 files
Browse files- DMSans-Regular.ttf +0 -0
- app.py +93 -0
- requirements.txt +6 -0
- template.png +0 -0
- utils.py +212 -0
DMSans-Regular.ttf
ADDED
Binary file (72 kB). View file
|
|
app.py
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from utils import *
|
3 |
+
|
4 |
+
duration = 35
|
5 |
+
start_patch = datetime.date(2023, 10, 11) # year, month, days
|
6 |
+
end_patch = start_patch + datetime.timedelta(days = duration)
|
7 |
+
print('patch 1.3: {0} - {1}'.format(start_patch, end_patch))
|
8 |
+
|
9 |
+
#depand on patch
|
10 |
+
data_patch = {'n_character_banner':3, 'n_character_quest':{'first_half':1,
|
11 |
+
'second_half':0}}
|
12 |
+
|
13 |
+
limited_event = {'gift_odyssey':{'reward':10, 'date':(start_patch, end_patch)}, #end date is completed event
|
14 |
+
#'gift_patrol':{'reward':800, 'date':(start_patch + datetime.timedelta(days = duration // 2), end_patch)},
|
15 |
+
'aetherium':{'reward':1200, 'date':(start_patch + datetime.timedelta(days = 2), start_patch + datetime.timedelta(days = 23))},
|
16 |
+
'SU_event':{'reward':500, 'date':(start_patch + datetime.timedelta(days = 24), start_patch + datetime.timedelta(days = 36))},
|
17 |
+
}
|
18 |
+
|
19 |
+
permanent_event = {'aetherium':{'reward':1040},
|
20 |
+
'S_training':{'reward':330},
|
21 |
+
'exploration':{'reward':300},
|
22 |
+
}
|
23 |
+
|
24 |
+
#user input
|
25 |
+
mode = 0
|
26 |
+
equilibrium = 0
|
27 |
+
MoC = False
|
28 |
+
ES = False
|
29 |
+
BP = False
|
30 |
+
|
31 |
+
def inference(mode_dropdown, equilibrium_dropdown, condition_checkbox):
|
32 |
+
global start_patch, end_patch, mode, equilibrium, MoC, ES, BP
|
33 |
+
|
34 |
+
mode = ["ทั้งหมด", "ครึ่งแรก", "ครึ่งหลัง"].index(mode_dropdown)
|
35 |
+
equilibrium = int(equilibrium_dropdown)
|
36 |
+
|
37 |
+
if "Memory of Chaos" in condition_checkbox:
|
38 |
+
MoC = True
|
39 |
+
else: MoC = False
|
40 |
+
|
41 |
+
if "บัตรเสบียงรถไฟ" in condition_checkbox:
|
42 |
+
ES = True
|
43 |
+
else: ES = False
|
44 |
+
|
45 |
+
if "Battle Pass" in condition_checkbox:
|
46 |
+
BP = True
|
47 |
+
else: BP = False
|
48 |
+
|
49 |
+
|
50 |
+
reward = estimator(start_patch, end_patch, mode, equilibrium, data_patch, limited_event, permanent_event, MoC, ES, BP)
|
51 |
+
|
52 |
+
reward_img = export_to_image(reward)
|
53 |
+
graph = export_to_graph(reward)
|
54 |
+
|
55 |
+
|
56 |
+
return reward_img, graph
|
57 |
+
|
58 |
+
js = """function () {
|
59 |
+
gradioURL = window.location.href
|
60 |
+
if (!gradioURL.endsWith('?__theme=dark')) {
|
61 |
+
window.location.replace(gradioURL + '?__theme=dark');
|
62 |
+
}
|
63 |
+
}"""
|
64 |
+
|
65 |
+
with gr.Blocks() as demo:
|
66 |
+
|
67 |
+
demo.load(None,None,None,_js=js)
|
68 |
+
|
69 |
+
gr.Markdown(
|
70 |
+
"""
|
71 |
+
# Stellar Jade Estimator Patch 1.4
|
72 |
+
ฝากติดตามผลงาน : https://www.youtube.com/@hewchayen
|
73 |
+
<br />last update : 13/10/2023, 10:48
|
74 |
+
"""
|
75 |
+
)
|
76 |
+
|
77 |
+
|
78 |
+
with gr.Row():
|
79 |
+
|
80 |
+
with gr.Column():
|
81 |
+
mode_dropdown = gr.Dropdown(["ทั้งหมด", "ครึ่งแรก", "ครึ่งหลัง"], label="ระยะเวลาในการนับ")
|
82 |
+
equilibrium_dropdown = gr.Dropdown([0, 1, 2, 3, 4, 5, 6], label="ระดับสมดุล", info="เลือกระดับสมดุลของไอดี")
|
83 |
+
condition_checkbox = gr.CheckboxGroup(["Memory of Chaos", "บัตรเสบียงรถไฟ", "Battle Pass"], label="สถานะ (optional)")
|
84 |
+
button = gr.Button("Calculate")
|
85 |
+
|
86 |
+
output = gr.Image(label = "Reward", type="pil")
|
87 |
+
|
88 |
+
output2 = gr.Image(label = "Resource")
|
89 |
+
|
90 |
+
button.click(fn=inference, inputs=[mode_dropdown, equilibrium_dropdown, condition_checkbox], outputs = [output, output2],)
|
91 |
+
|
92 |
+
demo.queue(api_open=False)
|
93 |
+
demo.launch()
|
requirements.txt
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
Pillow
|
3 |
+
pandas
|
4 |
+
opencv-python
|
5 |
+
numpy
|
6 |
+
matplotlib
|
template.png
ADDED
utils.py
ADDED
@@ -0,0 +1,212 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
import io
|
3 |
+
import cv2
|
4 |
+
import datetime
|
5 |
+
import calendar
|
6 |
+
import numpy as np
|
7 |
+
import pandas as pd
|
8 |
+
import gradio as gr
|
9 |
+
import matplotlib.pyplot as plt
|
10 |
+
from PIL import ImageFont, ImageDraw, Image
|
11 |
+
|
12 |
+
from datetime import date, timedelta
|
13 |
+
from collections import Counter
|
14 |
+
from typing import NamedTuple
|
15 |
+
|
16 |
+
class Reward():
|
17 |
+
def __init__(self):
|
18 |
+
self.stellar_jade = {}
|
19 |
+
self.special_pass = {}
|
20 |
+
self.oneiric_shard = 0
|
21 |
+
|
22 |
+
def weekday_count(start_date, end_date):
|
23 |
+
week = {}
|
24 |
+
for i in range((end_date - start_date).days):
|
25 |
+
day = calendar.day_name[(start_date + datetime.timedelta(days=i+1)).weekday()]
|
26 |
+
week[day] = week[day] + 1 if day in week else 1
|
27 |
+
return week
|
28 |
+
|
29 |
+
def daterange(start_date, end_date):
|
30 |
+
for n in range(int((end_date - start_date).days)):
|
31 |
+
yield start_date + timedelta(n)
|
32 |
+
|
33 |
+
def estimator(start_patch, end_patch, mode, equilibrium, data_patch, limited_event, permanent_event, play_memory_of_chaos, EXPRESS_SUPPLY, BP):
|
34 |
+
|
35 |
+
duration = abs(start_patch - end_patch).days
|
36 |
+
|
37 |
+
n_weekdays = weekday_count(start_patch, end_patch)
|
38 |
+
n_weeks = Counter(n_weekdays.values()).most_common(1)[0][0]
|
39 |
+
|
40 |
+
if mode == 1:
|
41 |
+
start_half = start_patch
|
42 |
+
end_half = start_half + datetime.timedelta(days = duration // 2 )
|
43 |
+
|
44 |
+
duration = abs(start_half - end_half).days
|
45 |
+
|
46 |
+
if mode == 2:
|
47 |
+
start_half = start_patch + datetime.timedelta(days = duration // 2 )
|
48 |
+
end_half = end_patch
|
49 |
+
|
50 |
+
duration = abs(start_half - end_half).days
|
51 |
+
|
52 |
+
reward = Reward()
|
53 |
+
reward_SU = {0:75, 1:75, 2:105, 3:135, 4:165, 5:195, 6:225}
|
54 |
+
|
55 |
+
reward.stellar_jade['daily_quest'] = 60 * duration
|
56 |
+
# reward.stellar_jade['chat'] = 5 * duration
|
57 |
+
|
58 |
+
if (mode == 0 or mode == 1) :
|
59 |
+
reward.stellar_jade['update'] = 600
|
60 |
+
reward.stellar_jade['permanent_event'] = np.sum([permanent_event[i]['reward'] for i in permanent_event])
|
61 |
+
|
62 |
+
|
63 |
+
special_event = 'gift_odyssey'
|
64 |
+
|
65 |
+
if mode == 0:
|
66 |
+
reward.stellar_jade['daily_login'] = 80
|
67 |
+
reward.stellar_jade['SU'] = reward_SU[equilibrium] * n_weekdays['Monday']
|
68 |
+
reward.stellar_jade['character_tryout'] = 20 * data_patch['n_character_banner']
|
69 |
+
reward.stellar_jade['character_quest'] = 100 * np.sum([data_patch['n_character_quest'][i] for i in data_patch['n_character_quest']])
|
70 |
+
reward.special_pass['Ember'] = 5 * Counter([single_date.day for single_date in daterange(start_patch, end_patch)])[1]
|
71 |
+
|
72 |
+
#edit every patch
|
73 |
+
reward.stellar_jade['event'] = np.sum([limited_event[i]['reward'] for i in limited_event if i != special_event])
|
74 |
+
reward.special_pass['event'] = limited_event[special_event]['reward']
|
75 |
+
|
76 |
+
if play_memory_of_chaos: reward.stellar_jade['memory_of_chaos'] = 600 * (n_weeks // 2)
|
77 |
+
|
78 |
+
if EXPRESS_SUPPLY:
|
79 |
+
reward.stellar_jade['EXPRESS_SUPPLY'] = 90 * duration
|
80 |
+
reward.oneiric_shard = int(300 * np.ceil(duration/30))
|
81 |
+
|
82 |
+
if BP:
|
83 |
+
reward.stellar_jade['BP'] = 680
|
84 |
+
reward.special_pass['BP'] = 4
|
85 |
+
|
86 |
+
reward.stellar_jade['redeem_code_next_patch'] = 300
|
87 |
+
|
88 |
+
else:
|
89 |
+
reward.stellar_jade['daily_login'] = 40
|
90 |
+
reward.stellar_jade['SU'] = reward_SU[equilibrium] * (n_weekdays['Monday'] // 2)
|
91 |
+
|
92 |
+
#companion quest
|
93 |
+
if mode == 1: reward.stellar_jade['character_quest'] = 100 * data_patch['n_character_quest']['first_half']
|
94 |
+
elif mode == 2: reward.stellar_jade['character_quest'] = 100 * data_patch['n_character_quest']['second_half']
|
95 |
+
|
96 |
+
#temporary
|
97 |
+
reward.stellar_jade['character_tryout'] = 20 * (data_patch['n_character_banner'] // 2)
|
98 |
+
reward.special_pass['Ember'] = 5 * Counter([single_date.day for single_date in daterange(start_half, end_half)])[1]
|
99 |
+
|
100 |
+
#edit every patch
|
101 |
+
reward.stellar_jade['event'] = np.sum([limited_event[i]['reward'] for i in limited_event if (i != special_event) and (limited_event[i]['date'][0] >= start_half and limited_event[i]['date'][0] + datetime.timedelta(days = 7) < end_half)])
|
102 |
+
reward.special_pass['event'] = limited_event[special_event]['reward'] if (limited_event[special_event]['date'][0] >= start_half and start_half + datetime.timedelta(days = 7) < end_half) else 0
|
103 |
+
|
104 |
+
if play_memory_of_chaos:
|
105 |
+
if mode == 1:
|
106 |
+
reward.stellar_jade['memory_of_chaos'] = 600 * 2
|
107 |
+
else: reward.stellar_jade['memory_of_chaos'] = 600
|
108 |
+
|
109 |
+
if EXPRESS_SUPPLY:
|
110 |
+
reward.stellar_jade['EXPRESS_SUPPLY'] = 90 * duration
|
111 |
+
reward.oneiric_shard = int(300 * np.ceil(duration/30))
|
112 |
+
|
113 |
+
if BP:
|
114 |
+
if mode == 2:
|
115 |
+
reward.stellar_jade['BP'] = 680
|
116 |
+
reward.special_pass['BP'] = 4
|
117 |
+
|
118 |
+
if mode == 2 : reward.stellar_jade['redeem_code_next_patch'] = 300
|
119 |
+
|
120 |
+
return reward
|
121 |
+
|
122 |
+
|
123 |
+
def export_to_image(data):
|
124 |
+
template = cv2.imread('./template.png')
|
125 |
+
|
126 |
+
font = ImageFont.truetype("./DMSans-Regular.ttf", 80)
|
127 |
+
color = (0, 78, 53)
|
128 |
+
|
129 |
+
image_rgb = cv2.cvtColor(template, cv2.COLOR_BGR2RGB)
|
130 |
+
pil_image = Image.fromarray(image_rgb)
|
131 |
+
draw = ImageDraw.Draw(pil_image)
|
132 |
+
|
133 |
+
pos = [(500, 50), (500, 280), (500, 530)]
|
134 |
+
text = [int(sum(data.stellar_jade.values())), int(sum(data.special_pass.values())), int(data.oneiric_shard)]
|
135 |
+
for d, position in zip(text, pos):
|
136 |
+
draw.text(position, str(d), font=font, fill=color)
|
137 |
+
|
138 |
+
return pil_image
|
139 |
+
|
140 |
+
def export_to_graph(data):
|
141 |
+
|
142 |
+
df = pd.DataFrame(sorted(data.stellar_jade.items(), key = lambda x:x[1], reverse = True), columns = ['source', 'stellar jade'])
|
143 |
+
|
144 |
+
source_map = {'daily_quest':'Daily Quest', 'permanent_event':'Permanent Event', 'event':'Limited Event', 'memory_of_chaos': 'Memory of Chaos', 'SU':'Simulate Universe', 'update':'Update', 'redeem_code_next_patch':'Code live next patch', 'character_quest':'Companion Quest', 'daily_login':'Website daily login', 'character_tryout':'Character trial', 'EXPRESS_SUPPLY':'Express supply', 'BP':'Battle pass', 'chat':'Daily Chat'}
|
145 |
+
|
146 |
+
filtered = df[df['stellar jade'] != 0]
|
147 |
+
|
148 |
+
source = [source_map[i] for i in filtered['source']]
|
149 |
+
|
150 |
+
filtered['source'] = source
|
151 |
+
|
152 |
+
df = filtered
|
153 |
+
|
154 |
+
df['stellar jade'] = df['stellar jade'].astype('int')
|
155 |
+
|
156 |
+
total_jade = df['stellar jade'].sum()
|
157 |
+
|
158 |
+
# Figure Size
|
159 |
+
fig, ax = plt.subplots(figsize =(16, 9))
|
160 |
+
|
161 |
+
stellar_jade = df['stellar jade']
|
162 |
+
|
163 |
+
# Horizontal Bar Plot
|
164 |
+
ax.barh(source, stellar_jade)
|
165 |
+
|
166 |
+
# Remove axes splines
|
167 |
+
for s in ['top', 'bottom', 'left', 'right']:
|
168 |
+
ax.spines[s].set_visible(False)
|
169 |
+
|
170 |
+
# Remove x, y Ticks
|
171 |
+
ax.xaxis.set_ticks_position('none')
|
172 |
+
ax.yaxis.set_ticks_position('none')
|
173 |
+
|
174 |
+
# Add padding between axes and labels
|
175 |
+
ax.xaxis.set_tick_params(pad = 5)
|
176 |
+
ax.yaxis.set_tick_params(pad = 10)
|
177 |
+
|
178 |
+
# Add x, y gridlines
|
179 |
+
ax.grid(color ='grey',linestyle ='--', linewidth = 0.5,alpha = 0.4)
|
180 |
+
|
181 |
+
# Show top values
|
182 |
+
ax.invert_yaxis()
|
183 |
+
|
184 |
+
# Add annotation to bars
|
185 |
+
for index, i in enumerate(ax.patches):
|
186 |
+
if index < 3 :
|
187 |
+
number_color = 'red'
|
188 |
+
elif index < 6:
|
189 |
+
number_color = 'orange'
|
190 |
+
else: number_color = 'grey'
|
191 |
+
|
192 |
+
plt.text(i.get_width()+10, i.get_y()+0.5,
|
193 |
+
str(round((i.get_width()), 2)) + ' ({0}%)'.format(round(100 * (i.get_width() / total_jade), 2)),
|
194 |
+
fontsize = 10,
|
195 |
+
color = number_color)
|
196 |
+
|
197 |
+
title = 'The most Stellar Jade Resource'
|
198 |
+
|
199 |
+
ax.set_title(title,
|
200 |
+
loc ='left', )
|
201 |
+
|
202 |
+
# Add Text watermark
|
203 |
+
fig.text(0.9, 0.15, 'CHAYEN', fontsize = 12,
|
204 |
+
color ='grey', ha ='right', va ='bottom',
|
205 |
+
alpha = 0.7)
|
206 |
+
|
207 |
+
buf = io.BytesIO()
|
208 |
+
fig.savefig(buf)
|
209 |
+
buf.seek(0)
|
210 |
+
img = Image.open(buf)
|
211 |
+
|
212 |
+
return img
|