-
[파이썬/Python] 텍스트 RPG(4): 슈슉 슉 고라니 전투깜빡의 취미/파이썬을 합니다. 2021. 10. 10. 23:55728x90
# 출력 화면은 모두 Pycharm을 이용했습니다.
이 글이 완료될 즈음 여러분은 가장 기초적인 형태의 턴제 RPG를 만들어볼 수 있을 것이다. 물론 가장 기초적인 형태라 실제 그래픽 구현 등은
거의되어 있지 않다. 그래도 파이썬으로 무언가 해보고 싶은데 무엇부터 해야 할지 모르겠어 막막한 초심자라면, 한 번쯤 도전해볼 만하다.지난 시간에는 스텟 분배에 관하여 짧게 다루어 보았다.
이번 시간에는 게임을 보다 다채롭게 해 줄, 두 번째 전투를 소개한다.
턴이 제한된 게임
말 그대로다. 주인공(플레이어)은 특정 턴 내에 적을 물리쳐야 한다. 먼저 빠르게 기본 세팅부터 시작하자.
체력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("도망에 실패했다!!!")
멘트를 제외하고는 앞서 제시한 첫 번째 전투의 플레이어 행동 패턴과 동일하니, 참고.
적의 패배
적이 패배하기 위해서는, 지정된 턴이 다 끝나기 전에 체력을 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 = 0turn 변수를 설정해 두었고, 전투를 원점으로 돌리려면 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
저 포함 두 명이서 식을 짜고 고민하면서 알아낸 사실들, 그리고 그렇게 해서 나온 결과물을 최대한 자세하게 설명드리고 싶었습니다. 이번에도 분량 조절에 실패해 버렸네요...ㅎㅎ 이 글을 통해 조금이나마 기초 개념의 사용 선택지를 늘려 가신다면 좋겠습니다. 방문 감사합니다~ 구독 공감도 감사히 받고 있습니다!(꾸벅)
반복적으로 등장하는 개념들은 백준 단계별로 풀어보기나 파이썬 기초에도 많이 사용되는 것들이니, 복습하신다는 마음으로 한 번씩 검토해 보시면 좋겠습니다. 시간이 지나면서 기존에 설명드렸던 내용은 조금씩 빼놓고 글을 써 내려갈 수 있는데, 혹시 불친절한 방식이라고 느껴진다면 주저 없이! 댓글 남겨주세요~ 다시 한번 들러주셔서 감사합니다!
'깜빡의 취미 > 파이썬을 합니다.' 카테고리의 다른 글
[파이썬/Python] 텍스트 RPG(5): 전투3 - 엑조디아식 전투 (2) 2021.10.17 [파이썬/Python] 텍스트 RPG(3): 스텟 분배 (2) 2021.10.03 [파이썬/Python] 텍스트 RPG(2): 튜토리얼(= 첫 전투) (4) 2021.09.26 [파이썬/Python] 텍스트 RPG(1): 이름, 기본 스텟 (0) 2021.09.19 [파이썬/Python] 백준 8393번(합) 단계별로 풀어보기 + ['+=' 에 관한 조금 더 자세한 설명] (2) 2021.09.12