본문 바로가기
파이썬 독학 (나도코딩)/Python

파이썬 독학 (나도코딩) 6

by Mecodata 2022. 5. 19.

객체 = 속성과 기능을 가지고 있는 자료

class = 객체를 만들기 위한 일종의 틀 ex) 붕어빵 틀

instance(인스턴스) = class로 만들어낸 객체 ex) 여러 종류의 붕어빵

field(필드) = class 속의 변수로 표현되는 객체의 속성

method(메서드) = 객체의 기능, 행동을 클래스 속의 함수로 표현하는 것

__init__ = 생성자 함수 = 생성할 객체의 필드의 초기값 설정 

※ __init__  설정시 첫 매개변수는 반드시 self로 입력해야함 ex) def __init__(self,....)

(인스턴스이름.변수) 형식으로 class의 변수를 사용할 수 있음  

 

-Unit class 정의-

클래스 = Unit

인스턴스 = class로부터 생성된 것 ex) marine, tank

값을 입력할때 self를 제외한 변수들의 갯수에 맞게 입력해야함

ex) Unit("마린"), unit(40, 5) -> 오류, Unit("마린", 40, 5) -> 정상 출력

 

wraith2.clocking 처럼 class와 별개로 하나의 속성을 추가할 수 있음

 

AttackUnit이라는 class 내에서 attack, damaged라는 method들을 만들어 이에 적용한 결과

 

()를 이용하여 AttackUnit에 Unit을 상속 -> 위 사진의 코드와 같은 결과값이 출력됨(대신 code는 더 깔끔해졌음)

이때, Unit = 부모 class, AttackUnit = 자식 class

 

FlyableAttackUnit처럼 상속은 다중상속이 가능함

 

 

유닛(부모 class)에 정의되어 있던 move 메서드와 별개로 FlyableAttackUnit(자식 class) 안에서 별개의 move 메서드를 재정의 -> 메서드 오버라이딩 

 

내부 동작은 필요 없고 껍데기뿐인 클래스가 필요할 경우 다음과 같이 pass를 통해 가능 (무시하고 넘어감)

 

위아래 두문장은 서로 같은 문장 (단, super를 이용할 경우에는 self를 입력할 필요 X)

 

super를 이용하여 다중상속을 받게 되면 순서상 맨처음 class에 대해서만 상속받음

 

모든 부모 class에 대하여 다중상속을 받아야할 경우에는 각각의 부모 class에 대하여 일일이 초기화 설정을 해야함

 

from random import *

class Unit: # 클래스 지명
    def __init__(self, name, hp, speed): # 클래스의 초기값 설정
        self.name = name
        self.hp = hp
        self.speed = speed
        print("{} 유닛이 생성되었습니다.".format(name))

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

    def damaged(self, damage): # 메서드
        print("{} : {} 데미지를 입었습니다.".format(self.name, damage))
        self.hp -= damage # hp에서 damage만큼 빼기
        print("{} : 현재 체력은 {} 입니다.".format(self.name, self.hp))
        if self.hp <= 0:
            print("{} : 파괴되었습니다.".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("{} : {} 방향으로 적군을 공격 합니다. [공격력 {}]"\
          .format(self.name, location, self.damage))

class Marine(AttackUnit):
    def __init__(self):
        AttackUnit.__init__(self, "마린", 40, 1, 5)

    def stimpack(self):
        if self.hp > 10:
            self.hp -= 10
            print("{} : 스팀팩을 사용합니다. (HP 10 감소)".format(self.name))
        else:
            print("{} : 체력이 부족하여 스팀팩을 사용하지 않습니다.".format(self.name))

class Tank(AttackUnit):
    seize_developed = False # 시즈모드 개발여부

    def __init__(self):
        AttackUnit.__init__(self, "탱크", 150, 1, 35)
        self.seize_mode = False

    def set_seize_mode(self):
        if Tank.seize_developed == False:
            return

        if self.seize_mode == False: # 시즈모드가 아닐 때 -> 시즈모드
            print("{} : 시즈모드로 전환합니다.".format(self.name))
            self.damage *= 2 # 공격력 2배
            self.seize_mode = True

        else: # 시즈모드 일때 -> 시즈모드 해제
            print("{} : 시즈모드를 해제합니다.".format(self.name))
            self.damage /= 2
            self.seize_mode = False

class Flyable: # 공중 유닛
    def __init__(self, flying_speed):
        self.flying_speed = flying_speed

    def fly(self, name, location):
        print("{} : {} 방향으로 날아갑니다. [속도 {}]"\
              .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 Wraith(FlyableAttackUnit):
    def __init__(self):
        FlyableAttackUnit.__init__(self, "레이스", 80, 20, 5)
        self.clocked = False # 클로킹 모드 (해제 상태)

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

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

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

game_start() # 게임 시작

m1 = Marine() # 마린 3명
m2 = Marine()
m3 = Marine()

t1 = Tank() # 탱크 2대
t2 = Tank()

w1 = Wraith() # 레이스 1기

# 유닛 일괄 관리 (생성된 모든 유닛 append)
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, 20)) # 공격을 랜덤으로 받음 (5~20)

game_over() # 게임 종료료




class BuildingUnit(Unit): # 건물
    def __init__(self, name, hp, location):
        # Unit.__init__(self, name, hp, 0)
        super().__init__(name, hp, 0) # 바로 윗줄과 같은 기능
        self.location = location


게임 시작 -> 마린 3명, 탱크 2대, 레이스 1기 생성 -> 모든 유닛 이동 -> 각 유닛별 특성 모드 작동 -> 공격(설정한 공격력 만큼) 및 데미지(랜덤) 반영 -> gg -> 게임 종료 순으로 출력됨  

 

practice_starcraft.py
0.00MB

# 3대의 매물
# 강남 아파트 매매 10억 2010년
# 마포 오피스텔 전세 5억 2007년
# 송파 빌라 월세 500/50 2000년

class House:
    def __init__(self, location, house_type, deal_type, price, completion_year):
        self.location = location
        self.house_type = house_type
        self.deal_type = deal_type
        self.price = price
        self.completion_year = completion_year

    def show_detail(self):
        print(self.location, self.house_type, self.deal_type, self.price, self.completion_year)

houses = []
gangnam = House("강남", "아파트", "매매", "10억", "2010년")
mapo = House("마포", "오피스텔", "전세", "5억", "2007년")
songpa = House("송파", "빌라", "전세", "500/50", "2000년")

houses.append(gangnam)
houses.append(mapo)
houses.append(songpa)

print("총 {}대의 매물이 있습니다.".format(len(houses)))
for house in houses:
    house.show_detail()

부동산 프로그램 만들기 (Quiz)

댓글