rcity-sampling / rcity_tenho_sampling.py
levena's picture
feat: update
7d2f292
import matplotlib.pyplot
import pandas as pd
import os
import random
import enum
import pydantic
def main():
df = readcsv(10)
if df is not None:
plt = simulate_games(df, num_games=2000)
plt.show()
class Platform(enum.IntEnum):
rcity = 1
tenhou = 2
def readcsv(
filter: int = 10,
platform: Platform = Platform.rcity,
) -> pd.DataFrame | None:
# CSVファイルの存在確認
if platform == Platform.rcity:
csv_file = "rcity_sanma.csv"
elif platform == Platform.tenhou:
csv_file = "tenho_sanma.csv"
current_dir = os.path.dirname(os.path.abspath(__file__))
csv_path = os.path.join(current_dir, csv_file)
if not os.path.isfile(csv_path):
print(f"Error: {csv_file} does not exist.")
return None
# CSVファイルの読み込み
df = pd.read_csv(csv_path)
filtered_df = df[df.iloc[:, 0] == filter]
# フィルター後のデータフレームを表示
print(filtered_df)
return filtered_df
def simulate_games(
df,
num_games: int = 1000,
max_score: int = 20000,
custom_rates: None | list[int, int, int] = None,
):
results = {}
for index, row in df.iterrows():
place = row["place"]
win_score = row["win"]
lose_score = row["lose"]
draw_score = row["draw"]
win_rate = row["win_rate"]
lose_rate = row["lose_rate"]
draw_rate = row["draw_rate"]
init_score = row["init_score"]
if custom_rates is not None:
win_rate, lose_rate, draw_rate = custom_rates
scores = [init_score]
for _ in range(num_games):
result = random.choices(
[1, 2, 3], weights=[win_rate, lose_rate, draw_rate]
)[0]
if result == 1:
scores.append(scores[-1] + win_score)
elif result == 2:
scores.append(scores[-1] + lose_score)
else:
scores.append(scores[-1] + draw_score)
results[place] = scores
df.at[index, "reached_goal"] = any(
[score >= row["rank_up_score"] for score in scores]
)
df.at[index, "rank_down"] = any([score <= 0 for score in scores])
matplotlib.pyplot.figure(figsize=(10, 6))
for place, scores in results.items():
matplotlib.pyplot.plot(range(num_games + 1), scores, label=place)
matplotlib.pyplot.axhline(
y=df.iloc[0]["init_score"], color="black", linestyle="--", label="initial score"
)
matplotlib.pyplot.axhline(
y=df.iloc[0]["rank_up_score"], color="red", linestyle="--", label="goal"
)
matplotlib.pyplot.xlabel("Game")
matplotlib.pyplot.ylabel("Score")
matplotlib.pyplot.ylim(0, max_score)
matplotlib.pyplot.title("Score Transition")
matplotlib.pyplot.legend()
return matplotlib.pyplot
class Result(pydantic.BaseModel):
place: str
is_reached_goal: bool
is_koudan: bool
def simulate_games_core(
df,
num_games: int = 1000,
custom_rates: None | list[int, int, int] = None,
) -> list[Result]:
results = []
for _, row in df.iterrows():
place = row["place"]
win_score = row["win"]
lose_score = row["lose"]
draw_score = row["draw"]
win_rate = row["win_rate"]
lose_rate = row["lose_rate"]
draw_rate = row["draw_rate"]
init_score = row["init_score"]
rank_up_score = row["rank_up_score"]
if custom_rates is not None:
win_rate, lose_rate, draw_rate = custom_rates
score = init_score
is_reached_goal = False
is_koudan = False
for _ in range(num_games):
result = random.choices(
[1, 2, 3], weights=[win_rate, lose_rate, draw_rate]
)[0]
if result == 1:
score += win_score
elif result == 2:
score += lose_score
else:
score += draw_score
if score >= rank_up_score:
is_reached_goal = True
break
if score <= 0:
is_koudan = True
break
results.append(
{"place": place, "is_reached_goal": is_reached_goal, "is_koudan": is_koudan}
)
return results
def testing(num: int = 20):
"""
simulate_gamesをn回回して、結果を表示する
"""
df = readcsv(10)
if df is not None:
place_stats = {}
for _ in range(num):
results = simulate_games_core(df, num_games=2000)
for res in results:
place = res["place"]
if place not in place_stats:
place_stats[place] = {"promotions": [], "demotions": []}
place_stats[place]["promotions"].append(res["is_reached_goal"])
place_stats[place]["demotions"].append(res["is_koudan"])
for place, stats in place_stats.items():
print("-----")
print(f"place: {place}")
print(f"回した回数: {num}")
print(f"昇段: {stats['promotions']}")
print(f"後段: {stats['demotions']}")
print(f"合計昇段回数: {sum(stats['promotions'])}")
print(f"合計後段回数: {sum(stats['demotions'])}")
if __name__ == "__main__":
testing()