코딩,해볼까

03.28. class 보충수업 및 과제 제출 본문

Back/TIL

03.28. class 보충수업 및 과제 제출

떠굥 2023. 3. 28. 21:38

 

0.  오늘 배운 것


class 보충수업

class 함수 과제에서 반복문 부분 추가 후 제출!

 

 

1. 문제점


class문법에 대한 이해가 부족하여 보충수업을 들었다.

while 문을 사용하는데 어려움이 있다.

 

 

2. 시행착오


1. 인벤토리 클래스를 생성하였다.

## 23.04.01 서경 인벤토리 클래스 시작 - 인벤토리 함수로 다시 만듦 

class Inventory(Player):
    def __init__(self):
        self.items = []
        
    def add_item(self, item):    
        if item in self.items:
            self.items[item] += 1
        else:
            self.items[item] = 1

        # 만약 아이템이 없다면 아이템을
        # 만약 아이템의 갯수가 하나 증가하면 value 의 숫자를 +1씩 증가시킨다.
        # 아이템값이 key 이름 :value 갯수 로 들어가야 할 듯

    # 아이템 사용 (사용 시 사라지는 아이템) > 전용 리무브 함수 짜야함
    def use_item(self, item_name):
        self.hp += item_name.hp
        self.mp += item_name.mp
        self.html += item_name.html
        self.javascript += item_name.javascript
        self.python += item_name.python

        # 사용시 사라지는 아이템은 일반적인 리무브 함수 실행하고
        # 사용시 장착되는 아이템은 장착해제를 했을 때 수량은 증가하고 
        # 올라가있던 경험치는 그만큼 내려와야한다. 그래서 리무브함수 두개여야할듯

    def remove_item(self, item):
        if self.items[item] > 1:
            self.items[item] -= 1
        else:
            self.items.remove(item)
        # 아이템을 사용한다면 value의 숫자를 -1씩 감소시킨다
        # 아이템의 벨류 == 0 아이템을 지운다.

        # 아이템 장착/ 장착해제
        # def equip_item(self, item_name):
        #     self.html += item_name.html
        #     self.javascript += item_name.javascript
        #     self.python += item_name.python

    def unequip_item(self, item_name):
        self.html -= item_name.html
        self.javascript -= item_name.javascript
        self.python -= item_name.python


    def view_items(self):
        for item in self.items:
            print(f'{item.name}: {item.quantity}')

 

 

2. 아이템과 관련된 모든 함수를 action으로 가져가서 함수로 만들기로 결정.

        if target.hp == 0:
            print(f"{target.id}이(가) 쓰러졌습니다.")
            target.drop_item(self)  # 몬스터가 죽으면 드랍
            
            
# drop_item 함수를 Inventory 클래스로 이동
    def drop_item(self, player):  # 몬스터가 죽으면 드랍 아이템 , 확률
        items = [redportion, blueportion, hongongpa, mouse, keyboard, macbook, chatgpt]  # 드랍 아이템 종류
        probabilities = [0.3, 0.3, 0.2, 0.09, 0.05, 0.05, 0.01] # 드랍 확률
   
        for i in range(len(items)):
            if random.random() < probabilities[i]:
                item = items[i]
                if item in items:
                    print(f"{player.id}이(가) {item.name}을(를) 획득하였습니다.")
                if item in [redportion, blueportion]:
                    print(f"{player.id}이(가) {item.name}을(를) 획득하였습니다.")
                    player.self.items(item)
                    print(f"{player.id}이(가) HP를 {item.hp}만큼 / MP를 {item.mp}만큼 회복시켰습니다.")
                else:
                    print(f"{player.id}이(가) {item.name}을(를) 획득하여. 장착했습니다")
                    player.self.items(item)
                    print(f"html: {item.html} / javascript: {item.javascript} / python: {item.python} 만큼 증가했습니다.")

 

 

3. 을 했다가 문득, target.hp == 0  ~ 함수를 action 으로 이식하면 아이템 인벤토리를 만들어도 문제가 없겠다고 생각되어 방향을 돌렸다. 인벤토리 클래스를 만들어 add_item을 drop_item으로 바꾸고(하는 일은 동일하다고 보면 된다.) action의 함수 안에 넣어주었다.

 

# 몬스터 리스트 제거 함수(반복문으로 간략화 가능해 보임)
def monster_death(monsters_list, player):  
    for m in monsters_list:
        if m.hp <= 0:
            print(f"{m.id}이(가) 쓰러졌습니다.")
            monsters_list.remove(m)
            player.gain_exp(m.get_exp())
            inventory.drop_item(p1)

 

            elif action_select == 3:
                print("=========인벤토리=========")
                print(inventory.view_items())

 

UnboundLocalError: local variable 'item' referenced before assignment

 

- 파이썬에서 외부에 선언한 변수를 함수속에서 호출하고자 할때 아래와 같은 오류가나는 경우가 있다고 한다. 위 에러는 전역변수를 지역 변수로 호출했기 때문에 발생하며 간단하게 함수 내부에 global '변수명' 을 추가하면 해결된다고 하는데... 이게 무슨 뜻이지..?

 

 

 

3. input을 2번 사용하여 if 와 elif를 적었을 때 오류가 발생했다.

 

        if input() == '1':
            P.attack(M)
        elif input() == '2':
            P.magic_attack(M)
        else:
            print("잘못 입력하셨습니다.")

 

 

4. while 문을 작성할 때, 정확하게 반복이 되어야 하는 부분을 몰라서 위치 순서를 잡는 것이 어려웠다. 

 

  • 순서를 맞춰서 출력하기 위해 아래와 같이 순서를 미리 생각하며 글로 정리하였다.
  • 글에 맞춰서 순서대로 함수를 구현하였다.
  • 순서가 맞지 않는다면 수정하고 추가해나갔다.

 

 

    # 이름입력
    # 떠경 캐릭터가 생성되었습니다.
    # 앗! 야생의 세히몬이 나타났다!
    # status + 세히몬 상태 출력
    # 떠경 상태 출력
    # 1. 일반공격, 2. 마법공격 고르고 이외숫자는 다시 입력해주세요
    # 1. 공격!

    # 2. 마법공격!
    # 플레이어가 몬스터에게 피해를 줬다. 세히몬의 체력이 얼마 남았습니다.
    # 세히몬이 일반공격! 몬스터가 플레이어에게 얼마 피해를 줬따.
    # 떠경이의 체력이 얼마 남았습니다.
    # status로 돌아간다
    # action = input()

 

 

4. mp가 0이 되면 공격방식을 재선택 하도록 하고싶은데 그냥 넘어가버리는 오류가 있었다.

 

 

5. hp가 0이 되어도 종료가 되지 않는 문제, 게임을 끝낼 수 있는 방법에 대해 고민했다.

try except 문 :

while 문 : continue, break

if 문 : return

 

 

6. 내용들이 시간에 맞춰서 한 줄 한 줄 출력되게 하고 싶어서 여러가지 함수를 찾아봤다.

 

 

3. 해결방법


1. 클래스를 가지고 객체를 생성할 때 변수 = 클래스(매게변수) 로 생성하였다.

 

# 인스턴스(객체) = 클래스
player = Character(input("이름을 입력하세요 : "), 1000, 200, 10, 10)
monster = Character("세히몬", 100, 0, 10, 0)

** player, monster 는 객체. 이 객채들은 Character 의 인스턴스.

 

 

2. choice라는 변수명에 input 함수를 집어넣어서 사용하였다.

 

 choice = input()
        if choice == '1':
            P.attack(M)
        elif choice == '2':
            P.magic_attack(M)
        else:
            print("잘못 입력하셨습니다.")

 

 

3. mp를 담당하는 magic_attack 부분에 몬스터가 쓰러지게 된다면 return을 넣어주어 게임이 끝나도록 했다.

 

 

4. hp == 0이면 쓰러졌습니다. 문구를 출력하고 return을 넣어 구문이 끝나도록 해봤다.

 

 

5. 반복이 되어야 하는 부분만을 while 문에 넣고, while문 안에 if문을 넣어 break와 continue를 사용할 수 있도록 했다.

 

 

6. import time 기능을 통해 만들었다.

 

  • print() 를 아래 함수로 감싸주었다. ment1(print()) 

 

def ment1(a):
    time.sleep(1)
    return a
    
def ment2(b):
    time.sleep(2)
    return b


def ment3(c):
    time.sleep(3)
    return c

 

 

 

4. 알게된 점


1. other.hp가 max( ~ , 0) 이 된 이유는 마이너스가 되도록 하지 않기 위함이 맞았다!

 

other.hp = max(other.hp - damage, 0)

 

 

2. 아직 해결하지 못한 부분이 있다. 이렇게 attack 함수를  같은 if문으로 감싸주지 않으면 0이 되더라도 꼭 ment1과 monster.attack 을 실행하기 때문이다..  이 부분은 내일 튜터님께 여쭤보거나 내 힘으로 한번 더 풀어보고나서 방법을 적으려고 한다.

 

 if player.hp == 0:
        ment1(print(f"플레이어 {P.name}의 체력이 0 이 되었다.\n 세히몬의 승리!"))
        break
    elif M.hp == 0:
        ment1(print(f"세히몬의 체력이 0 이 되었다. 플레이어 {P.name}의 승리!"))
        break

    ment1(print(f"세히몬이 떽떽거리기!! 를 시전합니다.\n"))
    monster.attack(player)

    if player.hp == 0:
        ment1(print(f"플레이어 {P.name}의 체력이 0 이 되었다.\n 세히몬의 승리!"))
        break
    elif monster.hp == 0:
        ment1(print(f"세히몬의 체력이 0 이 되었다. 플레이어 {P.name}의 승리!"))
        break

 

 

 

 

Comments