Python project for beginners : Dice Rolling Simulator

GYUBIN ·2021년 9월 23일
0

Dice Rolling Simulator

이번에는 주사위 게임을 만들어 보자
주사위를 굴리는 것은 random 모듈을 이용하면 간단히 해결되기에 좀 더 복잡한 게임을 만들고 싶었다

기획한 내용은 섯다를 응용해서 2명의 플레이어가 주사위 3개를 굴려 싱글, 더블, 트리플 총 세 가지 족보로 겨루는 것이다

순서대로 살펴보자 !

1. 플레이어 입력 / 주사위 설정

input을 이용해서 Player 이름을 각각 입력해주고 random 모듈을 이용해 주사위를 만들어주었다

import random

player1 = input('1P NAME : ')
player2 = input('2P NAME : ')

dice = random.randint(1, 6)

주사위를 3번 굴리는 행위를 for반복문을 사용해 list를 만들 계획이기에 각각 설정해주었다

player1_dice = []
player2_dice = []

2. 반복문 사용하기

2.1 for문 사용

random모듈을 이용하여 주사위 굴리는 행위를 실행했으니 for문을 이용하여 3번 반복하여 list에 넣어보겠다

for i in range(3):
  player1_dice.append(dice)

for i in range(3):
  player2_dice.append(dice)

코드를 실행해보니 결과값이 이상하다.. 같은 값이 반복된다

[1,1,1]
[1,1,1]

이런 형식으로 말이다

이유가 무엇인지 생각해보니 dice라는 변수를 만들면서 이미 주사위의 값이 하나로 정해졌기에 같은 값이 반복되는 것이었다

그래서 변수를 제거하고 반복문 안에서 random.randint(1,6)을 바로 사용해보았다

for i in range(3):
  player1_dice.append(random.randint(1, 6))

for i in range(3):
  player2_dice.append(random.randint(1, 6))

이제 내가 원하던 값이 제대로 출력된다

2.2 List 오름차순 정렬

플레이어들이 각각 3번씩 던진 주사위 값 list를 오름차순으로 정렬해보자
방법은 list.sort메소드를 사용했다

player1_dice.sort()
player2_dice.sort()

player1_diceplayer2_diceprint해보면 오름차순으로 출력되는 것을 확인해볼 수 있다

3. 함수 정의

주사위 3개로 싱글, 더블, 트리플 세 가지 방법을 이용해 점수를 겨루는 내용을 어떻게 코드로 풀어낼 수 있을까

나는 3가지 방법으로 정리해보았다

  1. 중복값을 제거한 후 길이가 짧은 쪽이 승리한다(싱글 길이 = 3, 더블 길이 = 2, 트리플 길이 = 1)
  2. 중복값이 존재한다면 listdictionary로 변경(중복값을 찾기 위해서)한 후value값을 이용해 key를 불러와 key 값이 큰 쪽이 승리한다
  3. 중복값이 없다면 list의 3번 째 값의 크기가 큰 쪽이 승리하며 값이 같다면 무승부로 한다

이 방법을 위해선 List → Dict, value로 key 찾기 2가지의 함수를 정의해야한다

3.1 List → Dict

list에서 중복 값을 찾아서 dictionary로 출력하는 방법은 infinitt.tistory 를 참고하였다

방법은 tryexcept를 사용한 for반복문이다

def get_duplication(any_list):
  new_list = {}
  for i in any_list:
    try: new_list[i] += 1
    except: new_list[i] = 1
  return(new_list)

간단히 설명하면 먼저 for문을 사용해 lists의 요소를 각각 꺼내서 new_list에 넣는다
해당 요소가 이미 존재하는 값이면 try문이 실행되면서 해당 요소의 value는 +1이 된다
없는 값이면 except문이 실행되면서 해당 요소의 value는 1로 저장된다

다음 단계를 위해 dictionary형태의 새로운 변수를 정의해주었다

player1_dict = get_duplication(player1_dice)
player2_dict = get_duplication(player2_dice)

3.2 Value값으로 Key값을 출력

Value값으로 Key값을 출력하는 방법은 delftstack 을 참고하였다

dict.items()메소드를 이용한 방법으로 중복 값(2 or 3)과 dictionary를 입력했을 때 해당 값이 존재하면 keyreturn받는 함수를 정의했다

def get_key(duplication, any_dict):
    for key, value in any_dict.items():
         if duplication == value:
             return key
    return "No key"

4. 주사위게임 경우의 수

주사위 게임의 경우의 수는

  1. 중복 값이 서로 다를 경우
  2. 중복 값이 둘 다 3일 경우
  3. 중복 값이 둘 다 2일 경우
  4. 중복 값이 둘 다 없을 경우
  5. 값이 같은 경우

총 5가지로 정리해서 코드를 작성했다

4.1 중복 값이 서로 다를 경우

중복 값이 서로 다른 경우에는 set을 사용해서 중복 값을 삭제하고 len을 사용해 길이가 더 짧은 쪽이 승리하도록 작성했다

if len(set(player1_dice)) > len(set(player2_dice)):
  print(f'{player2} is Winner !')
elif len(set(player1_dice)) < len(set(player2_dice)):
  print(f'{player1} is Winner !')

4.2 중복 값이 둘 다 3일 경우

중복 값이 둘 다 3인 경우에는 위에서 get_key로 정의한 함수를 사용해 크기가 큰 쪽이 이기도록 작성했다

elif get_key(3, player1_dict) > get_key(3, player2_dict):
  print(f'{player1} is Winner !')
elif get_key(3, player1_dict) < get_key(3, player2_dict):
  print(f'{player2} is Winner !')

4.3 중복 값이 둘 다 2일 경우

중복 값이 둘 다 2인 경우에는 3인 경우에서 get_key의 입력 값만 3→2로 변경했다

elif get_key(2, player1_dict) > get_key(2, player2_dict):
  print(f'{player1} is Winner !')
elif get_key(2, player1_dict) < get_key(2, player2_dict):
  print(f'{player2} is Winner !')

4.4 중복 값이 둘 다 없을 경우

중복 값이 둘 다 없는 경우에는 list에서 3번 째 값이 큰 쪽이 승리하도록 작성했다

elif player1_dice[2] > player2_dice[2]:
  print(f'{player1} is Winner !')
elif player1_dice[2] < player2_dice[2]:
  print(f'{player2} is Winner !')

4.5 값이 같은 경우

4.1 ~ 4.4 모두 적용이 되지 않는다면 중복 값도 없고 list 마지막 값 즉, 싱글에서 제일 높은 값이 같은 경우이기에 무승부로 작성했다

else:
  print('Draw !')

5. 게임 실행

플레이어 이름 입력 후 ------------print해서 칸을 나누어 주고 주사위 값을 알기 위해서 player1_diceplayer2_diceprint하였다

게임을 실행해보면



실행이 잘 되는 것을 볼 수 있다 !

문제 발생

실행은 잘 되지만 결과 값이 이상해서 코드를 다시 살펴보니 더블일 때 같은 값이면 비기는 경우가 작성이 되어있지않아 4.4번을 따라 3번 째 값이 큰 쪽이 이기게 되는 것이었다
부랴부랴 중간에 코드를 추가해보니

elif get_key(2, player1_dict) == get_key(2, player2_dict):
  print('Draw !')

이제는 싱글인 경우 다 Draw가 출력된다

코드를 점검하다 발견한 내용은 get_key를 정의할 때 해당하는 값이 없으면 출력에서 error가 나서 "No Key"가 return되도록 설정한 것이 그 이유였다
그렇다고 저 내용을 지울 수도 없고 이렇게 오류지옥에 빠져버렸다
...........................

고민을 열심히 하다가 너무 간단하게 해결이 되어버렸다
방법은 and를 이용해서 get_key의 값이 "No Key"와 다르다라고 추가하는 것이었다

코드로 보면 다음과 같다

elif (get_key(2, player1_dict) == get_key(2, player2_dict)) and (get_key(2, player1_dict) != "No key"):

간단하게 해결되서 좋기도한데 이걸로 고민한 내가 바보같이 느껴지기도 하고 복잡한 심정이다...

수정한 최종 코드를 정리했다

import random

player1 = input('1P NAME : ')
player2 = input('2P NAME : ')

player1_dice = []
player2_dice = []

for i in range(3):
  player1_dice.append(random.randint(1, 6))

for i in range(3):
  player2_dice.append(random.randint(1, 6))

player1_dice.sort()
player2_dice.sort()
print("------------")
print(player1_dice)
print(player2_dice)
print("------------")

def get_duplication(any_list):
  new_list = {}
  for i in any_list:
    try: new_list[i] += 1
    except: new_list[i] = 1
  return(new_list)

player1_dict = get_duplication(player1_dice)
player2_dict = get_duplication(player2_dice)

def get_key(duplication, any_dict):
    for key, value in any_dict.items():
         if duplication == value:
             return key
    return "No key"

if len(set(player1_dice)) > len(set(player2_dice)):
  print(f'{player2} is Winner !')
elif len(set(player1_dice)) < len(set(player2_dice)):
  print(f'{player1} is Winner !')
elif get_key(3, player1_dict) > get_key(3, player2_dict):
  print(f'{player1} is Winner !')
elif get_key(3, player1_dict) < get_key(3, player2_dict):
  print(f'{player2} is Winner !')
elif get_key(2, player1_dict) > get_key(2, player2_dict):
  print(f'{player1} is Winner !')
elif get_key(2, player1_dict) < get_key(2, player2_dict):
  print(f'{player2} is Winner !')
elif (get_key(2, player1_dict) == get_key(2, player2_dict)) and (get_key(2, player1_dict) != "No key"):
  print('Draw !')
elif player1_dice[2] > player2_dice[2]:
  print(f'{player1} is Winner !')
elif player1_dice[2] < player2_dice[2]:
  print(f'{player2} is Winner !')
else:
  print('Draw !')

0개의 댓글