ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [파이썬/Python] 텍스트 RPG(4): 슈슉 슉 고라니 전투
    깜빡의 취미/파이썬을 합니다. 2021. 10. 10. 23:55
    728x90

    # 출력 화면은 모두 Pycharm을 이용했습니다.

    블록블록님의 멋진 고라니 그림. 실제 게임에 들어갔다.

    이 글이 완료될 즈음 여러분은 가장 기초적인 형태의 턴제 RPG를 만들어볼 수 있을 것이다. 물론 가장 기초적인 형태라 실제 그래픽 구현 등은 거의 되어 있지 않다. 그래도 파이썬으로 무언가 해보고 싶은데 무엇부터 해야 할지 모르겠어 막막한 초심자라면, 한 번쯤 도전해볼 만하다.

     

    지난 시간에는 스텟 분배에 관하여 짧게 다루어 보았다.

     

    [파이썬/Python] 텍스트 RPG(3): 스텟 분배

    # 출력 화면은 모두 Pycharm을 이용했습니다. 이 글이 완료될 즈음 여러분은 가장 기초적인 형태의 턴제 RPG를 만들어볼 수 있을 것이다. 물론 가장 기초적인 형태라 실제 그래픽 구현 등은 거의 되

    ccamppak.tistory.com

     

    이번 시간에는 게임을 보다 다채롭게 해 줄, 두 번째 전투를 소개한다.


    턴이 제한된 게임

    말 그대로다. 주인공(플레이어)은 특정 턴 내에  적을 물리쳐야 한다. 먼저 빠르게 기본 세팅부터 시작하자.

    체력1 = 체력
    print(f"삽을 치켜든 {나}와, 3대 800은 칠 것 같은 순한 외모의 고라니와의 전투!")
    적체력 = 100
    print(f"상대방의 체력 {적체력}")
    적방어력 = 0
    적공격력 = 0
    적기 = 0
    적정신력 = 20
    turn = 0

    체력1이라는 저장소를 이용해 전투 직전의 체력 수치를 저장해 두자. 적의 스텟을 설정해 주고, 이 게임은 턴 수가 정해져 있으므로 turn이라는 요소를 도입해 준다.


    플레이어의 공격 패턴

    우선 플레이어의 패턴을 살펴보자.

    while 1:
        print(f"\n{나}의 턴!!!!")
        time.sleep(1)
        N = input("q)공격 w)방어 e)스킬 r)도망간다\n")
        if N == "q":
            print(f"삽을 치켜 든 {나}, 후려쳤다.")
            공격력1 = random.choice([1, 2, 3, 5, 8]) + 공격력
            if 공격력1 - 적방어력 <= 0:
                print("공격은 완전히 복부로 흡수돼 방어됐다...")
                적방어력 -= 공격력1
            else:
                적체력 -= (공격력1 - 방어력)
                print(f"상대방의 남은 체력 = {적체력}")
                적방어력 = 0
        elif N == "w":
            방어력 += 5 + 정신력
            print(f'{나}은 덜 아프게 맞을 자세를 취했다 방어도가 {방어력}가 되었다')
        elif N == "e":
            기 += 1
            print("기~")
            if 기 == 2:
                print(f"방독면 속에 왠지 모르게 들어 있던 쇠구슬을 던진 {나}. 큰 피해를 줬다!")
                적체력 -= 정신력 + random.choice([10, 15, 20, 25, 30])
                print(f"상대방의 남은 체력 = {적체력}")
                기 = 0
        elif N == "r":
            escape = random.random()
            if escape < 운/10:
                print(f"{나}는 군인의 본분을 져버리고 도망갔다... \n무언가 업보가 쌓이는 듯한 느낌이 든다...")
                도주 += 1
                break
            else:
                print("도망에 실패했다!!!")

    멘트를 제외하고는 앞서 제시한 첫 번째 전투의 플레이어 행동 패턴과 동일하니, 참고.

     

    [파이썬/Python] 텍스트 RPG(2): 튜토리얼(= 첫 전투)

    # 출력 화면은 모두 Pycharm을 이용했습니다. 이 글이 완료될 즈음 여러분은 가장 기초적인 형태의 턴제 RPG를 만들어볼 수 있을 것이다. 물론 가장 기초적인 형태라 실제 그래픽 구현 등은 거의 되

    ccamppak.tistory.com


    적의 패배

    적이 패배하기 위해서는, 지정된 턴이 다 끝나기 전에 체력을 0 미만으로 깎아야 한다.

        if 적체력 <= 0:
            print(f"{나}: 성공했나?")
            break

    턴 수가 지나 패배했을 경우

    적은 턴을 시작하며 아까 설정해 둔 turn이라는 변수를 1씩 올린다. 만일 이 단계에서 turn이 10보다 클 경우(10턴이 지났을 경우), 자동으로 플레이어의 패배가 선언된다.

        print("\n상대의 턴!!!")
        turn += 1
        print(f"{turn}번째 차례가 되었다. 분발하도록.")
        if turn >= 10:
            print("끝내지 못하다니, 더 이상 고라니의 힘을 감당할 수 없다.\n눈앞이 깜깜해졌다.\n\ntip: 공격공격공격공격")
            Count = input("다시 하시겠습니까? q: 다시 한다. w: 다시 한다. e: 다시 한다.\n... ")
            if Count != "블록블록님감사합니다.":
                t = 4
                while t >= 1:
                    t = t - 1
                    time.sleep(1)
                    print(f"로딩까지 {t}초")
                    turn = 0
                    체력 = 체력1
                    적체력 = 100
                    방어력 = 0
                    적방어력 = 0
            continue
        time.sleep(1)

     

    복잡하게 생각하지 말자. 세이브포인트를 따로 만들지 않았기 때문에, 차선책으로 게임에서 지게 되면 다시 시작할 수 있도록 설정해 두었다. 지난 글에서도 설명했지만, 로딩 시간을 생성하고 전투를 원점으로 돌리는 코드는 아래와 같다.
            if Count != "블록블록님감사합니다.":
                t = 4

    변수 t는 남은 시간이다.
                while t >= 1:
                    t = t - 1
                    time.sleep(1)
                    print(f"로딩까지 {t}초")

    t가 하나 줄어들면 1초가 지나고 멘트가 출력 → 다시 t가 줄어들고 1초가 지나고 멘트가 출력되는 식이다. 
                    turn = 0

    turn 변수를 설정해 두었고, 전투를 원점으로 돌리려면 turn도 0으로 만들어 주어야 한다.
                    체력 = 체력1
                    적체력 = 100
                    방어력 = 0
                    적방어력 = 0
            continue
        time.sleep(1)


    적의 행동 패턴

    이제 마지막으로 적 고라니의 행동 패턴을 알아볼 차례이다. 

        N = random.randrange(1, 4)
        if N == 1:
            print(f"고라니는 째려봤다. \n 고라니: (째릿) \n {나}: 어쩌라고. 내 뒤에 계신 분이 더 무섭다구...")
        elif N == 2:
            적방어력 += 5 + 적정신력
            print(f'상대는 덜 아프게 맞을 자세를 취했다 방어도가 {적방어력}가 되었다')
            print(f"{나}의 공격!")
        elif N == 3:
            적기 += 1
            print("고라니가 포효를 모으고 있다")
            if 적기 == 2:
                print("고라니의 괴횕뢱ㅇ괴힉욒기 정신이 혼미해진다")
                turn += 1
                print(f"{나}는 기절했다. 정신을 차리고 보니 어느새 한 턴이 지나 있다... \n 지난 턴 = {turn}")
                적기 = 0

        N = random.randrange(1, 4)

    random.randrange(a,b)는 a 이상 b 미만의 숫자 중 하나를 랜덤으로 선택한다.
        if N == 1:
            print(f"고라니는 째려봤다. \n 고라니: (째릿) \n {나}: 어쩌라고. 내 뒤에 계신 분이 더 무섭다구...")

    고라니에게는 공격 기술이 없다. 대신 시간을 끄는 데 특화되어 있다. 코드 간의 통일성을 지키기 위해 재미있는(?) 멘트를 대신 적었다.
        elif N == 2:
            적방어력 += 5 + 적정신력
            print(f'상대는 덜 아프게 맞을 자세를 취했다 방어도가 {적방어력}가 되었다')
            print(f"{나}의 공격!")

    방어를 선택했을 경우 앞선 플레이어의 행동 패턴 1번(공격)의 코드에 영향을 미친다. 방어력이 크면, 받는 대미지가 줄어든다.
        elif N == 3:
            적기 += 1
            print("고라니가 포효를 모으고 있다")
            if 적기 == 2:
                print("고라니의 괴횕뢱ㅇ괴힉욒기 정신이 혼미해진다")
                turn += 1
                print(f"{나}는 기절했다. 정신을 차리고 보니 어느새 한 턴이 지나 있다... \n 지난 턴 = {turn}")
                적기 = 0

    고라니가 기술을 사용하면 한 턴을 추가로 소모하도록 했다. 플레이어의 턴 수를 줄여질 확률을 높이게 된다.


    이 식이 끝나면

    전투가 끝나면 바로 전 시간에 올렸던 스텟 배분 식을 이용하면 된다. 자연스럽게 다음으로 이어질 수 있다. 

     

    마지막으로 실제 작동 예시, 그리고 앞서 정리했던 모든 식을 정리해 본다.

    import random
    import time
    print("당신의 이름을 선택하세요.")
    나 = input()
    # 전투 시 실제로 적용되는 요소들
    기초체력 = 75
    방어력 = 0
    공격력 = 0
    # 전투력: 공격력, 체력 상승 / 정신력: 방어력, 스킬 강해짐 / 운: 도주 확률 증가
    전투력 = 0
    정신력 = 0
    운 = 0
    
    # 기: 스킬을 위해 필요 / 도주: 보스를 위한 숨겨진 요소
    기 = 0
    도주 = 0
    
    while 1:
        전투력 = random.randrange(5, 11)
        체력 = 기초체력 + 전투력*1
        공격력 = 전투력
        정신력 = random.randrange(1, 6)
        운 = random.randrange(1, 6)
        print(f"전투력 = {전투력}, 국방력= {정신력}, 열외력={운}")
        print("다시 하겠습니까: a = 네, b = 아니오")
        A = input()
        if A == "a":
            continue
        if A == "b":
            print("\n정말 결정하셨습까?: a = 네, b = 아니오")
            B = input()
            if B == "b":
                continue
            elif B == "a":
                print("\n결정되었습니다.")
                print(f"""
            [스테이터스]
            이름 = {나}
            직업 = 훈련병
            체력=  {체력}
            전투력 = {전투력}
            국방력 = {정신력}
            열외력 = {운}""")
                break
    
    input(f"\n{나}: 뭐야? 왜 이렇게 조용해?")
    input(f"\n거울 속의 {나}: 뭐긴, 시작한 거지. 이번엔 이런 몸인가? 슬슬 나가자 좀.")
    input(f"\n{나}: 거울 속에서 말이? 아니 그럼 훈련병 괴담이 전부 사실이었단 말이야?")
    input(f"\n거울 속의 {나}: 뭐... 그건 잘 모르겠고. 일단 좀 맞자.")
    input(f"\n{나}: ???")
    
    적체력 = 50
    적방어력 = 0
    적공격력 = 7
    적기 = 0
    적정신력 = 0
    print(f"거울 속 {나}의 체력: {적체력}")
    체력1 = 체력
    
    while 1:
        #주인공의 행동 패턴
        print(f"\n{나}의 턴!!!!")
        time.sleep(1)
        N = input("q)공격 w)방어 e)스킬 r)도망간다\n")
        if N == "q":
            print(f"{나}은/는 잽을 두 번 날렸다.")
            공격력1 = 공격력 + random.choice([1, 2, 3, 5, 8])
            if 공격력1 - 적방어력 <= 0:
                print("공격은 완전히 복부로 흡수돼 방어됐다...")
                적방어력 -= 공격력1
            else:
                적체력 -= (공격력1 - 적방어력)
                print(f"상대방의 남은 체력 = {적체력}")
                적방어력 = 0
        elif N == "w":
            방어력 += 5 + 정신력
            print(f'{나}은 덜 아프게 맞을 자세를 취했다 방어도가 {방어력}가 되었다')
        elif N == "e":
            기 += 1
            print("기~")
            if 기 == 2:
                print(f"{나}의 어퍼컷!")
                적체력 -= 정신력 + random.choice([10, 15, 20, 25, 30])
                print(f"상대방의 남은 체력 = {적체력}")
                기 = 0
        elif N == "r":
            escape = random.random()
            if escape < 운/10:
                print(f"{나}는 군인의 본분을 져버리고 도망갔다... \n무언가 업보가 쌓이는 듯한 느낌이 든다...")
                도주 += 1
                break
            else:
                print("도망에 실패했다!!!")
        if 적체력 <= 0:
            print(f"거울 속의 {나}: 쳇, 이번에도 글렀나.")
            break
    
        #적의 행동 패턴
        N = random.randrange(1, 4)
        print("\n상대의 턴!!!")
        time.sleep(1)
        if N == 1:
            적공격력1 = 적공격력 + random.choice([1, 2, 3, 5, 8])
            if 적공격력1 - 방어력 <= 0:
                print("공격은 완전히 복부로 흡수돼 방어됐따 ^^7")
                방어력 -= 적공격력1
            else:
                print("상대는 잽을 두 번 날렸다.")
                체력 -= (적공격력1 - 방어력)
                print(f"{나}의 남은 체력 = {체력}")
                방어력 = 0
        elif N == 2:
            적방어력 += 5 + 적정신력
            print(f'상대는 덜 아프게 맞을 자세를 취했다 방어도가 {적방어력}가 되었다')
        elif N == 3:
            적기 += 1
            print("기~")
            if 적기 == 2:
                print("상대의 어퍼컷!")
                체력 -= 적정신력 + random.choice([10, 15, 20, 25, 30])
                print(f"{나}의 남은 체력 = {체력}")
                적기 = 0
        if 체력 <= 0:
            print("눈앞이 깜깜해졌다")
            print("\ntip: 이걸 지다니... 지나가던 개(발자)가 웃겠다.")
            Count = input("다시 하시겠습니까? q: 다시 한다. w: 다시 한다. e: 다시 한다.\n... ")
            if Count != "이걸맞추면당신은천재":
                t = 4
                while t >= 1:
                    t = t - 1
                    time.sleep(1)
                    print(f"로딩까지 {t}초")
                    체력 = 체력1
                    적체력 = 50
                    적방어력 = 0
                    방어력 = 0
                    continue
    
    체력 = 체력1
    방어력 = 0
    스킬포인트 = 3
    while 스킬포인트 > 0:
        print('\n하나 고르시오. q: 전투력 (공격력 상승 / 체력 상승) w: 국방력 (방어력 상승 / 스킬 상승) e: 열외력 (도주 확률 증가)')
        N = input('당신의 선택은? ...   ')
        if N == "q":
            전투력1 = 전투력
            체력1 = 체력
            전투력 += random.choice([1,2,3])
            공격력 = 전투력
            체력 += (전투력 - 전투력1)*5
            print(f"\n전투력이 {전투력 - 전투력1} 만큼 올라 {전투력}(이/가) 되었다. 체력이 {체력 - 체력1}만큼 올라 {체력}(이/가) 되었다.")
            스킬포인트 -= 1
        elif N == "w":
            정신력1 = 정신력
            정신력 += random.choice([1,2,3])
            print(f"\n국방력이 {정신력 - 정신력1} 만큼 올라 {정신력}(이/가) 되었다.")
            스킬포인트 -= 1
        elif N == "e":
            운1 = 운
            운 += random.choice([1,2,3])
            print(f"\n열외력이 {운 - 운1} 만큼 올라 {운}(이/가) 되었다.")
            스킬포인트 -= 1
    
    print("고라니: 꾸엥에에에에ㅔ에ㅔ엑")
    input(f"\n{나}: 저건 또 뭐야.")
    input("\n고라니: 꿰에에에에엑...에에엑...엑...에에엑...")
    input(f"\n{나}: 뭐야 왜 고라니가 두 발로 서? 어? 어?")
    input("\n고라니: 열 턴. 그 안에 슈슉 슉 날 슈슉 쓰러뜨리지 슉 못하면 넌 슉 슈슉 슈슈슉 죽는다.")
    input(f"\n{나}: 이젠 모르겠다. 덤벼.")
    
    # [적2] 고라니
    체력1 = 체력
    print(f"삽을 치켜든 {나}와, 3대 800은 칠 것 같은 순한 외모의 고라니와의 전투!")
    적체력 = 100
    print(f"상대방의 체력 {적체력}")
    적방어력 = 0
    적공격력 = 0
    적기 = 0
    적정신력 = 20
    turn = 0
    
    while 1:
        print(f"\n{나}의 턴!!!!")
        time.sleep(1)
        N = input("q)공격 w)방어 e)스킬 r)도망간다\n")
        if N == "q":
            print(f"삽을 치켜 든 {나}, 후려쳤다.")
            공격력1 = random.choice([1, 2, 3, 5, 8]) + 공격력
            if 공격력1 - 적방어력 <= 0:
                print("공격은 완전히 복부로 흡수돼 방어됐다...")
                적방어력 -= 공격력1
            else:
                적체력 -= (공격력1 - 방어력)
                print(f"상대방의 남은 체력 = {적체력}")
                적방어력 = 0
        elif N == "w":
            방어력 += 5 + 정신력
            print(f'{나}은 덜 아프게 맞을 자세를 취했다 방어도가 {방어력}가 되었다')
        elif N == "e":
            기 += 1
            print("기~")
            if 기 == 2:
                print(f"방독면 속에 왠지 모르게 들어 있던 쇠구슬을 던진 {나}. 큰 피해를 줬다!")
                적체력 -= 정신력 + random.choice([10, 15, 20, 25, 30])
                print(f"상대방의 남은 체력 = {적체력}")
                기 = 0
        elif N == "r":
            escape = random.random()
            if escape < 운/10:
                print(f"{나}는 군인의 본분을 져버리고 도망갔다... \n무언가 업보가 쌓이는 듯한 느낌이 든다...")
                도주 += 1
                break
            else:
                print("도망에 실패했다!!!")
    
        #상대의 공격 패턴
        if 적체력 <= 0:
            print(f"{나}: 성공했나?")
            break
        print("\n상대의 턴!!!")
        turn += 1
        print(f"{turn}번째 차례가 되었다. 분발하도록.")
        if turn >= 10:
            print("끝내지 못하다니, 더 이상 고라니의 힘을 감당할 수 없다.\n눈앞이 깜깜해졌다.\n\ntip: 공격공격공격공격")
            Count = input("다시 하시겠습니까? q: 다시 한다. w: 다시 한다. e: 다시 한다.\n... ")
            if Count != "블록블록님감사합니다.":
                t = 4
                while t >= 1:
                    t = t - 1
                    time.sleep(1)
                    print(f"로딩까지 {t}초")
                    turn = 0
                    체력 = 체력1
                    적체력 = 100
                    방어력 = 0
                    적방어력 = 0
            continue
        time.sleep(1)
        N = random.randrange(1, 4)
        if N == 1:
            print(f"고라니는 째려봤다. \n 고라니: (째릿) \n {나}: 어쩌라고. 내 뒤에 계신 분이 더 무섭다구...")
        elif N == 2:
            적방어력 += 5 + 적정신력
            print(f'상대는 덜 아프게 맞을 자세를 취했다 방어도가 {적방어력}가 되었다')
            print(f"{나}의 공격!")
        elif N == 3:
            적기 += 1
            print("고라니가 포효를 모으고 있다")
            if 적기 == 2:
                print("고라니의 괴횕뢱ㅇ괴힉욒기 정신이 혼미해진다")
                turn += 1
                print(f"{나}는 기절했다. 정신을 차리고 보니 어느새 한 턴이 지나 있다... \n 지난 턴 = {turn}")
                적기 = 0

    저 포함 두 명이서 식을 짜고 고민하면서 알아낸 사실들, 그리고 그렇게 해서 나온 결과물을 최대한 자세하게 설명드리고 싶었습니다. 이번에도 분량 조절에 실패해 버렸네요...ㅎㅎ 이 글을 통해 조금이나마 기초 개념의 사용 선택지를 늘려 가신다면 좋겠습니다. 방문 감사합니다~ 구독 공감도 감사히 받고 있습니다!(꾸벅) 

     

    반복적으로 등장하는 개념들은 백준 단계별로 풀어보기나 파이썬 기초에도 많이 사용되는 것들이니, 복습하신다는 마음으로 한 번씩 검토해 보시면 좋겠습니다. 시간이 지나면서 기존에 설명드렸던 내용은 조금씩 빼놓고 글을 써 내려갈 수 있는데, 혹시 불친절한 방식이라고 느껴진다면 주저 없이! 댓글 남겨주세요~ 다시 한번 들러주셔서 감사합니다!

    댓글

Designed by Tistory.