Discord.py로 퀴즈 봇 만들기 #5: 간단한 게임 요소 추가하기

안녕하세요! 김코딩입니다

지난 글에서 음악 봇과 날씨 봇을 다뤘다면, 이번에는 디스코드 서버를 더욱 재미있게 만들어줄 퀴즈 봇을 만들어보겠습니다.

이 퀴즈 봇을 이용하면 사용자가 퀴즈를 풀고 점수를 기록하며 경쟁할 수 있습니다. 간단한 게임 요소를 추가해 서버의 재미를 높여볼까요? 바로 시작해봅시다!

목표

quiz 명령어로 랜덤 퀴즈 제공
사용자가 답을 입력하면 정답 여부 확인 후 점수 기록
!score 명령어로 본인의 점수 확인


준비물

필요한 모듈

  • discord.py (이미 설치되어 있어야 합니다.)
  • Python 기본 모듈: random, json, asyncio

퀴즈 데이터

  • 간단한 퀴즈를 코드 내에 직접 작성 (나중에 외부 파일로 확장 가능)

봇 권한

  • “메시지 보내기(Send Messages)” 권한만 있으면 충분합니다.

완성 코드

import discord
from discord.ext import commands
import random
import json
import asyncio # 비동기 타이머를 위해 필요

# 봇 설정
bot = commands.Bot(command_prefix="!", intents=discord.Intents.all())

# 사용자 점수 및 현재 퀴즈 상태 저장
scores = {}
current_quiz = {}

# 퀴즈 데이터
QUIZZES = [
{"question": "파이썬을 만든 사람은 누구일까요?", "answer": "귀도 반 로섬", "hint": "네덜란드 출신이에요."},
{"question": "1년은 며칠일까요?", "answer": "365", "hint": "윤년은 제외!"},
{"question": "지구에서 가장 큰 대륙은?", "answer": "아시아", "hint": "인구도 많아요."}
]

# 점수 데이터 로드 및 저장
def load_scores():
global scores
try:
with open('scores.json', 'r', encoding='utf-8') as f:
scores = json.load(f)
except FileNotFoundError:
scores = {}

def save_scores():
with open('scores.json', 'w', encoding='utf-8') as f:
json.dump(scores, f, indent=4)

# 봇이 실행될 때
@bot.event
async def on_ready():
load_scores()
print(f"✅ {bot.user}가 온라인입니다!")
await bot.change_presence(activity=discord.Game(name="퀴즈 게임"))

# 퀴즈 시작 명령어
@bot.command()
async def quiz(ctx):
user_id = str(ctx.author.id)

if user_id in current_quiz:
await ctx.send("⚠ 이미 퀴즈를 진행 중입니다! 답을 입력하세요.")
return

quiz = random.choice(QUIZZES)
current_quiz[user_id] = quiz

embed = discord.Embed(title="🎯 퀴즈 시간!", color=discord.Color.green())
embed.add_field(name="문제", value=quiz["question"], inline=False)
embed.add_field(name="힌트", value=quiz["hint"], inline=False)
embed.set_footer(text="답을 채팅에 입력하세요! (10초 제한)")

await ctx.send(embed=embed)

# 10초 후 시간 초과 체크
await asyncio.sleep(10)
if user_id in current_quiz:
await ctx.send(f"⏳ {ctx.author.mention} 시간 초과! 정답은 `{quiz['answer']}`였습니다.")
del current_quiz[user_id]

# 퀴즈 답변 처리
@bot.event
async def on_message(message):
if message.author.bot:
return

user_id = str(message.author.id)

if user_id in current_quiz:
quiz = current_quiz[user_id]

if message.content.strip().lower() == quiz["answer"].lower():
scores[user_id] = scores.get(user_id, 0) + 10
save_scores()
await message.channel.send(f"🎉 {message.author.mention} 정답! +10점 (총 {scores[user_id]}점)")
else:
await message.channel.send(f"❌ {message.author.mention} 오답! 정답은 `{quiz['answer']}`였습니다.")

del current_quiz[user_id]

await bot.process_commands(message) # 다른 명령어도 처리 가능하도록 설정

# 점수 확인 명령어
@bot.command()
async def score(ctx):
user_id = str(ctx.author.id)
user_score = scores.get(user_id, 0)

embed = discord.Embed(title=f"📊 {ctx.author.name}님의 점수", color=discord.Color.blue())
embed.add_field(name="현재 점수", value=f"{user_score}점", inline=False)

await ctx.send(embed=embed)

# 봇 실행
bot.run("여기에-디스코드-토큰-입력")

코드 설명

1. 퀴즈 데이터

  • QUIZZES 리스트에 질문, 정답, 힌트를 포함
  • random.choice()로 무작위 문제를 선택

2. 퀴즈 진행 방식

  1. !quiz 명령어 입력 시 랜덤 문제 제공
  2. 사용자가 메시지로 답변 입력
  3. 정답 여부를 확인 후 점수 부여
  4. 정답을 맞히면 +10점, 틀리면 정답 공개
  5. 10초 안에 답을 입력하지 않으면 시간 초과 처리

3. 점수 관리

  • scores 딕셔너리를 JSON 파일(scores.json)로 저장하여 데이터를 영구적으로 유지
  • !score 명령어를 입력하면 현재 점수를 확인할 수 있음

실행 방법

  1. 위 코드를 quiz_bot.py로 저장
  2. bot.run("여기에-디스코드-토큰-입력") 부분에 본인의 디스코드 봇 토큰 입력
  3. 터미널에서 실행: python quiz_bot.py
  4. 디스코드 서버에서 테스트:
    • !quiz → 퀴즈 시작
    • (예: 귀도 반 로섬 입력)
    • !score → 점수 확인

문제 해결 팁

“답이 안 먹혀요!”
👉 소문자로 변환 후 비교하므로 대소문자 문제는 없지만, 띄어쓰기 차이도 고려하세요.

“점수가 저장되지 않아요!”
👉 scores.json 파일이 생성되었는지 확인하고, 파일 권한을 체크하세요.

“타이머가 정확하지 않아요!”
👉 asyncio.sleep(10)을 사용하면 환경에 따라 약간의 오차가 있을 수 있습니다.


더 발전시켜보기

난이도 추가: !quiz easy, !quiz hard
리더보드 추가: !leaderboard로 상위 점수 확인
외부 API 연동: 퀴즈 API (예: Open Trivia DB) 활용

오늘은 디스코드 퀴즈 봇을 만들어 보며 서버에 게임 요소를 추가하는 방법을 배웠어요!
다음에는 SQLite 연동 또는 추가 미니게임(예: 가위바위보) 등을 다뤄볼까요?
의견이 있다면 댓글로 남겨주세요!

One comment

  1. […] 지난번에는 디스코드 퀴즈 봇을 만들었는데요. 이번에는 미니 게임 기능을 추가해볼 거예요. 친구들과 간단하게 즐길 수 있는 가위바위보 게임을 구현해봅시다. 기존 퀴즈 점수 시스템과 연동하여, 게임에서 승리하면 점수를 얻을 수 있도록 만들 거예요.(간단한 미니 게임 봇) […]

Leave a Reply

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다