요즘의 일반적인 스마트폰 게임들은 시간을 들이거나 약간의 돈을 써서 게임 머니를 얻습니다. 이렇게 얻은 게임 머니로 아이템을 뽑을 수 있죠. 운은 게임의 즐거움을 더해주는 장치가 됩니다. 물론 때로는 빡침으로 변하기도 하지만요.
브롤스타즈는 티켓이라는 게임 머니로 아이템 박스를 까는 시스템입니다. 박스를 까면 캐릭터, 젬, 코인 등이 나옵니다. 다들 희귀 캐릭터가 나오기만 바라고 있지만요. 오늘은 이렇게 박스를 까서 내 플레이어를 성장(?) 시키는 시스템을 구현해 보겠습니다.
우선은 여러개의 아이템 중 랜덤으로 하나가 선택되는 코드가 필요해 보입니다. 이럴 때 파이썬에서는 random 모듈을 사용합니다.
import random
모듈이란 다른 곳에서 사용할 파이선 함수가 작성되어 있는 파일 (또는 파일들)을 의미합니다. 파이썬에는 이렇게 우리 개발자들이 자주 구현해야 하는 함수들이 미리 작성되어 있습니다. 이를 스탠다드 라이브러리라고 부릅니다. 파이썬을 많은 곳에서 사용하는 이유 중 하나가 스탠다드 라이브러리가 풍부하고 잘 작성되어 있기 때문입니다.
이 파일이 컴퓨터 안 어디에 존재하는지 검사하려면 아래처럼 random을 출력해보면 됩니다.
print(random)
# <module 'random' from '/usr/lib/python3.7/random.py'>
제 컴퓨터에서는 /usr/lib/python3.7/random.py에 random 모듈이 정의되어 있는 것을 알 수 있습니다.
저는 리눅스를 사용하고 있어 여러분의 파일 경로와 조금 다를 수 있습니다.
모듈 안에 어떤 함수들이 존재하는지는 아래처럼 dir을 통해 알 수 있습니다.
print(dir(random))
제게 필요한 것은 리스트의 각 아이템 중 하나를 선택해주는 함수입니다. 출력된 함수들 중 choice 라는 함수가 저한테 맞을 것 같네요. help를 이용해 확인해 볼까요?
print(help(random.choice))
# ...
# Choose a random element from a non-empty sequence.
비어있지 않은 리스트에서 임의의 엘리먼트를 선택한다고 하네요. 제가 생각했던 함수가 맞는것 같습니다. 실제 코드를 이용해서 테스트 해보겠습니다.
boxes = ["a", "b", "c"]
print(random.choice(boxes))
# 'c'
print(random.choice(boxes))
# 'a'
print(random.choice(boxes))
# 'a'
print(random.choice(boxes))
# 'c'
print(random.choice(boxes))
# 'b'
print(random.choice(boxes))
# 'c'
print(random.choice(boxes))
# 'a'
원하던 결과네요. 다만 박스안에 그냥 문자열이 들어가 있다는게 조금 아쉽습니다. 아이템 박스에 더 가까운 구조였으면 좋겠는데요. 이럴 때 뭐가 생각나시나요? 맞습니다. 클래스죠.
class Box:
Type = ""
Value = None
Type에는 "char", "coin", "gem" 셋 중 하나의 값만 넣을 생각입니다. 각각 캐릭터, 코인, 보석이 들어있음을 의미하죠. Value는 캐릭터 타입일 때는 문자열, 코인이나 보석일 때는 숫자를 넣으려고 합니다. 그래도 되나구요? 네 그래도 됩니다. 좋은 코딩 스타일은 아닐수도 있지만 작성할 코드의 양을 줄이려는 저의 눈물나는 노력이라고 봐주세요. Value의 형식이 때에 따라 바뀐다는건 이제 계속 기억하고 계셔야 합니다. 또는 다음처럼 주석을 통해 계속 상기시키는 것도 방법입니다.
# Box를 열면 캐릭터, 코인, 보석 중 하나가 나온다.
class Box:
# Type은 캐릭터일 경우 "char", 코인일 경우 "coin", 보석일 경우 "gem"이다.
Type = ""
# Value는 캐릭터일 경우 문자열, 코인이나 보석일 경우 숫자 형식이다.
Value = None
박스 안에 쉘리라는 캐릭터가 들어있는 걸 표현해 볼까요?
b = Box()
b.Type = "char"
b.Value = "shelly"
또 30 코인이 들어있는 것은
b = Box()
b.Type = "coin"
b.Value = 30
, 보석 5개가 들어있는 것은
b = Box()
b.Type = "gem"
b.Value = 5
처럼 표현할 수 있겠군요.
매번 이렇게 세줄씩 쓰는 건 귀찮으니 NewBox라는 함수를 하나 만들겠습니다.
def NewBox(type, value):
b = Box()
b.Type = type
b.Value = value
return b
NewBox를 이용하면 아래처럼 간결하게 다시 작성할 수 있겠군요.
NewBox("char", "shelly")
NewBox("coin", 30)
NewBox("gem", 5)
이 아이템 박스들을 한데 담아 보겠습니다.
boxes = [NewBox("char", "shelly"), NewBox("coin", 30), NewBox("gem",5)]
음. 좋아요, 좋은데... 뽑기를 하기에는 박스 경우의 수가 너무 작네요. 조금만 더 작성해 볼까요?
boxes = [
# 캐릭터 박스
NewBox("char", "shelly"),
NewBox("char", "nita"),
NewBox("char", "colt"),
NewBox("char", "bull"),
# 코인 박스
NewBox("coin", 18),
NewBox("coin", 30),
NewBox("coin", 50),
# 보석 박스
NewBox("gem", 3),
NewBox("gem", 5),
]
이제 좀 뽑기 하는 맛이 나겠네요.
다음은 뽑기를 하는 주체를 설정할 차례입니다.
class Player:
Chars = []
Coin = 0
Gem = 0
p = Player()
아직 이 플레이어는 빈털터리입니다. 캐릭터도 없고 돈도 없고 보석도 없죠. 불쌍한 우리 플레이어에게 아이템 박스를 10번 깔 찬스를 추겠습니다.
for _ in range(10):
b = random.choice(boxes)
# 박스 타입을 검사해서 그 안의 값을 적절한 곳에 추가한다.
if b.Type == "char":
p.Chars.append(b.Value)
if b.Type == "coin":
p.Coin += b.Value
if b.Type == "gem":
p.Gem += b.Value
마지막으로 플레이어가 무엇을 얻었는지 출력을 해볼까요?
print(p.Chars)
print(p.Coin)
print(p.Gem)
여러번 실행을 해서 이 값이 매번 달라지는지도 확인해보세요. 완전하지는 않지만 오늘은 이 정도면 충분한 것 같습니다. 다음 시간에 조금 더 개선해 보도록 해요~ 바이!