# 스타크레프트 전반전
개별 유닛별 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대의 매물이 있습니다.
'''
유튜버 '나도코딩' 님의 영상을 보며 공부 및 노트 작성합니다.
함께 공부해 나가실 분은
[Python 파이썬 독학 9-1일차] (0) | 2020.10.07 |
---|---|
[Python 파이썬 독학 8일차] (0) | 2020.10.04 |
[Python 파이썬 독학 7-2일차] (0) | 2020.09.28 |
[Python 파이썬 독학 7-1일차] (0) | 2020.09.28 |
[Python 파이썬 독학 자가 점검] (0) | 2020.09.26 |
댓글 영역