羽毛球比赛规则

import random
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton, QTextEdit, QGroupBox, QMessageBox
from PyQt5.QtCore import Qt

class Player:
def init(self, name, ability):
self.name = name
self.ability = ability
self.score = 0
self.games_won = 0

def win_point(self):
    self.score += 1
    
def reset_score(self):
    self.score = 0
    
def win_game(self):
    self.games_won += 1
    self.reset_score()
    
def reset(self):
    self.score = 0
    self.games_won = 0

class BadmintonMatch:
def init(self, player1, player2):
self.player1 = player1
self.player2 = player2
self.current_server = player1
self.match_history = []

def simulate_point(self)
    total_ability = self.player1.ability + self.player2.ability
    prob_player1_win = self.player1.ability / total_ability
    
    if random.random() < prob_player1_win:
        winner = self.player1
        loser = self.player2
    else:
        winner = self.player2
        loser = self.player1
        
    winner.win_point()
    
    point_result = {
        'server': self.current_server.name,
        'winner': winner.name,
        'score': (self.player1.score, self.player2.score)
    }
    self.match_history.append(point_result)
    
    # 发球权交换(每球得分后发球权交换)
    if winner == self.player1:
        self.current_server = self.player1
    else:
        self.current_server = self.player2
        
    return winner

def is_game_over(self):
    p1_score = self.player1.score
    p2_score = self.player2.score
    
    if p1_score >= 21 or p2_score >= 21:
        if abs(p1_score - p2_score) >= 2:
            return True
    
    if p1_score == 29 and p2_score == 29:
        if p1_score == 30 or p2_score == 30:
            return True
    
    return False

def simulate_game(self):
    self.player1.reset_score()
    self.player2.reset_score()
    
    game_log = []
    
    while not self.is_game_over():
        winner = self.simulate_point()
        game_log.append(f"{self.current_server.name}发球, {winner.name}得分: {self.player1.score}-{self.player2.score}")
        
        if self.player1.score == 20 and self.player2.score == 20:
            game_log.append("比分20平!需要领先2分才能获胜")
        elif self.player1.score == 29 and self.player2.score == 29:
            game_log.append("比分29平!下一分将决定胜负")
    
    if self.player1.score > self.player2.score:
        winner = self.player1
    else:
        winner = self.player2
        
    winner.win_game()
    game_log.append(f"本局结束!{winner.name}获胜,比分: {self.player1.score}-{self.player2.score}")

    self.current_server = winner
    
    return winner, game_log

def simulate_match(self):
    self.player1.reset()
    self.player2.reset()
    match_log = []
    
    match_log.append(f"比赛开始:{self.player1.name} vs {self.player2.name}")
    match_log.append(f"球员能力值: {self.player1.name}({self.player1.ability}) vs {self.player2.name}({self.player2.ability})")
    
    game_num = 1
    while self.player1.games_won < 2 and self.player2.games_won < 2:
        match_log.append(f"\n===== 第{game_num}局 =====")
        winner, game_log = self.simulate_game()
        match_log.extend(game_log)
        match_log.append(f"{winner.name}赢得第{game_num}局")
        game_num += 1
    
    if self.player1.games_won == 2:
        winner = self.player1
    else:
        winner = self.player2
        
    match_log.append(f"\n比赛结束!{winner.name}获胜!")
    match_log.append(f"最终比分: {self.player1.games_won}-{self.player2.games_won}")
    
    return winner, "\n".join(match_log)

class Tournament:
def init(self, players):
self.players = players # 球员列表 [(name, ability), ...]
self.standings = [] # 排名
self.matches = [] # 所有比赛

def simulate_tournament(self):
    player_objs = [Player(name, ability) for name, ability in self.players]
    
    for i in range(len(player_objs)):
        for j in range(i + 1, len(player_objs)):
            player1 = player_objs[i]
            player2 = player_objs[j]
            
            match = BadmintonMatch(player1, player2)
            winner, match_log = match.simulate_match()
            
            # 记录比赛结果
            self.matches.append({
                'player1': player1.name,
                'player2': player2.name,
                'winner': winner.name,
                'score': f"{player1.games_won}-{player2.games_won}",
                'log': match_log
            })
    
    player_stats = []
    for player in player_objs:
        wins = sum(1 for match in self.matches if match['winner'] == player.name)
        player_stats.append({
            'name': player.name,
            'ability': player.ability,
            'wins': wins
        })
    
    self.standings = sorted(player_stats, key=lambda x: (x['wins'], x['ability']), reverse=True)
    
    return self.standings

class BadmintonSimulatorGUI(QMainWindow):
def init(self):
super().init()
self.setWindowTitle("羽毛球比赛模拟器")
self.setGeometry(100, 100, 800, 600)

    self.central_widget = QWidget()
    self.setCentralWidget(self.central_widget)
    
    self.layout = QVBoxLayout()
    self.central_widget.setLayout(self.layout)
    
    self.create_input_section()
    self.create_output_section()
    self.create_buttons()

    self.tournament_players = []

def create_input_section(self):
    group = QGroupBox("球员信息")
    layout = QVBoxLayout()
    group.setLayout(layout)
    
    single_match_layout = QHBoxLayout()
    self.player1_label = QLabel("球员1:")
    self.player1_input = QLineEdit("A")
    self.ability1_label = QLabel("能力值 (0-1):")
    self.ability1_input = QLineEdit("0.6")
    
    self.player2_label = QLabel("球员2:")
    self.player2_input = QLineEdit("B")
    self.ability2_label = QLabel("能力值 (0-1):")
    self.ability2_input = QLineEdit("0.4")
    
    single_match_layout.addWidget(self.player1_label)
    single_match_layout.addWidget(self.player1_input)
    single_match_layout.addWidget(self.ability1_label)
    single_match_layout.addWidget(self.ability1_input)
    single_match_layout.addWidget(self.player2_label)
    single_match_layout.addWidget(self.player2_input)
    single_match_layout.addWidget(self.ability2_label)
    single_match_layout.addWidget(self.ability2_input)
    
    layout.addLayout(single_match_layout)
    
    # 锦标赛输入
    tournament_layout = QHBoxLayout()
    self.tournament_label = QLabel("锦标赛球员 (姓名:能力值, 用逗号分隔):")
    self.tournament_input = QLineEdit("A:0.7, B:0.6, C:0.5, D:0.4")
    tournament_layout.addWidget(self.tournament_label)
    tournament_layout.addWidget(self.tournament_input)
    
    layout.addLayout(tournament_layout)
    
    self.layout.addWidget(group)

def create_output_section(self):
    group = QGroupBox("比赛结果")
    layout = QVBoxLayout()
    group.setLayout(layout)
    
    self.output_area = QTextEdit()
    self.output_area.setReadOnly(True)
    layout.addWidget(self.output_area)
    
    self.layout.addWidget(group)

def create_buttons(self):
    button_layout = QHBoxLayout()
    
    self.simulate_button = QPushButton("模拟单场比赛")
    self.simulate_button.clicked.connect(self.simulate_match)
    
    self.tournament_button = QPushButton("模拟锦标赛")
    self.tournament_button.clicked.connect(self.simulate_tournament)
    
    self.clear_button = QPushButton("清空结果")
    self.clear_button.clicked.connect(self.clear_output)
    
    button_layout.addWidget(self.simulate_button)
    button_layout.addWidget(self.tournament_button)
    button_layout.addWidget(self.clear_button)
    
    self.layout.addLayout(button_layout)

def validate_input(self, player1, ability1, player2, ability2):
    errors = []
    
    if not player1 or not player2:
        errors.append("球员姓名不能为空")
    
    try:
        ability1 = float(ability1)
        if ability1 < 0 or ability1 > 1:
            errors.append("球员1能力值必须在0-1之间")
    except ValueError:
        errors.append("球员1能力值必须是数字")
    
    try:
        ability2 = float(ability2)
        if ability2 < 0 or ability2 > 1:
            errors.append("球员2能力值必须在0-1之间")
    except ValueError:
        errors.append("球员2能力值必须是数字")
    
    return errors

def simulate_match(self):
    player1 = self.player1_input.text().strip()
    ability1 = self.ability1_input.text().strip()
    player2 = self.player2_input.text().strip()
    ability2 = self.ability2_input.text().strip()
    
    errors = self.validate_input(player1, ability1, player2, ability2)
    if errors:
        QMessageBox.warning(self, "输入错误", "\n".join(errors))
        return

    p1 = Player(player1, float(ability1))
    p2 = Player(player2, float(ability2))
    match = BadmintonMatch(p1, p2)
    
    winner, match_log = match.simulate_match()
    
    self.output_area.clear()
    self.output_area.append(match_log)
    self.output_area.append(f"\n最终胜者: {winner.name}")

def simulate_tournament(self):
    tournament_input = self.tournament_input.text().strip()
    if not tournament_input:
        QMessageBox.warning(self, "输入错误", "请输入锦标赛球员信息")
        return
    
    players = []
    entries = tournament_input.split(',')
    for entry in entries:
        parts = entry.strip().split(':')
        if len(parts) != 2:
            QMessageBox.warning(self, "输入错误", f"格式错误: {entry}")
            return
        
        name = parts[0].strip()
        ability_str = parts[1].strip()
        
        try:
            ability = float(ability_str)
            if ability < 0 or ability > 1:
                QMessageBox.warning(self, "输入错误", f"能力值必须在0-1之间: {entry}")
                return
        except ValueError:
            QMessageBox.warning(self, "输入错误", f"无效的能力值: {entry}")
            return
        
        players.append((name, ability))
    
    if len(players) < 2:
        QMessageBox.warning(self, "输入错误", "至少需要2名球员")
        return

    tournament = Tournament(players)
    standings = tournament.simulate_tournament()
    
    self.output_area.clear()
    self.output_area.append("===== 锦标赛结果 =====")
    self.output_area.append(f"参赛球员: {', '.join([f'{name}({ability})' for name, ability in players])}")
    self.output_area.append("\n最终排名:")
    
    for i, player in enumerate(standings):
        self.output_area.append(f"{i+1}. {player['name']} - 胜场: {player['wins']} (能力值: {player['ability']})")
    
    self.output_area.append("\n===== 比赛详情 =====")
    for match in tournament.matches:
        self.output_area.append(f"\n{match['player1']} vs {match['player2']}:")
        self.output_area.append(f"胜者: {match['winner']}, 比分: {match['score']}")
        self.output_area.append(f"比赛记录:\n{match['log']}")

def clear_output(self):
    self.output_area.clear()

def main():
app = QApplication(sys.argv)
window = BadmintonSimulatorGUI()
window.show()
sys.exit(app.exec_())

if name == "main":
main()

posted @ 2025-06-21 16:02  低矮的高原  阅读(21)  评论(0)    收藏  举报