levena commited on
Commit
7d2f292
1 Parent(s): 50dcba3

feat: update

Browse files
__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 sample
 
 
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 = sample.readcsv(filter=num_dan)
 
 
13
  if df is not None:
14
  if st.button("再計算") or num_games is not None:
15
  col1, col2 = st.columns(2)
16
- plt = sample.simulate_games(df, num_games=num_games, max_score=num_max_pt)
 
 
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