안녕하세요~~~!!
27년차 진로탐색꾼 조녁입니다!!
class 오늘 2번째편으로 마무리하려합니다! 오늘은 지난번에 배운 메소드, 상속과 같은 개념들을 활용한 예제들을 주를 이룹니다!
강의에선 배운 내용들을 기반으로 스타크래프트 전,후반전을 진행해보고, 부동산 프로그램도 작성해봤습니다.
모든 코드는 아래 git_hub 에 올려둔 Colab 노트북 참고 부탁드려요.
github.com/jonhyuk0922/Python-basic
파이썬 설치 방법은 아래 글 참고해주세요! (주피터 노트북 환경 + 구글 클라우드 사용이 가능한 Colab 환경 추천드립니다.)
파이썬 기초 6-2강 내용
1. 메소드 오버라이딩
2. pass
3. super
4. 스타크래프트 전반전
5. 스타크래프트 후반전
6.부동산 프로그램 작성
1. 메소드 오버라이딩
: 부모 클래스에서 정의된 메소드를 자식 클래스에서 사용할 때, 같은 이름의 메소드를 새롭게 정의해서 사용하는 것.
스타크래프트에서 각 유닛들은 이동이 가능합니다. 이동 함수를 정의해주고 , 속도 변수를 Unit 클래스에 추가해주도록 하겠습니다.
# 일반 유닛
class Unit:
def __init__(self, name, hp, speed): # speed 추가
self.name = name
self.hp = hp
self.speed = speed # 지상 이동 속도
def move(self, location): # 이동 함수 정의
print("[지상 유닛 이동]")
print("{0} : {1} 방향으로 이동합니다. [속도 {2}]"\
.format(self.name, location, self.speed))
이렇게 되면 Unit의 자녀 클래스들의 init 에도 speed 변수가 추가되어야합니다.
# 공격 유닛
class AttackUnit(Unit):
def __init__(self, name, hp, speed, damage): # speed 추가
Unit.__init__(self, name, hp, speed) # speed 추가
self.damage = damage
... # 메소드 생략
그리고 AttackUnit의 자녀 클래스인 FlyableAttackUnit 클래스도 수정해줘야 합니다.
다만 공중유닛은 speed 가 아닌 flying_speed를 사용(move 재정의)합니다. 그래서 우선 Flyable class를 수정해준 후 상속해줍니다.
다만! FlyableAttackUnit 클래스는 AttackUnit 클래스로 부터 상속을 받기때문에 지상속도(speed)는 0으로 받아줍니다.
#날 수 있는 기능을 가진 클래스
class Flyable:
def __init__(self,flying_speed):
self.flying_speed = flying_speed
def fly(self, name, location):
print(f"{name} : {location} 방향으로 날아갑니다. [속도 {self.flying_speed}]")
#공중 공격 유닛 클래스
class FlyableAttackUnit(AttackUnit,Flyable):
def __init__(self,name,hp,damage,flying_speed):
AttackUnit.__init__(self,name,hp,damage,0) #지상 속도 : 0
Flyable.__init__(self,flying_speed)
def move(self,location):
print("[공중 유닛 이동]")
self.fly(self.name, location)
이동이 잘 정의되었나 확인하기 위해, 지상 유닛 '벌쳐'와 공중 유닛 '배틀크루저' 를 생성해봅니다.
#벌쳐 : 지상 유닛, 기동성이 좋음
vulture = AttackUnit("벌쳐",80,20,10)
#배틀크루저 : 공중 유닛, 체력도 굉장히 좋음, 공격력도 좋음.
battlecruiser = FlyableAttackUnit("배틀크루저",500,25,3)
vulture.move("11시")
#battlecruiser.fly(battlecruiser.name,"9시")
battlecruiser.move("9시")
2. pass
: pass 는 함수에서 아무것도 하지 않고 일단은 그냥 넘어간다는 의미로 사용됩니다.
만약 스타크래프트 도중 건물을 지어야 하는 상황이라고 상상해봅시다. 이 때 건물을 짓는 클래스를 만들고 서플라이 디폿이라는 건물을 지었습니다. 그런데 일단은 건물만 지어놓고 다른 작업 먼저하고 나중에 코드를 완성한다고 가정해봅시다. 이럴 때 파이썬에서는 pass를 사용합니다.
# 건물
class BuildingUnit(Unit):
def __init__(self, name, hp, location):
pass
# 서플라이 디폿 : 건물, 1개 건물 = 8 유닛.
supply_depot = BuildingUnit("서플라이 디폿", 500, "7시") # 체력 500, 생성 위치 7시
3. super
: 부모 클래스의 이름을 직접 적지 않고도 부모 클래스에 접근할 수 있다.
마치 우리가 부모님께 OO님 이라고 안하고 엄마! 라고 부르듯이 클래스에도 이러한 기능이 있습니다.
위에서 만들다만 BuildingUnit class를 마저 만들어 보겠습니다.
class BuildingUnit(Unit):
def __init__(self, name, hp, location):
Unit.__init__(self, name, hp, 0) # speed 0 : 건물은 지상 이동 불가
self.location = location
여기서는 부모 클래스인 Unit의 init을 불러왔는데 suepr()을 사용하면 아래와 같이 불러올 수 있습니다.
* 한 가지 주의할 점은, super을 사용할 때 변수로 self는 불러오지 않습니다!
class BuildingUnit(Unit):
def __init__(self, name, hp, location):
super().__init__(name, hp, 0) # 부모 클래스 접근. self 없이 사용
self.location = location
다만, suepr()을 사용해서 다중 상속을 원할 경우에는 순서상 맨 위에 클래스를 상속해온다.
그러므로 다중상속을 원할 시에는 각 부모 클래스의 이름을 명시해서 접근해야합니다.
4. 스타크래프트 전반전
: 지금까지 배운 것들을 활용하여 스타크래프트를 진행해보겠습니다. 우선 전반전에선 사용할 클래스들을 준비하고, 후반전에서 전투를 진행합니다.
첫번째로, 가장 기본이 되는 Unit class부터 정의해보겠습니다. 메소드로는 move와 damaged 를 만들겠습니다.
# 일반 유닛
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("[지상 유닛 이동]") # 출력문 제외
print("{0} : {1} 방향으로 이동합니다. [속도 {2}]"\
.format(self.name, location, self.speed))
def damaged(self, damage): # AttackUnit 에서 Unit 으로 이동
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,speed,hp)
self.damage = damage
def attack(self,location):
print(f"{self.name} : {location} 방향으로 적군을 공격 합니다. [공격력 {self.damage}]")
이제 공격 유닛들을 만들어볼 건데, 이전에는 공격유닛 클래스를 이용해 마린과 탱크를 만들었습니다. 그런데 이번에는 마린과 탱크의 고유 스킬들을 표현하고자 따로 클래스를 만들도록하겠습니다.
#마린
class Marine(AttackUnit):
#아카데미에서 개발해야 사용 가능하다.
stimpack_developed = False
def __init__(self):
AttackUnit.__init__(self,"마린",40,1,5)
#스팀팩 : 일정 시간 동안 이동 및 공격 속도를 증가, 체력 10 감소
def stimpack(self):
if Marine.stimpack_developed == False:
return
if self.hp > 10:
self.hp -=10
print(f"{self.name} : 스팀팩을 사용합니다. (HP 10 감소)")
else:
print(f"{self.name} : 체력이 부족하여 스팀팩을 사용하지 않습니다.")
우선 마린은 공격유닛 클래스를 상속받고, 스팀팩이라는 기능을 추가해줍니다(개발되지 않은 경우는 사용 불가). 스팀팩은 체력 10을 깎는 대신, 일정 시간동안 공격속도와 이동속도를 높여주는 스킬입니다. 그렇기 때문에 체력이 11이상일 때만 사용할 수 있고, 10이하인 경우는 체력이 부족하여 스팀팩을 사용할 수 없습니다.
다음으로 탱크 클래스를 만들건데 탱크는 무시무시한 위력을 자랑하는 시즈 모드를 추가해줄 겁니다.
#탱크
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(f"{self.name} : 시즈모드로 전환합니다.")
self.damage *=2
self.seize_mode = True
#현재 시즈모드일 때 -> 시즈모드 해제
else:
print(f"{self.name} : 시즈모드를 해제합니다..")
self.damage /=2
self.seize_mode = False
시즈모드는 위의 마린과 달리 on/off 개념입니다. 만약 시즈모드가 아닐 때 시즈모드를 가동하면, 공격력은 두배가 되고 seize_mode = True가 됩니다. 반대로 시즈모드가 아닐 때 시즈모드를 누르면, 공격력은 다시 1/2가 되고 seize_mode = False가 됩니다.
이제 지상 유닛들은 정의했으니 공중유닛들의 클래스를 만들도록 하겠습니다.
우선 공중유닛은 "날아야 하므로" flyable 클래스를 먼저 생성해줍니다.
#날 수 있는 기능을 가진 클래스
class Flyable:
def __init__(self,flying_speed):
self.flying_speed = flying_speed
def fly(self, name, location):
print(f"{name} : {location} 방향으로 날아갑니다. [속도 {self.flying_speed}]")
그 다음에는 공중 유닛중에 공격이 가능한 클래스를 생성해주겠습니다.
공격유닛 클래스와 위에서 생성한 flyable 클래스로부터 상속받은 후 move 함수만 재정의 해줍니다.
#공중 공격 유닛 클래스
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):
self.fly(self.name, location)
이젠 레이스 클래스를 만들어줄건데요. 레이스가 투명해져서 안보이게되는 클로킹 모드를 추가해줄 겁니다.
클로킹도 탱크의 시즈모드와 비슷하게 on/off 개념입니다. (아직 mp는 추가안했습니다)
# 레이스
class Wraith(FlyableAttackUnit):
def __init__(self):
FlyableAttackUnit.__init__(self,"레이스",80,20,5)
self.clocked = False #클로킹 모드 (해제 상태)
def clocking(self):
if self.clocked == True : #클로킹 모드 -> 모드 해제
print(f"{self.name} : 클로킹 모드 해제합니다.")
self.clocked == False
else: #클로킹 모드 해제 -> 모드 설정
print(f"{self.name} : 클로킹 모드 설정합니다.")
self.clocked == True
5. 스타크래프트 후반전
: 이제는 만들어 놓은 클래스들을 활용하여서 유닛들을 만들고 전투를 구현해보도록 하겠습니다.
우선 게임의 시작과 끝을 알리는 함수를 정의해줍니다.
def game_start():
print("[알림] 새로운 게임을 시작합니다.")
def game_over():
print("Player : gg") # good game
print("[Player] 님이 게임에서 퇴장하셨습니다.")
그 다음에 바로 게임을 진행해볼 건데요, 전체 코드와 출력값은 아래와 같습니다.
직접 한번씩 쳐보시면서 상상력을 동원해 게임한판 해보시길 추천드립니다.
#실제 게임 진행
game_start()
#마린 3기 생성
m1 = Marine()
m2 = Marine()
m3 = Marine()
#탱크 2기 생성
t1 = Tank()
t2 = Tank()
#레이스 1기 생성
w1 = Wraith()
#유닛 일괄 관리 (생성된 모든 유닛 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()
6. 퀴즈 : 부동산 프로그램 작성하기
Quiz) 주어진 코드를 활용하여 부동산 프로그램을 작성하시오. (출력 예제) 총 3대의 매물이 있습니다. 강남 아파트 매매 10억 2010년 마포 오피스텔 전세 5억 2007년 송파 빌라 월세 500/50 2000년 |
class House:
# 매물 초기화 : 위치, 건물 종류, 매물 종류, 가격, 준공년도
def __init__(self, location, house_type, deal_type, price, completion_year):
pass
# 매물 정보 표시
def show_detail(self):
pass
정답 코드
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 = []
house1 = House("강남","아파트","매매","10억","2010년")
house2 = House("마포","오피스텔","전세","5억","2007년")
house3 = House("송파","빌라","월세","500/50","2000년")
houses.append(house1)
houses.append(house2)
houses.append(house3)
print(f"총 {len(houses)}대의 매물이 있습니다.")
for house in houses:
house.show_detail()
'프로그래밍 공부 > Python' 카테고리의 다른 글
[파이썬 기초 6-1강] 클래스(클래스, init, 멤버변수, 메소드, 상속 & 다중 상속) (0) | 2021.04.26 |
---|---|
[Python] 타입 힌팅(Type Hinting) 이란? (0) | 2021.04.21 |
[파이썬 기초 5강] 입출력(표준입출력, 다양한 출력포맷, 파일입출력, pickle, with) + 업무자동화_ 보고서 50개 만들기 (0) | 2021.03.15 |
[파이썬 기초 4강] 함수(전달값과 반환값, 기본값 ,가변인자, 지역변수와 전역변수) + 성별 적정체중 예측 (0) | 2021.03.11 |
[파이썬 기초 3강] 제어문(if문, for문,while문, continue,break, 한줄for문 ) + cocoa 택시 매칭방법 (2) | 2021.02.18 |