상세 컨텐츠

본문 제목

[Python 파이썬 독학 7-3일차]

파이썬 스터디/파이썬-Python 기본편

by 후즈테크 2020. 9. 30. 23:39

본문

반응형

 

# 스타크레프트 전반전

 

개별 유닛별 class 생성

 

# 마린 class

  - 부모 class 로 사용되는 Unit 과 AttackUnit 에서 상속 받는 마린 class 생성

  -  stimpack(스팀팩) : 특수 기능 옵션 추가.

# 일반 유닛
class Unit: # 대소문자 구분함
    def __init__(self, name, hp, speed):
        self.name = name
        self.hp = hp
        self.speed = speed
        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))




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

    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 marine(AttackUnit):
    def __init__(self):
        AttackUnit.__init__(self, "마린", 40, 1, 5)

    # 스팀팩 : 일정 시간 동안 이동 및 공격 속도를 증가. 체력 10 감소
    def stimpack(self):
        if self.hp > 10:
            self.hp -= 10
            print("{0} 유닛이 스팀팩을 사용합니다. (hp 10 감소)".format(self.name))

        else :
            print("{0} 체력이 부족하여 스팀팩을 사용하지 않습니다.".format(self.name))

 

# 탱크 class

  - 부모 class 로 사용되는 Unit 과 AttackUnit 에서 상속 받는 탱크 class 생성

    * 위 마린 class 이후 붙여 넣기 할 경우, class Tank 만 복사./ 개별로 할 경우, ''' 제거 후 실행

  -  size_mode : 특수 기능 옵션 추가.

'''
class Unit: # 대소문자 구분함
    def __init__(self, name, hp, speed):
        self.name = name
        self.hp = hp
        self.speed = speed
        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))




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

    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 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.set_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

  - 부모 class 로 사용되는 AttackUnit 과 Flyable 에서 상속 받는 레이스 class 생성

    * 위 탱크 class 이후 붙여 넣기 할 경우, class Flyable, FlyableAttackUnit, wraith 만 복사./ 개별로 할 경우, ''' 제거 후 실행

  -  cloking : 특수 기능 옵션 추가.

 

'''

# 일반 유닛
class Unit: # 대소문자 구분함
    def __init__(self, name, hp, speed):
        self.name = name
        self.hp = hp
        self.speed = speed
        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))




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

    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 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)  # 지상 speed = 0 , flying_speed 값이 있음
        Flyable.__init__(self, flying_speed)

    def move(self, location):
        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("{0} : 클로킹 모드 해제합니다. ".format(self.name))
            self.clocked = False
            
        else :
            #self.clocked = False: # 클로킹 해제 모드 -> 클로킹 모드
            print("{0} : 클로킹 모드 설정합니다. ".format(self.name))
            self.clocked = True

        
반응형

 

# 스타크레프트 후반전(작성된 코딩을 기준으로 시나리오 대로 동작 확인)

  - 시나리오 :

  1) 게임시작

  2) 마린 3, 탱크 2, 레이스 1기 생산

  3) 전군 이동 (1시)

  4) 시즈모드 업그레이드 완료

  5) 공격 모드 준비(마린 : 스팀팩, 탱크 : 시즈모드 ,레이스 : 클로킹)

  6) 전군 공격(1시)

  7) random 으로 피해 발생

  8) 게임 종료

 


# 일반 유닛
class Unit: # 대소문자 구분함
    def __init__(self, name, hp, speed):
        self.name = name
        self.hp = hp
        self.speed = speed
        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))




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

    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 marine(AttackUnit):
    def __init__(self):
        AttackUnit.__init__(self, "마린", 40, 1, 5)

    # 스팀팩 : 일정 시간 동안 이동 및 공격 속도를 증가. 체력 10 감소
    def stimpack(self):
        if self.hp > 10:
            self.hp -= 10
            print("{0} 유닛이 스팀팩을 사용합니다. (hp 10 감소)".format(self.name))

        else :
            print("{0} 체력이 부족하여 스팀팩을 사용하지 않습니다.".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.set_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 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)  # 지상 speed = 0 , flying_speed 값이 있음
        Flyable.__init__(self, flying_speed)

    def move(self, location):
        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("{0} : 클로킹 모드 해제합니다. ".format(self.name))
            self.clocked = False
            
        else :
            #self.clocked = False: # 클로킹 해제 모드 -> 클로킹 모드
            print("{0} : 클로킹 모드 설정합니다. ".format(self.name))
            self.clocked = True

        # 현재 시즈모드 일 때 -> 시즈 모드 해제





# 스타크래픛트 후반전

# 실제 게임 시나리오 시작

from  random import *

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

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




# 시나리오 시작

game_start()

m1 = marine()
m2 = marine()
m3 = marine()


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

# 레이스 1기 생성
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,20)) # 공격은 랜덤으로 받음 (5~20)


game_over()

 

# 결과 값 : (피해 상황은 randint 함수로 인해 5~20 사이의 damaged를 받는다.)

[알림] 새로운 게임을 시작합니다.
마린 유닛이 생성되었습니다.
마린 유닛이 생성되었습니다.
마린 유닛이 생성되었습니다.
탱크 유닛이 생성되었습니다.
탱크 유닛이 생성되었습니다.
레이스 유닛이 생성되었습니다.
마린 : 1시 방향으로 이동합니다. [속도 : 1]
마린 : 1시 방향으로 이동합니다. [속도 : 1]
마린 : 1시 방향으로 이동합니다. [속도 : 1]
탱크 : 1시 방향으로 이동합니다. [속도 : 1]
탱크 : 1시 방향으로 이동합니다. [속도 : 1]
레이스 : 1시 방향으로 날아갑니다. [속도 5]
[알림] 탱크 시즈모드 개발이 완료 되었습니다.
마린 유닛이 스팀팩을 사용합니다. (hp 10 감소)
마린 유닛이 스팀팩을 사용합니다. (hp 10 감소)
마린 유닛이 스팀팩을 사용합니다. (hp 10 감소)
탱크 : 시즈 모드를 해제합니다.
탱크 : 시즈 모드를 해제합니다.
마린 : 1시 방향으로 적군을 공격합니다.[공격력 5]
마린 : 1시 방향으로 적군을 공격합니다.[공격력 5]
마린 : 1시 방향으로 적군을 공격합니다.[공격력 5]
탱크 : 1시 방향으로 적군을 공격합니다.[공격력 17.5]
탱크 : 1시 방향으로 적군을 공격합니다.[공격력 17.5]
레이스 : 1시 방향으로 적군을 공격합니다.[공격력 20]
마린 : 5 데미지를 입었습니다.
마린 : 현재 체력은 25 입니다.
마린 : 14 데미지를 입었습니다.
마린 : 현재 체력은 16 입니다.
마린 : 19 데미지를 입었습니다.
마린 : 현재 체력은 11 입니다.
탱크 : 9 데미지를 입었습니다.
탱크 : 현재 체력은 141 입니다.
탱크 : 14 데미지를 입었습니다.
탱크 : 현재 체력은 136 입니다.
레이스 : 9 데미지를 입었습니다.
레이스 : 현재 체력은 71 입니다.
Player : gg
[Player] 님이 게임에서 퇴장하였습니다.

 

 

# 판타스틱하고 센세이션한 스타크레프트의 코딩과 시나리오 대로의 진행의 위와 같다....

# 시나리오 진행에서 중요한 포인트 중 하나는 생성된 유닛을 리스트 형태로 관리하는 방법이다.

# 유닛 일괄 관리

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)

 * 해당 형태로 리스트 생성 후, 추가가 되었기 때문에 일관적으로 해당 유닛들을 관리할 수 있다.

 

# 두번째 중요 포인트는 ininstance를 통해 해당 객체가 어느 class를 통해 생성되었는지 확인하고,

   필요한 특수기능들을 한번에 적용하는 것이 가능하다는 것이다.

# 공격 모드 준비(마린 : 스팀팩, 탱크 : 시즈모드 ,레이스 : 클로킹)

for unit in attack_units:
    if isinstance(unit, marine): # 해당 객체가 특정 클래스의 객체인지 확인하는 방법
        unit.stimpack() # 위 조건 처럼 해당 unit 이 marine class 가 맞을 경우 stimpack
    elif isinstance(unit, Tank):
        unit.set_seize_mode() # 위 조건 처럼 해당 unit 이 tank class 가 맞을 경우 set_seize_mode
    elif isinstance(unit, wraith):
        unit.clocking # 위 조건 처럼 해당 unit 이 wraith class 가 맞을 경우 clocking

 

-----------------------------------------------------------------------------------------------

 

Quiz 8. 

 

# 주어진 코드를 활용하여 부동산 프로그램을 작성하시오.

 

# (출력 예제)

# 총 3대의 매물이 있습니다.

# 강남 아파트 매물 10억 2010년

# 마포 오피스텔 전세 5억 2007년

# 송파 빌라 월세 500/50 2000년

 

# [코드]

# class House:

#   # 매물 초기화

#   def __init__(self, location, house_type, deal_type, price, mopletion_year):

#       pass

 

#   #매물 정보 표시

#   def show_detail(self):

#   pass

 

-----------------------------------------------------------------------------------------------

 

Ans 1. 내가 작성한 코드

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)
       


h1 = House("강남", "아파트", "매물", "10억", "2010년")
h2 = House("마포", "오피스텔", "전세", "5억", "2007년")
h3 = House("송파", "빌라", "월세", "500/50", "2000년")


lists = []

lists.append(h1)
lists.append(h2)
lists.append(h3)


cnt = 0
for house in lists:
    if isinstance(house, House):
        cnt += 1
        
print("총 {0}대의 매물이 있습니다.".format(cnt))


for house in lists:
    house.show_detail()


''' 결과 값 : 
총 3대의 매물이 있습니다.
강남 아파트 매물 10억 2010년
마포 오피스텔 전세 5억 2007년
송파 빌라 월세 500/50 2000년

'''

 * 총 3대의 매물이 있습니다. 를 for 문을 통해 생성.

 

 

 

Ans 2. 나도코딩님 답안

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)



h1 = House("강남", "아파트", "매물", "10억", "2010년")
h2 = House("마포", "오피스텔", "전세", "5억", "2007년")
h3 = House("송파", "빌라", "월세", "500/50", "2000년")


houses = []

houses.append(h1)
houses.append(h2)
houses.append(h3)

print("총 {0}대의 매물이 있습니다.".format(len(houses)))


for house in houses:
    house.show_detail()

''' 결과 값 : 
총 3대의 매물이 있습니다.
강남 아파트 매물 10억 2010년
마포 오피스텔 전세 5억 2007년
송파 빌라 월세 500/50 2000년
'''

 

 

 

FeedBack...

 - 매물 건수 출력이 가능한 len 함수를 몰라 for 문을 1개 더 작성해서 나타냈고, 나도코딩님은 한줄로 작성 가능했다...

 역시 손발이 고생안하려면 많이 알아야한다......

 문제 제출 시 큰 틀이 맞춰져 있어 내용에서 큰 차이 없이 동일한 구조였고, 관리를 위한 리스트 생성 시, 생성명을 제외하고는 나도코딩님과 동일했다.

 

 - for 문을 하나만 쓰는 형태로 만들어 보려 고민했으나, 결과 값 출력 순서 때문에 실패....하였다. 아래의 2가지 실패 사례는 안될 걸 알았지만, 결과 검증 상 진행해 보았던 내용들이고 역시나 원하는 결과 출력은 되지 않았다. 

 

시도 1 - 출력 순서가 다름

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)



h1 = House("강남", "아파트", "매물", "10억", "2010년")
h2 = House("마포", "오피스텔", "전세", "5억", "2007년")
h3 = House("송파", "빌라", "월세", "500/50", "2000년")

lists = []

lists.append(h1)
lists.append(h2)
lists.append(h3)

cnt = 0
for house in lists:
    house.show_detail()
    if isinstance(house, House):
        cnt += 1
        
print("총 {0}대의 매물이 있습니다.".format(cnt))


''' 결과 값 :
강남 아파트 매물 10억 2010년
마포 오피스텔 전세 5억 2007년
송파 빌라 월세 500/50 2000년
총 3대의 매물이 있습니다.
'''

 

시도 2 - 중간 중간 print 문이 합쳐짐.

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)



h1 = House("강남", "아파트", "매물", "10억", "2010년")
h2 = House("마포", "오피스텔", "전세", "5억", "2007년")
h3 = House("송파", "빌라", "월세", "500/50", "2000년")

lists = []

lists.append(h1)
lists.append(h2)
lists.append(h3)

cnt = 0
for house in lists:
    house.show_detail()
    if isinstance(house, House):
        cnt += 1
        print("총 {0}대의 매물이 있습니다.".format(cnt))
        



''' 결과 값 :
강남 아파트 매물 10억 2010년
총 1대의 매물이 있습니다.
마포 오피스텔 전세 5억 2007년
총 2대의 매물이 있습니다.
송파 빌라 월세 500/50 2000년
총 3대의 매물이 있습니다.
'''

 

유튜버 '나도코딩' 님의 영상을 보며 공부 및 노트 작성합니다.

 

함께 공부해 나가실 분은

www.youtube.com/watch?v=kWiCuklohdY&feature=youtu.be

반응형

관련글 더보기

댓글 영역