Spaces:
Sleeping
Sleeping
feat: update
Browse files- __pycache__/sample.cpython-310.pyc +0 -0
- app.py +24 -4
- rcity_sanma.csv +17 -0
- rcity_tenho_sampling.py +185 -0
- tenho_sanma.csv +41 -0
__pycache__/sample.cpython-310.pyc
CHANGED
Binary files a/__pycache__/sample.cpython-310.pyc and b/__pycache__/sample.cpython-310.pyc differ
|
|
app.py
CHANGED
@@ -1,19 +1,39 @@
|
|
1 |
import streamlit as st
|
2 |
-
import
|
|
|
|
|
3 |
|
4 |
st.set_page_config(layout="wide")
|
5 |
-
st.title("rcity 10dan saka Sampling")
|
6 |
|
7 |
num_games = st.selectbox("Number of games", [100, 500, 1000, 2000, 3000], index=1)
|
8 |
num_dan = st.selectbox("Number of dan", [7, 8, 9, 10], index=3)
|
|
|
|
|
9 |
num_max_pt = st.selectbox("Number of max points", [9000, 10000, 15000, 20000], index=3)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
if num_games is None or num_dan is None:
|
11 |
st.stop()
|
12 |
-
df =
|
|
|
|
|
13 |
if df is not None:
|
14 |
if st.button("再計算") or num_games is not None:
|
15 |
col1, col2 = st.columns(2)
|
16 |
-
plt =
|
|
|
|
|
17 |
with col1:
|
18 |
st.pyplot(plt)
|
19 |
with col2:
|
|
|
1 |
import streamlit as st
|
2 |
+
import rcity_tenho_sampling
|
3 |
+
|
4 |
+
# import yonma_sample
|
5 |
|
6 |
st.set_page_config(layout="wide")
|
7 |
+
st.title("tenho or rcity 10dan saka Sampling")
|
8 |
|
9 |
num_games = st.selectbox("Number of games", [100, 500, 1000, 2000, 3000], index=1)
|
10 |
num_dan = st.selectbox("Number of dan", [7, 8, 9, 10], index=3)
|
11 |
+
platform = st.selectbox("platform", ("rcity", "tenhou"), key="platform")
|
12 |
+
print(f"platform: {platform}, enum: {rcity_tenho_sampling.Platform[platform]}")
|
13 |
num_max_pt = st.selectbox("Number of max points", [9000, 10000, 15000, 20000], index=3)
|
14 |
+
col1, col2, col3 = st.columns(3)
|
15 |
+
with col1:
|
16 |
+
custom_1st_p = st.number_input("1st rate(custom)", min_value=0.0, max_value=1.0)
|
17 |
+
with col2:
|
18 |
+
custom_2nd_p = st.number_input("2nd rate(custom)", min_value=0.0, max_value=1.0)
|
19 |
+
with col3:
|
20 |
+
custom_3rd_p = st.number_input("3rd rate(custom)", min_value=0.0, max_value=1.0)
|
21 |
+
custom_rates = None
|
22 |
+
if custom_1st_p + custom_2nd_p + custom_3rd_p == 1.0:
|
23 |
+
st.info("custom rating enabled")
|
24 |
+
custom_rates = [custom_1st_p, custom_2nd_p, custom_3rd_p]
|
25 |
+
print(f"1st: {custom_1st_p}, 2nd: {custom_2nd_p}, 3rd: {custom_3rd_p}")
|
26 |
if num_games is None or num_dan is None:
|
27 |
st.stop()
|
28 |
+
df = rcity_tenho_sampling.readcsv(
|
29 |
+
filter=num_dan, platform=rcity_tenho_sampling.Platform[platform]
|
30 |
+
)
|
31 |
if df is not None:
|
32 |
if st.button("再計算") or num_games is not None:
|
33 |
col1, col2 = st.columns(2)
|
34 |
+
plt = rcity_tenho_sampling.simulate_games(
|
35 |
+
df, num_games=num_games, max_score=num_max_pt, custom_rates=custom_rates
|
36 |
+
)
|
37 |
with col1:
|
38 |
st.pyplot(plt)
|
39 |
with col2:
|
rcity_sanma.csv
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
dan,place,win,draw,lose,win_rate,draw_rate,lose_rate,init_score,rank_up_score
|
2 |
+
10,enton,90,0,-120,0.3506,0.3742,0.2752,3800,7600
|
3 |
+
10,enhan,135,0,-180,0.35,0.38,0.30,3800,7600
|
4 |
+
10,ginton,160,0,-180,0.3636,0.3322,0.3042,3800,7600
|
5 |
+
10,ginhan,240,0,-270,0.3481,0.3754,0.2827,3800,7600
|
6 |
+
7,ginton,160,0,-150,0.35,0.38,0.27,2300,4600
|
7 |
+
8,ginton,160,0,-160,0.35,0.38,0.27,2800,5600
|
8 |
+
9,ginton,160,0,-170,0.35,0.38,0.27,3300,6600
|
9 |
+
7,ginhan,240,0,-225,0.35,0.38,0.27,2300,4600
|
10 |
+
8,ginhan,240,0,-240,0.35,0.38,0.27,2800,5600
|
11 |
+
9,ginhan,240,0,-255,0.35,0.38,0.27,3300,6600
|
12 |
+
7,enton,90,0,-90,0.35,0.38,0.27,2300,4600
|
13 |
+
8,enton,90,0,-100,0.35,0.38,0.27,2800,5600
|
14 |
+
9,enton,90,0,-110,0.35,0.38,0.27,3300,6600
|
15 |
+
7,enhan,135,0,-135,0.35,0.38,0.27,2300,4600
|
16 |
+
8,enhan,135,0,-150,0.35,0.38,0.27,2800,5600
|
17 |
+
9,enhan,135,0,-165,0.35,0.38,0.27,3300,6600
|
rcity_tenho_sampling.py
ADDED
@@ -0,0 +1,185 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import matplotlib.pyplot
|
2 |
+
import pandas as pd
|
3 |
+
import os
|
4 |
+
import random
|
5 |
+
import enum
|
6 |
+
import pydantic
|
7 |
+
|
8 |
+
|
9 |
+
def main():
|
10 |
+
df = readcsv(10)
|
11 |
+
if df is not None:
|
12 |
+
plt = simulate_games(df, num_games=2000)
|
13 |
+
plt.show()
|
14 |
+
|
15 |
+
|
16 |
+
class Platform(enum.IntEnum):
|
17 |
+
rcity = 1
|
18 |
+
tenhou = 2
|
19 |
+
|
20 |
+
|
21 |
+
def readcsv(
|
22 |
+
filter: int = 10,
|
23 |
+
platform: Platform = Platform.rcity,
|
24 |
+
) -> pd.DataFrame | None:
|
25 |
+
# CSVファイルの存在確認
|
26 |
+
if platform == Platform.rcity:
|
27 |
+
csv_file = "rcity_sanma.csv"
|
28 |
+
elif platform == Platform.tenhou:
|
29 |
+
csv_file = "tenho_sanma.csv"
|
30 |
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
31 |
+
csv_path = os.path.join(current_dir, csv_file)
|
32 |
+
if not os.path.isfile(csv_path):
|
33 |
+
print(f"Error: {csv_file} does not exist.")
|
34 |
+
return None
|
35 |
+
|
36 |
+
# CSVファイルの読み込み
|
37 |
+
df = pd.read_csv(csv_path)
|
38 |
+
|
39 |
+
filtered_df = df[df.iloc[:, 0] == filter]
|
40 |
+
|
41 |
+
# フィルター後のデータフレームを表示
|
42 |
+
print(filtered_df)
|
43 |
+
return filtered_df
|
44 |
+
|
45 |
+
|
46 |
+
def simulate_games(
|
47 |
+
df,
|
48 |
+
num_games: int = 1000,
|
49 |
+
max_score: int = 20000,
|
50 |
+
custom_rates: None | list[int, int, int] = None,
|
51 |
+
):
|
52 |
+
results = {}
|
53 |
+
|
54 |
+
for index, row in df.iterrows():
|
55 |
+
place = row["place"]
|
56 |
+
win_score = row["win"]
|
57 |
+
lose_score = row["lose"]
|
58 |
+
draw_score = row["draw"]
|
59 |
+
win_rate = row["win_rate"]
|
60 |
+
lose_rate = row["lose_rate"]
|
61 |
+
draw_rate = row["draw_rate"]
|
62 |
+
init_score = row["init_score"]
|
63 |
+
if custom_rates is not None:
|
64 |
+
win_rate, lose_rate, draw_rate = custom_rates
|
65 |
+
scores = [init_score]
|
66 |
+
for _ in range(num_games):
|
67 |
+
result = random.choices(
|
68 |
+
[1, 2, 3], weights=[win_rate, lose_rate, draw_rate]
|
69 |
+
)[0]
|
70 |
+
if result == 1:
|
71 |
+
scores.append(scores[-1] + win_score)
|
72 |
+
elif result == 2:
|
73 |
+
scores.append(scores[-1] + lose_score)
|
74 |
+
else:
|
75 |
+
scores.append(scores[-1] + draw_score)
|
76 |
+
|
77 |
+
results[place] = scores
|
78 |
+
df.at[index, "reached_goal"] = any(
|
79 |
+
[score >= row["rank_up_score"] for score in scores]
|
80 |
+
)
|
81 |
+
df.at[index, "rank_down"] = any([score <= 0 for score in scores])
|
82 |
+
|
83 |
+
matplotlib.pyplot.figure(figsize=(10, 6))
|
84 |
+
for place, scores in results.items():
|
85 |
+
matplotlib.pyplot.plot(range(num_games + 1), scores, label=place)
|
86 |
+
matplotlib.pyplot.axhline(
|
87 |
+
y=df.iloc[0]["init_score"], color="black", linestyle="--", label="initial score"
|
88 |
+
)
|
89 |
+
matplotlib.pyplot.axhline(
|
90 |
+
y=df.iloc[0]["rank_up_score"], color="red", linestyle="--", label="goal"
|
91 |
+
)
|
92 |
+
matplotlib.pyplot.xlabel("Game")
|
93 |
+
matplotlib.pyplot.ylabel("Score")
|
94 |
+
matplotlib.pyplot.ylim(0, max_score)
|
95 |
+
matplotlib.pyplot.title("Score Transition")
|
96 |
+
matplotlib.pyplot.legend()
|
97 |
+
return matplotlib.pyplot
|
98 |
+
|
99 |
+
|
100 |
+
class Result(pydantic.BaseModel):
|
101 |
+
place: str
|
102 |
+
is_reached_goal: bool
|
103 |
+
is_koudan: bool
|
104 |
+
|
105 |
+
|
106 |
+
def simulate_games_core(
|
107 |
+
df,
|
108 |
+
num_games: int = 1000,
|
109 |
+
custom_rates: None | list[int, int, int] = None,
|
110 |
+
) -> list[Result]:
|
111 |
+
results = []
|
112 |
+
|
113 |
+
for _, row in df.iterrows():
|
114 |
+
place = row["place"]
|
115 |
+
win_score = row["win"]
|
116 |
+
lose_score = row["lose"]
|
117 |
+
draw_score = row["draw"]
|
118 |
+
win_rate = row["win_rate"]
|
119 |
+
lose_rate = row["lose_rate"]
|
120 |
+
draw_rate = row["draw_rate"]
|
121 |
+
init_score = row["init_score"]
|
122 |
+
rank_up_score = row["rank_up_score"]
|
123 |
+
|
124 |
+
if custom_rates is not None:
|
125 |
+
win_rate, lose_rate, draw_rate = custom_rates
|
126 |
+
|
127 |
+
score = init_score
|
128 |
+
is_reached_goal = False
|
129 |
+
is_koudan = False
|
130 |
+
|
131 |
+
for _ in range(num_games):
|
132 |
+
result = random.choices(
|
133 |
+
[1, 2, 3], weights=[win_rate, lose_rate, draw_rate]
|
134 |
+
)[0]
|
135 |
+
if result == 1:
|
136 |
+
score += win_score
|
137 |
+
elif result == 2:
|
138 |
+
score += lose_score
|
139 |
+
else:
|
140 |
+
score += draw_score
|
141 |
+
|
142 |
+
if score >= rank_up_score:
|
143 |
+
is_reached_goal = True
|
144 |
+
break
|
145 |
+
if score <= 0:
|
146 |
+
is_koudan = True
|
147 |
+
break
|
148 |
+
|
149 |
+
results.append(
|
150 |
+
{"place": place, "is_reached_goal": is_reached_goal, "is_koudan": is_koudan}
|
151 |
+
)
|
152 |
+
|
153 |
+
return results
|
154 |
+
|
155 |
+
|
156 |
+
def testing(num: int = 20):
|
157 |
+
"""
|
158 |
+
simulate_gamesをn回回して、結果を表示する
|
159 |
+
"""
|
160 |
+
df = readcsv(10)
|
161 |
+
|
162 |
+
if df is not None:
|
163 |
+
place_stats = {}
|
164 |
+
|
165 |
+
for _ in range(num):
|
166 |
+
results = simulate_games_core(df, num_games=2000)
|
167 |
+
for res in results:
|
168 |
+
place = res["place"]
|
169 |
+
if place not in place_stats:
|
170 |
+
place_stats[place] = {"promotions": [], "demotions": []}
|
171 |
+
place_stats[place]["promotions"].append(res["is_reached_goal"])
|
172 |
+
place_stats[place]["demotions"].append(res["is_koudan"])
|
173 |
+
|
174 |
+
for place, stats in place_stats.items():
|
175 |
+
print("-----")
|
176 |
+
print(f"place: {place}")
|
177 |
+
print(f"回した回数: {num}")
|
178 |
+
print(f"昇段: {stats['promotions']}")
|
179 |
+
print(f"後段: {stats['demotions']}")
|
180 |
+
print(f"合計昇段回数: {sum(stats['promotions'])}")
|
181 |
+
print(f"合計後段回数: {sum(stats['demotions'])}")
|
182 |
+
|
183 |
+
|
184 |
+
if __name__ == "__main__":
|
185 |
+
testing()
|
tenho_sanma.csv
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
dan,place,win,draw,lose,win_rate,draw_rate,lose_rate,init_score,rank_up_score
|
2 |
+
1,basic_nan,45,0,-30,0.3481,0.3754,0.2827,200,400
|
3 |
+
2,basic_nan,45,0,-60,0.3481,0.3754,0.2827,400,800
|
4 |
+
3,basic_nan,45,0,-75,0.3481,0.3754,0.2827,600,1200
|
5 |
+
4,basic_nan,45,0,-90,0.3481,0.3754,0.2827,800,1600
|
6 |
+
5,basic_nan,45,0,-105,0.3481,0.3754,0.2827,1000,2000
|
7 |
+
6,basic_nan,45,0,-120,0.3481,0.3754,0.2827,1200,2400
|
8 |
+
7,basic_nan,45,0,-135,0.3481,0.3754,0.2827,1400,2800
|
9 |
+
8,basic_nan,45,0,-150,0.3481,0.3754,0.2827,1600,3200
|
10 |
+
9,basic_nan,45,0,-165,0.3481,0.3754,0.2827,1800,3600
|
11 |
+
10,basic_nan,45,0,-180,0.3481,0.3754,0.2827,2000,4000
|
12 |
+
1,joukyu_nan,75,0,-30,0.3481,0.3754,0.2827,200,400
|
13 |
+
2,joukyu_nan,75,0,-60,0.3481,0.3754,0.2827,400,800
|
14 |
+
3,joukyu_nan,75,0,-75,0.3481,0.3754,0.2827,600,1200
|
15 |
+
4,joukyu_nan,75,0,-90,0.3481,0.3754,0.2827,800,1600
|
16 |
+
5,joukyu_nan,75,0,-105,0.3481,0.3754,0.2827,1000,2000
|
17 |
+
6,joukyu_nan,75,0,-120,0.3481,0.3754,0.2827,1200,2400
|
18 |
+
7,joukyu_nan,75,0,-135,0.3481,0.3754,0.2827,1400,2800
|
19 |
+
8,joukyu_nan,75,0,-150,0.3481,0.3754,0.2827,1600,3200
|
20 |
+
9,joukyu_nan,75,0,-165,0.3481,0.3754,0.2827,1800,3600
|
21 |
+
10,joukyu_nan,75,0,-180,0.3481,0.3754,0.2827,2000,4000
|
22 |
+
1,tokujou_nan,105,0,-30,0.3481,0.3754,0.2827,200,400
|
23 |
+
2,tokujou_nan,105,0,-60,0.3481,0.3754,0.2827,400,800
|
24 |
+
3,tokujou_nan,105,0,-75,0.3481,0.3754,0.2827,600,1200
|
25 |
+
4,tokujou_nan,105,0,-90,0.3481,0.3754,0.2827,800,1600
|
26 |
+
5,tokujou_nan,105,0,-105,0.3481,0.3754,0.2827,1000,2000
|
27 |
+
6,tokujou_nan,105,0,-120,0.3481,0.3754,0.2827,1200,2400
|
28 |
+
7,tokujou_nan,105,0,-135,0.3481,0.3754,0.2827,1400,2800
|
29 |
+
8,tokujou_nan,105,0,-150,0.3481,0.3754,0.2827,1600,3200
|
30 |
+
9,tokujou_nan,105,0,-165,0.3481,0.3754,0.2827,1800,3600
|
31 |
+
10,tokujou_nan,105,0,-180,0.3481,0.3754,0.2827,2000,4000
|
32 |
+
1,houou_nan,135,0,-30,0.3481,0.3754,0.2827,200,400
|
33 |
+
2,houou_nan,135,0,-60,0.3481,0.3754,0.2827,400,800
|
34 |
+
3,houou_nan,135,0,-75,0.3481,0.3754,0.2827,600,1200
|
35 |
+
4,houou_nan,135,0,-90,0.3481,0.3754,0.2827,800,1600
|
36 |
+
5,houou_nan,135,0,-105,0.3481,0.3754,0.2827,1000,2000
|
37 |
+
6,houou_nan,135,0,-120,0.3481,0.3754,0.2827,1200,2400
|
38 |
+
7,houou_nan,135,0,-135,0.3481,0.3754,0.2827,1400,2800
|
39 |
+
8,houou_nan,135,0,-150,0.3481,0.3754,0.2827,1600,3200
|
40 |
+
9,houou_nan,135,0,-165,0.3481,0.3754,0.2827,1800,3600
|
41 |
+
10,houou_nan,135,0,-180,0.3481,0.3754,0.2827,2000,4000
|