스타크래프트 프로젝트 (나도코딩)

최창환·2022년 2월 22일
0
post-thumbnail

나도코딩 파이썬 무료 강의에서 스타크래프트 프로젝트를 실습하고 조금씩 변형해보면서 클래스에 대한 개념을 복습해보았다.


강의에서 테란유닛을 활용한 스타크래프트 프로젝트를 실습하였는데 개인적으로 테란종족을 선호하지 않기도하고 그대로 실습하는것보다 이것저것 변형해보고싶어서 저그유닛을 활용한 프로젝트로 바꾸어보았다.

from random import *

# 일반유닛
class ZergUnit:
    def __init__(self, name, hp, speed):
        self.name = name
        self.hp = hp
        self.speed = speed
        self.burrowed = False
        print("{0} 유닛이 생성되었습니다.".format(name))

    def move(self, location):
        print("{0} : {1} 방향으로 이동합니다. [속도 {2}]"\
            .format(self.name, location, self.speed))

    def damaged(self, damage):
        print("{0} : {1} 데미지를 입었습니다.".format(self.name, damage))
        self.hp -= damage
        print("{0} : 현재 체력은 {1}입니다.".format(self.name, self.hp))
        if self.hp <= 0:
            print("{0} : 파괴되었습니다.".format(self.name))

    def burrow(self):
        if self.burrowed == True:
            print("{0} : 잠복을 해제합니다.".format(self.name))
            self.burrowed == False
        else:
            print("{0} : 잠복합니다.".format(self.name))
            self.burrowed == True

# 공격유닛
class AttackUnit(ZergUnit):
    def __init__(self, name, hp, speed, damage):
        ZergUnit.__init__(self, name, hp, speed)
        self.damage = damage
    
    def attack(self, location):
        print("{0} : {1} 방향으로 적군을 공격합니다. [공격력 {2}]"\
            .format(self.name, location, self.damage))

class Zergling(AttackUnit):
    def __init__(self):
        AttackUnit.__init__(self, "저글링", 35, 2, 5)

# 히드라
class Hydra(AttackUnit):
    lurker_developed = False # 럴커 개발여부
    
    def __init__(self):
        AttackUnit.__init__(self, "히드라", 80, 1, 10)
        self.lurker = False
    def evolve_lurker(self):
        if Hydra.lurker_developed == False:
            return
        
        if self.lurker == False:
            print("{0} : 럴커로 진화합니다.".format(self.name))
            self.lurker = True

# 럴커
class Lurker(Hydra):
    def __init__(self):
        AttackUnit.__init__(self, "럴커", 125, 1, 20)
        self.lurker = False

    def burrow(self):
        if self.burrowed == True:
            print("{0} : 잠복을 해제합니다.".format(self.name))
            print("{0} : 공격할 수 없습니다.".format(self.name))
            self.burrowed == False
        else:
            print("{0} : 잠복합니다.".format(self.name))
            print("{0} : 이제 공격할 수 있습니다.".format(self.name))
            self.burrowed == True

# 날 수 있는 기능을 가진 클래스
class Flyable:
    def __init__(self, flying_speed):
        self.flying_speed = flying_speed

    def fly(self, name, location):
        print("{0} : {1} 방향으로 날아갑니다. [속도 {2}]"\
            .format(name, location, self.flying_speed))

# 공중 공격 유닛 클래스
class FlyableAttackUnit(AttackUnit, Flyable):
    def __init__(self, name, hp, damage, flying_speed):
        AttackUnit.__init__(self, name, hp, 0, damage) # 지상 스피드 0
        Flyable.__init__(self, flying_speed)

    def move(self, location): # move함수 재정의
        self.fly(self.name, location)


# 뮤탈
class Mutalisk(FlyableAttackUnit):
    def __init__(self):
        FlyableAttackUnit.__init__(self,"뮤탈", 120, 9, 15)


def game_start():
    print("[알림] 새로운 게임을 시작합니다.")

def game_over():
    print("Player : gg")
    print("[Player]님이 game에서 퇴장하셨습니다.")

모든 저그유닛이 burrow기능을 가지고 있는것을 고려해 일반유닛 클래스에 burrow함수를 추가하였고 기능을 장착, 해제하는 테란과 달리 저그의 진화기능을 나타내기 위해 히드라에서 럴커로 진화하는 코드를 작성해보았다.

# 게임 진행

game_start()

z1 = Zergling()
z2 = Zergling()
z3 = Zergling()

h1 = Hydra()
h2 = Hydra()

m1 = Mutalisk()

attack_units = []
attack_units.append(z1)
attack_units.append(z2)
attack_units.append(z3)
attack_units.append(h1)
attack_units.append(h2)
attack_units.append(m1)

for unit in attack_units: # 전군이동
    unit.move("1시")

Hydra.lurker_developed = True # 럴커 진화 개발
print("[알림] 럴커 진화 개발이 완료되었습니다.")


for unit in attack_units: # 공격모드 준비
    if isinstance(unit, Hydra):
        unit.evolve_lurker()
        h1 = Lurker()
        h2 = Lurker()
        attack_units[3:5] = [h1, h2]

    if isinstance(unit, Lurker):
        unit.burrow()


for unit in attack_units: # 전군 공격
    unit.attack("1시")

for unit in attack_units: # 전군 피해
    unit.damaged(randint(5, 21))

game_over()

유닛공격의 출력값이 히드라에서 럴커로 변환되지 않고 그대로 출력되어서 계속 수정을 해보았다. 알고보니 리스트 변경을 해야하는데 그렇게 하지않고 위의 생성자쪽 코드에 조건문을 달아서 값이 변경되지 않는것이였다. 리스트 값을 변경하니 다행히도 원하던 출력내용이 나왔다.
생각보다 시간이 걸렸지만 클래스의 여러가지 개념을 정리하고 이해할 수 있는 좋은 시간이였다.

profile
포기하지 않는 개발자

0개의 댓글