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

如何简化多参数else if判断并解决问答游戏空值问题

优化“21问”游戏代码:简化逻辑+解决空值与归类歧义问题

我正在开发一款类似“21问”的游戏,让用户想一个食物、动物或物品词汇,电脑通过提问猜测词汇。目前的核心代码存在两个关键问题:

  • 硬编码大量判断条件,新增或修改词汇时维护成本极高
  • 条件触发式提问导致空值问题,且部分词汇存在归类歧义(比如用户可能把企鹅归为水生或陆生,干扰识别)

以下是针对性的优化方案:


1. 用数据驱动替代硬编码判断

把每个动物的属性抽象为实体类,将所有动物数据存储在集合中,匹配时遍历集合检查属性是否符合,彻底消除冗长的if-else链。

定义动物属性实体类

import java.util.List;

class Animal {
    private String name;
    private List<String> sizes; // 支持多尺寸,比如猫可以是Small/Medium
    private List<String> domains; // 支持多领域,比如企鹅同时属于Land/Water
    private List<String> bodyOfWaters;
    private boolean hasWings;
    private int legs;
    private List<String> skinTypes;
    private boolean isCommonPet;
    private boolean isDomesticated;
    private String dangerLevel;
    private String category; // Feline/Canine等

    // 构造器
    public Animal(String name, List<String> sizes, List<String> domains, List<String> bodyOfWaters, boolean hasWings, int legs, List<String> skinTypes, boolean isCommonPet, boolean isDomesticated, String dangerLevel, String category) {
        this.name = name;
        this.sizes = sizes;
        this.domains = domains;
        this.bodyOfWaters = bodyOfWaters;
        this.hasWings = hasWings;
        this.legs = legs;
        this.skinTypes = skinTypes;
        this.isCommonPet = isCommonPet;
        this.isDomesticated = isDomesticated;
        this.dangerLevel = dangerLevel;
        this.category = category;
    }

    // getter方法
    public String getName() { return name; }
    public List<String> getSizes() { return sizes; }
    public List<String> getDomains() { return domains; }
    public List<String> getBodyOfWaters() { return bodyOfWaters; }
    public boolean isHasWings() { return hasWings; }
    public int getLegs() { return legs; }
    public List<String> getSkinTypes() { return skinTypes; }
    public boolean isCommonPet() { return isCommonPet; }
    public boolean isDomesticated() { return isDomesticated; }
    public String getDangerLevel() { return dangerLevel; }
    public String getCategory() { return category; }
}

初始化动物数据

import java.util.List;
import java.util.ArrayList;

List<Animal> animals = new ArrayList<>();
// 添加老鼠
animals.add(new Animal("Mouse",
        List.of("Small"),
        List.of("Land"),
        null,
        false,
        4,
        List.of("Fur", "Hair"),
        true,
        false,
        null,
        null));
// 添加鱼
animals.add(new Animal("Fish",
        List.of("Small"),
        List.of("Water"),
        List.of("Most"),
        false,
        0,
        List.of("Scales"),
        true,
        false,
        null,
        null));
// 添加鲨鱼
animals.add(new Animal("Shark",
        List.of("Large"),
        List.of("Water"),
        List.of("Oceans", "Seas"),
        false,
        0,
        List.of("Skin"),
        false,
        false,
        "Dangerous",
        null));
// 添加猫
animals.add(new Animal("Cat",
        List.of("Small", "Medium"),
        List.of("Land"),
        null,
        false,
        4,
        List.of("Fur"),
        true,
        true,
        null,
        "Feline"));
// 添加企鹅(解决归类歧义)
animals.add(new Animal("Penguin",
        List.of("Small", "Medium"),
        List.of("Land", "Water"),
        List.of("Oceans", "Antarctic"),
        false,
        2,
        List.of("Feathers"),
        false,
        false,
        null,
        null));

2. 解决空值与条件触发提问问题

对于未触发提问的属性(值为null),匹配时直接跳过检查;对于用户输入的答案,用Optional包装避免空指针异常。

编写匹配逻辑

import java.util.Optional;
import java.util.ArrayList;
import java.util.List;

// 用户输入的答案,用Optional包装避免空值
Optional<String> userSize = Optional.ofNullable(aA1);
Optional<String> userDomain = Optional.ofNullable(aA2);
Optional<String> userBodyOfWater = Optional.ofNullable(aAw1);
Optional<String> userWings = Optional.ofNullable(aA3);
Optional<Integer> userLegs = Optional.ofNullable(aA4);
Optional<String> userSkinType = Optional.ofNullable(aA5);
Optional<String> userCommonPet = Optional.ofNullable(aA6);
Optional<String> userDomesticated = Optional.ofNullable(aAld2);
Optional<String> userDangerLevel = Optional.ofNullable(aAl1);
Optional<String> userCategory = Optional.ofNullable(aAfc);

// 遍历动物列表匹配
List<Animal> matches = new ArrayList<>();
for (Animal animal : animals) {
    boolean match = true;

    // 检查尺寸:用户输入不为空时,动物尺寸列表包含用户输入
    if (userSize.isPresent() && !animal.getSizes().contains(userSize.get())) {
        match = false;
    }
    // 检查领域:用户输入不为空时,动物领域列表包含用户输入(解决企鹅归类问题)
    if (match && userDomain.isPresent() && !animal.getDomains().contains(userDomain.get())) {
        match = false;
    }
    // 检查水域类型:用户输入不为空时,动物水域列表包含用户输入
    if (match && userBodyOfWater.isPresent() && animal.getBodyOfWaters() != null && !animal.getBodyOfWaters().contains(userBodyOfWater.get())) {
        match = false;
    }
    // 检查翅膀:用户输入不为空时,转换为boolean匹配
    if (match && userWings.isPresent()) {
        boolean hasWings = "Yes".equals(userWings.get());
        if (animal.isHasWings() != hasWings) {
            match = false;
        }
    }
    // 检查腿数:用户输入不为空时匹配
    if (match && userLegs.isPresent() && animal.getLegs() != userLegs.get()) {
        match = false;
    }
    // 检查皮肤类型:用户输入不为空时,动物皮肤列表包含用户输入
    if (match && userSkinType.isPresent() && !animal.getSkinTypes().contains(userSkinType.get())) {
        match = false;
    }
    // 检查是否常见宠物:用户输入不为空时转换为boolean匹配
    if (match && userCommonPet.isPresent()) {
        boolean isPet = "Yes".equals(userCommonPet.get());
        if (animal.isCommonPet() != isPet) {
            match = false;
        }
    }
    // 检查是否驯化:用户输入不为空时转换为boolean匹配
    if (match && userDomesticated.isPresent()) {
        boolean isDomesticated = "Yes".equals(userDomesticated.get());
        if (animal.isDomesticated() != isDomesticated) {
            match = false;
        }
    }
    // 检查危险等级:用户输入不为空时匹配
    if (match && userDangerLevel.isPresent() && !userDangerLevel.get().equals(animal.getDangerLevel())) {
        match = false;
    }
    // 检查类别:用户输入不为空时匹配
    if (match && userCategory.isPresent() && !userCategory.get().equals(animal.getCategory())) {
        match = false;
    }

    if (match) {
        matches.add(animal);
    }
}

// 输出结果
if (matches.size() == 1) {
    System.out.println(matches.get(0).getName() + "!");
} else if (matches.size() > 1) {
    System.out.println("我猜可能是:");
    matches.forEach(animal -> System.out.println("- " + animal.getName()));
} else {
    System.out.println("Sorry! That's not an animal we recognize yet. Better luck next time!");
    System.exit(1);
}

3. 核心优化点总结

  • 数据驱动:新增动物只需添加实体对象,无需修改判断逻辑,大幅降低维护成本
  • 空值安全:用Optional包装用户输入,未提问的属性直接跳过检查,避免空指针异常
  • 歧义兼容:每个属性支持多值(比如企鹅同时属于陆生和水生),只要用户选择的属性在动物的属性列表中即视为匹配
  • 扩展性强:后续新增食物、物品类别时,只需复用相同的实体类设计和匹配逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 20:59:53