
本文讲解如何通过嵌套循环结构,在每次武器抽取后保留背包中各类武器的累计数量,避免因重复初始化导致数据丢失,并确保随机值实时更新。
本文讲解如何通过嵌套循环结构,在每次武器抽取后保留背包中各类武器的累计数量,避免因重复初始化导致数据丢失,并确保随机值实时更新。
在开发类似RPG背包系统的控制台程序时,一个常见误区是将计数器(如 common, rare 等)声明在循环内部,导致每次迭代都重置为 0;同时,Math.random() 若只计算一次并复用,也会造成“随机值不变化”的假象。要实现“循环重启但背包状态持久”,关键在于分离逻辑层级:外层控制整体流程(如用户交互或批量抽取),内层执行单次掉落判定,而所有计数变量必须声明在外层作用域中,且绝不重复初始化。
以下是重构后的专业写法(含完整可运行逻辑):
import java.util.Scanner;
public class WeaponDropSystem {
public static void main(String[] args) {
// ✅ 背包计数器:声明在外层,生命周期覆盖整个程序运行期
int common = 0, rare = 0, epic = 0, legendary = 0, exotic = 0, unique = 0;
// 武器描述常量(推荐使用 final 提升可维护性)
final String COMMON = "You found a Common Sword!";
final String RARE = "You found a Rare Sword!";
final String EPIC = "You found an Epic Sword!";
final String LEGENDARY = "You found a Legendary Sword!";
final String EXOTIC = "You found an Exotic Sword!";
final String UNIQUE = "You found a Unique Sword!";
Scanner scanner = new Scanner(System.in);
System.out.println("=== Weapon Drop Simulator ===");
System.out.println("Press Enter to draw a weapon (or 'q' to quit):");
// ? 外层主循环:持续接受用户指令,不重置背包
while (true) {
System.out.print("> ");
String input = scanner.nextLine().trim();
if ("q".equalsIgnoreCase(input)) break;
// ? 内层单次掉落逻辑:每次重新生成随机值
double dropRoll = Math.random() * 101; // 注意:范围是 [0.0, 101.0)
System.out.printf("Roll: %.2f%n", dropRoll);
// ⚔️ 概率判定(修复原逻辑漏洞:99.9% 阈值过高且区间有缝隙)
if (dropRoll <= 60.0) {
System.out.println(COMMON);
common++;
} else if (dropRoll <= 80.0) {
System.out.println(RARE);
rare++;
} else if (dropRoll <= 90.0) {
System.out.println(EPIC);
epic++;
} else if (dropRoll <= 95.0) {
System.out.println(LEGENDARY);
legendary++;
} else if (dropRoll <= 99.0) {
System.out.println(EXOTIC);
exotic++;
} else { // 剩余 [99.0, 101.0) → 实际概率约 2%,更合理
System.out.println(UNIQUE);
unique++;
}
}
// ? 最终背包展示(移出循环,仅在退出时输出汇总)
System.out.println("\n--- FINAL BACKPACK ---");
System.out.println(common + " Common Weapons");
System.out.println(rare + " Rare Weapons");
System.out.println(epic + " Epic Weapons");
System.out.println(legendary + " Legendary Weapons");
System.out.println(exotic + " Exotic Weapons");
System.out.println(unique + " Unique Weapons");
System.out.println("Total weapons: " + (common + rare + epic + legendary + exotic + unique));
scanner.close();
}
}? 关键改进说明:
- 变量作用域正确:所有 int 计数器定义在 main() 开头,不受任何循环影响;
- 随机值动态刷新:dropRoll 在每次抽取前重新计算,杜绝“固定随机”问题;
- 概率区间严谨:修正了原代码中 >= 99.9 导致 99.0–99.899… 区间无匹配的逻辑缺口,改用 else 覆盖剩余概率;
- 用户体验增强:支持交互式逐次抽取,便于测试与演示;
- 代码健壮性:添加 Scanner 资源关闭、格式化输出、常量定义等工程实践。
? 进阶建议:后续可将背包封装为 class Backpack,掉落逻辑抽离为 WeaponDropTable,并通过枚举(enum Rarity)管理品质,大幅提升可扩展性与可读性。

















