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

Unity猜字母游戏:如何从列表按指定比例(如30%)选取元素?

猜字母游戏:按比例抽取正确字母的实现方案

问题背景

我正在开发一款猜字母游戏,玩家猜测目标词中的字母,猜中即可获得对应分数。目前已按分值划分4组字母列表:

//List of letters:
private string[] fivePointsLetters = { "q", "w", "ď", "x", "ň", "ú", "g", "ä", "ô", "ó" };
private List<string> fourPointsLetters = new List<string> { "f", "ů", "š", "č", "ž", "ý", "ch", "í", "ú", "é", "á", "ý" };
private List<string> threePointsLetters = new List<string> { "ř", "h", "é", "b", "c", "ě", "j", "z", "á", "k", "f", "v", "r", "y" };
private List<string> twoPointsLetters = new List<string> { "a", "e", "i", "o", "u", "d", "n", "t", "v", "s", "l", "k", "r", "p", "í", "m" };

原本逻辑是随机选取4个2分字母、3个3分字母、2个4分字母和1个5分字母,凑成10个候选字母供玩家选择,但会出现候选字母中没有目标词正确字母的问题。现在计划从目标词拆分出的正确字母列表中选取30%的字母加入候选池,保证10个候选里约3个正确字母,需要实现按指定比例抽取元素的逻辑。

原随机选字母示例代码:

for (int i = 0; i < button2b_value.Count; i++)
{
    List<string> filteredStrings = twoPointsLetters.Except(usedLetters).Except(button2b_value).ToList();
    if (filteredStrings.Count == 0)
    {
        Debug.LogWarning("No possible 2 point letters in list");
    }
    else
    {
        int index = UnityEngine.Random.Range(0, filteredStrings.Count);
        view.RPC("Set2ButtonsValuesRPC", RpcTarget.All, filteredStrings[index], i);
    }
}

实现步骤与代码示例

1. 预处理正确字母列表

将目标词拆分为单个字母并去重,避免重复抽取同一正确字母:

// 假设targetWord是你的目标词字符串
List<string> correctLetters = targetWord.Select(c => c.ToString()).Distinct().ToList();

2. 计算需抽取的正确字母数量

按30%比例计算,同时处理边界情况(至少1个,不超过正确字母总数):

// 按30%比例计算数量,四舍五入取整
int requiredCorrectCount = Mathf.RoundToInt(correctLetters.Count * 0.3f);
// 确保数量合法:至少1个,且不超过正确字母总数
requiredCorrectCount = Math.Clamp(requiredCorrectCount, 1, correctLetters.Count);

3. 随机抽取指定数量的正确字母

通过临时列表避免修改原正确字母列表,随机选取后移除已选元素防止重复:

List<string> selectedCorrectLetters = new List<string>();
List<string> tempCorrectList = new List<string>(correctLetters); // 复制原列表用于抽取

for (int i = 0; i < requiredCorrectCount; i++)
{
    if (tempCorrectList.Count == 0) break;
    int randomIndex = UnityEngine.Random.Range(0, tempCorrectList.Count);
    selectedCorrectLetters.Add(tempCorrectList[randomIndex]);
    tempCorrectList.RemoveAt(randomIndex); // 移除已选字母,避免重复抽取
}

4. 调整候选字母池的补充数量

原本计划的各分值字母数量,需要减去已选中的正确字母中对应分值的数量:

// 原计划的各分值字母需求
int needTwoPoints = 4;
int needThreePoints = 3;
int needFourPoints = 2;
int needFivePoints = 1;

// 遍历已选正确字母,调整各分值的需求数量
foreach (string letter in selectedCorrectLetters)
{
    if (twoPointsLetters.Contains(letter)) needTwoPoints--;
    else if (threePointsLetters.Contains(letter)) needThreePoints--;
    else if (fourPointsLetters.Contains(letter)) needFourPoints--;
    else if (fivePointsLetters.Contains(letter)) needFivePoints--;
}

// 确保需求数量不为负数
needTwoPoints = Math.Max(0, needTwoPoints);
needThreePoints = Math.Max(0, needThreePoints);
needFourPoints = Math.Max(0, needFourPoints);
needFivePoints = Math.Max(0, needFivePoints);

5. 补充非正确字母到候选池

参考原有随机选字母逻辑,从各分值组中排除已选正确字母和已用字母,补充剩余数量的字母:

// 补充2分字母
for (int i = 0; i < needTwoPoints; i++)
{
    List<string> filtered = twoPointsLetters.Except(usedLetters).Except(selectedCorrectLetters).ToList();
    if (filtered.Count == 0)
    {
        Debug.LogWarning("No available 2-point letters left");
        break;
    }
    int index = UnityEngine.Random.Range(0, filtered.Count);
    string selected = filtered[index];
    view.RPC("Set2ButtonsValuesRPC", RpcTarget.All, selected, i);
    usedLetters.Add(selected);
}

// 补充3分字母
for (int i = 0; i < needThreePoints; i++)
{
    List<string> filtered = threePointsLetters.Except(usedLetters).Except(selectedCorrectLetters).ToList();
    if (filtered.Count == 0)
    {
        Debug.LogWarning("No available 3-point letters left");
        break;
    }
    int index = UnityEngine.Random.Range(0, filtered.Count);
    string selected = filtered[index];
    view.RPC("Set3ButtonsValuesRPC", RpcTarget.All, selected, i);
    usedLetters.Add(selected);
}

// 补充4分字母
for (int i = 0; i < needFourPoints; i++)
{
    List<string> filtered = fourPointsLetters.Except(usedLetters).Except(selectedCorrectLetters).ToList();
    if (filtered.Count == 0)
    {
        Debug.LogWarning("No available 4-point letters left");
        break;
    }
    int index = UnityEngine.Random.Range(0, filtered.Count);
    string selected = filtered[index];
    view.RPC("Set4ButtonsValuesRPC", RpcTarget.All, selected, i);
    usedLetters.Add(selected);
}

// 补充5分字母
for (int i = 0; i < needFivePoints; i++)
{
    List<string> filtered = fivePointsLetters.Except(usedLetters).Except(selectedCorrectLetters).ToList();
    if (filtered.Count == 0)
    {
        Debug.LogWarning("No available 5-point letters left");
        break;
    }
    int index = UnityEngine.Random.Range(0, filtered.Count);
    string selected = filtered[index];
    view.RPC("Set5ButtonsValuesRPC", RpcTarget.All, selected, i);
    usedLetters.Add(selected);
}

6. 将选中的正确字母加入候选池

把抽取的正确字母设置到候选按钮上(需根据你的按钮管理逻辑调整,这里假设存在空按钮可填充):

// 假设buttonList是所有候选按钮的列表,找到未设置的按钮并填充正确字母
foreach (string correctLetter in selectedCorrectLetters)
{
    int emptyButtonIndex = buttonList.FindIndex(btn => string.IsNullOrEmpty(btn.text));
    if (emptyButtonIndex != -1)
    {
        view.RPC("SetButtonValueRPC", RpcTarget.All, correctLetter, emptyButtonIndex);
        usedLetters.Add(correctLetter);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 23:28:08