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;
}
.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;
}
.add-new-section {
margin-top: 20px;
padding: 15px;
background-color: #e8f5e9;
border-radius: 5px;
}
.recommendation-item {
margin-bottom: 15px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
display: flex;
justify-content: space-between;
align-items: center;
}
.add-new-btn {
background-color: #4caf50;
}
.add-new-btn:hover {
background-color: #388e3c;
}
.tail-number-section {
margin-top: 10px;
}
.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-section {
margin-top: 10px;
}
.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-section {
margin-top: 10px;
}
.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;
}
.ball-odd-even-section {
margin-top: 10px;
}
.ball-odd-even-options {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 5px;
}
.ball-odd-even-option {
padding: 5px 10px;
border: 1px solid #ddd;
border-radius: 3px;
cursor: pointer;
}
.ball-odd-even-option.selected {
background-color: #e60012;
color: white;
border-color: #e60012;
}
.combination-section {
margin-top: 10px;
}
.combination-options {
display: flex;
flex-wrap: wrap;
gap: 5px;
margin-top: 5px;
}
.combination-option {
padding: 5px 10px;
border: 1px solid #ddd;
border-radius: 3px;
cursor: pointer;
}
.combination-option.selected {
background-color: #e60012;
color: white;
border-color: #e60012;
}
.combination-input {
display: flex;
flex-wrap: wrap;
gap: 5px;
margin-top: 5px;
}
.combination-input input {
width: 30px;
text-align: center;
}
.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;
}
.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;
}
.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;
}
</style>
</head>
<body>
<div class="container">
<h1>大乐透智能选号模拟器</h1>
<div class="section">
<div class="section-title">历史数据录入</div>
<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>
<button onclick="addNewRow()">新增一行</button>
</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">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">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">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">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">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">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="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">任意</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">任意</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">任意</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">任意</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">任意</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">任意</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>
</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>
<script>
document.addEventListener('DOMContentLoaded', function() {
const historyTableBody = document.querySelector('#history-table tbody');
for (let i = 0; i < 5; i++) {
addNewRow();
}
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.textContent = i;
ball.dataset.num = i;
ball.addEventListener('click', function() {
this.classList.toggle('selected');
updateSelectedBalls();
});
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.textContent = i;
ball.dataset.num = i;
ball.addEventListener('click', function() {
this.classList.toggle('selected');
updateSelectedBalls();
});
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.textContent = i;
option.dataset.tail = i;
option.addEventListener('click', function() {
this.classList.toggle('selected');
});
tailNumberOptions.appendChild(option);
}
document.querySelectorAll('.tail-size-option').forEach(option => {
option.addEventListener('click', function() {
this.classList.toggle('selected');
});
});
document.querySelectorAll('.area-serial-option').forEach(option => {
option.addEventListener('click', function() {
this.classList.toggle('selected');
});
});
document.querySelectorAll('.odd-even-btn').forEach(btn => {
btn.addEventListener('click', function() {
const ballNum = this.dataset.ball;
const currentSelected = document.querySelector(`.odd-even-btn[data-ball="${ballNum}"].selected`);
if (currentSelected) {
currentSelected.classList.remove('selected');
if (currentSelected !== this) {
this.classList.add('selected');
}
} else {
this.classList.add('selected');
}
});
});
});
function addNewRow() {
const historyTableBody = document.querySelector('#history-table tbody');
const rows = historyTableBody.querySelectorAll('tr');
if (rows.length >= 10) {
historyTableBody.removeChild(rows[0]);
}
const newRow = document.createElement('tr');
const periodCell = document.createElement('td');
periodCell.textContent = rows.length + 1;
newRow.appendChild(periodCell);
for (let i = 0; i < 5; i++) {
const cell = document.createElement('td');
const input = document.createElement('input');
input.type = 'number';
input.min = '1';
input.max = '35';
cell.appendChild(input);
newRow.appendChild(cell);
}
for (let i = 0; i < 2; i++) {
const cell = document.createElement('td');
const input = document.createElement('input');
input.type = 'number';
input.min = '1';
input.max = '12';
cell.appendChild(input);
newRow.appendChild(cell);
}
historyTableBody.appendChild(newRow);
}
function updateSelectedBalls() {
}
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 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 generateRecommendations() {
const progressContainer = document.getElementById('progress-container');
const progressBar = document.getElementById('progress-bar');
progressContainer.style.display = 'block';
progressBar.style.width = '0%';
progressBar.textContent = '0%';
const historyData = [];
const rows = document.querySelectorAll('#history-table tbody tr');
rows.forEach(row => {
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({
red: redBalls.sort((a, b) => a - b),
blue: blueBalls.sort((a, b) => a - b)
});
}
});
if (historyData.length < 5) {
alert('请至少输入5期完整的历史数据!');
progressContainer.style.display = 'none';
return;
}
const favoriteBalls = getFavoriteBalls();
const tailSettings = getTailNumberSettings();
const tailSizeSettings = getTailSizeSettings();
const areaSerialSettings = getAreaSerialSettings();
const ballOddEvenSettings = getBallOddEvenSettings();
const combinationSettings = getCombinationSettings();
const analysis = analyzeHistory(historyData);
const params = {
sizeRatio: document.getElementById('size-ratio').value,
areaRatio: document.getElementById('area-ratio').value,
oddEven: document.getElementById('odd-even').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
};
const recommendations = [];
const maxAttempts = 500;
const targetCount = 5;
setTimeout(() => {
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 recommendation = generateNumber(historyData, analysis, params, favoriteBalls);
if (recommendation) {
const exists = recommendations.some(item =>
item.red.join(',') === recommendation.red.join(',') &&
item.blue.join(',') === recommendation.blue.join(',')
);
if (!exists) {
recommendations.push(recommendation);
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) {
alert('无法生成符合所有条件的号码,请尝试放宽一些限制条件!');
return;
}
displayResults(recommendations, analysis);
}
}
generateBatch();
}, 0);
}
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 redFrequencies = Object.values(redStats);
const redAvg = redFrequencies.reduce((a, b) => a + b, 0) / redFrequencies.length;
const hotRed = [];
const coldRed = [];
for (const num in redStats) {
if (redStats[num] >= redAvg) {
hotRed.push(parseInt(num));
} else {
coldRed.push(parseInt(num));
}
}
const blueFrequencies = Object.values(blueStats);
const blueAvg = blueFrequencies.reduce((a, b) => a + b, 0) / blueFrequencies.length;
const hotBlue = [];
const coldBlue = [];
for (const num in blueStats) {
if (blueStats[num] >= blueAvg) {
hotBlue.push(parseInt(num));
} else {
coldBlue.push(parseInt(num));
}
}
return {
hotRed: hotRed,
coldRed: coldRed,
hotBlue: hotBlue,
coldBlue: coldBlue,
redStats: redStats,
blueStats: blueStats
};
}
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 generateNumber(history, analysis, params, favoriteBalls) {
let redBalls = [];
let blueBalls = [];
redBalls = generateRedBalls(history, analysis, params, favoriteBalls);
blueBalls = generateBlueBalls(history, analysis, params, favoriteBalls);
if (!checkRedConditions(redBalls, history[history.length - 1].red, params)) {
return null;
}
for (const item of history) {
const sameRed = item.red.every((num, index) => num === redBalls[index]);
const sameBlue = item.blue.every((num, index) => num === blueBalls[index]);
if (sameRed && sameBlue) {
return null;
}
}
return {
red: redBalls,
blue: blueBalls
};
}
function generateRedBalls(history, analysis, params, favoriteBalls) {
let redBalls = [];
let useFavoriteRatio = 0.5;
if (params.favoriteWeight === 'low') useFavoriteRatio = 0.3;
if (params.favoriteWeight === 'high') useFavoriteRatio = 0.7;
if (favoriteBalls.red.length > 0 && Math.random() < useFavoriteRatio) {
const favoriteCount = Math.min(
Math.floor(Math.random() * 3) + 1,
favoriteBalls.red.length
);
const shuffledFavorites = [...favoriteBalls.red].sort(() => 0.5 - Math.random());
for (let i = 0; i < favoriteCount && redBalls.length < 5; i++) {
if (!redBalls.includes(shuffledFavorites[i])) {
redBalls.push(shuffledFavorites[i]);
}
}
}
if (redBalls.length < 5) {
const hotColdRatio = Math.random();
const useHot = hotColdRatio > 0.3;
let pool = useHot ? [...analysis.hotRed] : [...analysis.coldRed];
if (pool.length < 5) {
pool.push(...analysis.hotRed);
}
while (redBalls.length < 5 && pool.length > 0) {
const randomIndex = Math.floor(Math.random() * pool.length);
const num = pool[randomIndex];
if (!redBalls.includes(num)) {
redBalls.push(num);
}
pool.splice(randomIndex, 1);
}
}
if (redBalls.length < 5) {
const allNumbers = Array.from({length: 35}, (_, i) => i + 1).filter(n => !redBalls.includes(n));
while (redBalls.length < 5 && allNumbers.length > 0) {
const randomIndex = Math.floor(Math.random() * allNumbers.length);
redBalls.push(allNumbers[randomIndex]);
allNumbers.splice(randomIndex, 1);
}
}
redBalls.sort((a, b) => a - b);
return redBalls;
}
function checkRedConditions(redBalls, lastRed, params) {
const big = redBalls.filter(num => num > 17).length;
const small = 5 - big;
const sizeRatio = `${big}:${small}`;
if (params.sizeRatio !== 'any' && sizeRatio !== params.sizeRatio) {
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;
const areaRatio = `${area1}:${area2}:${area3}`;
if (params.areaRatio !== 'any' && areaRatio !== params.areaRatio) {
return false;
}
const odd = redBalls.filter(num => num % 2 === 1).length;
const even = 5 - odd;
const oddEven = `${odd}:${even}`;
if (params.oddEven !== 'any' && oddEven !== params.oddEven) {
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;
const primeRatio = `${prime}:${composite}`;
if (params.primeRatio !== 'any' && primeRatio !== params.primeRatio) {
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 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 !== 'any' && combinationSettings.combinations.length > 0) {
let hasValidCombination = false;
for (const comb of combinationSettings.combinations) {
const allIncluded = comb.every(ball => redBalls.includes(ball));
if (combinationSettings.mode === 'include') {
if (allIncluded) {
hasValidCombination = true;
break;
}
} else if (combinationSettings.mode === 'exclude') {
if (allIncluded) {
return false;
}
}
}
if (combinationSettings.mode === 'include' && !hasValidCombination) {
return false;
}
}
return true;
}
function generateBlueBalls(history, analysis, params, favoriteBalls) {
let blueBalls = [];
if (favoriteBalls.blue.length > 0) {
const useFavorite = Math.random() < 0.7;
if (useFavorite) {
const favoriteCount = Math.min(
Math.floor(Math.random() * 2) + 1,
favoriteBalls.blue.length
);
const shuffledFavorites = [...favoriteBalls.blue].sort(() => 0.5 - Math.random());
for (let i = 0; i < favoriteCount && blueBalls.length < 2; i++) {
if (!blueBalls.includes(shuffledFavorites[i])) {
blueBalls.push(shuffledFavorites[i]);
}
}
}
}
if (blueBalls.length < 2) {
const hotColdRatio = Math.random();
const useHot = hotColdRatio > 0.3;
let pool = useHot ? [...analysis.hotBlue] : [...analysis.coldBlue];
if (pool.length < 2) {
pool.push(...analysis.hotBlue);
}
while (blueBalls.length < 2 && pool.length > 0) {
const randomIndex = Math.floor(Math.random() * pool.length);
const num = pool[randomIndex];
if (!blueBalls.includes(num)) {
blueBalls.push(num);
}
pool.splice(randomIndex, 1);
}
}
if (blueBalls.length < 2) {
const allNumbers = Array.from({length: 12}, (_, i) => i + 1).filter(n => !blueBalls.includes(n));
while (blueBalls.length < 2 && allNumbers.length > 0) {
const randomIndex = Math.floor(Math.random() * allNumbers.length);
blueBalls.push(allNumbers[randomIndex]);
allNumbers.splice(randomIndex, 1);
}
}
if (params.blueSize === 'small') {
blueBalls = blueBalls.filter(num => num <= 6);
while (blueBalls.length < 2) {
const num = Math.floor(Math.random() * 6) + 1;
if (!blueBalls.includes(num)) {
blueBalls.push(num);
}
}
} else if (params.blueSize === 'big') {
blueBalls = blueBalls.filter(num => num > 6);
while (blueBalls.length < 2) {
const num = Math.floor(Math.random() * 6) + 7;
if (!blueBalls.includes(num)) {
blueBalls.push(num);
}
}
}
blueBalls.sort((a, b) => a - b);
return blueBalls;
}
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 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);
}
</script>
</body>
</html>