loading
본문 바로가기
파이썬 테스트 [Python]

파이썬 턴제(Turn-based Strategy) 게임

by GSTGTS 2021. 12. 22.

파이썬 턴제(Turn-based Strategy) 게임

내배캠 슬랙에 보니까 '오늘 프로젝트 개같이 멸망'이라고 올리신 분이 계셨다.

나도 오늘 진짜 개같이 멸망할 뻔 했다.. 1주차부터 힘들었는데 오늘은 진짜 못해먹겠다는 생각까지 들었다. ㅜㅜㅜ

나도코딩님 강의를 보면서 class를 짜고나서, 잘하시는 팀원분에게 코드를 보여드리니, 85% 완성했다고 하셨다.

 

출처. 유튜브 나도코딩

 

?? 85% ??    한 10%한 거 같은데....?

 

이때 느꼈다..

 

아 .. 내가 함수와 반복문, 조건문 같은거 잘 못쓰지... ㅜㅜㅜㅜ

 

그냥 기초가 부족한거였다..

 

진짜 꾸역꾸역 짰는데, 내 지식으로는 도저히 해결하지 못하는 부분이 있어서 팀원분의 코드의 도움을 받았다.

 

조건:

Monster = 고블린, 미니고블린, 슈퍼고블린

고블린 : 공격력 30, HP 30

미니 고블린 : 공격력 10, HP 10

슈퍼 고블린 : 공격력 50, HP 50

 

Player  = 전사

전사 : 공격력 10, 마법공격력 50, HP 100

 

1. 선공은 랜덤하게 진행된다.

2. 전사는 자신의 턴에서 공격, 마법공격input을 통해 정한다. 한마리의 고블린을 랜덤하게 공격한다.

3. Monster 집단은 자신의 턴에서 3마리 고블린이 모두 행동한다. 행동은 공격, 대기, 회복 중 한가지를 랜덤하게 선택한다.

4. 전사의 HP가 0이 되면 패배!, 고블린 3마리의 HP가 모두 0이 되면 승리!

 

개인적으로 추가한 조건 있다면, 마법공격은 2회까지만 가능하게 제한을 걸어둔 것.

무제한으로 마법공격을 해버리면 대부분의 경우 전사가 이기기 때문이다.

import random

print( " ")
print("-------------------")
print("전투를 시작합니다.")
print("-------------------")
print( " ")

class Object:
    def __init__(self, name, hp, power):
        self.power = power
        self.name = name
        self.hp = hp
        
    def attack(self, damaged):
        damaged.hp -= self.power
        if damaged.hp <= 0:
            damaged.hp = 0
            print("{0}가 {1}을 죽였습니다.".format(self.name, damaged.name))
            
        else:
            print("{0}가 공격했고, {1}의 hp는 {2}만큼 남았습니다.".format(self.name, damaged.name, damaged.hp))
      
###################################################################################################################################      
          
class Monster(Object):
           
    def stand(self):
        print("{0}가 대기했습니다.".format(self.name))
        

    def heal(self):
        self.hp =+ 10
        print("{0}가 자신의 체력을 10만큼 회복시켰습니다.".format(self.name))
  
###################################################################################################################################      

class Player(Object):
                    
    def magic(self, damaged):
        damaged.hp -= 50
        if damaged.hp <= 0:
            damaged.hp = 0
            print("warrior가 마법공격으로 {0}을 죽였습니다.".format(damaged.name))
        else:
            print("warrior가 {0}을 마법공격했고, {0}의 hp는 {1}만큼 남았습니다.".format(damaged.name, damaged.hp))
        
###################################################################################################################################
    
    
## 게임 진행하기


goblin = Monster("goblin", 30, 30)
mini_goblin = Monster("mini_goblin", 10, 10)
super_goblin = Monster("super_goblin", 50, 50)
Goblins = [goblin, mini_goblin, super_goblin]

warrior_attack = ["공격", "마법공격"]
warrior = Player("warrior", 100, 10)
magic_count = 2
turn = random.randrange(0, 2) # 홀, 짝으로 턴 변경  
while True:
    
    if turn % 2 == 0:
        
          
            P_attack = input(f"공격 or 마법공격({str(magic_count)}회 남음):")
            
            m = random.choice(Goblins)
            
            
            if m in Goblins:
                
                 
                if P_attack == "공격":
                    
                    warrior.attack(m)
                    
                    
                elif magic_count > 0 and P_attack == '마법공격':
                            
                    warrior.magic(m)
                
                
                elif magic_count == 0 and P_attack == '마법공격':
                    while "마법공격":
                        print("더이상 마법공격을 할 수 없습니다.")
                        P_attack = input("공격만 가능합니다.")
                        
                        if P_attack == "공격":
                            break  
                    
                    
                else:   
                    while P_attack not in warrior_attack:
                        print("공격과 마법공격 중에 선택하세요.")
                        P_attack = input("공격 or 마법공격:")
                        
                        if P_attack in warrior_attack:
                            break

       
                if m.hp <= 0:
                    Goblins.remove(m)
   
                    
            if len(Goblins) == 0:
                print('승리')
                break
            
            
            if magic_count > 0:
                magic_count -= 1  
                
            else:
                magic_count == 0
                                              

    else:
            for m in Goblins:
                choice = random.randrange(0,3)
                if choice == 0:
                    m.attack(warrior)
                elif choice == 1:
                    m.heal()               
                else:
                    m.stand()
                    
            if warrior.hp <= 0:
                print('패배')
                break
    
    turn += 1

 

 

게임을 진행하는데 있어서 가장 고민 했던 부분.

어떻게 하면 고블린 3마리의 HP가 다 없어지는걸 확인하고 승리!를 외치지??

 

Goblins라는 리스트 안에 고블린 3마리를 넣어두고, hp가 0이 되는 고블린을 Goblins.remove()를 통해 날리고, list의 length가 0이 되면 승리!가 print되게 했다.

 

리스트에서 제거해나가라고 했는데 무슨 말인지 못알아들어서 코드를 보여주셨다.... 응용 응용 응용...

    if m.hp <= 0:
    Goblins.remove(m)

if len(Goblins) == 0:
print('승리')
break

 

 

혼자 해결했지만 오래 걸렸던 부분!

Goblins 리스트에서 random.choice()로 뽑힌 고블린을 한마리를 공격하고 싶은데,

고블린이 공격할 때와 다르게, for문을 쓰면 공격이 고블린 3마리에게 모두 들어가서 for문을 쓰지 않았다.

 


m = random.choice(Goblins)
if m in Goblins:
              
                
                if P_attack == "공격":
                    
                    warrior.attack(m)
      
                elif P_attack == "마법공격":
                    
                    warrior.attack(m)
                        
                else:
                    P_attack = input("공격 or 마법공격:")

 

 

그리고 Goblins 리스트의 요소들은 class의 객체라서 print해보면 이름이 나오는게 아니고, 아래처럼 출력된다.

<__main__.Monster object at 0x10eb27fd0>
<__main__.Monster object at 0x10eb27e20>
<__main__.Monster object at 0x10eb25db0>

 

따라서 전사나 고블린의 상태를 출력하기 위해서는 class안의 메소드(함수)에서 출력하는게 편리하다.

 

 

또 중요하게 알아둬야 할 것이 하나 있다.

Class의 속성의 주소가 바뀔 수 있어서 damaged.hp -= self.power와 같은 식이 가능하다는 것.

 

이와 관련된 내용은 우리 팀원분이 상세하게 적어놓으셨다.

뮤터블(mutable)객체와 이뮤터블(immutable)객체에 관한 내용과 얕은 복사와 깊은 복사에 관한 내용을 알고 있어야 이해하기 수월하다.

윤성우의 열혈 파이썬 중급편을 들으면 친절한 설명을 들을 수 있다.

 

세 번째 개인 과제 고블린 사냥

더보기 import random class Object(): def __init__(self, name, hp, power): self.name = name self.hp = hp self.power = power self.critic_damage = 10 self.amor = 0 self.miss = 0 def attack(self, enemy)..

taehyeki.tistory.com

반응형

댓글