console
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>大乐透智能选号模拟器 - 动态优先级版</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 1000px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
h1 {
color: #e60012;
text-align: center;
}
.container {
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
.section {
margin-bottom: 20px;
padding: 15px;
border: 1px solid #ddd;
border-radius: 5px;
}
.section-title {
font-weight: bold;
margin-bottom: 10px;
color: #e60012;
}
table {
width: 100%;
border-collapse: collapse;
margin-bottom: 15px;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: center;
}
th {
background-color: #f2f2f2;
}
input {
width: 40px;
text-align: center;
padding: 5px;
}
button {
background-color: #e60012;
color: white;
border: none;
padding: 10px 15px;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
margin: 10px 0;
}
button:hover {
background-color: #c5000f;
}
.clear-history {
background-color: #f44336;
margin-left: 10px;
}
.save-history {
background-color: #4CAF50;
margin-left: 10px;
}
.result {
background-color: #f9f9f9;
padding: 15px;
border-radius: 5px;
margin-top: 20px;
}
.ball {
display: inline-block;
width: 30px;
height: 30px;
border-radius: 50%;
text-align: center;
line-height: 30px;
margin: 5px;
color: white;
font-weight: bold;
}
.red-ball {
background-color: #e60012;
}
.blue-ball {
background-color: #1e50a2;
}
.flex-container {
display: flex;
flex-wrap: wrap;
gap: 15px;
}
.flex-item {
flex: 1;
min-width: 200px;
}
.analysis-item {
margin-bottom: 8px;
}
label {
display: inline-block;
width: 120px;
margin-right: 10px;
}
select {
padding: 5px;
width: 150px;
}
.favorite-balls {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 15px;
}
.favorite-ball {
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-weight: bold;
}
.favorite-red {
background-color: #ffebee;
border: 2px solid #e60012;
color: #e60012;
}
.favorite-blue {
background-color: #e3f2fd;
border: 2px solid #1e50a2;
color: #1e50a2;
}
.favorite-red.selected {
background-color: #e60012;
color: white;
border-color: #e60012;
}
.favorite-blue.selected {
background-color: #1e50a2;
color: white;
border-color: #1e50a2;
}
.favorite-section {
margin-top: 15px;
}
.recommendation-item {
margin-bottom: 15px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
display: flex;
justify-content: space-between;
align-items: center;
}
.tail-number-options {
display: flex;
flex-wrap: wrap;
gap: 5px;
margin-top: 5px;
}
.tail-number-option {
padding: 5px 10px;
border: 1px solid #ddd;
border-radius: 3px;
cursor: pointer;
}
.tail-number-option.selected {
background-color: #e60012;
color: white;
border-color: #e60012;
}
.area-serial-options {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 5px;
}
.area-serial-option {
padding: 5px 10px;
border: 1px solid #ddd;
border-radius: 3px;
cursor: pointer;
}
.area-serial-option.selected {
background-color: #e60012;
color: white;
border-color: #e60012;
}
.tail-size-options {
display: flex;
flex-wrap: wrap;
gap: 5px;
margin-top: 5px;
}
.tail-size-option {
padding: 5px 10px;
border: 1px solid #ddd;
border-radius: 3px;
cursor: pointer;
}
.tail-size-option.selected {
background-color: #e60012;
color: white;
border-color: #e60012;
}
.odd-even-selector {
display: flex;
gap: 5px;
margin-top: 5px;
}
.odd-even-btn {
padding: 3px 8px;
border: 1px solid #ddd;
border-radius: 3px;
cursor: pointer;
}
.odd-even-btn.selected {
background-color: #e60012;
color: white;
border-color: #e60012;
}
.combination-input {
display: flex;
flex-wrap: wrap;
gap: 5px;
margin-top: 5px;
}
.combination-list {
margin-top: 10px;
max-height: 150px;
overflow-y: auto;
border: 1px solid #ddd;
padding: 5px;
border-radius: 5px;
}
.combination-item {
display: flex;
justify-content: space-between;
padding: 3px 0;
border-bottom: 1px solid #eee;
}
.combination-balls {
display: flex;
gap: 3px;
}
.combination-ball {
width: 20px;
height: 20px;
border-radius: 50%;
text-align: center;
line-height: 20px;
font-size: 12px;
font-weight: bold;
}
.combination-red {
background-color: #ffebee;
border: 1px solid #e60012;
color: #e60012;
}
.combination-remove {
color: #e60012;
cursor: pointer;
font-size: 12px;
}
.progress-container {
width: 100%;
background-color: #f1f1f1;
border-radius: 5px;
margin: 10px 0;
display: none;
}
.progress-bar {
height: 20px;
background-color: #4CAF50;
border-radius: 5px;
width: 0%;
transition: width 0.3s;
text-align: center;
line-height: 20px;
color: white;
}
.side-number-section {
margin-top: 10px;
}
.button-group {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.history-container {
max-height: 500px;
overflow-y: auto;
}
.smart-btn {
background-color: #2196F3;
}
.smart-btn:hover {
background-color: #0b7dda;
}
.analysis-result {
margin-top: 20px;
}
.analysis-table {
width: 100%;
margin-top: 10px;
}
.analysis-table th {
background-color: #f2f2f2;
}
.analysis-table td {
padding: 5px;
}
.frequency-bar {
height: 20px;
background-color: #4CAF50;
display: inline-block;
vertical-align: middle;
margin-left: 5px;
}
.frequency-cell {
display: flex;
align-items: center;
}
.tab-container {
margin-top: 15px;
}
.tab-buttons {
display: flex;
border-bottom: 1px solid #ddd;
}
.tab-button {
padding: 8px 15px;
background-color: #f1f1f1;
border: none;
cursor: pointer;
margin-right: 5px;
border-radius: 5px 5px 0 0;
}
.tab-button.active {
background-color: #e60012;
color: white;
}
.tab-content {
display: none;
padding: 15px;
border: 1px solid #ddd;
border-top: none;
}
.tab-content.active {
display: block;
}
.stat-card {
border: 1px solid #ddd;
border-radius: 5px;
padding: 10px;
margin-bottom: 10px;
}
.stat-card-title {
font-weight: bold;
margin-bottom: 5px;
color: #e60012;
}
.stat-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 10px;
}
.zone-options {
display: flex;
flex-wrap: wrap;
gap: 5px;
margin-top: 5px;
}
.zone-option {
padding: 5px 10px;
border: 1px solid #ddd;
border-radius: 3px;
cursor: pointer;
}
.zone-option.selected {
background-color: #e60012;
color: white;
border-color: #e60012;
}
.priority-sequence {
min-height: 50px;
border: 1px dashed #ccc;
padding: 10px;
margin-bottom: 15px;
background-color: #f9f9f9;
}
.priority-list {
margin-top: 10px;
}
.priority-item {
display: flex;
justify-content: space-between;
align-items: center;
margin: 5px 0;
padding: 8px;
background-color: #e6f7ff;
border-left: 4px solid #1890ff;
border-radius: 4px;
}
.priority-item .priority-name {
flex-grow: 1;
}
.priority-item .priority-remove {
color: #ff4d4f;
cursor: pointer;
margin-left: 10px;
}
.priority-empty {
color: #999;
text-align: center;
padding: 10px;
}
.priority-actions {
margin-top: 10px;
display: flex;
gap: 10px;
}
.priority-btn {
padding: 5px 10px;
background-color: #f0f0f0;
border: 1px solid #d9d9d9;
border-radius: 4px;
cursor: pointer;
}
.priority-btn:hover {
background-color: #e6e6e6;
}
@media (max-width: 768px) {
.flex-container {
flex-direction: column;
}
input {
width: 35px;
}
.section {
padding: 10px;
}
#history-table {
display: block;
overflow-x: auto;
}
.stat-grid {
grid-template-columns: 1fr;
}
}
@media print {
.container {
box-shadow: none;
padding: 0;
}
button, .section:not(.result) {
display: none;
}
.result {
background-color: white;
border: none;
padding: 0;
}
}
</style>
</head>
<body>
<div class="container">
<h1>大乐透智能选号模拟器 - 动态优先级版</h1>
<div class="section">
<div class="section-title">参数优先级设置(最先设置的优先)</div>
<div id="priority-display" class="priority-sequence">
<div class="priority-empty">尚未设置任何参数</div>
<div class="priority-list" id="priority-list"></div>
<div class="priority-actions">
<button class="priority-btn" onclick="clearPriorityQueue()">清空优先级</button>
<button class="priority-btn" onclick="resetDefaultPriority()">恢复默认优先级</button>
</div>
</div>
</div>
<div class="section">
<div class="section-title">历史数据录入</div>
<div class="history-container">
<table id="history-table">
<thead>
<tr>
<th>期号</th>
<th>红球1</th>
<th>红球2</th>
<th>红球3</th>
<th>红球4</th>
<th>红球5</th>
<th>蓝球1</th>
<th>蓝球2</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<div class="button-group">
<button onclick="addNewRow()">新增一行</button>
<button onclick="saveHistoryToLocalStorage()" class="save-history">保存数据</button>
<button onclick="clearHistoryData()" class="clear-history">清空历史</button>
<button onclick="importDefaultData()" class="save-history">导入默认数据</button>
<button onclick="adjustParameters()" class="smart-btn">智能参数推荐</button>
<button onclick="analyzeData()" class="smart-btn">数据分析</button>
</div>
</div>
<div class="flex-container">
<div class="flex-item">
<div class="section">
<div class="section-title">基本参数设置</div>
<div class="analysis-item">
<label for="size-ratio">大小比:</label>
<select id="size-ratio">
<option value="any">任意</option>
<option value="5:0">5:0</option>
<option value="4:1">4:1</option>
<option value="3:2" selected>3:2</option>
<option value="2:3">2:3</option>
<option value="1:4">1:4</option>
<option value="0:5">0:5</option>
</select>
</div>
<div class="analysis-item">
<label for="area-ratio">区域比:</label>
<select id="area-ratio">
<option value="any">任意</option>
<option value="5:0:0">5:0:0</option>
<option value="4:1:0">4:1:0</option>
<option value="4:0:1">4:0:1</option>
<option value="3:2:0">3:2:0</option>
<option value="3:1:1" selected>3:1:1</option>
<option value="3:0:2">3:0:2</option>
<option value="2:3:0">2:3:0</option>
<option value="2:2:1">2:2:1</option>
<option value="2:1:2">2:1:2</option>
<option value="2:0:3">2:0:3</option>
<option value="1:4:0">1:4:0</option>
<option value="1:3:1">1:3:1</option>
<option value="1:2:2">1:2:2</option>
<option value="1:1:3">1:1:3</option>
<option value="1:0:4">1:0:4</option>
<option value="0:5:0">0:5:0</option>
<option value="0:4:1">0:4:1</option>
<option value="0:3:2">0:3:2</option>
<option value="0:2:3">0:2:3</option>
<option value="0:1:4">0:1:4</option>
<option value="0:0:5">0:0:5</option>
</select>
</div>
<div class="analysis-item">
<label for="odd-even">奇偶比:</label>
<select id="odd-even">
<option value="any">任意</option>
<option value="5:0">5:0</option>
<option value="4:1">4:1</option>
<option value="3:2" selected>3:2</option>
<option value="2:3">2:3</option>
<option value="1:4">1:4</option>
<option value="0:5">0:5</option>
</select>
</div>
<div class="analysis-item">
<label for="hot-cold-ratio">冷热比:</label>
<select id="hot-cold-ratio">
<option value="any">任意</option>
<option value="5:0">5:0</option>
<option value="4:1">4:1</option>
<option value="3:2" selected>3:2</option>
<option value="2:3">2:3</option>
<option value="1:4">1:4</option>
<option value="0:5">0:5</option>
</select>
</div>
<div class="analysis-item">
<label for="sum-min">和值范围:</label>
<input type="number" id="sum-min" min="15" max="165" value="70"> -
<input type="number" id="sum-max" min="15" max="165" value="120">
</div>
<div class="analysis-item">
<label for="span-min">跨度范围:</label>
<input type="number" id="span-min" min="4" max="34" value="20"> -
<input type="number" id="span-max" min="4" max="34" value="30">
</div>
<div class="analysis-item">
<label for="repeat-num">与上期重复:</label>
<select id="repeat-num">
<option value="any">任意</option>
<option value="0">0个</option>
<option value="1" selected>1个</option>
<option value="2">2个</option>
<option value="3">3个</option>
<option value="4">4个</option>
</select>
</div>
<div class="analysis-item">
<label for="prime-ratio">质合比:</label>
<select id="prime-ratio">
<option value="any">任意</option>
<option value="5:0">5:0</option>
<option value="4:1">4:1</option>
<option value="3:2" selected>3:2</option>
<option value="2:3">2:3</option>
<option value="1:4">1:4</option>
<option value="0:5">0:5</option>
</select>
</div>
<div class="analysis-item">
<label for="serial-num">连号组数:</label>
<select id="serial-num">
<option value="any">任意</option>
<option value="0">0组</option>
<option value="1" selected>1组</option>
<option value="2">2组</option>
</select>
</div>
<div class="analysis-item">
<label for="blue-size">蓝球大小:</label>
<select id="blue-size">
<option value="any">任意</option>
<option value="small">小(1-6)</option>
<option value="big">大(7-12)</option>
</select>
</div>
</div>
</div>
<div class="flex-item">
<div class="section">
<div class="section-title">高级参数设置</div>
<div class="section">
<div class="section-title">分区选号设置</div>
<div class="analysis-item">
<label for="zone-selection-mode">分区模式:</label>
<select id="zone-selection-mode">
<option value="any" selected>任意</option>
<option value="include">必须包含</option>
<option value="exclude">必须排除</option>
</select>
</div>
<div>选择分区:</div>
<div class="zone-options" id="zone-options">
<div class="zone-option" data-zone="1">一区(1-9)</div>
<div class="zone-option" data-zone="2">二区(10-20)</div>
<div class="zone-option" data-zone="3">三区(21-29)</div>
<div class="zone-option" data-zone="4">四区(30-35)</div>
</div>
</div>
<div class="section">
<div class="section-title">龙头凤尾设置</div>
<div class="analysis-item">
<label for="dragon-head-range">龙头范围:</label>
<select id="dragon-head-range">
<option value="any" selected>任意</option>
<option value="1-3">1-3</option>
<option value="4-6">4-6</option>
<option value="7-9">7-9</option>
<option value="10-12">10-12</option>
<option value="13-15">13-15</option>
<option value="16-18">16-18</option>
<option value="19-21">19-21</option>
</select>
</div>
<div class="analysis-item">
<label for="phoenix-tail-range">凤尾范围:</label>
<select id="phoenix-tail-range">
<option value="any" selected>任意</option>
<option value="22-24">22-24</option>
<option value="25-27">25-27</option>
<option value="28-30">28-30</option>
<option value="31-33">31-33</option>
<option value="34-35">34-35</option>
</select>
</div>
</div>
<div class="side-number-section">
<div class="section-title">边号(邻号)设置</div>
<div class="analysis-item">
<label for="side-number-mode">边号模式:</label>
<select id="side-number-mode">
<option value="any">任意</option>
<option value="include" selected>必须包含</option>
<option value="exclude">必须排除</option>
</select>
</div>
<div class="analysis-item">
<label for="side-number-count">边号数量:</label>
<select id="side-number-count">
<option value="any">任意</option>
<option value="1">1个</option>
<option value="2" selected>2个</option>
<option value="3">3个</option>
<option value="4">4个</option>
</select>
</div>
</div>
<div class="favorite-section">
<div class="section-title">自选号码</div>
<div class="analysis-item">
<label for="favorite-weight">自选权重:</label>
<select id="favorite-weight">
<option value="low">低</option>
<option value="medium" selected>中</option>
<option value="high">高</option>
</select>
</div>
<div>红球选择:</div>
<div class="favorite-balls" id="favorite-red-balls">
</div>
<div>蓝球选择:</div>
<div class="favorite-balls" id="favorite-blue-balls">
</div>
</div>
<div class="tail-number-section">
<div class="section-title">尾号设置</div>
<div class="analysis-item">
<label for="tail-number-mode">尾号模式:</label>
<select id="tail-number-mode">
<option value="any" selected>任意</option>
<option value="include">必须包含</option>
<option value="exclude">必须排除</option>
</select>
</div>
<div class="analysis-item">
<label for="tail-number-count">尾号数量:</label>
<select id="tail-number-count">
<option value="any" selected>任意</option>
<option value="1">1个</option>
<option value="2">2个</option>
<option value="3">3个</option>
<option value="4">4个</option>
<option value="5">5个</option>
</select>
</div>
<div>选择尾号(0-9):</div>
<div class="tail-number-options" id="tail-number-options">
</div>
</div>
<div class="tail-size-section">
<div class="section-title">尾号大小设置</div>
<div class="analysis-item">
<label for="tail-size-mode">大小模式:</label>
<select id="tail-size-mode">
<option value="any" selected>任意</option>
<option value="include">必须包含</option>
<option value="exclude">必须排除</option>
</select>
</div>
<div>选择尾号大小:</div>
<div class="tail-size-options" id="tail-size-options">
<div class="tail-size-option" data-size="small">小(1-3)</div>
<div class="tail-size-option" data-size="medium">中(4-6)</div>
<div class="tail-size-option" data-size="large">大(7-9,0)</div>
</div>
</div>
<div class="area-serial-section">
<div class="section-title">区域连号设置</div>
<div class="analysis-item">
<label for="area-serial-mode">连号模式:</label>
<select id="area-serial-mode">
<option value="any" selected>任意</option>
<option value="include">必须包含</option>
</select>
</div>
<div>选择区域:</div>
<div class="area-serial-options" id="area-serial-options">
<div class="area-serial-option" data-area="1">一区(1-10)</div>
<div class="area-serial-option" data-area="2">二区(11-20)</div>
<div class="area-serial-option" data-area="3">三区(21-35)</div>
</div>
</div>
<div class="ball-odd-even-section">
<div class="section-title">各球位奇偶设置</div>
<div class="analysis-item">
<label for="ball-odd-even-mode">设置模式:</label>
<select id="ball-odd-even-mode">
<option value="any" selected>任意</option>
<option value="include">必须符合</option>
<option value="exclude">必须不符</option>
</select>
</div>
<div class="odd-even-selector">
<div>红球1:</div>
<div class="odd-even-btn" data-ball="1" data-type="odd">奇</div>
<div class="odd-even-btn" data-ball="1" data-type="even">偶</div>
</div>
<div class="odd-even-selector">
<div>红球2:</div>
<div class="odd-even-btn" data-ball="2" data-type="odd">奇</div>
<div class="odd-even-btn" data-ball="2" data-type="even">偶</div>
</div>
<div class="odd-even-selector">
<div>红球3:</div>
<div class="odd-even-btn" data-ball="3" data-type="odd">奇</div>
<div class="odd-even-btn" data-ball="3" data-type="even">偶</div>
</div>
<div class="odd-even-selector">
<div>红球4:</div>
<div class="odd-even-btn" data-ball="4" data-type="odd">奇</div>
<div class="odd-even-btn" data-ball="4" data-type="even">偶</div>
</div>
<div class="odd-even-selector">
<div>红球5:</div>
<div class="odd-even-btn" data-ball="5" data-type="odd">奇</div>
<div class="odd-even-btn" data-ball="5" data-type="even">偶</div>
</div>
</div>
<div class="combination-section">
<div class="section-title">组合设置</div>
<div class="analysis-item">
<label for="combination-mode">组合模式:</label>
<select id="combination-mode">
<option value="any" selected>任意</option>
<option value="include">必须包含</option>
<option value="exclude">必须排除</option>
</select>
</div>
<div class="combination-input">
<input type="number" min="1" max="35" placeholder="红球" id="combination-input-1">
<input type="number" min="1" max="35" placeholder="红球" id="combination-input-2">
<input type="number" min="1" max="35" placeholder="红球" id="combination-input-3">
<button onclick="addCombination()">添加组合</button>
</div>
<div class="combination-list" id="combination-list">
</div>
</div>
</div>
</div>
</div>
<div class="section" style="text-align: center;">
<button onclick="generateRecommendations()" style="padding: 12px 30px; font-size: 18px;">生成推荐号码</button>
<button onclick="window.print()" style="margin-left: 20px; background-color: #2196F3;">打印结果</button>
</div>
<div class="progress-container" id="progress-container">
<div class="progress-bar" id="progress-bar">0%</div>
</div>
<div class="result" id="result">
</div>
<div class="analysis-result" id="analysis-result" style="display: none;">
<div class="section-title">数据分析结果</div>
<div class="tab-container">
<div class="tab-buttons">
<button class="tab-button active" onclick="showAnalysisTab('basic')">基本统计</button>
<button class="tab-button" onclick="showAnalysisTab('frequency')">号码频率</button>
<button class="tab-button" onclick="showAnalysisTab('pattern')">模式分析</button>
<button class="tab-button" onclick="showAnalysisTab('trend')">趋势分析</button>
</div>
<div id="basic-tab" class="tab-content active">
</div>
<div id="frequency-tab" class="tab-content">
</div>
<div id="pattern-tab" class="tab-content">
</div>
<div id="trend-tab" class="tab-content">
</div>
</div>
</div>
</div>
<script>
const predefinedHistory = [
{period: "24136", red: [1,17,20,29,34], blue: [7,8]},
{period: "24137", red: [8,15,16,17,21], blue: [2,5]},
{period: "24138", red: [5,17,22,28,34], blue: [4,9]},
{period: "24139", red: [5,12,20,23,24], blue: [5,7]},
{period: "24140", red: [3,6,15,23,31], blue: [1,12]},
{period: "24141", red: [2,6,11,16,20], blue: [2,11]},
{period: "24142", red: [8,21,24,33,34], blue: [3,10]},
{period: "24143", red: [16,20,22,24,31], blue: [4,5]},
{period: "24144", red: [6,7,8,21,30], blue: [1,5]},
{period: "24145", red: [1,6,9,22,24], blue: [1,3]},
{period: "24146", red: [5,20,21,22,32], blue: [3,4]},
{period: "24147", red: [12,18,21,22,31], blue: [1,7]},
{period: "24148", red: [6,9,20,32,35], blue: [8,11]},
{period: "24149", red: [2,5,16,18,22], blue: [7,9]},
{period: "24150", red: [4,11,23,25,34], blue: [5,7]},
{period: "24151", red: [5,12,17,19,35], blue: [10,11]},
{period: "24152", red: [1,2,7,8,31], blue: [2,10]},
{period: "25001", red: [5,8,16,17,27], blue: [4,7]},
{period: "25002", red: [19,21,22,28,32], blue: [6,9]},
{period: "25003", red: [10,25,30,32,34], blue: [4,10]},
{period: "25004", red: [2,5,9,13,33], blue: [1,7]},
{period: "25005", red: [5,6,8,31,32], blue: [9,11]},
{period: "25006", red: [3,4,13,19,35], blue: [3,10]},
{period: "25007", red: [15,22,23,25,31], blue: [1,9]},
{period: "25008", red: [1,5,7,13,35], blue: [5,12]},
{period: "25009", red: [3,19,21,30,32], blue: [6,9]},
{period: "25010", red: [5,21,28,30,32], blue: [7,12]},
{period: "25011", red: [3,6,7,11,27], blue: [2,8]},
{period: "25012", red: [2,18,19,21,25], blue: [2,11]},
{period: "25013", red: [14,16,18,20,35], blue: [2,5]},
{period: "25014", red: [5,19,22,29,35], blue: [2,10]},
{period: "25015", red: [7,10,24,31,35], blue: [1,8]},
{period: "25016", red: [5,7,12,20,29], blue: [8,12]},
{period: "25017", red: [10,12,26,28,31], blue: [3,10]},
{period: "25018", red: [1,7,9,20,28], blue: [1,4]},
{period: "25019", red: [7,8,11,18,23], blue: [3,11]},
{period: "25020", red: [1,9,12,22,29], blue: [5,9]},
{period: "25021", red: [10,18,25,30,35], blue: [3,12]},
{period: "25022", red: [1,11,13,27,29], blue: [4,10]},
{period: "25023", red: [10,20,22,24,25], blue: [9,12]},
{period: "25024", red: [6,12,13,16,23], blue: [5,8]}
];
let historyData = [];
const zoneOptions = [
{zone: 1, min: 1, max: 9},
{zone: 2, min: 10, max: 20},
{zone: 3, min: 21, max: 29},
{zone: 4, min: 30, max: 35}
];
const DEFAULT_PRIORITY = [
'mustInclude',
'combinations',
'zones',
'dragonHead',
'phoenixTail',
'tailNumbers',
'sideNumbers',
'oddEven',
'sizeRatio',
'hotCold',
'favorites'
];
let userPriorityQueue = [];
const PARAM_MAPPING = {
'size-ratio': {type: 'sizeRatio', name: '大小比例'},
'area-ratio': {type: 'areaRatio', name: '区域比例'},
'odd-even': {type: 'oddEven', name: '奇偶比例'},
'hot-cold-ratio': {type: 'hotCold', name: '冷热比例'},
'sum-min': {type: 'sumRange', name: '和值范围'},
'sum-max': {type: 'sumRange', name: '和值范围'},
'span-min': {type: 'spanRange', name: '跨度范围'},
'span-max': {type: 'spanRange', name: '跨度范围'},
'repeat-num': {type: 'repeatNum', name: '重复号码'},
'prime-ratio': {type: 'primeRatio', name: '质合比例'},
'serial-num': {type: 'serialNum', name: '连号组数'},
'blue-size': {type: 'blueSize', name: '蓝球大小'},
'favorite-weight': {type: 'favorites', name: '自选号码'},
'zone-selection-mode': {type: 'zones', name: '分区设置'},
'dragon-head-range': {type: 'dragonHead', name: '龙头范围'},
'phoenix-tail-range': {type: 'phoenixTail', name: '凤尾范围'},
'side-number-mode': {type: 'sideNumbers', name: '边号设置'},
'side-number-count': {type: 'sideNumbers', name: '边号设置'},
'tail-number-mode': {type: 'tailNumbers', name: '尾号设置'},
'tail-number-count': {type: 'tailNumbers', name: '尾号设置'},
'tail-size-mode': {type: 'tailSize', name: '尾号大小'},
'area-serial-mode': {type: 'areaSerial', name: '区域连号'},
'ball-odd-even-mode': {type: 'ballOddEven', name: '球位奇偶'},
'combination-mode': {type: 'combinations', name: '组合设置'},
'favorite-red': {type: 'favorites', name: '自选红球'},
'favorite-blue': {type: 'favorites', name: '自选蓝球'},
'zone-option': {type: 'zones', name: '分区选择'},
'tail-number-option': {type: 'tailNumbers', name: '尾号选择'},
'tail-size-option': {type: 'tailSize', name: '尾号大小选择'},
'area-serial-option': {type: 'areaSerial', name: '区域连号选择'},
'odd-even-btn': {type: 'ballOddEven', name: '球位奇偶选择'}
};
function trackUserInteraction(sourceId) {
if (sourceId === 'generate-btn' || sourceId === 'print-btn' ||
sourceId.includes('priority-btn') || sourceId === '') {
return;
}
let paramInfo = PARAM_MAPPING[sourceId];
if (!paramInfo) {
if (sourceId.includes('favorite-red')) {
paramInfo = PARAM_MAPPING['favorite-red'];
} else if (sourceId.includes('favorite-blue')) {
paramInfo = PARAM_MAPPING['favorite-blue'];
} else if (sourceId.includes('zone-option')) {
paramInfo = PARAM_MAPPING['zone-option'];
} else if (sourceId.includes('tail-number-option')) {
paramInfo = PARAM_MAPPING['tail-number-option'];
} else if (sourceId.includes('tail-size-option')) {
paramInfo = PARAM_MAPPING['tail-size-option'];
} else if (sourceId.includes('area-serial-option')) {
paramInfo = PARAM_MAPPING['area-serial-option'];
} else if (sourceId.includes('odd-even-btn')) {
paramInfo = PARAM_MAPPING['odd-even-btn'];
}
}
if (!paramInfo) return;
const existingIndex = userPriorityQueue.findIndex(item => item.type === paramInfo.type);
if (existingIndex >= 0) {
userPriorityQueue[existingIndex].timestamp = Date.now();
userPriorityQueue[existingIndex].source = sourceId;
} else {
userPriorityQueue.push({
type: paramInfo.type,
name: paramInfo.name,
timestamp: Date.now(),
source: sourceId
});
}
updatePriorityDisplay();
}
function updatePriorityDisplay() {
const display = document.getElementById('priority-display');
const list = document.getElementById('priority-list');
list.innerHTML = '';
if (userPriorityQueue.length === 0) {
display.querySelector('.priority-empty').style.display = 'block';
return;
}
display.querySelector('.priority-empty').style.display = 'none';
userPriorityQueue.forEach((item, index) => {
const itemElement = document.createElement('div');
itemElement.className = 'priority-item';
itemElement.innerHTML = `
<div class="priority-name">
${index + 1}. ${item.name}
</div>
<div class="priority-remove" onclick="removePriorityItem('${item.type}')">
×
</div>
`;
list.appendChild(itemElement);
});
}
function removePriorityItem(type) {
userPriorityQueue = userPriorityQueue.filter(item => item.type !== type);
updatePriorityDisplay();
}
function clearPriorityQueue() {
if (confirm('确定要清空所有优先级设置吗?')) {
userPriorityQueue = [];
updatePriorityDisplay();
}
}
function resetDefaultPriority() {
if (confirm('确定要恢复默认优先级吗?这将覆盖当前设置。')) {
userPriorityQueue = DEFAULT_PRIORITY.map(type => ({
type: type,
name: getConditionName(type),
timestamp: Date.now(),
source: 'default'
}));
updatePriorityDisplay();
}
}
function getConditionName(type) {
const names = {
'mustInclude': '必须包含号码',
'combinations': '组合条件',
'zones': '分区要求',
'dragonHead': '龙头范围',
'phoenixTail': '凤尾范围',
'tailNumbers': '尾号要求',
'sideNumbers': '边号要求',
'oddEven': '奇偶比例',
'sizeRatio': '大小比例',
'hotCold': '冷热比例',
'favorites': '自选号码',
'sumRange': '和值范围',
'spanRange': '跨度范围',
'repeatNum': '重复号码',
'primeRatio': '质合比例',
'serialNum': '连号组数',
'blueSize': '蓝球大小',
'tailSize': '尾号大小',
'areaSerial': '区域连号',
'ballOddEven': '球位奇偶'
};
return names[type] || type;
}
function getParametersWithPriority() {
const baseParams = getBaseParameters();
const priorityOrder = userPriorityQueue.map(item => item.type);
const finalPriority = [...new Set([...priorityOrder, ...DEFAULT_PRIORITY])];
return {
params: baseParams,
priority: finalPriority
};
}
function getBaseParameters() {
const favoriteBalls = getFavoriteBalls();
const tailSettings = getTailNumberSettings();
const tailSizeSettings = getTailSizeSettings();
const areaSerialSettings = getAreaSerialSettings();
const ballOddEvenSettings = getBallOddEvenSettings();
const combinationSettings = getCombinationSettings();
const sideSettings = getSideNumberSettings();
const zoneSettings = getZoneSettings();
const dragonPhoenixSettings = getDragonPhoenixSettings();
return {
sizeRatio: document.getElementById('size-ratio').value,
areaRatio: document.getElementById('area-ratio').value,
oddEven: document.getElementById('odd-even').value,
hotColdRatio: document.getElementById('hot-cold-ratio').value,
sumMin: parseInt(document.getElementById('sum-min').value) || 70,
sumMax: parseInt(document.getElementById('sum-max').value) || 120,
spanMin: parseInt(document.getElementById('span-min').value) || 20,
spanMax: parseInt(document.getElementById('span-max').value) || 30,
repeatNum: document.getElementById('repeat-num').value,
primeRatio: document.getElementById('prime-ratio').value,
serialNum: document.getElementById('serial-num').value,
blueSize: document.getElementById('blue-size').value,
favoriteWeight: document.getElementById('favorite-weight').value,
tailSettings: tailSettings,
tailSizeSettings: tailSizeSettings,
areaSerialSettings: areaSerialSettings,
ballOddEvenSettings: ballOddEvenSettings,
combinationSettings: combinationSettings,
sideSettings: sideSettings,
zoneSettings: zoneSettings,
dragonPhoenixSettings: dragonPhoenixSettings,
favoriteBalls: favoriteBalls
};
}
function generateRedBallsWithPriority(history, analysis, paramInfo) {
const { params, priority } = paramInfo;
const lastRed = history[history.length - 1].red;
let redBalls = [];
let candidates = Array.from({length: 35}, (_, i) => i + 1);
for (const condition of priority) {
if (redBalls.length >= 5) break;
switch(condition) {
case 'mustInclude':
if (params.combinationSettings.mode === 'include' && params.combinationSettings.combinations.length > 0) {
const validCombs = params.combinationSettings.combinations.filter(comb =>
comb.every(num => candidates.includes(num))
);
if (validCombs.length > 0) {
const selected = validCombs[Math.floor(Math.random() * validCombs.length)];
const toAdd = selected.filter(n => !redBalls.includes(n));
redBalls.push(...toAdd.slice(0, 5 - redBalls.length));
candidates = candidates.filter(n => !redBalls.includes(n));
}
}
break;
case 'combinations':
if (params.combinationSettings.mode === 'include' && params.combinationSettings.combinations.length > 0) {
const validCombs = params.combinationSettings.combinations.filter(comb =>
comb.every(num => candidates.includes(num))
);
if (validCombs.length > 0) {
const selected = validCombs[Math.floor(Math.random() * validCombs.length)];
const toAdd = selected.filter(n => !redBalls.includes(n));
redBalls.push(...toAdd.slice(0, 5 - redBalls.length));
candidates = candidates.filter(n => !redBalls.includes(n));
}
}
break;
case 'zones':
if (params.zoneSettings.mode !== 'any' && params.zoneSettings.zones.length > 0) {
const selectedZones = params.zoneSettings.zones;
const zoneRanges = selectedZones.map(z => zoneOptions.find(o => o.zone === z));
if (params.zoneSettings.mode === 'include') {
candidates = candidates.filter(num => {
return zoneRanges.some(z => num >= z.min && num <= z.max);
});
} else if (params.zoneSettings.mode === 'exclude') {
candidates = candidates.filter(num => {
return !zoneRanges.some(z => num >= z.min && num <= z.max);
});
}
}
break;
case 'dragonHead':
if (params.dragonPhoenixSettings.dragonHead !== 'any' && redBalls.length === 0) {
const [min, max] = params.dragonPhoenixSettings.dragonHead.split('-').map(Number);
candidates = candidates.filter(num => num >= min && num <= max);
if (candidates.length === 0) {
candidates = Array.from({length: max - min + 1}, (_, i) => min + i);
}
}
break;
case 'phoenixTail':
if (params.dragonPhoenixSettings.phoenixTail !== 'any' && redBalls.length === 4) {
const [min, max] = params.dragonPhoenixSettings.phoenixTail.split('-').map(Number);
candidates = candidates.filter(num => num >= min && num <= max);
if (redBalls.length > 0) {
const maxSelected = Math.max(...redBalls);
candidates = candidates.filter(num => num > maxSelected);
}
if (candidates.length === 0) {
candidates = Array.from({length: max - min + 1}, (_, i) => min + i);
}
}
break;
case 'tailNumbers':
if (params.tailSettings.mode !== 'any' && params.tailSettings.tails.length > 0) {
if (params.tailSettings.mode === 'include') {
candidates = candidates.filter(num =>
params.tailSettings.tails.includes(num % 10)
);
} else if (params.tailSettings.mode === 'exclude') {
candidates = candidates.filter(num =>
!params.tailSettings.tails.includes(num % 10)
);
}
}
break;
case 'sideNumbers':
if (params.sideSettings.mode !== 'any') {
const sideNumbers = getEnhancedSideNumbers(lastRed, history);
const requiredCount = parseInt(params.sideSettings.count);
if (params.sideSettings.mode === 'include') {
if (requiredCount > 0 && redBalls.length < requiredCount) {
const available = [...sideNumbers].filter(n => candidates.includes(n));
const toAdd = selectRandomElements(available, Math.min(requiredCount - redBalls.length, available.length));
redBalls.push(...toAdd);
candidates = candidates.filter(n => !redBalls.includes(n));
}
} else if (params.sideSettings.mode === 'exclude') {
candidates = candidates.filter(num => !sideNumbers.has(num));
}
}
break;
case 'favorites':
if (params.favoriteBalls.red.length > 0 && redBalls.length < 5) {
const useFavoriteRatio = getFavoriteRatio(params.favoriteWeight);
if (Math.random() < useFavoriteRatio) {
const available = params.favoriteBalls.red.filter(n => candidates.includes(n));
const maxFavorite = Math.min(3, 5 - redBalls.length, available.length);
const favoriteCount = Math.floor(Math.random() * maxFavorite) + 1;
const selectedFavorites = selectRandomElements(available, favoriteCount);
redBalls.push(...selectedFavorites);
candidates = candidates.filter(n => !redBalls.includes(n));
}
}
break;
}
}
while (redBalls.length < 5 && candidates.length > 0) {
if (redBalls.length === 0 && params.dragonPhoenixSettings.dragonHead !== 'any') {
const [min, max] = params.dragonPhoenixSettings.dragonHead.split('-').map(Number);
candidates = candidates.filter(num => num >= min && num <= max);
}
if (redBalls.length === 4 && params.dragonPhoenixSettings.phoenixTail !== 'any') {
const [min, max] = params.dragonPhoenixSettings.phoenixTail.split('-').map(Number);
candidates = candidates.filter(num => num >= min && num <= max);
if (redBalls.length > 0) {
const maxSelected = Math.max(...redBalls);
candidates = candidates.filter(num => num > maxSelected);
}
}
if (candidates.length === 0) {
candidates = Array.from({length: 35}, (_, i) => i + 1)
.filter(n => !redBalls.includes(n));
}
const filtered = filterCandidates(candidates, redBalls, params, analysis, history);
const selected = selectByPriority(
filtered.length > 0 ? filtered : candidates,
redBalls,
params,
analysis
);
redBalls.push(selected);
candidates = candidates.filter(n => n !== selected);
}
return redBalls.sort((a, b) => a - b);
}
function getFavoriteBalls() {
const redBalls = [];
const blueBalls = [];
document.querySelectorAll('.favorite-red.selected').forEach(ball => {
redBalls.push(parseInt(ball.dataset.num));
});
document.querySelectorAll('.favorite-blue.selected').forEach(ball => {
blueBalls.push(parseInt(ball.dataset.num));
});
return {
red: redBalls,
blue: blueBalls
};
}
function getTailNumberSettings() {
const mode = document.getElementById('tail-number-mode').value;
const count = document.getElementById('tail-number-count').value;
const tails = [];
document.querySelectorAll('.tail-number-option.selected').forEach(option => {
tails.push(parseInt(option.dataset.tail));
});
return {
mode: mode,
count: count,
tails: tails
};
}
function getTailSizeSettings() {
const mode = document.getElementById('tail-size-mode').value;
const sizes = [];
document.querySelectorAll('.tail-size-option.selected').forEach(option => {
sizes.push(option.dataset.size);
});
return {
mode: mode,
sizes: sizes
};
}
function getAreaSerialSettings() {
const mode = document.getElementById('area-serial-mode').value;
const areas = [];
document.querySelectorAll('.area-serial-option.selected').forEach(option => {
areas.push(parseInt(option.dataset.area));
});
return {
mode: mode,
areas: areas
};
}
function getBallOddEvenSettings() {
const mode = document.getElementById('ball-odd-even-mode').value;
const settings = {};
for (let i = 1; i <= 5; i++) {
const selectedBtn = document.querySelector(`.odd-even-btn[data-ball="${i}"].selected`);
if (selectedBtn) {
settings[i] = selectedBtn.dataset.type;
} else {
settings[i] = 'any';
}
}
return {
mode: mode,
settings: settings
};
}
function getSideNumberSettings() {
return {
mode: document.getElementById('side-number-mode').value,
count: document.getElementById('side-number-count').value
};
}
function getZoneSettings() {
const mode = document.getElementById('zone-selection-mode').value;
const zones = [];
document.querySelectorAll('.zone-option.selected').forEach(option => {
zones.push(parseInt(option.dataset.zone));
});
return {
mode: mode,
zones: zones
};
}
function getDragonPhoenixSettings() {
return {
dragonHead: document.getElementById('dragon-head-range').value,
phoenixTail: document.getElementById('phoenix-tail-range').value
};
}
function addCombination() {
const input1 = document.getElementById('combination-input-1');
const input2 = document.getElementById('combination-input-2');
const input3 = document.getElementById('combination-input-3');
const combinationList = document.getElementById('combination-list');
const balls = [];
if (input1.value && parseInt(input1.value) >= 1 && parseInt(input1.value) <= 35) {
balls.push(parseInt(input1.value));
}
if (input2.value && parseInt(input2.value) >= 1 && parseInt(input2.value) <= 35) {
balls.push(parseInt(input2.value));
}
if (input3.value && parseInt(input3.value) >= 1 && parseInt(input3.value) <= 35) {
balls.push(parseInt(input3.value));
}
if (balls.length < 2) {
alert('请至少输入2个有效的红球号码!');
return;
}
const uniqueBalls = [...new Set(balls)];
const item = document.createElement('div');
item.className = 'combination-item';
const ballsDiv = document.createElement('div');
ballsDiv.className = 'combination-balls';
uniqueBalls.forEach(ball => {
const ballDiv = document.createElement('div');
ballDiv.className = 'combination-ball combination-red';
ballDiv.textContent = ball;
ballsDiv.appendChild(ballDiv);
});
const removeDiv = document.createElement('div');
removeDiv.className = 'combination-remove';
removeDiv.textContent = '删除';
removeDiv.addEventListener('click', function() {
combinationList.removeChild(item);
});
item.appendChild(ballsDiv);
item.appendChild(removeDiv);
combinationList.appendChild(item);
input1.value = '';
input2.value = '';
input3.value = '';
}
function getCombinationSettings() {
const mode = document.getElementById('combination-mode').value;
const combinations = [];
document.querySelectorAll('.combination-item').forEach(item => {
const balls = [];
item.querySelectorAll('.combination-ball').forEach(ball => {
balls.push(parseInt(ball.textContent));
});
if (balls.length >= 2) {
combinations.push(balls);
}
});
return {
mode: mode,
combinations: combinations
};
}
function getEnhancedSideNumbers(lastRed, history) {
const sideNumbers = new Set();
lastRed.forEach(num => {
if (num > 1) sideNumbers.add(num - 1);
if (num < 35) sideNumbers.add(num + 1);
});
if (history.length > 5) {
const recentNumbers = history.slice(-5).flatMap(item => item.red);
const freqMap = new Map();
recentNumbers.forEach(num => {
freqMap.set(num, (freqMap.get(num) || 0) + 1);
});
const sorted = [...freqMap.entries()].sort((a, b) => b[1] - a[1]);
const topNumbers = sorted.slice(0, 5).map(item => item[0]);
topNumbers.forEach(num => {
if (num > 1) sideNumbers.add(num - 1);
if (num < 35) sideNumbers.add(num + 1);
});
}
return sideNumbers;
}
function selectRandomElements(array, count) {
const shuffled = [...array].sort(() => 0.5 - Math.random());
return shuffled.slice(0, count);
}
function getFavoriteRatio(weight) {
switch(weight) {
case 'low': return 0.3;
case 'medium': return 0.5;
case 'high': return 0.7;
default: return 0.5;
}
}
function filterCandidates(candidates, selectedBalls, params, analysis, history) {
let filtered = [...candidates];
if (params.tailSettings.mode !== 'any' && params.tailSettings.tails.length > 0) {
if (params.tailSettings.mode === 'include') {
filtered = filtered.filter(num =>
params.tailSettings.tails.includes(num % 10)
);
} else if (params.tailSettings.mode === 'exclude') {
filtered = filtered.filter(num =>
!params.tailSettings.tails.includes(num % 10)
);
}
}
if (params.tailSizeSettings.mode !== 'any' && params.tailSizeSettings.sizes.length > 0) {
const selectedSizes = params.tailSizeSettings.sizes;
if (params.tailSizeSettings.mode === 'include') {
filtered = filtered.filter(num => {
const tail = num % 10;
if (tail >= 1 && tail <= 3 && selectedSizes.includes('small')) return true;
if (tail >= 4 && tail <= 6 && selectedSizes.includes('medium')) return true;
if ((tail >= 7 && tail <= 9 || tail === 0) && selectedSizes.includes('large')) return true;
return false;
});
} else if (params.tailSizeSettings.mode === 'exclude') {
filtered = filtered.filter(num => {
const tail = num % 10;
if (tail >= 1 && tail <= 3 && selectedSizes.includes('small')) return false;
if (tail >= 4 && tail <= 6 && selectedSizes.includes('medium')) return false;
if ((tail >= 7 && tail <= 9 || tail === 0) && selectedSizes.includes('large')) return false;
return true;
});
}
}
if (params.combinationSettings.mode !== 'any' && params.combinationSettings.combinations.length > 0) {
if (params.combinationSettings.mode === 'exclude') {
filtered = filtered.filter(num => {
for (const comb of params.combinationSettings.combinations) {
if (comb.includes(num)) {
const otherBallsInComb = comb.filter(n => n !== num);
const hasOther = otherBallsInComb.some(n => selectedBalls.includes(n));
if (hasOther) return false;
}
}
return true;
});
}
}
if (params.zoneSettings.mode !== 'any' && params.zoneSettings.zones.length > 0) {
const selectedZones = params.zoneSettings.zones;
const zoneRanges = selectedZones.map(z => zoneOptions.find(o => o.zone === z));
if (params.zoneSettings.mode === 'include') {
filtered = filtered.filter(num => {
return zoneRanges.some(z => num >= z.min && num <= z.max);
});
} else if (params.zoneSettings.mode === 'exclude') {
filtered = filtered.filter(num => {
return !zoneRanges.some(z => num >= z.min && num <= z.max);
});
}
}
return filtered;
}
function selectByPriority(candidates, selectedBalls, params, analysis) {
if (params.hotColdRatio !== 'any') {
const [targetHot, targetCold] = params.hotColdRatio.split(':').map(Number);
const currentHot = selectedBalls.filter(n => analysis.hotRed.includes(n)).length;
const currentCold = selectedBalls.filter(n => analysis.coldRed.includes(n)).length;
const remaining = 5 - selectedBalls.length;
const needHot = Math.max(0, targetHot - currentHot);
const needCold = Math.max(0, targetCold - currentCold);
if (needHot > 0) {
const hotCandidates = candidates.filter(n => analysis.hotRed.includes(n));
if (hotCandidates.length > 0) {
return hotCandidates[Math.floor(Math.random() * hotCandidates.length)];
}
}
if (needCold > 0) {
const coldCandidates = candidates.filter(n => analysis.coldRed.includes(n));
if (coldCandidates.length > 0) {
return coldCandidates[Math.floor(Math.random() * coldCandidates.length)];
}
}
const needWarm = remaining - needHot - needCold;
if (needWarm > 0) {
const warmCandidates = candidates.filter(n =>
!analysis.hotRed.includes(n) && !analysis.coldRed.includes(n)
);
if (warmCandidates.length > 0) {
return warmCandidates[Math.floor(Math.random() * warmCandidates.length)];
}
}
}
if (Math.random() < 0.7 && analysis.hotRed.length > 0) {
const hotCandidates = candidates.filter(n => analysis.hotRed.includes(n));
if (hotCandidates.length > 0) {
return hotCandidates[Math.floor(Math.random() * hotCandidates.length)];
}
}
if (Math.random() < 0.2) {
const warmCandidates = candidates.filter(n =>
!analysis.hotRed.includes(n) && !analysis.coldRed.includes(n)
);
if (warmCandidates.length > 0) {
return warmCandidates[Math.floor(Math.random() * warmCandidates.length)];
}
}
return candidates[Math.floor(Math.random() * candidates.length)];
}
function generateBlueBalls(history, analysis, params, favoriteBalls) {
let blueBalls = [];
if (favoriteBalls.blue.length > 0) {
const useFavorite = Math.random() < 0.7;
if (useFavorite) {
const randomIndex = Math.floor(Math.random() * favoriteBalls.blue.length);
blueBalls.push(favoriteBalls.blue[randomIndex]);
}
}
while (blueBalls.length < 2) {
let candidate;
if (params.blueSize === 'small') {
candidate = Math.floor(Math.random() * 6) + 1;
} else if (params.blueSize === 'big') {
candidate = Math.floor(Math.random() * 6) + 7;
} else {
if (analysis.hotBlue.length > 0 && Math.random() < 0.7) {
candidate = analysis.hotBlue[Math.floor(Math.random() * analysis.hotBlue.length)];
} else {
candidate = Math.floor(Math.random() * 12) + 1;
}
}
if (!blueBalls.includes(candidate)) {
blueBalls.push(candidate);
}
}
blueBalls.sort((a, b) => a - b);
return blueBalls;
}
function saveHistoryToLocalStorage() {
const historyData = [];
const rows = document.querySelectorAll('#history-table tbody tr');
rows.forEach(row => {
const period = row.querySelector('td:first-child').textContent;
const inputs = row.querySelectorAll('input');
const redBalls = [];
let valid = true;
for (let i = 0; i < 5; i++) {
const value = parseInt(inputs[i].value);
if (!isNaN(value) && value >= 1 && value <= 35) {
redBalls.push(value);
} else {
valid = false;
}
}
const blueBalls = [];
for (let i = 5; i < 7; i++) {
const value = parseInt(inputs[i].value);
if (!isNaN(value) && value >= 1 && value <= 12) {
blueBalls.push(value);
} else {
valid = false;
}
}
if (valid && redBalls.length === 5 && blueBalls.length === 2) {
historyData.push({
period: period,
red: redBalls.sort((a, b) => a - b),
blue: blueBalls.sort((a, b) => a - b)
});
}
});
localStorage.setItem('dltHistoryData', JSON.stringify(historyData));
alert('历史数据已保存!');
return historyData;
}
function loadHistoryFromLocalStorage() {
const savedData = localStorage.getItem('dltHistoryData');
const historyTableBody = document.querySelector('#history-table tbody');
historyTableBody.innerHTML = '';
if (savedData) {
historyData = JSON.parse(savedData);
historyData.forEach(item => {
addHistoryRow(item.period, item.red, item.blue);
});
}
}
function importDefaultData() {
if (confirm('确定要导入默认历史数据吗?这将覆盖当前数据!')) {
const historyTableBody = document.querySelector('#history-table tbody');
historyTableBody.innerHTML = '';
historyData = [...predefinedHistory];
predefinedHistory.forEach(item => {
addHistoryRow(item.period, item.red, item.blue);
});
saveHistoryToLocalStorage();
}
}
function addHistoryRow(period, redBalls, blueBalls) {
const historyTableBody = document.querySelector('#history-table tbody');
const rows = historyTableBody.querySelectorAll('tr');
if (rows.length >= 100) {
historyTableBody.removeChild(rows[0]);
}
const newRow = document.createElement('tr');
const periodCell = document.createElement('td');
periodCell.textContent = period;
newRow.appendChild(periodCell);
redBalls.forEach(num => {
const cell = document.createElement('td');
const input = document.createElement('input');
input.type = 'number';
input.min = '1';
input.max = '35';
input.value = num;
cell.appendChild(input);
newRow.appendChild(cell);
});
blueBalls.forEach(num => {
const cell = document.createElement('td');
const input = document.createElement('input');
input.type = 'number';
input.min = '1';
input.max = '12';
input.value = num;
cell.appendChild(input);
newRow.appendChild(cell);
});
historyTableBody.appendChild(newRow);
}
function addNewRow() {
const rows = document.querySelectorAll('#history-table tbody tr');
let maxPeriod = 25024;
if (rows.length > 0) {
const lastPeriod = parseInt(rows[rows.length - 1].querySelector('td:first-child').textContent);
maxPeriod = Math.max(maxPeriod, lastPeriod);
}
const newPeriod = maxPeriod + 1;
const randomData = generateRandomDLT();
addHistoryRow(newPeriod, randomData.red, randomData.blue);
}
function generateRandomDLT() {
const redBalls = [];
const redPool = Array.from({length: 35}, (_, i) => i + 1);
for(let i = 0; i < 5; i++) {
const randomIndex = Math.floor(Math.random() * redPool.length);
redBalls.push(redPool.splice(randomIndex, 1)[0]);
}
redBalls.sort((a, b) => a - b);
const blueBalls = [];
const bluePool = Array.from({length: 12}, (_, i) => i + 1);
for(let i = 0; i < 2; i++) {
const randomIndex = Math.floor(Math.random() * bluePool.length);
blueBalls.push(bluePool.splice(randomIndex, 1)[0]);
}
blueBalls.sort((a, b) => a - b);
return {
red: redBalls,
blue: blueBalls
};
}
function clearHistoryData() {
if (confirm('确定要清空所有历史数据吗?')) {
localStorage.removeItem('dltHistoryData');
document.querySelector('#history-table tbody').innerHTML = '';
historyData = [];
}
}
function analyzeHistory(data) {
if (data.length === 0) return {};
const redStats = {};
for (let i = 1; i <= 35; i++) redStats[i] = 0;
const blueStats = {};
for (let i = 1; i <= 12; i++) blueStats[i] = 0;
data.forEach(item => {
item.red.forEach(num => redStats[num]++);
item.blue.forEach(num => blueStats[num]++);
});
const allRedNumbers = Object.keys(redStats).map(Number);
const sortedByFrequency = allRedNumbers.sort((a, b) => redStats[b] - redStats[a]);
const groupSize = Math.floor(sortedByFrequency.length / 3);
const hotRed = sortedByFrequency.slice(0, groupSize);
const warmRed = sortedByFrequency.slice(groupSize, -groupSize);
const coldRed = sortedByFrequency.slice(-groupSize);
const blueFrequencies = Object.values(blueStats);
const blueAvg = blueFrequencies.reduce((a, b) => a + b, 0) / blueFrequencies.length;
const blueHotThreshold = blueAvg * 1.2;
const blueColdThreshold = blueAvg * 0.8;
const hotBlue = [];
const coldBlue = [];
for (const num in blueStats) {
if (blueStats[num] >= blueHotThreshold) {
hotBlue.push(parseInt(num));
} else if (blueStats[num] <= blueColdThreshold) {
coldBlue.push(parseInt(num));
}
}
let sumTotal = 0;
let spanTotal = 0;
let oddEvenCount = {odd: 0, even: 0};
let sizeCount = {big: 0, small: 0};
let areaCount = {area1: 0, area2: 0, area3: 0};
let primeCount = {prime: 0, composite: 0};
let repeatCount = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0};
let serialCount = {0: 0, 1: 0, 2: 0};
let tailCount = {};
let sideCount = 0;
const primes = [2,3,5,7,11,13,17,19,23,29,31];
for (let i = 0; i < data.length; i++) {
const redBalls = data[i].red;
const sum = redBalls.reduce((a, b) => a + b, 0);
const span = redBalls[4] - redBalls[0];
sumTotal += sum;
spanTotal += span;
const odd = redBalls.filter(num => num % 2 === 1).length;
oddEvenCount.odd += odd;
oddEvenCount.even += (5 - odd);
const big = redBalls.filter(num => num > 17).length;
sizeCount.big += big;
sizeCount.small += (5 - big);
const area1 = redBalls.filter(num => num <= 10).length;
const area2 = redBalls.filter(num => num > 10 && num <= 20).length;
const area3 = 5 - area1 - area2;
areaCount.area1 += area1;
areaCount.area2 += area2;
areaCount.area3 += area3;
const prime = redBalls.filter(num => primes.includes(num)).length;
primeCount.prime += prime;
primeCount.composite += (5 - prime);
if (i > 0) {
const prevRed = data[i-1].red;
const repeat = redBalls.filter(num => prevRed.includes(num)).length;
repeatCount[repeat]++;
}
let serialGroups = 0;
for (let j = 1; j < 5; j++) {
if (redBalls[j] === redBalls[j-1] + 1) {
serialGroups++;
}
}
serialGroups = serialGroups > 2 ? 2 : serialGroups;
serialCount[serialGroups]++;
redBalls.forEach(num => {
const tail = num % 10;
tailCount[tail] = (tailCount[tail] || 0) + 1;
});
if (i > 0) {
const prevRed = data[i-1].red;
const sideNumbers = new Set();
prevRed.forEach(num => {
if (num > 1) sideNumbers.add(num - 1);
if (num < 35) sideNumbers.add(num + 1);
});
const side = redBalls.filter(num => sideNumbers.has(num)).length;
sideCount += side;
}
}
const avgSum = sumTotal / data.length;
const avgSpan = spanTotal / data.length;
const avgSide = sideCount / (data.length - 1);
const oddEvenRatio = {
odd: oddEvenCount.odd / (data.length * 5) * 100,
even: oddEvenCount.even / (data.length * 5) * 100
};
const sizeRatio = {
big: sizeCount.big / (data.length * 5) * 100,
small: sizeCount.small / (data.length * 5) * 100
};
const areaRatio = {
area1: areaCount.area1 / (data.length * 5) * 100,
area2: areaCount.area2 / (data.length * 5) * 100,
area3: areaCount.area3 / (data.length * 5) * 100
};
const primeRatio = {
prime: primeCount.prime / (data.length * 5) * 100,
composite: primeCount.composite / (data.length * 5) * 100
};
const hotColdRatio = {
hot: hotRed.length / 35 * 100,
warm: warmRed.length / 35 * 100,
cold: coldRed.length / 35 * 100
};
return {
hotRed: hotRed,
warmRed: warmRed,
coldRed: coldRed,
hotBlue: hotBlue,
coldBlue: coldBlue,
redStats: redStats,
blueStats: blueStats,
avgSum: avgSum,
avgSpan: avgSpan,
avgSide: avgSide,
oddEvenRatio: oddEvenRatio,
sizeRatio: sizeRatio,
areaRatio: areaRatio,
primeRatio: primeRatio,
hotColdRatio: hotColdRatio,
repeatCount: repeatCount,
serialCount: serialCount,
tailCount: tailCount
};
}
function generateRecommendations() {
historyData = saveHistoryToLocalStorage();
const progressContainer = document.getElementById('progress-container');
const progressBar = document.getElementById('progress-bar');
progressContainer.style.display = 'block';
progressBar.style.width = '0%';
progressBar.textContent = '0%';
if (historyData.length < 5) {
alert('请至少输入5期完整的历史数据!');
progressContainer.style.display = 'none';
return;
}
const paramInfo = getParametersWithPriority();
const analysis = analyzeHistory(historyData);
const recommendations = [];
const maxAttempts = 1000;
const targetCount = 5;
const originalParams = JSON.parse(JSON.stringify(paramInfo));
let relaxedParams = paramInfo;
let relaxationLevel = 0;
function generateWithRelaxedConditions() {
let attempts = 0;
let generated = 0;
function generateBatch() {
const batchSize = 10;
let batchGenerated = 0;
for (let i = 0; i < batchSize && attempts < maxAttempts && generated < targetCount; i++) {
attempts++;
const redBalls = generateRedBallsWithPriority(historyData, analysis, relaxedParams);
const blueBalls = generateBlueBalls(historyData, analysis, relaxedParams.params, relaxedParams.params.favoriteBalls);
if (checkRedConditions(redBalls, historyData[historyData.length - 1].red, relaxedParams.params, analysis)) {
const exists = recommendations.some(item =>
item.red.join(',') === redBalls.join(',') &&
item.blue.join(',') === blueBalls.join(',')
);
if (!exists) {
recommendations.push({
red: redBalls,
blue: blueBalls
});
generated++;
batchGenerated++;
}
}
const progress = Math.min(100, Math.floor(attempts / maxAttempts * 100));
progressBar.style.width = progress + '%';
progressBar.textContent = progress + '%';
}
if (generated < targetCount && attempts < maxAttempts) {
setTimeout(generateBatch, 0);
} else {
progressContainer.style.display = 'none';
if (recommendations.length === 0 && relaxationLevel < 3) {
relaxationLevel++;
relaxedParams = relaxConditions(originalParams, relaxationLevel);
setTimeout(generateWithRelaxedConditions, 0);
} else if (recommendations.length === 0) {
alert('经过多次尝试仍无法生成符合要求的号码,请尝试放宽更多限制条件!');
return;
} else {
displayResults(recommendations, analysis);
}
}
}
generateBatch();
}
generateWithRelaxedConditions();
}
function relaxConditions(paramInfo, level) {
const relaxed = JSON.parse(JSON.stringify(paramInfo));
switch(level) {
case 1:
relaxed.params.sumMin = Math.max(15, relaxed.params.sumMin - 10);
relaxed.params.sumMax = Math.min(165, relaxed.params.sumMax + 10);
relaxed.params.spanMin = Math.max(4, relaxed.params.spanMin - 3);
relaxed.params.spanMax = Math.min(34, relaxed.params.spanMax + 3);
break;
case 2:
if (relaxed.params.sizeRatio !== 'any') relaxed.params.sizeRatio = 'any';
if (relaxed.params.areaRatio !== 'any') relaxed.params.areaRatio = 'any';
if (relaxed.params.oddEven !== 'any') relaxed.params.oddEven = 'any';
if (relaxed.params.hotColdRatio !== 'any') relaxed.params.hotColdRatio = 'any';
break;
case 3:
relaxed.params.sideSettings.mode = 'any';
relaxed.params.tailSettings.mode = 'any';
relaxed.params.tailSizeSettings.mode = 'any';
relaxed.params.areaSerialSettings.mode = 'any';
relaxed.params.ballOddEvenSettings.mode = 'any';
relaxed.params.combinationSettings.mode = 'any';
relaxed.params.zoneSettings.mode = 'any';
relaxed.params.dragonPhoenixSettings.dragonHead = 'any';
relaxed.params.dragonPhoenixSettings.phoenixTail = 'any';
break;
}
return relaxed;
}
function checkRedConditions(redBalls, lastRed, params, analysis) {
if (redBalls.length !== 5) return false;
const uniqueBalls = [...new Set(redBalls)];
if (uniqueBalls.length !== 5) return false;
if (!checkRatioWithTolerance(redBalls, {
sizeRatio: params.sizeRatio,
areaRatio: params.areaRatio,
oddEven: params.oddEven,
hotColdRatio: params.hotColdRatio,
analysis: analysis
})) {
return false;
}
const sum = redBalls.reduce((a, b) => a + b, 0);
if (sum < params.sumMin || sum > params.sumMax) {
return false;
}
const span = redBalls[4] - redBalls[0];
if (span < params.spanMin || span > params.spanMax) {
return false;
}
if (params.repeatNum !== 'any') {
const repeat = redBalls.filter(num => lastRed.includes(num)).length;
if (parseInt(params.repeatNum) !== repeat) {
return false;
}
}
const primes = [2,3,5,7,11,13,17,19,23,29,31];
const prime = redBalls.filter(num => primes.includes(num)).length;
const composite = 5 - prime;
if (params.primeRatio !== 'any') {
const [targetPrime, targetComposite] = params.primeRatio.split(':').map(Number);
if (Math.abs(prime - targetPrime) > 1) {
return false;
}
}
let serialCount = 0;
for (let i = 1; i < 5; i++) {
if (redBalls[i] === redBalls[i-1] + 1) {
serialCount++;
}
}
const serialGroups = serialCount > 2 ? 2 : serialCount;
if (params.serialNum !== 'any' && serialGroups !== parseInt(params.serialNum)) {
return false;
}
const sideSettings = params.sideSettings;
if (sideSettings.mode !== 'any') {
const sideNumbers = getEnhancedSideNumbers(lastRed, historyData);
const sideCount = redBalls.filter(num => sideNumbers.has(num)).length;
if (sideSettings.mode === 'include') {
if (sideSettings.count !== 'any') {
const requiredCount = parseInt(sideSettings.count);
if (sideCount < requiredCount) {
return false;
}
} else if (sideCount === 0) {
return false;
}
} else if (sideSettings.mode === 'exclude') {
if (sideCount > 0) {
return false;
}
}
}
const tailSettings = params.tailSettings;
if (tailSettings.mode !== 'any' && tailSettings.tails.length > 0) {
const tailsInBalls = new Set();
redBalls.forEach(num => {
tailsInBalls.add(num % 10);
});
if (tailSettings.mode === 'include') {
for (const tail of tailSettings.tails) {
if (!tailsInBalls.has(tail)) {
return false;
}
}
} else if (tailSettings.mode === 'exclude') {
for (const tail of tailSettings.tails) {
if (tailsInBalls.has(tail)) {
return false;
}
}
}
if (tailSettings.count !== 'any') {
const requiredCount = parseInt(tailSettings.count);
if (tailsInBalls.size !== requiredCount) {
return false;
}
}
}
const tailSizeSettings = params.tailSizeSettings;
if (tailSizeSettings.mode !== 'any' && tailSizeSettings.sizes.length > 0) {
const tailSizesInBalls = new Set();
redBalls.forEach(num => {
const tail = num % 10;
if (tail >= 1 && tail <= 3) {
tailSizesInBalls.add('small');
} else if (tail >= 4 && tail <= 6) {
tailSizesInBalls.add('medium');
} else {
tailSizesInBalls.add('large');
}
});
if (tailSizeSettings.mode === 'include') {
for (const size of tailSizeSettings.sizes) {
if (!tailSizesInBalls.has(size)) {
return false;
}
}
} else if (tailSizeSettings.mode === 'exclude') {
for (const size of tailSizeSettings.sizes) {
if (tailSizesInBalls.has(size)) {
return false;
}
}
}
}
const areaSerialSettings = params.areaSerialSettings;
if (areaSerialSettings.mode === 'include' && areaSerialSettings.areas.length > 0) {
const area1Balls = redBalls.filter(num => num <= 10).sort((a, b) => a - b);
const area2Balls = redBalls.filter(num => num > 10 && num <= 20).sort((a, b) => a - b);
const area3Balls = redBalls.filter(num => num > 20).sort((a, b) => a - b);
for (const area of areaSerialSettings.areas) {
let hasSerial = false;
if (area === 1) {
hasSerial = hasSerialInArea(area1Balls);
} else if (area === 2) {
hasSerial = hasSerialInArea(area2Balls);
} else if (area === 3) {
hasSerial = hasSerialInArea(area3Balls);
}
if (!hasSerial) {
return false;
}
}
}
const ballOddEvenSettings = params.ballOddEvenSettings;
if (ballOddEvenSettings.mode !== 'any') {
for (let i = 0; i < 5; i++) {
const ballNum = i + 1;
const setting = ballOddEvenSettings.settings[ballNum];
if (setting && setting !== 'any') {
const isOdd = redBalls[i] % 2 === 1;
if (ballOddEvenSettings.mode === 'include') {
if ((setting === 'odd' && !isOdd) || (setting === 'even' && isOdd)) {
return false;
}
} else if (ballOddEvenSettings.mode === 'exclude') {
if ((setting === 'odd' && isOdd) || (setting === 'even' && !isOdd)) {
return false;
}
}
}
}
}
const combinationSettings = params.combinationSettings;
if (combinationSettings.mode === 'include' && combinationSettings.combinations.length > 0) {
let hasValidCombination = false;
for (const comb of combinationSettings.combinations) {
const allIncluded = comb.every(ball => redBalls.includes(ball));
if (allIncluded) {
hasValidCombination = true;
break;
}
}
if (!hasValidCombination) {
return false;
}
}
const zoneSettings = params.zoneSettings;
if (zoneSettings.mode !== 'any' && zoneSettings.zones.length > 0) {
const selectedZones = zoneSettings.zones;
const presentZones = new Set();
redBalls.forEach(num => {
const zone = zoneOptions.find(z => num >= z.min && num <= z.max);
if (zone) presentZones.add(zone.zone);
});
if (zoneSettings.mode === 'include') {
for (const zone of selectedZones) {
if (!presentZones.has(zone)) {
return false;
}
}
} else if (zoneSettings.mode === 'exclude') {
for (const zone of selectedZones) {
if (presentZones.has(zone)) {
return false;
}
}
}
}
if (params.dragonPhoenixSettings.dragonHead !== 'any') {
const [min, max] = params.dragonPhoenixSettings.dragonHead.split('-').map(Number);
if (redBalls[0] < min || redBalls[0] > max) {
return false;
}
}
if (params.dragonPhoenixSettings.phoenixTail !== 'any') {
const [min, max] = params.dragonPhoenixSettings.phoenixTail.split('-').map(Number);
if (redBalls[4] < min || redBalls[4] > max) {
return false;
}
}
return true;
}
function checkRatioWithTolerance(redBalls, params) {
const big = redBalls.filter(num => num > 17).length;
const small = 5 - big;
if (params.sizeRatio !== 'any') {
const [targetBig, targetSmall] = params.sizeRatio.split(':').map(Number);
if (Math.abs(big - targetBig) > 1) {
return false;
}
}
const area1 = redBalls.filter(num => num <= 10).length;
const area2 = redBalls.filter(num => num > 10 && num <= 20).length;
const area3 = 5 - area1 - area2;
if (params.areaRatio !== 'any') {
const [target1, target2, target3] = params.areaRatio.split(':').map(Number);
if (Math.abs(area1 - target1) > 1 ||
Math.abs(area2 - target2) > 1 ||
Math.abs(area3 - target3) > 1) {
return false;
}
}
const odd = redBalls.filter(num => num % 2 === 1).length;
const even = 5 - odd;
if (params.oddEven !== 'any') {
const [targetOdd, targetEven] = params.oddEven.split(':').map(Number);
if (Math.abs(odd - targetOdd) > 1) {
return false;
}
}
if (params.hotColdRatio !== 'any') {
const hot = redBalls.filter(num => params.analysis.hotRed.includes(num)).length;
const warm = redBalls.filter(num => params.analysis.warmRed.includes(num)).length;
const cold = redBalls.filter(num => params.analysis.coldRed.includes(num)).length;
const [targetHot, targetCold] = params.hotColdRatio.split(':').map(Number);
const targetWarm = 5 - targetHot - targetCold;
if (Math.abs(hot - targetHot) > 1 ||
Math.abs(cold - targetCold) > 1 ||
Math.abs(warm - targetWarm) > 1) {
return false;
}
}
return true;
}
function hasSerialInArea(balls) {
if (balls.length < 2) return false;
for (let i = 1; i < balls.length; i++) {
if (balls[i] === balls[i-1] + 1) {
return true;
}
}
return false;
}
function displayResults(recommendations, analysis) {
const resultDiv = document.getElementById('result');
resultDiv.innerHTML = '';
const recTitle = document.createElement('div');
recTitle.className = 'section-title';
recTitle.textContent = '推荐号码';
resultDiv.appendChild(recTitle);
recommendations.forEach((rec, index) => {
const item = document.createElement('div');
item.className = 'recommendation-item';
const ballsDiv = document.createElement('div');
rec.red.forEach(num => {
const ball = document.createElement('span');
ball.className = 'ball red-ball';
ball.textContent = num < 10 ? '0' + num : num;
ballsDiv.appendChild(ball);
});
const separator = document.createElement('span');
separator.textContent = ' + ';
separator.style.margin = '0 5px';
separator.style.color = '#333';
ballsDiv.appendChild(separator);
rec.blue.forEach(num => {
const ball = document.createElement('span');
ball.className = 'ball blue-ball';
ball.textContent = num < 10 ? '0' + num : num;
ballsDiv.appendChild(ball);
});
item.appendChild(ballsDiv);
resultDiv.appendChild(item);
});
const analysisTitle = document.createElement('div');
analysisTitle.className = 'section-title';
analysisTitle.textContent = '分析结果';
resultDiv.appendChild(analysisTitle);
const analysisDiv = document.createElement('div');
analysisDiv.className = 'flex-container';
const hotRedDiv = document.createElement('div');
hotRedDiv.className = 'flex-item';
addAnalysisItem(hotRedDiv, '红球热号', analysis.hotRed);
analysisDiv.appendChild(hotRedDiv);
const warmRedDiv = document.createElement('div');
warmRedDiv.className = 'flex-item';
addAnalysisItem(warmRedDiv, '红球温号', analysis.warmRed);
analysisDiv.appendChild(warmRedDiv);
const coldRedDiv = document.createElement('div');
coldRedDiv.className = 'flex-item';
addAnalysisItem(coldRedDiv, '红球冷号', analysis.coldRed);
analysisDiv.appendChild(coldRedDiv);
const hotBlueDiv = document.createElement('div');
hotBlueDiv.className = 'flex-item';
addAnalysisItem(hotBlueDiv, '蓝球热号', analysis.hotBlue);
analysisDiv.appendChild(hotBlueDiv);
const coldBlueDiv = document.createElement('div');
coldBlueDiv.className = 'flex-item';
addAnalysisItem(coldBlueDiv, '蓝球冷号', analysis.coldBlue);
analysisDiv.appendChild(coldBlueDiv);
resultDiv.appendChild(analysisDiv);
}
function addAnalysisItem(container, title, stats) {
const titleDiv = document.createElement('div');
titleDiv.className = 'section-title';
titleDiv.textContent = title;
container.appendChild(titleDiv);
const statsDiv = document.createElement('div');
statsDiv.style.display = 'flex';
statsDiv.style.flexWrap = 'wrap';
statsDiv.style.gap = '5px';
stats.forEach(num => {
const ball = document.createElement('div');
ball.className = 'ball ' + (title.includes('红球') ? 'red-ball' : 'blue-ball');
ball.textContent = num < 10 ? '0' + num : num;
statsDiv.appendChild(ball);
});
container.appendChild(statsDiv);
}
function adjustParameters() {
historyData = saveHistoryToLocalStorage();
if (historyData.length < 5) {
alert('请至少输入5期历史数据以进行智能分析');
return;
}
const analysis = analyzeHistory(historyData);
document.getElementById('size-ratio').value = '3:2';
document.getElementById('odd-even').value = '3:2';
document.getElementById('hot-cold-ratio').value = '3:2';
document.getElementById('repeat-num').value = '1';
document.getElementById('serial-num').value = '1';
document.querySelectorAll('.favorite-ball.selected').forEach(ball => {
ball.classList.remove('selected');
});
analysis.hotRed.slice(0, 5).forEach(num => {
const ball = document.querySelector(`.favorite-red[data-num="${num}"]`);
if (ball) ball.classList.add('selected');
});
analysis.hotBlue.slice(0, 2).forEach(num => {
const ball = document.querySelector(`.favorite-blue[data-num="${num}"]`);
if (ball) ball.classList.add('selected');
});
document.getElementById('zone-selection-mode').value = 'include';
document.querySelectorAll('.zone-option.selected').forEach(opt => {
opt.classList.remove('selected');
});
const recommendedZones = selectRandomElements([1, 2, 3, 4], Math.floor(Math.random() * 2) + 2);
recommendedZones.forEach(zone => {
document.querySelector(`.zone-option[data-zone="${zone}"]`).classList.add('selected');
});
const lastFirst = historyData[historyData.length-1].red[0];
const lastLast = historyData[historyData.length-1].red[4];
const headMin = Math.max(1, lastFirst - 3);
const headMax = Math.min(21, lastFirst + 3);
const headRange = `${headMin}-${headMin+2}`;
document.getElementById('dragon-head-range').value = headRange;
const tailMin = Math.max(22, lastLast - 3);
const tailMax = Math.min(35, lastLast + 3);
const tailRange = `${tailMax-2}-${tailMax}`;
document.getElementById('phoenix-tail-range').value = tailRange;
document.getElementById('side-number-mode').value = 'include';
document.getElementById('side-number-count').value = '2';
const sumMin = Math.max(15, Math.floor(analysis.avgSum) - 15);
const sumMax = Math.min(165, Math.ceil(analysis.avgSum) + 15);
document.getElementById('sum-min').value = sumMin;
document.getElementById('sum-max').value = sumMax;
const spanMin = Math.max(4, Math.floor(analysis.avgSpan) - 5);
const spanMax = Math.min(34, Math.ceil(analysis.avgSpan) + 5);
document.getElementById('span-min').value = spanMin;
document.getElementById('span-max').value = spanMax;
alert('智能参数推荐已完成!请点击"生成推荐号码"按钮获取推荐号码。');
}
function analyzeData() {
historyData = saveHistoryToLocalStorage();
if (historyData.length < 5) {
alert('请至少输入5期历史数据以进行分析');
return;
}
const analysis = analyzeHistory(historyData);
const resultDiv = document.getElementById('analysis-result');
resultDiv.style.display = 'block';
const basicTab = document.getElementById('basic-tab');
basicTab.innerHTML = '';
const statGrid = document.createElement('div');
statGrid.className = 'stat-grid';
const redStatCard = document.createElement('div');
redStatCard.className = 'stat-card';
redStatCard.innerHTML = `
<div class="stat-card-title">红球统计</div>
<div>平均和值: ${analysis.avgSum.toFixed(1)}</div>
<div>平均跨度: ${analysis.avgSpan.toFixed(1)}</div>
<div>平均边号: ${analysis.avgSide.toFixed(1)}</div>
`;
statGrid.appendChild(redStatCard);
const oddEvenCard = document.createElement('div');
oddEvenCard.className = 'stat-card';
oddEvenCard.innerHTML = `
<div class="stat-card-title">奇偶比例</div>
<div>奇数: ${analysis.oddEvenRatio.odd.toFixed(1)}%</div>
<div>偶数: ${analysis.oddEvenRatio.even.toFixed(1)}%</div>
`;
statGrid.appendChild(oddEvenCard);
const sizeCard = document.createElement('div');
sizeCard.className = 'stat-card';
sizeCard.innerHTML = `
<div class="stat-card-title">大小比例</div>
<div>大数(18-35): ${analysis.sizeRatio.big.toFixed(1)}%</div>
<div>小数(1-17): ${analysis.sizeRatio.small.toFixed(1)}%</div>
`;
statGrid.appendChild(sizeCard);
const areaCard = document.createElement('div');
areaCard.className = 'stat-card';
areaCard.innerHTML = `
<div class="stat-card-title">区域比例</div>
<div>一区(1-10): ${analysis.areaRatio.area1.toFixed(1)}%</div>
<div>二区(11-20): ${analysis.areaRatio.area2.toFixed(1)}%</div>
<div>三区(21-35): ${analysis.areaRatio.area3.toFixed(1)}%</div>
`;
statGrid.appendChild(areaCard);
const primeCard = document.createElement('div');
primeCard.className = 'stat-card';
primeCard.innerHTML = `
<div class="stat-card-title">质合比例</div>
<div>质数: ${analysis.primeRatio.prime.toFixed(1)}%</div>
<div>合数: ${analysis.primeRatio.composite.toFixed(1)}%</div>
`;
statGrid.appendChild(primeCard);
const repeatCard = document.createElement('div');
repeatCard.className = 'stat-card';
repeatCard.innerHTML = `
<div class="stat-card-title">与上期重复</div>
<div>0个: ${analysis.repeatCount[0] || 0}次</div>
<div>1个: ${analysis.repeatCount[1] || 0}次</div>
<div>2个: ${analysis.repeatCount[2] || 0}次</div>
<div>3个: ${analysis.repeatCount[3] || 0}次</div>
`;
statGrid.appendChild(repeatCard);
const serialCard = document.createElement('div');
serialCard.className = 'stat-card';
serialCard.innerHTML = `
<div class="stat-card-title">连号组数</div>
<div>0组: ${analysis.serialCount[0] || 0}次</div>
<div>1组: ${analysis.serialCount[1] || 0}次</div>
<div>2组: ${analysis.serialCount[2] || 0}次</div>
`;
statGrid.appendChild(serialCard);
basicTab.appendChild(statGrid);
const frequencyTab = document.getElementById('frequency-tab');
frequencyTab.innerHTML = '';
const redFreqTable = document.createElement('table');
redFreqTable.className = 'analysis-table';
redFreqTable.innerHTML = `
<tr>
<th>红球</th>
<th>出现次数</th>
<th>频率</th>
</tr>
`;
const maxRedFreq = Math.max(...Object.values(analysis.redStats));
for (let num = 1; num <= 35; num++) {
const freq = analysis.redStats[num] || 0;
const percentage = (freq / historyData.length * 100).toFixed(1);
const barWidth = (freq / maxRedFreq * 100).toFixed(1);
const row = document.createElement('tr');
row.innerHTML = `
<td>${num < 10 ? '0' + num : num}</td>
<td>${freq}</td>
<td class="frequency-cell">
${percentage}%
<div class="frequency-bar" style="width: ${barWidth}%"></div>
</td>
`;
redFreqTable.appendChild(row);
}
frequencyTab.appendChild(document.createElement('div')).textContent = '红球频率统计';
frequencyTab.appendChild(redFreqTable);
const blueFreqTable = document.createElement('table');
blueFreqTable.className = 'analysis-table';
blueFreqTable.innerHTML = `
<tr>
<th>蓝球</th>
<th>出现次数</th>
<th>频率</th>
</tr>
`;
const maxBlueFreq = Math.max(...Object.values(analysis.blueStats));
for (let num = 1; num <= 12; num++) {
const freq = analysis.blueStats[num] || 0;
const percentage = (freq / historyData.length * 100).toFixed(1);
const barWidth = (freq / maxBlueFreq * 100).toFixed(1);
const row = document.createElement('tr');
row.innerHTML = `
<td>${num < 10 ? '0' + num : num}</td>
<td>${freq}</td>
<td class="frequency-cell">
${percentage}%
<div class="frequency-bar" style="width: ${barWidth}%"></div>
</td>
`;
blueFreqTable.appendChild(row);
}
frequencyTab.appendChild(document.createElement('div')).textContent = '蓝球频率统计';
frequencyTab.appendChild(blueFreqTable);
const patternTab = document.getElementById('pattern-tab');
patternTab.innerHTML = '';
const tailTable = document.createElement('table');
tailTable.className = 'analysis-table';
tailTable.innerHTML = `
<tr>
<th>尾号</th>
<th>出现次数</th>
<th>频率</th>
</tr>
`;
const tailFreq = {};
for (let i = 0; i <= 9; i++) {
tailFreq[i] = 0;
}
for (const num in analysis.redStats) {
const tail = num % 10;
tailFreq[tail] += analysis.redStats[num];
}
const maxTailFreq = Math.max(...Object.values(tailFreq));
for (let i = 0; i <= 9; i++) {
const freq = tailFreq[i];
const percentage = (freq / (historyData.length * 5) * 100).toFixed(1);
const barWidth = (freq / maxTailFreq * 100).toFixed(1);
const row = document.createElement('tr');
row.innerHTML = `
<td>${i}</td>
<td>${freq}</td>
<td class="frequency-cell">
${percentage}%
<div class="frequency-bar" style="width: ${barWidth}%"></div>
</td>
`;
tailTable.appendChild(row);
}
patternTab.appendChild(document.createElement('div')).textContent = '尾号统计';
patternTab.appendChild(tailTable);
const trendTab = document.getElementById('trend-tab');
trendTab.innerHTML = '';
const recentTrendDiv = document.createElement('div');
recentTrendDiv.innerHTML = `
<div class="section-title">近期趋势</div>
<div>最近5期热号: ${analysis.hotRed.slice(0, 10).join(', ')}</div>
<div>最近5期温号: ${analysis.warmRed.slice(0, 10).join(', ')}</div>
<div>最近5期冷号: ${analysis.coldRed.slice(0, 10).join(', ')}</div>
<div>最近5期蓝球热号: ${analysis.hotBlue.join(', ')}</div>
`;
trendTab.appendChild(recentTrendDiv);
const sumTrendDiv = document.createElement('div');
sumTrendDiv.innerHTML = `
<div class="section-title">和值趋势</div>
<div>近期平均和值: ${analysis.avgSum.toFixed(1)}</div>
<div>建议和值范围: ${Math.floor(analysis.avgSum) - 15}-${Math.ceil(analysis.avgSum) + 15}</div>
`;
trendTab.appendChild(sumTrendDiv);
const spanTrendDiv = document.createElement('div');
spanTrendDiv.innerHTML = `
<div class="section-title">跨度趋势</div>
<div>近期平均跨度: ${analysis.avgSpan.toFixed(1)}</div>
<div>建议跨度范围: ${Math.floor(analysis.avgSpan) - 5}-${Math.ceil(analysis.avgSpan) + 5}</div>
`;
trendTab.appendChild(spanTrendDiv);
}
function showAnalysisTab(tabName) {
document.querySelectorAll('.tab-button').forEach(btn => {
btn.classList.remove('active');
});
document.querySelectorAll('.tab-content').forEach(content => {
content.classList.remove('active');
});
document.querySelector(`.tab-button[onclick="showAnalysisTab('${tabName}')"]`).classList.add('active');
document.getElementById(`${tabName}-tab`).classList.add('active');
}
function initPage() {
loadHistoryFromLocalStorage();
const favoriteRedBalls = document.getElementById('favorite-red-balls');
for (let i = 1; i <= 35; i++) {
const ball = document.createElement('div');
ball.className = 'favorite-ball favorite-red';
ball.dataset.num = i;
ball.textContent = i < 10 ? '0' + i : i;
ball.addEventListener('click', function() {
this.classList.toggle('selected');
trackUserInteraction('favorite-red');
});
favoriteRedBalls.appendChild(ball);
}
const favoriteBlueBalls = document.getElementById('favorite-blue-balls');
for (let i = 1; i <= 12; i++) {
const ball = document.createElement('div');
ball.className = 'favorite-ball favorite-blue';
ball.dataset.num = i;
ball.textContent = i < 10 ? '0' + i : i;
ball.addEventListener('click', function() {
this.classList.toggle('selected');
trackUserInteraction('favorite-blue');
});
favoriteBlueBalls.appendChild(ball);
}
const tailNumberOptions = document.getElementById('tail-number-options');
for (let i = 0; i <= 9; i++) {
const option = document.createElement('div');
option.className = 'tail-number-option';
option.dataset.tail = i;
option.textContent = i;
option.addEventListener('click', function() {
this.classList.toggle('selected');
trackUserInteraction('tail-number-option');
});
tailNumberOptions.appendChild(option);
}
const zoneOptions = document.getElementById('zone-options');
for (let i = 1; i <= 4; i++) {
const option = document.querySelector(`.zone-option[data-zone="${i}"]`);
option.addEventListener('click', function() {
this.classList.toggle('selected');
trackUserInteraction('zone-option');
});
}
const tailSizeOptions = document.getElementById('tail-size-options');
document.querySelectorAll('.tail-size-option').forEach(option => {
option.addEventListener('click', function() {
this.classList.toggle('selected');
trackUserInteraction('tail-size-option');
});
});
const areaSerialOptions = document.getElementById('area-serial-options');
document.querySelectorAll('.area-serial-option').forEach(option => {
option.addEventListener('click', function() {
this.classList.toggle('selected');
trackUserInteraction('area-serial-option');
});
});
document.querySelectorAll('.odd-even-btn').forEach(btn => {
btn.addEventListener('click', function() {
const ballNum = this.dataset.ball;
document.querySelectorAll(`.odd-even-btn[data-ball="${ballNum}"]`).forEach(b => {
b.classList.remove('selected');
});
this.classList.add('selected');
trackUserInteraction('odd-even-btn');
});
});
document.querySelectorAll('input, select').forEach(input => {
input.addEventListener('change', function() {
trackUserInteraction(this.id);
});
});
resetDefaultPriority();
}
window.onload = initPage;
</script>
</body>
</html>