from math import pow


class Character:
    def __init__(self, name, speed, skills):
        """
        skills : 사용할 스킬들의 필요 게이지 리스트
                 예) [1000, 700, 1500]
        """
        self.name = name
        self.speed = speed
        self.gauge_gain = pow(speed / 100, 0.65)

        self.gauge = 0
        self.skills = skills
        self.skill_index = 0

    @property
    def current_cost(self):
        return self.skills[self.skill_index]

    def time_until_action(self):
        return (self.current_cost - self.gauge) / self.gauge_gain

    def gain_gauge(self, dt):
        self.gauge += self.gauge_gain * dt

    def act(self):
        cost = self.current_cost
        self.gauge -= cost
        self.skill_index = (self.skill_index + 1) % len(self.skills)
        return cost


class BattleSimulator:
    ROUND_TIME = 1000

    def __init__(self, char1, char2):
        self.char1 = char1
        self.char2 = char2

        self.time = 0
        self.log = []

    def record(self, character, first=False):
        round_num = int(self.time // self.ROUND_TIME) + 1

        self.log.append({
            "round": round_num,
            "time": self.time,
            "name": character.name,
            "first": first
        })

    def simulate(self, rounds=5):

        # -------------------------
        # 첫 턴 (시간 0)
        # -------------------------
        if self.char1.speed >= self.char2.speed:
            self.record(self.char1, True)
            self.record(self.char2, True)
        else:
            self.record(self.char2, True)
            self.record(self.char1, True)

        # -------------------------
        # 이후 진행
        # -------------------------
        while self.time < rounds * self.ROUND_TIME:

            t1 = self.char1.time_until_action()
            t2 = self.char2.time_until_action()

            dt = min(t1, t2)

            self.time += dt

            self.char1.gain_gauge(dt)
            self.char2.gain_gauge(dt)

            # 동시에 행동하는 경우도 처리
            if self.char1.gauge >= self.char1.current_cost - 1e-9:
                self.char1.act()
                self.record(self.char1)

            if self.char2.gauge >= self.char2.current_cost - 1e-9:
                self.char2.act()
                self.record(self.char2)

    def print_log(self):

        current_round = 0

        for item in self.log:

            if item["round"] != current_round:
                current_round = item["round"]
                print(f"\n===== {current_round} 라운드 =====")

            tag = " (첫 턴)" if item["first"] else ""

            print(
                f"{item['time']:8.2f} | {item['name']}{tag}"
            )


# --------------------------
# 예시
# --------------------------

a = Character(
    name="나",
    speed=1464,
    skills=[1000, 2000, 1000, 1500, 1500, 1500, 1500, 1500]
)

b = Character(
    name="보스",
    speed=2262,
    skills=[1000]
)

battle = BattleSimulator(a, b)

battle.simulate(rounds=3)

battle.print_log()

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: