js实现赛程
实现赛程的基本思路
使用JavaScript实现赛程功能通常涉及生成比赛对阵表、处理轮次安排以及确保每支队伍公平比赛。常见的赛程类型包括单循环赛、双循环赛和淘汰赛。
单循环赛实现
单循环赛指每支队伍与其他队伍比赛一次。可以使用数组的轮转算法生成对阵表。
function generateRoundRobin(teams) {
const schedule = [];
const numTeams = teams.length;
const rounds = numTeams - 1;
for (let round = 0; round < rounds; round++) {
const matches = [];
for (let i = 0; i < numTeams / 2; i++) {
const home = teams[i];
const away = teams[numTeams - 1 - i];
if (home && away) {
matches.push({ home, away });
}
}
schedule.push({ round: round + 1, matches });
// 轮转数组(固定第一支队伍)
teams.splice(1, 0, teams.pop());
}
return schedule;
}
const teams = ['A', 'B', 'C', 'D'];
console.log(generateRoundRobin(teams));
双循环赛实现
双循环赛每支队伍与其他队伍比赛两次(主场和客场)。可以在单循环赛基础上扩展,交换主客场。
function generateDoubleRoundRobin(teams) {
const firstHalf = generateRoundRobin(teams);
const secondHalf = firstHalf.map(round => ({
round: round.round + teams.length - 1,
matches: round.matches.map(match => ({
home: match.away,
away: match.home
}))
}));
return [...firstHalf, ...secondHalf];
}
console.log(generateDoubleRoundRobin(teams));
淘汰赛实现
淘汰赛每轮淘汰一半队伍,直到决出冠军。可以使用递归或迭代方式生成对阵表。
function generateKnockout(teams) {
const schedule = [];
let currentTeams = [...teams];
let round = 1;
while (currentTeams.length > 1) {
const matches = [];
for (let i = 0; i < currentTeams.length; i += 2) {
if (currentTeams[i + 1]) {
matches.push({
home: currentTeams[i],
away: currentTeams[i + 1]
});
} else {
// 轮空处理
matches.push({
home: currentTeams[i],
away: null
});
}
}
schedule.push({ round, matches });
currentTeams = matches.map(match =>
Math.random() > 0.5 ? match.home : match.away
);
round++;
}
return schedule;
}
console.log(generateKnockout(teams));
赛程可视化
可以使用HTML和CSS将生成的赛程渲染为可视化的对阵表。

<div id="schedule"></div>
<script>
function renderSchedule(schedule) {
const container = document.getElementById('schedule');
schedule.forEach(round => {
const roundDiv = document.createElement('div');
roundDiv.innerHTML = `<h3>Round ${round.round}</h3>`;
round.matches.forEach(match => {
roundDiv.innerHTML += `
<div class="match">
${match.home} vs ${match.away || 'BYE'}
</div>
`;
});
container.appendChild(roundDiv);
});
}
const schedule = generateRoundRobin(['A', 'B', 'C', 'D']);
renderSchedule(schedule);
</script>
<style>
.match {
padding: 8px;
margin: 4px;
background: #f0f0f0;
}
</style>
注意事项
- 队伍数量为奇数时需要处理轮空(BYE)。
- 实际应用中可能需要考虑主客场平衡、休息时间等复杂因素。
- 大规模赛程建议使用专业算法库或后端服务生成。






