You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java条件分支逻辑问题:Codewars用户Rank进度计算代码调试

Codewars 用户Rank进度计算问题调试

业务规则

  • 用户初始Rank为-8,最高到8,无0 Rank,-1之后直接升级至1
  • 完成对应Rank的活动后更新进度(progress),累计满100 progress即可升级Rank,剩余进度保留;Rank达到8后停止更新
  • 有效Rank范围:[-8,-7,-6,-5,-4,-3,-2,-1,1,2,3,4,5,6,7,8],传入非法值需抛出异常
  • 进度计算规则:
    • 完成同Rank活动:增加3 progress
    • 完成比当前Rank低1级的活动:增加1 progress
    • 完成比当前Rank低2级及以上的活动:无进度
    • 完成比当前Rank高的活动:进度增加10*d*d(d为Rank差值,需跳过0的Rank)

问题现象

调用incProgress(1)后,预期用户Rank变为-1,但实际结果为-2。

现有代码

public class User {
int rank = -8;
int progress = 0;
public User() {

}

public int getRank() {
    return rank;
}

public void setRank(int rank) {
    this.rank = rank;
}

public int getRankProgress() {
    return progress;
}

public void setRankProgress(int progress) {
    this.progress = progress;
}

public void updateRank() {
    while (progress >= 100) {
        int newRank = this.rank + 1;
        if (rank == -1) {
            newRank = 1;
        } else if (rank == 8) {
            return;
        }
        setRank(newRank);
        setRankProgress(progress - 100);
    }
}

public void incProgress(int activityRank) {
    if (activityRank < -8 || activityRank == 0 || activityRank > 8) {
        throw new IllegalArgumentException();
    }

    System.out.println("Called with activity rank " + activityRank + " user rank " + getRank());
    if (activityRank == getRank()) {
        setRankProgress(progress + 3);
    } else if (getRank() > activityRank && getRank() - activityRank == 1) {
        setRankProgress(progress + 1);
    } else if (getRank() > activityRank && getRank() - activityRank >= 2) {
        return;
    } else if (activityRank > getRank()) {
        System.out.println("Called 5");
        int d;
        if (activityRank >= 0 && getRank() < 0) {
            d = (activityRank - getRank()) - 1;
        } else {
            d = activityRank - getRank();
        }

        int progress = 10 * d * d;
        setRankProgress(progress);
    }
    updateRank();
}

}

问题原因及修复方案

1. 进度覆盖而非累加(核心错误)

在处理高Rank活动的分支中,代码直接用新计算的进度覆盖了原有进度,没有执行累加操作。比如用户原有进度为70,完成高Rank活动得到40进度,正确总进度应为110,但原代码直接设置为40,导致无法触发升级。

修复代码:
将高Rank分支中的:

int progress = 10 * d * d;
setRankProgress(progress);

修改为:

int addProgress = 10 * d * d;
setRankProgress(this.progress + addProgress);

2. Rank升级逻辑的循环漏洞

原updateRank方法中,当Rank达到8时直接返回,但未清零进度;同时循环条件未判断Rank是否已到上限,可能出现无效循环。另外,升级后进度更新的逻辑可以更简洁直观。

修复后的updateRank方法:

public void updateRank() {
    // 仅在未达最高Rank且进度足够时循环升级
    while (progress >= 100 && rank != 8) {
        if (rank == -1) {
            setRank(1);
        } else {
            setRank(rank + 1);
        }
        // 扣除升级消耗的进度
        setRankProgress(progress - 100);
    }
    // 达到最高Rank后清零进度
    if (rank == 8) {
        setRankProgress(0);
    }
}

3. 变量命名优化(可选)

高Rank分支中,局部变量progress与成员变量重名,容易造成混淆,建议修改为addProgress之类的命名,提升代码可读性。

内容的提问来源于stack exchange,提问作者Amos Machora

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 00:46:09