MATLAB实现DND规则公平骰子掷骰器的循环优化求助
DnD属性掷骰器MATLAB代码优化建议
需求回顾
编程新手(仅学习5天),需开发MATLAB版DnD属性生成器:遵循掷4枚d6骰子,减去最小值的规则,生成8组总数值相同的掷骰结果以保证游戏公平。现有代码存在冗余、循环逻辑错误,需精简优化。
现有代码问题
clc, clearvars, format compact num1 = randi(6,1,4); num2 = randi(6,1,4); num3 = randi(6,1,4); num4 = randi(6,1,4); num5 = randi(6,1,4); num6 = randi(6,1,4); ab1 = sum(num1,"all") - min(num1); ab2 = sum(num2,"all") - min(num2); ab3 = sum(num3,"all") - min(num3); ab4 = sum(num4,"all") - min(num4); ab5 = sum(num5,"all") - min(num5); ab6 = sum(num6,"all") - min(num6); set = [ab1 ab2 ab3 ab4 ab5 ab6]; settot = sum(set,"all"); threshold = 78 while true if settot >= threshold disp(settot) break end disp("done") end
- 手动定义
num1-num6、ab1-ab6,代码冗余严重 - 循环逻辑失效:仅判断一次总和,不重新生成数据,要么直接退出要么无限输出"done"
- 未实现“生成8组总和相同结果”的核心需求
精简优化后的代码
clc, clearvars, format compact % 配置参数:8组、每组6个属性、总和阈值78 target_groups = 8; attrs_per_group = 6; threshold = 78; valid_groups = []; while size(valid_groups, 1) < target_groups % 一次性生成一组6个属性的4d6骰子数据(每行对应一个属性的4枚骰子) dice = randi(6, attrs_per_group, 4); % 计算每个属性值:求和后减去该行最小值 group_attrs = sum(dice, 2) - min(dice, [], 2); group_total = sum(group_attrs); % 筛选符合条件的组:总和达标,且与已存组总和一致(第一组为基准) if group_total >= threshold if isempty(valid_groups) valid_groups = [valid_groups; group_attrs]; elseif group_total == sum(valid_groups(1, :)) valid_groups = [valid_groups; group_attrs]; end end end % 输出结果 disp('生成的8组属性(每组6个值,总和一致):'); disp(valid_groups); disp(['每组总和:', num2str(sum(valid_groups(1, :)))]);
优化要点
- 消除冗余:用矩阵一次性生成所有骰子数据,替代手动重复定义变量,利用MATLAB向量化特性批量计算属性值
- 修复循环逻辑:循环内每次重新生成一组属性,严格筛选总和达标且与基准组总和一致的结果,直到凑够8组
- 效率提升:向量化运算(
sum、min按行处理)比逐变量计算快得多,符合MATLAB的最佳实践 - 需求落地:直接完成“8组总和相同”的核心要求,同时保留原有的总和阈值判断
内容的提问来源于stack exchange,提问作者TSC_2023
相关产品推荐
相关产品推荐

