Python | 노래 맞추기 게임

지현·2021년 1월 8일
1

Python

목록 보기
3/9

목표: 가수의 노래 맞추기 (술)게임 구현

  • 게임 방법:
  1. 나 포함 4명의 플레이어와 술게임을 시작한다.
  2. 게임을 시작하기 전, 나와 플레이어의 주량을 정해준다.
  3. 랜덤으로 게임 시작 순서를 정한다.
  4. 첫 플레이어가 '가수 이름'을 정한다.
  5. 순서대로 가수의 노래를 하나씩 말한다.
  6. 가수의 노래를 생각해내지 못하면 지게 된다.
  7. 진 플레이어는 첫 번째 설정된 주량에서 -1 된다.
import requests
import json
import random

class Info:
    def __init__(self):
        self.yourCap = int(input("당신의 주량은 몇 잔?"))
        self.p1_Cap = int(input("컴퓨터1의 주량은 몇 잔?"))
        self.p2_Cap = int(input("컴퓨터2의 주량은 몇 잔?"))
        self.p3_Cap = int(input("컴퓨터3의 주량은 몇 잔?"))
        print()
        
    def WhoIsWinner(self):
        """술게임의 전체 승자 출력"""
        """중요 ! 매 게임이 한 판 끝날 때마다 '정산' 진행되어야 함."""
        """(즉, 본 함수 WhoisWinner 실행)"""
        if self.p1_Cap == 0:
            print('\n컴퓨터1이 뻗어버렸습니다!')
        elif self.p2_Cap == 0:
            print('\n컴퓨터2이 뻗어버렸습니다!')
        elif self.p3_Cap == 0:
            print('\n컴퓨터3이 뻗어버렸습니다!')
        elif self.yourCap == 0:
            print('\n당신이 뻗어버렸습니다!')
        else:
            print('\n아무도 뻗은 사람이 없습니다! 다음 게임을 계속 진행하십시오.')
            

class SONG_GAME:
    def __init__(self, yourCap, p1_Cap, p2_Cap, p3_Cap):
        """가수가 지목된 경우 노래를 한 개 말해야 하는 게임입니다!"""
        """제대로 못 말하면 한 잔~"""
        
        print()
        print('='*40, end="\n\n")
        print('              ✦‿✦ 집중 ✦‿✦              ', end="\n\n")
        print('지금부터 노래 맞추기 게임을 시작하겠습니다!!', end="\n\n")
        print('게임의 참가 순서를 무작위로 정하겠습니다.')
        print('이 순서는 노래 맞추기 게임이 종료될 때까지 반복됩니다.')
        print()
        print('='*40)
        print()
        
        self.random_guess = random.randint(2, 4)       # 2, 3, 4
        self.actual_guess = 0
        self.singer_list = ['블랙핑크', '방탄소년단', '아이유', '빅뱅', '트와이스', '적재', '로꼬', '레드벨벳']
        
        self.Caps = [yourCap, p1_Cap, p2_Cap, p3_Cap]
        self.order = [0, 1, 2, 3]
        random.shuffle(self.order)
        
    def main_game(self):
        """게임 전반의 흐름"""
        i = 0
        players = ['당신', '컴퓨터1', '컴퓨터2', '컴퓨터3']
        
        print('자! 이제 게임을 시작해볼까요~? ✿˘◡˘✿', end="\n\n\n")
        print(self.order)
        print(f'{players[self.order[0]]}이/가 게임을 시작하겠습니다!!', end="\n")
        #만약 사람의 턴이라면
        if self.order[0] == 0: 
            #사람은 본인이 하고 싶은 가수를 입력하고 그 가수에 대한 노래가 self.song_list에 저장된
            self.song_game_human() 
            #print(self.song_list)
        else: # 컴퓨터는 self.singer_list에서 랜덤으 가수를 하나 뽑고 그 가수에 해당하는 노래들이 self.song_list에 저장됨
            self.song_game_com()
            #print(self.song_list)
        
        break_signal = 0

        while True:
            turn = self.order[i] # 이번 턴은 누구인가!

            if turn == 0: # 만약 '사람'의 턴이라면,
                answer = input("▶ 대답은?: ")
            else: # 만약 '컴퓨터'들의 턴이라면,
                if break_signal == 1:
                    answer = "모르겠어요...."
                else: 
                    answer = random.choice(self.song_list)
                print("▶ {}의 대답 : {}".format(players[turn], answer))
            
            if answer in self.song_list:
                print("맞았습니다! ♪♪(oᐛ)o~♪♪", end = "\n\n")
                del self.song_list[self.song_list.index(answer)]
            else:
                print("틀렸습니다!!∑(;°Д°) 마시면서 배우는 술게임~~ᕦ( ᐛ )ᕡ ", end = "\n\n")
                break

            i += 1
            i = i % 4
            
            self.actual_guess += 1
            if self.actual_guess >= self.random_guess:
                break_signal = 1
                

        print(f'{players[turn]}이 패배! 주량에서 한 잔 까세요~')
        self.Caps[turn] -= 1
        return self.Caps


    def load_song_list(self, singer):
        """주어진 가수의 대표 노래 리스트를 멜론으로부터 크롤링합니다."""
        """사람이 플레이할 때만 실행됩니다."""
        url = "https://www.melon.com/search/keyword/index.json"
        params = {
            'jscallback' : "jQuery19105357803934720518_1603168193882",
            'query' : singer}

        headers = {
            'Referer' : "http://www.melon.com/index.htm",
            "User-Agent" : ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\
                            (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36")}
        response = requests.get(url, headers = headers, params = params)
        response = response.text

        json_string = response.replace(params['jscallback'] + '(', '').replace(');', '')
        result_dict = json.loads(json_string)
        return result_dict


    def song_game_human(self):
        """사람을 위한 song_game입니다"""
        while True:
            # 가수 이름 똑바로 입력하기 전까진
            # 이 루프를 탈출할 수 없다.
            singer = input('가수를 입력하세요 : ')
            song_dict = self.load_song_list(singer)    # 크롤링으로 얻은 dict


            if 'SONGCONTENTS' not in song_dict.keys():
                print("그런 가수가 어딨어ㅡㅡ;;;")
                print('가수 이름 다시 입력하세요')
            elif len(song_dict['SONGCONTENTS']) == 0:
                print("그런 가수가 어딨어ㅡㅡ;;;")
                print('가수 이름 다시 입력하세요')
            else:
                break # 정상적으로 검색이 되는 가수를 입력한 것.
                
        # print(f'\n"{song_dict["KEYWORD"]}" 검색결과')  # 가수 검색 결과
        self.song_list = self.get_song_list(singer, song_dict)


    def get_song_list(self, singer, song_dict):
        song_list = []
        for song in song_dict["SONGCONTENTS"]:

            temp = song['SONGNAME'].split("(")     # 뚜두뚜두 (DDU-DU DDU-DU)와 같이 괄호가 있을 경우, 풀네임 아니라 괄호 전까지만 입력해도 정답 인정
            song_list.append(temp[0].strip())      # 노래 제목 뒤에 띄어쓰기 제거
            
        #print(song_list)   
        return song_list      # list


    
    def song_game_com(self):
        """컴퓨터를 위한 song_game입니다"""
        """가수와 곡 후보 리스트는 사전에 지정되며,"""
        """컴퓨터는 랜덤 확률로 곡을 고른 후, 평가를 받습니다."""
        
        singer = random.choice(self.singer_list)
        print(f"플레이어가 선택한 가수는 [ {singer} ]입니다. ", end = '\n\n')
        print(f'▶▶▶ [ {singer} ]의 노래를 말해주세요!! ◀◀◀', end = '\n\n\n')
        song_dict = self.load_song_list(singer)

        #컴퓨터가 랜덤하게 뽑은 가수를 검색한 결과 리스트
        self.song_list = self.get_song_list(singer, song_dict)

        
        
# 실제 실행!
        
info = Info()
print()
game = SONG_GAME(info.yourCap, info.p1_Cap, info.p2_Cap, info.p3_Cap)
print()
new_Caps = game.main_game()
print(new_Caps)
  • 코드 실행 (정상적인 실행)
  • 코드 실행 2 (중복된 노래를 하면 짐...)
  • 오늘의 깨달음
  1. class 내부 함수(method)에서 return이 없더라도 self.abcabc와 같이 내부 변수를 생성하거나 변경할 수 있다.
    --> 모든 함수가 return이 꼭 필요한 건 아니지만, 가급적으로 return 사용
  2. return 할 게 없더라도, return 0 하는 것을 습관화 하자
    --> return 0 의 의미: 함수의 종료

1개의 댓글

comment-user-thumbnail
2022년 9월 9일

오! 재미있어 보이네요
잘 봤습니다

답글 달기