43. 경험치 누적·레벨업의 비원자 처리 (C#)

난이도 중 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C#
// 시나리오: MMORPG 성장 — 경험치 획득과 레벨업(다중 레벨 상승) 처리
//
// 서버 권위(server-authoritative)로 경험치를 관리한다. 한 플레이어는 여러 경로에서
// 거의 동시에 경험치를 얻을 수 있다(파티 몹 처치 보상, 퀘스트 완료 보상, 이벤트 등).
// 경험치가 다음 레벨 요구치를 넘으면 레벨이 오르고, 한 번에 여러 레벨이 오를 수도
// 있다(대량 경험치). 레벨업 시 스탯 포인트/HP 상한 등이 증가한다.
//
// 요구사항:
//  - 부여한 총 경험치는 유실·이중 반영 없이 정확히 누적되어야 한다.
//  - 레벨은 건너뛰지 않고 순차적으로 올라야 하며, 레벨업 보상(스탯 등)은 오른 레벨
//    수만큼 정확히 한 번씩만 적용되어야 한다.
//  - 서로 다른 경로의 동시 경험치 부여에도 정확해야 한다.
//
// 다수의 게임 로직 스레드가 같은 플레이어에게 경험치를 부여할 수 있다. 아래를 검토하라.

using System;

public sealed class PlayerProgress
{
    public long Xp;          // 현재 레벨 기준 누적 경험치
    public int Level = 1;
    public int StatPoints;

    // 레벨 L 에서 L+1 로 가는 데 필요한 경험치
    private static long XpToNext(int level) => 100L * level;

    // 로직 스레드: 경험치 부여 + 레벨업 처리
    public void GrantXp(long amount)
    {
        Xp = Xp + amount;                        // (A) 경험치 누적

        while (Xp >= XpToNext(Level))            // (B) 여러 레벨 동시 상승 처리
        {
            Xp -= XpToNext(Level);
            Level++;                             // (C)
            StatPoints += 5;                     // 레벨업 보상
        }
    }

    public (int level, long xp, int sp) Snapshot() => (Level, Xp, StatPoints);
}
내 리뷰 · C#
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.