본문 바로가기
파이썬

파이썬으로 주사위 게임(Dice 10000, Farkle) 만들기 (2)

by 수퍼스타 2021. 3. 23.

2021.01.17 - [파이썬] - 파이썬으로 주사위 게임(Dice 10000, Farkle) 만들기 (1)

 

지난 번 만들었던 코드를 바탕으로 계속 추가하려다 보니 약간의 문제가 있었다. 문제는 바로... 내 실력이었다. 여러 종류의 주사위를 적용한다거나(예를 들면 1이 잘 나오는 주사위라던가), 선택한 주사위에 룰을 적용해 점수를 얻고, 나머지 주사위는 다시 한 번 굴려서 더 높은 점수를 노리거나, 현재 얻은 점수만을 얻고 턴을 넘길 수 있는 게임의 형태로 만들기에는 내 수준에 꽤나 어려웠다. 하려고 한다면야 할 수야 있었겠지만 현재 실력에서 만든 코드는 너무 복잡해 나도 이해하기 힘들 정도였다.

 

그래서 주사위 6개의 값을 무작위로 얻고, 그 주사위를 대상으로 점수를 얻는 정도까지만 미리 만들어봤다. 먼저 주사위 6개를 던져 6개의 값을 얻는 건 random 라이브러리를 사용하면 되니 굉장히 쉬웠다. 다음 단계로는 앞에서 얻은 6개의 주사위 값을 1부터 6까지 갯수로 변환해서 새로운 리스트를 만들었다. 문제는 룰을 이용해 점수를 얻는 부분이었는데, 처음엔 모든 경우의 수를 다 만들어보려고 했다가 기본서를 통해 리스트 비교에도 부등호를 사용할 수 있다는 걸 알게 되었다. 그래서 리스트의 부등호 비교를 이용해서 문제를 해결했다.

 

다만 풀스트레이트(1부터 6까지 모두 1개씩)의 경우와 달리 하이스트레이트(2부터 6까지 모두 1개씩), 로우스트레이트(1부터 5까지 모두 1개씩)는 부등호만을 이용해서 구분해내기에는 문제가 있었다. 리스트 간 부등호를 이용해 비교할 때는 앞쪽 인덱스부터 비교하면서 리스트의 크기를 정한다. 하이스트레이트와 로우스트레이트는 5개의 주사위만 있으면 되기 때문에 내가 직접 주사위를 선택하는 것이 아니고 던져서 나온 6개의 주사위를 모두 사용하는 경우 new_list 의 값에 음수가 나오는 오류가 발생했다. 그래서 최소한 모든 눈의 값이 1개 이상일 때만 해당 룰이 적용되도록 and 조건을 하나씩 더 넣어서 해결하였다.

 

그렇게 가장 나오기 어려운 경우의 수 3개를 미리 정의해놓고 나오기 어려운 순서대로 룰을 적용해 점수를 누적해나가는 함수를 만들었다. 임의로 6개씩 주사위를 던져서 테스트 해본 결과 룰 적용과 점수 획득에는 문제가 없었다.

 

이제 다음 단계로는 앞에서 막혀서 포기했던 주사위의 종류를 적용하고, 일부 주사위만 선택해가며 점수를 얻어나가는 형태를 구현해봐야겠다.

 

import random

# 변수 정의
new_list = []
full_straight = [1, 1, 1, 1, 1, 1]
high_straight = [0, 1, 1, 1, 1, 1]
low_straight = [1, 1, 1, 1, 1, 0]

# 함수 정의
def get_new_list():
   
    # spots 에서 얻은 주사위 눈 1에서 6까지 숫자를 new_list 로 변환
    # 예) spots = [1, 2, 3, 4, 5, 6]
    #     new_list = [1, 1, 1, 1, 1, 1]

    for i in range(1, 7):
        new_list.append(spots.count(i))

    print()
    print("new_list = {}".format(new_list))

def scoring():

    # rule 을 적용하면서 점수를 얻을 수 있는 경우 get_score 에 누적
    # 가장 상위 룰부터 차례대로 적용
    
    get_score = 0

    if new_list == full_straight:
        get_score += 1500
        for i in range(0, 6):
            new_list[i] -= 1

    if new_list >= high_straight and new_list[1:6].count(0) < 1:
        get_score += 750
        for i in range(1, 6):
            new_list[i] -= 1

    if new_list >= low_straight and new_list[0:5].count(0) < 1:
        get_score += 500
        for i in range(0, 5):
            new_list[i] -= 1

    if new_list[0] >= 3:
        get_score += (1000 * (2 ** (new_list[0] - 3)))
        new_list[0] = 0

    for i in range(1, 6):
        if new_list[i] >= 3:
            get_score += ((i+1) * (100 * (2 ** (new_list[i] - 3))))
            new_list[i] = 0

    if new_list[0] >= 1:
        get_score += new_list[0] * 100
        new_list[0] = 0

    if new_list[4] >= 1:
        get_score += new_list[4] * 50
        new_list[4] = 0

    print()

    if get_score > 0:
        print("점수를 계산합니다.")
        print("{} 점을 얻습니다.".format(get_score))
    else:
        print("점수를 얻을 수 없습니다.")

    print()
    print("new_list = {}".format(new_list))

# 테스트
spots = [random.randint(1, 6) for i in range(6)]

print("spots :", spots)
get_new_list()
scoring()

댓글