打开matlab,创新新脚本,复制粘贴如下代码并保存。
现在,可以在脚本中直接修改输入参数和使用了,参数输入完成后直接点击运行即可。 更多详情请参考@完全忠实涵子
function artifact_calculator()
% 圣遗物强化概率计算器 - MATLAB版本
% 基于原C++代码改写,用于计算游戏装备强化后获得更高评分的概率
% 源码来自B站@完全忠实函子,uid:3546373515381442
%% 预设配置
criteria_presets = containers.Map();
criteria_presets('atkem') = [777, 777, 583, 583]; % cr, cd, em, atk%
criteria_presets('atk') = [777, 777, 583, 0]; % cr, cd, atk%, 其他
criteria_presets('hpem') = [777, 777, 777, 777]; % cr, cd, em, hp%
criteria_presets('hp') = [777, 777, 777, 0]; % cr, cd, hp%, 其他
% 词条成长值映射 (对应原代码value_to_growths)
value_growths = containers.Map();
value_growths('cr') = 389; % 暴击率
value_growths('cd') = 777; % 暴击伤害
value_growths('em') = 2331; % 元素精通
value_growths('atk%') = 583; % 攻击力%
value_growths('atk') = 1945; % 攻击力
value_growths('hp%') = 583; % 生命值%
value_growths('hp') = 29875; % 生命值
value_growths('def%') = 729; % 防御力%
value_growths('def') = 2315; % 防御力
value_growths('er') = 648; % 元素充能效率

%% 输入参数
sub_types = {'cr', 'cd', 'em', 'atk'}; % 4个词条类型
current_values = [3.9, 19.4, 72, 14]; % 当前显示数值
base_growths = [4, 1, 1, 1]; % 基础成长值 (1-4)
preset_name = 'atk'; % 使用的预设
growth_times = 5; % 强化次数 (默认5次,-4选项时为4次)
n_guarantees = 2; % 前n次保底在前2个词条
alt_score = 50; % 备选分数用于比较
%% 主计算流程
fprintf('=== 圣遗物强化概率计算器 ===\n\n');
% 获取评分权重
if criteria_presets.isKey(preset_name)
criteria = criteria_presets(preset_name);
else
error('未知预设: %s', preset_name);
end
% 转换当前数值为内部格式
original = zeros(1, 4);
for i = 1:4
if value_growths.isKey(sub_types{i})
growth_val = value_growths(sub_types{i});
original(i) = round(current_values(i) * 1000 / growth_val);
else
error('未知词条类型: %s', sub_types{i});
end
end
% 基础成长值转换 (1->7, 2->8, 3->9, 4->10)
base = base_growths + 6;
% 计算当前分数
current_score = mult_add(original, criteria);
% 显示转换函数
function display_name = get_stat_display(stat_name)
switch stat_name
case 'cr', display_name = 'cr(暴击率)';
case 'cd', display_name = 'cd(暴击伤害)';
case 'em', display_name = 'em(元素精通)';
case 'atk%', display_name = 'atk%(攻击力%)';
case 'atk', display_name = 'atk(攻击力)';
case 'hp%', display_name = 'hp%(生命值%)';
case 'hp', display_name = 'hp(生命值)';
case 'def%', display_name = 'def%(防御力%)';
case 'def', display_name = 'def(防御力)';
case 'er', display_name = 'er(元素充能效率)';
otherwise, display_name = stat_name;
end
end
function preset_display = get_preset_display(preset_name)
switch preset_name
case 'atkem', preset_display = 'atkem(攻击+精通型)';
case 'atk', preset_display = 'atk(攻击型)';
case 'hpem', preset_display = 'hpem(生命+精通型)';
case 'hp', preset_display = 'hp(生命型)';
otherwise, preset_display = preset_name;
end
end
% 显示当前状态
fprintf('装备词条: ');
for i = 1:4
fprintf('%s %.1f', get_stat_display(sub_types{i}), current_values(i));
if i < 4, fprintf(', '); end
end
fprintf(' | 总分: %.2f\n', current_score / 1000);
fprintf('基础成长: ');
for i = 1:4
fprintf('%s %d档', get_stat_display(sub_types{i}), base_growths(i));
if i < 4, fprintf(', '); end
end
fprintf('\n');
fprintf('使用预设: %s\n', get_preset_display(preset_name));
fprintf('保底强化: 前%d次必定强化前2个词条\n\n', n_guarantees);
% 生成所有可能的强化结果
fprintf('正在计算所有可能的强化路径...\n');
tic;
grown_subs = grow5(base, growth_times, growth_times - n_guarantees);
fprintf('生成了 %d 种可能结果,用时 %.2f 秒\n', length(grown_subs), toc);
% 直接计算所有分数
all_scores = zeros(length(grown_subs), 1);
for i = 1:length(grown_subs)
result = grown_subs{i};
all_scores(i) = mult_add(result, criteria);
end
expected_total = 2^(4 * growth_times);
fprintf('总结果数: %d (期望: %d)\n', length(all_scores), expected_total);
% 分析结果
improve_count = sum(all_scores > current_score);
improve_prob = improve_count / length(all_scores);
if improve_count > 0
better_scores = all_scores(all_scores > current_score);
expected_improvement = mean(better_scores) - current_score;
else
expected_improvement = 0;
end
fprintf('\n=== 强化结果分析 ===\n');
fprintf('使用启圣之尘后评分提升概率: %.1f%%\n', improve_prob * 100);
fprintf('若评分提升,期望增加分数: %.2f\n', expected_improvement / 1000);
% 简单建议
if improve_prob > 0.6
fprintf('💡 建议: 提升概率很高,推荐使用\n');
elseif improve_prob > 0.3
fprintf('💡 建议: 提升概率适中,可以考虑\n');
else
fprintf('💡 建议: 提升概率较低,建议谨慎\n');
end
% 备选分数分析
if ~isempty(alt_score)
alt_score_int = round(alt_score * 1000);
alt_count = sum(all_scores > alt_score_int);
alt_prob = alt_count / length(all_scores);
if alt_count > 0
alt_better_scores = all_scores(all_scores > alt_score_int);
alt_expected_improvement = mean(alt_better_scores) - alt_score_int;
else
alt_expected_improvement = 0;
end
fprintf('\n--- 目标分数对比分析 ---\n');
fprintf('目标分数: %.2f\n', alt_score);
fprintf('达到目标分数概率: %.1f%%\n', alt_prob * 100);
fprintf('若达到目标,期望超出分数: %.2f\n', alt_expected_improvement / 1000);
end
% 带信息面板的可视化
figure('Name', '启圣之尘强化分数分布', 'Position', [100, 100, 1200, 600]);
% 分数分布 - 占左侧1/3
subplot(1, 3, 1);
histogram(all_scores/1000, 50, 'Normalization', 'probability');
hold on;
y_max = max(ylim);
h1 = plot([current_score/1000, current_score/1000], [0, y_max], 'r-', 'LineWidth', 2);
legend_handles = h1;
legend_labels = {'当前分数'};
if ~isempty(alt_score)
h2 = plot([alt_score, alt_score], [0, y_max], 'g--', 'LineWidth', 2);
legend_handles = [legend_handles, h2];
legend_labels{end+1} = '目标分数';
end
xlabel('分数'); ylabel('概率'); title('分数分布');
legend(legend_handles, legend_labels, 'Location', 'northeast');
% 累积概率 - 占中间1/3
subplot(1, 3, 2);
sorted_scores = sort(all_scores);
y_values = (1:length(sorted_scores)) / length(sorted_scores) * 100;
plot(sorted_scores/1000, y_values, 'b-', 'LineWidth', 2);
hold on;
plot([current_score/1000, current_score/1000], [0, 100], 'r-', 'LineWidth', 2);
if ~isempty(alt_score)
plot([alt_score, alt_score], [0, 100], 'g--', 'LineWidth', 2);
end
xlabel('分数'); ylabel('累积概率 (%)'); title('累积概率');
ylim([0, 100]);
% 信息面板 - 占右侧1/3
subplot(1, 3, 3);
axis off; % 关闭坐标轴
% 准备信息文本
info_text = {};
info_text{end+1} = '═══ 圣遗物信息 ═══';
info_text{end+1} = '';
% 当前词条信息 - 合并显示数值和档位
for i = 1:4
info_text{end+1} = sprintf('%s: %.1f %d档', ...
get_stat_display(sub_types{i}), current_values(i), base_growths(i));
end
info_text{end+1} = sprintf('当前总分: %.2f', current_score/1000);
info_text{end+1} = '';
% 评分规则
info_text{end+1} = '═══ 评分规则 ═══';
info_text{end+1} = sprintf('预设: %s', get_preset_display(preset_name));
info_text{end+1} = '权重设置:';
for i = 1:4
if criteria(i) > 0
info_text{end+1} = sprintf(' %s: %d', get_stat_display(sub_types{i}), criteria(i));
end
end
info_text{end+1} = '';
% 强化设置
info_text{end+1} = '═══ 强化设置 ═══';
info_text{end+1} = sprintf('强化次数: %d次', growth_times);
info_text{end+1} = sprintf('保底强化: 前%d次', n_guarantees);
info_text{end+1} = sprintf('计算结果: %d种可能', length(all_scores));
info_text{end+1} = '';
% 分析结果
info_text{end+1} = '═══ 分析结果 ═══';
info_text{end+1} = sprintf('提升概率: %.1f%%', improve_prob * 100);
info_text{end+1} = sprintf('期望提升: %.2f分', expected_improvement / 1000);
if improve_prob > 0.6
suggestion = '推荐使用';
elseif improve_prob > 0.3
suggestion = '可以考虑';
else
suggestion = '建议谨慎';
end
info_text{end+1} = sprintf('使用建议: %s', suggestion);
info_text{end+1} = '';
% 目标分数分析
if ~isempty(alt_score)
info_text{end+1} = '═══ 目标分析 ═══';
info_text{end+1} = sprintf('目标分数: %.2f', alt_score);
info_text{end+1} = sprintf('达成概率: %.1f%%', alt_prob * 100);
info_text{end+1} = sprintf('期望超出: %.2f分', alt_expected_improvement / 1000);
end
% 在子图中显示文本信息
text(0.05, 0.95, info_text, 'Units', 'normalized', 'VerticalAlignment', 'top', ...
'FontSize', 9, 'FontName', 'SimHei', 'Interpreter', 'none');
fprintf('\nDone!\n');
end
%% 辅助函数
function result = mult_add(a, b)
% 向量点积计算
result = sum(a .* b);
end
function results = grow1(sub, only2)
% 模拟单次强化的16种可能结果
if nargin < 2
only2 = false;
end
results = cell(16, 1);
for i = 0:15 % 改为0开始,对应C++逻辑
new_sub = sub;
sub_to_grow = floor(i / 4) + 1; % 0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3 -> 1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4
if only2
sub_to_grow = mod(floor(i / 4), 2) + 1; % 限制为1-2
end
growth = mod(i, 4) + 7; % 7,8,9,10,7,8,9,10...
new_sub(sub_to_grow) = new_sub(sub_to_grow) + growth;
results{i+1} = new_sub;
end
end
function results = grow5(sub, max_growth, allow_misses)
% 递归模拟多次强化
if max_growth == 0
results = {sub};
return;
end
results = {};
subs_next = grow1(sub, allow_misses == 0);
for i = 1:length(subs_next)
s = subs_next{i};
% 检查是否歪到后两个词条
if_miss = (s(3) > sub(3)) || (s(4) > sub(4));
sub_results = grow5(s, max_growth - 1, allow_misses - if_miss);
results = [results; sub_results];
end
end
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删