php实现单淘汰赛制
PHP实现单淘汰赛制的方法
单淘汰赛制是一种竞赛形式,每场比赛的败者被淘汰,胜者进入下一轮,直到决出冠军。以下是实现单淘汰赛制的几种方法:
生成比赛对阵表
使用数组存储参赛选手或队伍,通过循环生成对阵表:

$players = ['选手1', '选手2', '选手3', '选手4', '选手5', '选手6', '选手7', '选手8'];
shuffle($players); // 随机打乱顺序
while (count($players) > 1) {
$winners = [];
for ($i = 0; $i < count($players); $i += 2) {
$player1 = $players[$i];
$player2 = $players[$i + 1] ?? null;
if ($player2) {
echo "比赛: $player1 vs $player2\n";
$winner = rand(0, 1) ? $player1 : $player2; // 模拟随机胜负
$winners[] = $winner;
echo "胜者: $winner\n\n";
} else {
$winners[] = $player1; // 轮空直接晋级
}
}
$players = $winners;
}
echo "冠军是: " . $players[0];
处理轮空情况
当参赛人数不是2的幂次方时,需要处理轮空:

function generateBrackets($players) {
$totalRounds = ceil(log(count($players), 2));
$idealSize = pow(2, $totalRounds);
$byes = $idealSize - count($players);
$brackets = [];
$round = 1;
$currentPlayers = $players;
while (count($currentPlayers) > 1) {
$nextRound = [];
$matches = [];
// 处理轮空
if ($round == 1 && $byes > 0) {
$byedPlayers = array_slice($currentPlayers, 0, $byes);
$currentPlayers = array_merge(
$byedPlayers,
array_slice($currentPlayers, $byes)
);
}
// 生成比赛
for ($i = 0; $i < count($currentPlayers); $i += 2) {
$player1 = $currentPlayers[$i];
$player2 = $currentPlayers[$i + 1] ?? null;
if ($player2) {
$match = "$player1 vs $player2";
$winner = rand(0, 1) ? $player1 : $player2;
$matches[] = $match;
$nextRound[] = $winner;
} else {
$nextRound[] = $player1;
}
}
$brackets["第{$round}轮"] = $matches;
$currentPlayers = $nextRound;
$round++;
}
return [
'brackets' => $brackets,
'champion' => $currentPlayers[0]
];
}
$result = generateBrackets(['A', 'B', 'C', 'D', 'E', 'F', 'G']);
print_r($result);
数据库存储赛果
对于更复杂的比赛系统,可以使用数据库存储比赛结果:
// 数据库表结构示例
/*
CREATE TABLE tournaments (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255)
);
CREATE TABLE matches (
id INT AUTO_INCREMENT PRIMARY KEY,
tournament_id INT,
round INT,
player1_id INT,
player2_id INT,
winner_id INT,
FOREIGN KEY (tournament_id) REFERENCES tournaments(id)
);
*/
// 插入比赛记录示例
function recordMatchResult($db, $tournamentId, $round, $player1, $player2, $winner) {
$stmt = $db->prepare("INSERT INTO matches (tournament_id, round, player1_id, player2_id, winner_id) VALUES (?, ?, ?, ?, ?)");
$stmt->execute([$tournamentId, $round, $player1, $player2, $winner]);
}
// 查询某轮比赛
function getRoundMatches($db, $tournamentId, $round) {
$stmt = $db->prepare("SELECT * FROM matches WHERE tournament_id = ? AND round = ?");
$stmt->execute([$tournamentId, $round]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
可视化对阵表
使用HTML输出可视化的对阵表:
function renderBracket($players) {
$rounds = [];
$currentRound = $players;
while (count($currentRound) > 1) {
$nextRound = [];
$matches = [];
for ($i = 0; $i < count($currentRound); $i += 2) {
$player1 = $currentRound[$i];
$player2 = $currentRound[$i + 1] ?? '轮空';
$winner = $player2 == '轮空' ? $player1 : (rand(0, 1) ? $player1 : $player2);
$matches[] = [
'players' => [$player1, $player2],
'winner' => $winner
];
$nextRound[] = $winner;
}
$rounds[] = $matches;
$currentRound = $nextRound;
}
echo '<div style="display: flex; gap: 20px;">';
foreach ($rounds as $roundNum => $matches) {
echo '<div style="border: 1px solid #ccc; padding: 10px;">';
echo "<h3>第" . ($roundNum + 1) . "轮</h3>";
foreach ($matches as $match) {
echo '<div style="margin-bottom: 10px; padding: 5px; background: #f5f5f5;">';
echo "{$match['players'][0]} vs " . ($match['players'][1] ?? '轮空') . "<br>";
echo "<strong>胜者: {$match['winner']}</strong>";
echo '</div>';
}
echo '</div>';
}
echo '</div>';
echo "<h2>冠军: {$currentRound[0]}</h2>";
}
renderBracket(['选手A', '选手B', '选手C', '选手D', '选手E', '选手F']);
这些方法提供了从简单到复杂的单淘汰赛制实现方案,可以根据实际需求选择适合的方式或组合使用。






