新球体育网(球探)手机端网页,在赛程页面加入“统计”按钮,统计当前页面里所有已完场的比赛。在分析页面加入“统计”,“表格”,“预测”按钮,“统计”按钮统计当前页面这场比赛。“表格”按钮生成各个公司对已统计场次的准确度表格,误差越低的公司越准确。选择公司后可点击“预测”按钮,比较两极分化的公司预测赛果。
// ==UserScript==
// @name 新球体育网欧赔统计
// @namespace http://dol.freevar.com/
// @version 0.941
// @description 新球体育网(球探)手机端网页,在赛程页面加入“统计”按钮,统计当前页面里所有已完场的比赛。在分析页面加入“统计”,“表格”,“预测”按钮,“统计”按钮统计当前页面这场比赛。“表格”按钮生成各个公司对已统计场次的准确度表格,误差越低的公司越准确。选择公司后可点击“预测”按钮,比较两极分化的公司预测赛果。
// @author Dolphin
// @match https://m.titan007.com/info/*
// @match https://m.titan007.com/Analy/Analysis/*
// @match https://m.titan007.com/analy/Analysis/*
// @run-at document-end
// @grant GM_xmlhttpRequest
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 存储表格数据
let tableData = [];
// 检查当前页面类型并执行相应操作
if (window.location.href.includes('/info/')) {
// info页面
addButtonsToInfoPage();
} else if (window.location.href.includes('/Analysis/')) {
// Analysis页面
addButtonsToAnalysisPage();
}
/**
* 在info页面添加按钮
*/
function addButtonsToInfoPage() {
const contentDiv = document.getElementById('content');
if (!contentDiv) return;
// 创建按钮容器
const buttonContainer = document.createElement('div');
buttonContainer.style.cssText = 'text-align: right;';
// 清除按钮
const clearBtn = document.createElement('button');
clearBtn.id = 'clearEuroStatsBtn';
clearBtn.textContent = '清除';
clearBtn.style.cssText = 'margin: 5px; font-size: 18px; background: #fbb;';
// 统计按钮
const statsBtn = document.createElement('button');
statsBtn.id = 'calcEuroStatsBtn';
statsBtn.textContent = '统计';
statsBtn.style.cssText = 'margin: 5px; font-size: 18px; background: #bfb;';
// 添加按钮事件
clearBtn.addEventListener('click', clearEuroStats);
statsBtn.addEventListener('click', calculateEuroStatsForInfoPage);
// 添加按钮到容器
buttonContainer.appendChild(clearBtn);
buttonContainer.appendChild(statsBtn);
// 插入到content第一个元素前
contentDiv.insertBefore(buttonContainer, contentDiv.firstChild);
}
/**
* 在Analysis页面添加按钮
*/
function addButtonsToAnalysisPage() {
const contentDiv = document.getElementById('content');
if (!contentDiv) return;
// 创建按钮容器
const buttonContainer = document.createElement('div');
buttonContainer.style.cssText = 'text-align: right;';
// 清除按钮
const clearBtn = document.createElement('button');
clearBtn.id = 'clearEuroStatsBtn';
clearBtn.textContent = '清除';
clearBtn.style.cssText = 'margin: 5px; font-size: 18px; background: #fbb;';
// 统计按钮
const statsBtn = document.createElement('button');
statsBtn.id = 'calcEuroStatsBtn';
statsBtn.textContent = '统计';
statsBtn.style.cssText = 'margin: 5px; font-size: 18px; background: #bfb;';
// 表格按钮
const tableBtn = document.createElement('button');
tableBtn.id = 'showTableBtn';
tableBtn.textContent = '表格';
tableBtn.style.cssText = 'margin: 5px; font-size: 18px; background: #ffb;';
// 预测按钮
const predictBtn = document.createElement('button');
predictBtn.id = 'predictBtn';
predictBtn.textContent = '预测';
predictBtn.style.cssText = 'margin: 5px; font-size: 18px; background: #bbf;';
// 添加按钮事件
clearBtn.addEventListener('click', clearEuroStats);
statsBtn.addEventListener('click', calculateEuroStatsForAnalysisPage);
tableBtn.addEventListener('click', showTable);
predictBtn.addEventListener('click', showPrediction);
// 添加按钮到容器
buttonContainer.appendChild(clearBtn);
buttonContainer.appendChild(statsBtn);
buttonContainer.appendChild(tableBtn);
buttonContainer.appendChild(predictBtn);
// 插入到content第一个元素前
contentDiv.insertBefore(buttonContainer, contentDiv.firstChild);
}
/**
* 清除统计数据
*/
function clearEuroStats() {
localStorage.removeItem('euroStats');
alert('统计数据已清除!');
}
/**
* 为info页面统计误差
*/
function calculateEuroStatsForInfoPage() {
const btn = document.getElementById('calcEuroStatsBtn');
btn.disabled = true;
btn.textContent = '统计中';
// 查找所有红色比分元素
const redSpans = document.querySelectorAll('span[style*="color:red"], span.red');
const matches = [];
// 提取比赛信息
redSpans.forEach(span => {
const tr = span.closest('tr');
if (!tr) return;
// 提取比赛ID
const onclickAttr = tr.getAttribute('onclick');
if (!onclickAttr) return;
const matchIdMatch = onclickAttr.match(/ToAnaly\((\d+)/);
if (!matchIdMatch) return;
const scheduleId = matchIdMatch[1];
// 提取比分
const scoreText = span.textContent.trim();
if (!scoreText || !scoreText.includes(':')) return;
matches.push({
scheduleId: scheduleId,
score: scoreText
});
});
if (matches.length === 0) {
alert('没有完场比分!');
btn.disabled = false;
btn.textContent = '统计';
return;
}
// 开始逐场比赛统计
processMatchesSequentially(matches, 0, btn);
}
/**
* 为Analysis页面统计误差
*/
function calculateEuroStatsForAnalysisPage() {
const btn = document.getElementById('calcEuroStatsBtn');
btn.disabled = true;
btn.textContent = '统计中';
// 从页面变量获取比赛ID
if (typeof scheduleId === 'undefined') {
alert('未找到比赛ID');
btn.disabled = false;
btn.textContent = '统计';
return;
}
// 提取比分
const homeScoreEl = document.getElementById('homeScore');
const guestScoreEl = document.getElementById('guestScore');
if (!homeScoreEl || !guestScoreEl) {
alert('没有比分!');
btn.disabled = false;
btn.textContent = '统计';
return;
}
const homeScore = parseInt(homeScoreEl.textContent.trim());
const guestScore = parseInt(guestScoreEl.textContent.trim());
if (isNaN(homeScore) || isNaN(guestScore)) {
alert('比分数据无效');
btn.disabled = false;
btn.textContent = '统计';
return;
}
const score = `${homeScore}:${guestScore}`;
// 单场比赛统计
const matches = [{
scheduleId: scheduleId.toString(),
score: score
}];
processMatchesSequentially(matches, 0, btn);
}
/**
* 顺序处理多场比赛
*/
function processMatchesSequentially(matches, index, btn) {
if (index >= matches.length) {
// 所有比赛处理完成
btn.disabled = false;
btn.textContent = '统计';
if (match.length > 1) alert(`已统计 ${matches.length} 场比赛`);
return;
}
const match = matches[index];
// 获取赔率数据
getOddsData(match.scheduleId)
.then(companiesData => {
if (!companiesData || companiesData.length === 0) {
console.warn(`比赛 ${match.scheduleId} 无赔率数据`);
// 继续处理下一场
setTimeout(() => {
processMatchesSequentially(matches, index + 1, btn);
}, 100);
return;
}
// 计算误差
const errorData = calculateMatchError(companiesData, match.score, match.scheduleId);
// 保存到localStorage
saveErrorData(errorData);
// 间隔100毫秒后处理下一场
setTimeout(() => {
processMatchesSequentially(matches, index + 1, btn);
}, 100);
})
.catch(error => {
console.error(`处理比赛 ${match.scheduleId} 时出错:`, error);
// 继续处理下一场
setTimeout(() => {
processMatchesSequentially(matches, index + 1, btn);
}, 100);
});
}
/**
* 获取赔率数据
*/
function getOddsData(scheduleId) {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: 'GET',
url: `https://txt.titan007.com/1x2/${scheduleId}.js`,
timeout: 10000,
onload: function(response) {
if (response.status !== 200) {
alert('请求失败,比赛ID: ' + scheduleId);
reject(new Error(`请求失败: ${response.status}`));
return;
}
try {
// 提取game数组数据
const gameMatch = response.responseText.match(/game=Array\(([\s\S]*?)\);/);
if (!gameMatch) {
resolve([]);
return;
}
const gameData = gameMatch[1];
// 清理数据并解析
const companies = parseGameData(gameData);
resolve(companies);
} catch (error) {
reject(error);
}
},
onerror: function(error) {
reject(error);
},
ontimeout: function() {
reject(new Error('请求超时'));
}
});
});
}
/**
* 解析game数据
*/
function parseGameData(gameData) {
// 移除首尾引号并按行分割
const cleanedData = gameData.replace(/^"|"$/g, '').replace(/\\"/g, '"');
const items = cleanedData.split('","');
const companies = [];
items.forEach(item => {
const parts = item.split('|');
if (parts.length >= 6) {
const companyName = parts[2].trim();
const winOdds = parseFloat(parts[3]);
const drawOdds = parseFloat(parts[4]);
const loseOdds = parseFloat(parts[5]);
if (companyName && !isNaN(winOdds) && !isNaN(drawOdds) && !isNaN(loseOdds)) {
// 计算归一化概率
const winProb = 100 / winOdds;
const drawProb = 100 / drawOdds;
const loseProb = 100 / loseOdds;
const totalProb = winProb + drawProb + loseProb;
// 归一化
const normalizedWinProb = winProb / totalProb * 100;
const normalizedDrawProb = drawProb / totalProb * 100;
const normalizedLoseProb = loseProb / totalProb * 100;
companies.push({
name: companyName,
winOdds: winOdds,
drawOdds: drawOdds,
loseOdds: loseOdds,
winProb: normalizedWinProb,
drawProb: normalizedDrawProb,
loseProb: normalizedLoseProb
});
}
}
});
return companies;
}
/**
* 计算单场比赛误差
*/
function calculateMatchError(companiesData, score, scheduleId) {
// 解析比分
const [homeScoreStr, awayScoreStr] = score.split(':');
const homeScore = parseInt(homeScoreStr);
const awayScore = parseInt(awayScoreStr);
if (isNaN(homeScore) || isNaN(awayScore)) {
return {};
}
const goalDiff = homeScore - awayScore;
let standardProb = 0;
let targetType = ''; // 'win', 'draw', 或 'lose'
// 确定标准概率和目标类型
if (goalDiff === 0) {
// 平局
targetType = 'draw';
// 找出平概率最高的公司
companiesData.sort((a, b) => b.drawProb - a.drawProb);
standardProb = companiesData[0].drawProb;
} else if (Math.abs(goalDiff) === 1) {
// 净胜1球
if (goalDiff > 0) {
targetType = 'win';
// 找出胜概率最接近60%的公司
companiesData.sort((a, b) => Math.abs(a.winProb - 60) - Math.abs(b.winProb - 60));
standardProb = companiesData[0].winProb;
} else {
targetType = 'lose';
// 找出负概率最接近60%的公司
companiesData.sort((a, b) => Math.abs(a.loseProb - 60) - Math.abs(b.loseProb - 60));
standardProb = companiesData[0].loseProb;
}
} else if (Math.abs(goalDiff) === 2) {
// 净胜2球
if (goalDiff > 0) {
targetType = 'win';
// 找出胜概率最接近80%的公司
companiesData.sort((a, b) => Math.abs(a.winProb - 80) - Math.abs(b.winProb - 80));
standardProb = companiesData[0].winProb;
} else {
targetType = 'lose';
// 找出负概率最接近80%的公司
companiesData.sort((a, b) => Math.abs(a.loseProb - 80) - Math.abs(b.loseProb - 80));
standardProb = companiesData[0].loseProb;
}
} else {
// 净胜2球以上
if (goalDiff > 0) {
targetType = 'win';
// 找出胜概率最高的公司
companiesData.sort((a, b) => b.winProb - a.winProb);
standardProb = companiesData[0].winProb;
} else {
targetType = 'lose';
// 找出负概率最高的公司
companiesData.sort((a, b) => b.loseProb - a.loseProb);
standardProb = companiesData[0].loseProb;
}
}
// 计算各公司误差
const errorData = {};
companiesData.forEach(company => {
let companyProb = 0;
switch(targetType) {
case 'win':
companyProb = company.winProb;
break;
case 'draw':
companyProb = company.drawProb;
break;
case 'lose':
companyProb = company.loseProb;
break;
}
const error = standardProb - companyProb;
errorData[company.name] = {
[scheduleId]: error
};
});
return errorData;
}
/**
* 保存误差数据到localStorage
*/
function saveErrorData(newErrorData) {
// 读取现有数据
let euroStats = JSON.parse(localStorage.getItem('euroStats') || '{}');
// 合并新数据
Object.keys(newErrorData).forEach(companyName => {
if (!euroStats[companyName]) {
euroStats[companyName] = {};
}
// 合并比赛数据
Object.assign(euroStats[companyName], newErrorData[companyName]);
});
// 保存回localStorage
localStorage.setItem('euroStats', JSON.stringify(euroStats));
}
/**
* 显示表格
*/
function showTable() {
// 移除现有表格
const existingTable = document.getElementById('euroStatsTable');
if (existingTable) {
existingTable.remove();
}
// 获取当前比赛ID
if (typeof scheduleId === 'undefined') {
alert('未找到比赛ID');
return;
}
const scheduleIdStr = scheduleId.toString();
// 获取赔率数据
getOddsData(scheduleIdStr)
.then(companiesData => {
if (!companiesData || companiesData.length === 0) {
alert('无赔率数据');
return;
}
// 获取误差统计数据
const euroStats = JSON.parse(localStorage.getItem('euroStats') || '{}');
// 计算每个公司的统计数据
tableData = [];
companiesData.forEach(company => {
const companyName = company.name;
const companyStats = euroStats[companyName] || {};
// 计算开盘次数和平均误差
const matchIds = Object.keys(companyStats);
const openCount = matchIds.length;
let totalAbsError = 0;
matchIds.forEach(matchId => {
totalAbsError += Math.abs(companyStats[matchId]);
});
const avgError = openCount > 0 ? totalAbsError / openCount : 0;
tableData.push({
name: companyName,
openCount: openCount,
avgError: avgError,
winProb: company.winProb,
drawProb: company.drawProb,
loseProb: company.loseProb
});
});
// 按平均误差排序
tableData.sort((a, b) => a.avgError - b.avgError);
// 创建表格
createTable();
})
.catch(error => {
alert(`获取数据失败: ${error.message}`);
});
}
/**
* 创建表格
*/
function createTable() {
// 创建表格容器
const tableContainer = document.createElement('div');
tableContainer.id = 'euroStatsTable';
tableContainer.style.cssText = 'overflow-x: auto;';
// 创建表格
const table = document.createElement('table');
table.style.cssText = 'border-collapse: collapse; font-size: 16px; text-align: center; margin: 0 auto;';
// 创建表头
const thead = document.createElement('thead');
thead.style.cssText = 'background-color: #efe;';
const headerRow = document.createElement('tr');
const headers = ['公司', '开盘', '平均误差', '胜概率', '平概率', '负概率', '选'];
headers.forEach(headerText => {
const th = document.createElement('th');
th.textContent = headerText;
th.style.cssText = 'border: 1px solid #888;';
headerRow.appendChild(th);
});
thead.appendChild(headerRow);
table.appendChild(thead);
// 创建表格主体
const tbody = document.createElement('tbody');
tableData.forEach((company, index) => {
const row = document.createElement('tr');
row.style.cssText = index % 2 === 0 ? 'background-color: #fff;' : 'background-color: #ffe;';
// 公司名称
const nameCell = document.createElement('td');
nameCell.textContent = company.name;
nameCell.style.cssText = 'font-size: 12px; border: 1px solid #888;';
row.appendChild(nameCell);
// 开盘次数
const openCountCell = document.createElement('td');
openCountCell.textContent = company.openCount;
openCountCell.style.cssText = 'border: 1px solid #888;';
row.appendChild(openCountCell);
// 平均误差
const avgErrorCell = document.createElement('td');
avgErrorCell.textContent = company.avgError.toFixed(4);
avgErrorCell.style.cssText = 'border: 1px solid #888;';
row.appendChild(avgErrorCell);
// 胜平负概率
const winProbCell = document.createElement('td');
winProbCell.textContent = company.winProb ? company.winProb.toFixed(2) : '没开盘';
winProbCell.style.cssText = 'border: 1px solid #888;';
row.appendChild(winProbCell);
const drawProbCell = document.createElement('td');
drawProbCell.textContent = company.drawProb ? company.drawProb.toFixed(2) : '没开盘';
drawProbCell.style.cssText = 'border: 1px solid #888;';
row.appendChild(drawProbCell);
const loseProbCell = document.createElement('td');
loseProbCell.textContent = company.loseProb ? company.loseProb.toFixed(2) : '没开盘';
loseProbCell.style.cssText = 'border: 1px solid #888;';
row.appendChild(loseProbCell);
// 选择复选框
const selectCell = document.createElement('td');
selectCell.style.cssText = 'border: 1px solid #888;';
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = `company_${index}`;
checkbox.style.position = 'initial';
checkbox.dataset.companyName = company.name;
selectCell.appendChild(checkbox);
row.appendChild(selectCell);
tbody.appendChild(row);
});
table.appendChild(tbody);
tableContainer.appendChild(table);
// 插入到按钮容器后面
const buttonContainer = document.querySelector('#content > div:first-child');
if (buttonContainer && buttonContainer.nextSibling) {
buttonContainer.parentNode.insertBefore(tableContainer, buttonContainer.nextSibling);
} else {
document.getElementById('content').appendChild(tableContainer);
}
}
/**
* 显示预测结果
*/
function showPrediction() {
// 移除现有预测结果
const existingPrediction = document.getElementById('predictionResult');
if (existingPrediction) {
existingPrediction.remove();
}
if (!tableData || tableData.length === 0) {
alert('请先点击"表格"按钮生成数据');
return;
}
// 获取已选择的公司
const selectedCompanies = [];
const checkboxes = document.querySelectorAll('#euroStatsTable input[type="checkbox"]');
checkboxes.forEach(checkbox => {
if (checkbox.checked && checkbox.dataset.companyName) {
const companyName = checkbox.dataset.companyName;
const companyData = tableData.find(c => c.name === companyName);
if (companyData) {
selectedCompanies.push(companyData);
}
}
});
if (selectedCompanies.length < 2) {
alert('请至少选择两家公司');
return;
}
// 按平均误差排序
selectedCompanies.sort((a, b) => a.avgError - b.avgError);
// 分组
let lowErrorGroup = [];
let highErrorGroup = [];
if (selectedCompanies.length % 2 === 1) {
// 奇数个,去掉中间那个
const middleIndex = Math.floor(selectedCompanies.length / 2);
lowErrorGroup = selectedCompanies.slice(0, middleIndex);
highErrorGroup = selectedCompanies.slice(middleIndex + 1);
} else {
// 偶数个,平均分
const half = selectedCompanies.length / 2;
lowErrorGroup = selectedCompanies.slice(0, half);
highErrorGroup = selectedCompanies.slice(half);
}
// 计算各组平均概率
const allAvg = calculateAverageProbabilities(selectedCompanies);
const lowAvg = calculateAverageProbabilities(lowErrorGroup);
const highAvg = calculateAverageProbabilities(highErrorGroup);
// 创建预测结果显示表格
const predictionDiv = document.createElement('div');
predictionDiv.id = 'predictionResult';
// 标题
const title = document.createElement('h3');
title.textContent = '对比概率,让1球60%,让2球80%';
title.style.cssText = 'padding: 5px; background: #eee;';
predictionDiv.appendChild(title);
// 创建预测结果表格
const predictionTable = document.createElement('table');
predictionTable.style.cssText = 'border-collapse: collapse; font-size: 16px; text-align: center; margin: 5px auto;';
// 创建表头
const predictionThead = document.createElement('thead');
predictionThead.style.cssText = 'background-color: #eef;';
const predictionHeaderRow = document.createElement('tr');
const predictionHeaders = ['分组', '个', '平均胜', '平均平', '平均负'];
predictionHeaders.forEach(headerText => {
const th = document.createElement('th');
th.textContent = headerText;
th.style.cssText = 'border: 1px solid #888;';
predictionHeaderRow.appendChild(th);
});
predictionThead.appendChild(predictionHeaderRow);
predictionTable.appendChild(predictionThead);
// 创建表格主体
const predictionTbody = document.createElement('tbody');
// 误差偏小组数据行
const lowErrorRow = document.createElement('tr');
const lowErrorGroupCell = document.createElement('td');
lowErrorGroupCell.textContent = '误差小';
lowErrorGroupCell.style.cssText = 'border: 1px solid #888;';
lowErrorRow.appendChild(lowErrorGroupCell);
const lowErrorCountCell = document.createElement('td');
lowErrorCountCell.textContent = lowErrorGroup.length;
lowErrorCountCell.style.cssText = 'border: 1px solid #888;';
lowErrorRow.appendChild(lowErrorCountCell);
const lowWinProbCell = document.createElement('td');
lowWinProbCell.textContent = lowAvg.win.toFixed(2);
lowWinProbCell.style.cssText = 'border: 1px solid #888;';
lowErrorRow.appendChild(lowWinProbCell);
const lowDrawProbCell = document.createElement('td');
lowDrawProbCell.textContent = lowAvg.draw.toFixed(2);
lowDrawProbCell.style.cssText = 'border: 1px solid #888;';
lowErrorRow.appendChild(lowDrawProbCell);
const lowLoseProbCell = document.createElement('td');
lowLoseProbCell.textContent = lowAvg.lose.toFixed(2);
lowLoseProbCell.style.cssText = 'border: 1px solid #888;';
lowErrorRow.appendChild(lowLoseProbCell);
predictionTbody.appendChild(lowErrorRow);
// 所有已选公司数据行
const allGroupRow = document.createElement('tr');
allGroupRow.style.cssText = 'background-color: #ffe;';
const allGroupCell = document.createElement('td');
allGroupCell.textContent = '已选择';
allGroupCell.style.cssText = 'border: 1px solid #888;';
allGroupRow.appendChild(allGroupCell);
const allCountCell = document.createElement('td');
allCountCell.textContent = selectedCompanies.length;
allCountCell.style.cssText = 'border: 1px solid #888;';
allGroupRow.appendChild(allCountCell);
const allWinProbCell = document.createElement('td');
allWinProbCell.textContent = allAvg.win.toFixed(2);
allWinProbCell.style.cssText = 'border: 1px solid #888;';
allGroupRow.appendChild(allWinProbCell);
const allDrawProbCell = document.createElement('td');
allDrawProbCell.textContent = allAvg.draw.toFixed(2);
allDrawProbCell.style.cssText = 'border: 1px solid #888;';
allGroupRow.appendChild(allDrawProbCell);
const allLoseProbCell = document.createElement('td');
allLoseProbCell.textContent = allAvg.lose.toFixed(2);
allLoseProbCell.style.cssText = 'border: 1px solid #888;';
allGroupRow.appendChild(allLoseProbCell);
predictionTbody.appendChild(allGroupRow);
// 误差偏大组数据行
const highErrorRow = document.createElement('tr');
const highErrorGroupCell = document.createElement('td');
highErrorGroupCell.textContent = '误差大';
highErrorGroupCell.style.cssText = 'border: 1px solid #888;';
highErrorRow.appendChild(highErrorGroupCell);
const highErrorCountCell = document.createElement('td');
highErrorCountCell.textContent = highErrorGroup.length;
highErrorCountCell.style.cssText = 'border: 1px solid #888;';
highErrorRow.appendChild(highErrorCountCell);
const highWinProbCell = document.createElement('td');
highWinProbCell.textContent = highAvg.win.toFixed(2);
highWinProbCell.style.cssText = 'border: 1px solid #888;';
highErrorRow.appendChild(highWinProbCell);
const highDrawProbCell = document.createElement('td');
highDrawProbCell.textContent = highAvg.draw.toFixed(2);
highDrawProbCell.style.cssText = 'border: 1px solid #888;';
highErrorRow.appendChild(highDrawProbCell);
const highLoseProbCell = document.createElement('td');
highLoseProbCell.textContent = highAvg.lose.toFixed(2);
highLoseProbCell.style.cssText = 'border: 1px solid #888;';
highErrorRow.appendChild(highLoseProbCell);
predictionTbody.appendChild(highErrorRow);
predictionTable.appendChild(predictionTbody);
predictionDiv.appendChild(predictionTable);
// 插入到表格后面
const tableContainer = document.getElementById('euroStatsTable');
if (tableContainer) {
tableContainer.parentNode.insertBefore(predictionDiv, tableContainer);
}
}
/**
* 计算平均概率
*/
function calculateAverageProbabilities(companies) {
if (companies.length === 0) {
return { win: 0, draw: 0, lose: 0 };
}
let totalWin = 0;
let totalDraw = 0;
let totalLose = 0;
let count = 0;
companies.forEach(company => {
if (company.winProb && company.drawProb && company.loseProb) {
totalWin += company.winProb;
totalDraw += company.drawProb;
totalLose += company.loseProb;
count++;
}
});
if (count === 0) {
return { win: 0, draw: 0, lose: 0 };
}
return {
win: totalWin / count,
draw: totalDraw / count,
lose: totalLose / count
};
}
})();