문제 생성이 핵심이다.
초등 1학년이 풀 수 있는 문제만 나와야 함.
난이도 설정
const DIFFICULTY_SETTINGS = {
easy: { maxNum: 10, mulMax: 5, label: '쉬움' },
medium: { maxNum: 20, mulMax: 9, label: '보통' },
hard: { maxNum: 100, mulMax: 12, label: '어려움' },
expert: { maxNum: 500, mulMax: 15, label: '전문가' },
master: { maxNum: 1000, mulMax: 20, label: '마스터' }
};
maxNum: 덧셈/뺄셈 최대 숫자mulMax: 곱셈/나눗셈 최대 숫자
덧셈
if (op === '+') {
num1 = Math.floor(Math.random() * maxNum) + 1;
num2 = Math.floor(Math.random() * (maxNum - num1)) + 1;
answer = num1 + num2;
}
결과가 maxNum 넘지 않도록 num2 범위 조절.
뺄셈
if (op === '-') {
num1 = Math.floor(Math.random() * maxNum) + 1;
num2 = Math.floor(Math.random() * num1) + 1;
answer = num1 - num2;
}
핵심: num2가 num1보다 크면 안 됨.
음수 나오면 아이 혼란.
✅ 8 - 3 = 5
❌ 3 - 8 = -5 ← 이러면 안 됨
곱셈
if (op === '×') {
num1 = Math.floor(Math.random() * mulMax) + 1;
num2 = Math.floor(Math.random() * mulMax) + 1;
answer = num1 * num2;
}
구구단 범위 내에서 생성.
나눗셈
if (op === '÷') {
num2 = Math.floor(Math.random() * mulMax) + 1;
answer = Math.floor(Math.random() * mulMax) + 1;
num1 = num2 * answer;
}
핵심: 역으로 생성.
먼저 나누는 수와 답을 정하고, 곱해서 num1 만듦.
num2 = 3
answer = 4
num1 = 3 × 4 = 12
문제: 12 ÷ 3 = 4 ← 딱 떨어짐
소수점 안 나옴.
연산 선택
let ops = [];
if (operation === 'add') ops = ['+'];
else if (operation === 'sub') ops = ['-'];
else if (operation === 'mul') ops = ['×'];
else if (operation === 'div') ops = ['÷'];
else if (operation === 'addsub') ops = ['+', '-'];
else if (operation === 'muldiv') ops = ['×', '÷'];
else ops = ['+', '-', '×', '÷']; // all
const op = ops[Math.floor(Math.random() * ops.length)];
사용자가 선택한 연산만 나옴.
전체 함수
const generateProblem = useCallback(() => {
const settings = DIFFICULTY_SETTINGS[difficulty];
const maxNum = settings.maxNum;
const mulMax = settings.mulMax;
// 연산 선택
let ops = [];
if (operation === 'add') ops = ['+'];
// ... (생략)
const op = ops[Math.floor(Math.random() * ops.length)];
let num1, num2, answer;
if (op === '+') {
// 덧셈 로직
} else if (op === '-') {
// 뺄셈 로직
} else if (op === '×') {
// 곱셈 로직
} else {
// 나눗셈 로직
}
return { num1, num2, op, answer };
}, [difficulty, operation]);
useCallback으로 메모이제이션. difficulty나 operation 바뀔 때만 재생성.
다음 글에서 숫자 키패드 UI.