""" Chess tournament Swiss system pairing calculator. Fetches data from chess-results.com and calculates next round pairings. Usage: python -m swiss_calc python -m swiss_calc --standings """ import sys import argparse from .parser import fetch_tournament from .swiss import calculate_next_round from .display import format_pairings_table, format_player_standings def main(): parser = argparse.ArgumentParser( description='Chess tournament pairing calculator for chess-results.com' ) parser.add_argument('url', nargs='?', help='chess-results.com tournament URL') parser.add_argument('--standings', '-s', action='store_true', help='Show standings instead of next round') parser.add_argument('--top', type=int, default=20, help='Number of top players to show in standings (default: 20)') parser.add_argument('--player', '-p', type=int, default=None, help='Player rank to highlight') parser.add_argument('--json', action='store_true', help='Output JSON instead of formatted text') args = parser.parse_args() url = args.url if not url: url = input('URL турнира chess-results.com: ').strip() if not url: print('❌ URL не указан', file=sys.stderr) sys.exit(1) print(f'⏳ Загружаю: {url}', file=sys.stderr) try: tournament = fetch_tournament(url) except Exception as e: print(f'❌ Ошибка: {e}', file=sys.stderr) sys.exit(1) print(f'✅ {tournament["name"]}', file=sys.stderr) print(f'📅 Тур {tournament["current_round"]} из {tournament["num_rounds"]}', file=sys.stderr) print(f'👥 {len(tournament["standings"])} участников', file=sys.stderr) print(file=sys.stderr) if tournament['current_round'] >= tournament['num_rounds']: if args.json: import json json.dump({'status': 'completed', 'round': tournament['current_round'], 'total_rounds': tournament['num_rounds']}, sys.stdout, ensure_ascii=False) return print('🏁 Турнир завершён!') print() print(format_player_standings(tournament, args.top)) return if args.standings: output = format_player_standings(tournament, args.top) if args.json: import json json.dump({'type': 'standings', 'data': tournament['standings'][:args.top]}, sys.stdout, ensure_ascii=False) return print(output) return # Calculate next round print('🧮 Считаю следующий тур...', file=sys.stderr) next_round = calculate_next_round(tournament) # Cross-check against pre-calculated if available precalc = sum(1 for s in tournament['standings'] if s.get('next_opponent')) if precalc > 0: print(f'📊 На сайте уже рассчитан {precalc} пар', file=sys.stderr) output = format_pairings_table(next_round, tournament['name']) if args.json: import json pairs = [] for pairing in next_round['pairings']: if len(pairing) == 3: p1, p2, color = pairing if color == 'bye': pairs.append({ 'board': 0, 'bye': {'name': p1.name, 'rank': p1.sno, 'rating': p1.rating, 'points': p1.points}, }) elif color == 'w': pairs.append({ 'board': len(pairs) + 1, 'white': {'name': p1.name, 'rank': p1.sno, 'rating': p1.rating, 'points': p1.points}, 'black': {'name': p2.name, 'rank': p2.sno, 'rating': p2.rating, 'points': p2.points}, }) else: pairs.append({ 'board': len(pairs) + 1, 'white': {'name': p2.name, 'rank': p2.sno, 'rating': p2.rating, 'points': p2.points}, 'black': {'name': p1.name, 'rank': p1.sno, 'rating': p1.rating, 'points': p1.points}, }) json.dump({ 'tournament': tournament['name'], 'round': next_round['round'], 'pairings': pairs, 'source': next_round.get('source', 'algorithm'), }, sys.stdout, ensure_ascii=False) return print(output) # Player highlight if args.player: rank = args.player for p in tournament['standings']: if p['rank'] == rank: # Find this player's pairing for pairing in next_round['pairings']: if len(pairing) == 3: p1, p2, color = pairing if p1.sno == rank or p2.sno == rank: if p1.sno == rank: opp = p2 player_color = color # color belongs to p1 else: opp = p1 player_color = 'b' if color == 'w' else 'w' # opposite for p2 print() print(f"🔍 **{p['name']}** (#{rank}, {p['points']} очков):") print(f" {'🏳️' if player_color == 'w' else '🏁'} vs **{opp.name}**") print(f" Рейтинг: {opp.rating} | Очки: {opp.points}") break if __name__ == '__main__': main()