본문 바로가기
프로젝트/강화학습1

게임 구현하기: ABC를 사용하여 카드의 추상 베이스 클래스 만들기

by soypablo 2023. 4. 15.

Slay the Spire게임을 구축하는데 가장 오래걸리고 힘든 일은, 게임 내의 상호작용 하는 요소 중 가장 많은 비중을 차지하고 가장 많은 종류가 있는 '카드'를 구현하는 것이다.

Slay the spire의 가장 기본적인 카드인 '타격'(strike)

이 카드를 구현하는 방법은 여러가지가 있을 수 있는데, 내가 사용하고자 하는 방법은 다음과 같다.

카드 구현 방법

  1. '카드'라는 공통 기능을 정의하는 추상 베이스 클래스를 만들기 위해 ABC 클래스를 사용한다.
  2. '카드'를 상속받는 더 작은 범위의 카드 클래스를 만든다.(마찬가지로 ABC를 사용할 것이다.) 예를 들어, 'AttackCard', 'SkillCard', 'PowerCard' 등이 있다.
  3. 각 카드의 데이터(이름, 등급, 타입, 에너지, 효과 등)를 JSON 파일 형태로 저장한다.
  4. 모든 카드의 효과를 코드에서 구현한다.
  5. 테스트 과정을 거친다.

1. ABC클래스를 사용하여 'Card' 추상 베이스 클래스 만들기

카드는 공통된 특성과 기능을 가지고 있으므로, ABC 클래스를 사용하여 추상 베이스 클래스를 정의해야 한다.

예를 들어, 모든 카드는 이름, 카드 종류, 적용 대상 등의 공통 속성을 가집니다. 이러한 공통 기능을 추상적으로 선언하기 위해 ABC를 사용하여 다음과 같이 코드를 구현할 수 있다.

from abc import ABC, abstractmethod

class Card(ABC):
    def __init__(self, name, cost, card_type, rarity, target):
        self.name = name
        self.cost = cost
        self.card_type = card_type
        self.rarity = rarity
        self.target = target

    @abstractmethod
    def use(self, player, target):
        pass

이 Card라는 클래스는 모든 카드가 가지는 특성인 이름, 코스트, 카드의 타입, 희귀도, 적용 대상을 명시하는 init 메서드를 가지며, use라는 추상메서드가 있다.

예를 들어, 가장 기본적인 카드인 '타격'(Strike)를 해당 Card를 상속해서 구현한다고 해보자.(임시로 구현하는 것이다.)

class Strike(Card):
    def __init__(self):
        super().__init__(name="Strike", cost=1, card_type="Attack", rarity="Common", target="Enemy")

    def use(self, player, enemy):
        damage = player.calculate_damage(6) # 기본 데미지는 6이지만, 플레이어의 힘, 약화에 따라 데미지가 달라진다.
        enemy.take_damage(damage)

이 클래스는 'Card'를 상속받아, 'Card'의 __init__ 함수와 use 메서드를 구체적으로 정의했다. 이렇게 모든 카드에 공통된 기능을 재사용할 수 있도록 설계하면, 카드를 정의하는 작업을 단순화할 수 있다.

좀 더 자세히 설명하면, 위의 예시에서 'Strike' 클래스는 'Card'를 상속받아 구현했다. 'Strike' 클래스의 __init__ 메서드에서는 슈퍼 클래스(Card)의 __init__ 메서드를 호출하여 공통 속성을 해당 카드에 맞게 초기화한다. 또한 use 메서드를 통해 공격 카드에 해당하는 데미지 계산과 적에게 데미지를 입히는 기능을 구현했다.

같은 방식으로 다양한 종류의 카드를 구현할 수 있으며, 이렇게 구현된 카드들을 통해 게임의 다양한 상호작용을 만들어낼 수 있을 것이다.

이 예시에서는 'Card'의 클래스에서 바로 Strike 단일 카드의 클래스 구현을 했지만, 실제 구현에서는 더 세분화된 추상 클래스를 만들어서, 거기에 JSON파일 객체를 읽어와서 자동으로 카드 객체를 만들도록 구현할 것이다.


오늘의 TMI: 최근 서브 모니터와 모니터암을 구매했다. 모니터 높이가 안 맞아서 거북목이 생겼는데, 모니터암을 설치하니 한결 낫다. 최근 산 것중에 제일 맘에 든다.