오늘 구현한 풋살온라인 프로젝트 API
오늘은 사용자들이 특정 비용을 지불하고 카드를 뽑을 수 있는 API를 작성하였다
단일 뽑기와, 5장 뽑기 두 가지 API를 구현하였다
단일뽑기 API
사용자는 500 골드를 소모하여 랜덤으로 카드를 뽑는다
뽑은 카드는 UserCard 테이블에 저장되며, 유저의 cash는 자동으로 차감된다.
확률
노말 70%
레어 25%
에픽 4.5%
레전더리 0.5%
router.post('/users/:user_id/cards', authMidWare, async (req, res, next) => {
const userId = req.params.user_id; // URL 경로에서 user_id 가져오기
const gachaCost = 500; // 가챠 비용
try {
await stringSchema.validateAsync(req.user.id);
// 사용자 정보 조회
const user = await prisma.user.findUnique({
where: { id: userId },
});
if (!user) {
return res.status(404).json({ message: '로그인 후 이용해주세요.' });
}
// 가챠 비용 확인
if (user.cash < gachaCost) {
return res
.status(400)
.json({ message: '뽑기를 하기 위한 골드가 부족합니다.' });
}
// 랜덤 숫자 생성 (0~100 사이)
const random = Math.random() * 100; // 0.0 ~ 100.0
let selectedGrade;
// 등급 확률에 따른 결정
if (random < 70) {
selectedGrade = 'NORMAL'; // 70%
} else if (random < 95) {
selectedGrade = 'RARE'; // 25% (70 ~ 95)
} else if (random < 99.5) {
selectedGrade = 'EPIC'; // 4.5% (95 ~ 99.5)
} else {
selectedGrade = 'LEGENDARY'; // 0.5% (99.5 ~ 100)
}
// 해당 등급의 카드 중 랜덤 선택
const cardsByGrade = await prisma.card.findMany({
where: { grade: selectedGrade },
});
const randomCard =
cardsByGrade[Math.floor(Math.random() * cardsByGrade.length)];
// UserCard 테이블에 카드 추가
const userCard = await prisma.userCard.create({
data: {
user_id: userId,
card_idx: randomCard.idx,
},
});
// 유저 캐시 차감//
await prisma.user.update({
where: { id: userId },
data: { cash: user.cash - gachaCost },
})
// 가챠 결과 반환
return res.status(200).json({
message: '선수카드를 뽑았습니다!',
data: {
grade: selectedGrade,
card: randomCard,
},
});
} catch (error) {
next(error);
}
});
5번 뽑기 API
한 번에 5장의 카드를 뽑는 기능으로. 각 카드당 400 골드로 할인되여, 총 2000골드가 소모된다.
5번의 뽑기 과정을 반복하여 결과로 배열을 반환한다,
느낀 점과 개선할 점
API 작성 과정에서 확률 분배와 DB 작업이 결합된 로직을 구현하는 것은 재밌으면서도 도전적이었다.
특히 가챠 시스템은 사용자 경험에 큰 영향을 미치는 만큼 확률의 설계와 밸런스 조정이 중요하다고 느꼈다
유효하지 않은 사용자 요청(잔액 부족, 로그인 필요 등)에 대한 예외 처리 코드를 꼼꼼히 작성했다.
try-catch 블록으로 오류를 잡고 사용자에게 적절한 에러 메시지를 반환하는 로직을 강화했다.
단일 뽑기와 5번 뽑기 로직을 통합하거나, 공통 기능을 다른 함수로 분리하여 중복 코드를 줄이면 좋겠다는 생각이 들었다.
'내일배움캠프 TIL' 카테고리의 다른 글
OSI 7계층에서 데이터링크 계층이란? 본캠프 12/10 (0) | 2024.12.10 |
---|---|
본캠프 12/06 TIL (0) | 2024.12.06 |
본캠프 12/02 TIL (0) | 2024.12.02 |
본캠프 11/29 TIL (0) | 2024.11.29 |
아이템 시뮬레이터 과제 트러블 슈팅 (0) | 2024.11.28 |