본문 바로가기
개발(Develop)/파이썬(Python)

[Python] 파이썬으로 스타크래프트 게임 / 파이썬 클래스, 상속, 다중상속, 함수 연습하기 / 파이썬 프로젝트

by 왁왁s 2022. 2. 28.

파이썬의 여러 클래스의 상속, 다중 상속을 연습해보는 겸

'스타크래프트'를 구현해보았다.

 

 

기본 유닛에 대한 클래스 : Unit

 

공격 유닛에 대한 클래스 : AttackUnit

 

날 수 있는 기능 클래스 : Flyable

 

날 수 있는 공격 유닛 : FlyableAttackUnit

 

 

상속 구조 

Unit > AttackUnit > Marine, Tank

 

Flyable, AttackUnit (다중 상속) > FlyableAttackUnit > Wraith

 

|

캐릭터 정보

이름(name), 체력(hp), 속도(speed), 공중유닛속도(flying_speed)

 

|

기능

Unit 클래스 : 이동(move),  공격받음(damaged)

 

AttackUnit 클래스 : 어디를 공격하다(attack)

 

Flyable 클래스 : 어디로 날아가다(fly)

 

FlyableAttackUnit 클래스 : 이동(move)

 

Marine 클래스 : 마린 유닛으로 공격속도가 빨라지나 체력이 닳는 '스팀팩 기능' 구현

 

Tank 클래스 : 탱크 유닛으로 seize_developed (시즈모드 개발 여부)를 두어

시즈모드를 개발하였을 때, 시즈모드를 전환해 공격력을 높여줌

 

Wraith 클래스 : clocking 투명모드 기능을 두어 설정 및 해제가 가능하도록 한다

from random import *

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

  def move(self, location):
    print("[지상 유닛 이동]")
    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))

#공격유닛
class AttackUnit(Unit):
  def __init__(self, name, hp, speed, damage):
    Unit.__init__(self, name, hp, speed)
    self.damage = damage

  def attack(self, location):
    print("{0} : {1} 방향으로 적군을 공격합니다. [공격력 {2}]".format(self.name, location, self.damage))

#하늘을 날 수 있는
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)
    Flyable.__init__(self, flying_speed)

  def move(self, location):
    print("[공중 유닛 이동]")
    self.fly(self.name, location)  

#마린
class Marine(AttackUnit):
  def __init__(self):
    AttackUnit.__init__(self, "마린", 40, 5, 5)
  #스팀팩 : 일정 시간동안 이동 및 공격 속도 증가
  def stimpack(self):
    if self.hp > 10:
      self.hp -= 10
      print("{0} : 스팀팩을 사용합니다. (HP 10 감소)".format(self.name))
    else:
      print("{0} : 체력이 부족합니다. (HP 잔량 : {1})".format(self.name, self.hp))

class Tank(AttackUnit):
  seize_developed = False #시즈모드 개발여부
  
  def __init__(self):
    AttackUnit.__init__(self, "탱크", 150, 1, 5)
    self.seize_mode = False
    
  #시즈모드 : 탱크를 고정 시켜 더 높은 공격력
  def set_seize_mode(self):
    if Tank.seize_developed == False:
      return

    if self.seize_mode == False:
      print("{0} : 시즈모드로 전환합니다.".format(self.name))
      self.damage *= 2
      self.seize_mode = True

    else:
      print("{0} : 시즈모드로 해제합니다.".format(self.name))
      self.damage /= 2
      self.seize_mode = False

#공중유닛 레이스
class Wraith(FlyableAttackUnit):
  def __init__(self):
    FlyableAttackUnit.__init__(self, "레이스", 80, 20, 5)
    self.clocked = False #클로킹 모드 (해제상태)

  def clocking(self):
    if self.clocked == False:
      print("{0} : 클로킹 모드를 설정합니다.".format(self.name))
      self.clocked = True
    else:
      print("{0} : 클로킹 모드를 해제합니다.".format(self.name))
      self.clocked = False

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

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


#게임 시작
game_start()

#마린 생성
m1 = Marine()
m2 = Marine()
m3 = Marine()

#탱크 생성
t1 = Tank()
t2 = Tank()

#레이스 생성
w1 = Wraith()

#유닛 일괄 관리 / 리스트
attack_units = []
attack_units.append(m1)
attack_units.append(m2)
attack_units.append(m3)
attack_units.append(t1)
attack_units.append(t2)
attack_units.append(w1)

#유닛 이동
for unit in attack_units:
    unit.move("1시")

#탱크 시즈모드 개발
Tank.seize_developed = True
print("[알림] 탱크 시즈 모드 개발이 완료되었습니다")

#공격 모드 준비 (마린 : 스팀팩, 탱크 : 시즈모드, 레이스 : 클로킹 모드)
for unit in attack_units:
    if isinstance(unit, Marine):
        unit.stimpack()
    elif isinstance(unit, Tank):
        unit.set_seize_mode()
    elif isinstance(unit, Wraith):
        unit.clocking()

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

#전군 피해
for unit in attack_units:
    unit.damaged(randint(5, 50)) #랜덤으로 공격을 받음
    print("{0} : 공격을 받아 체력이 {1}을 남았습니다".format(unit.name, unit.hp))

#게임 종료
game_over()

실행했을 때.

 

댓글