added new tournament mode.
This commit is contained in:
@@ -299,7 +299,17 @@ def create_results_structure(tournament_data):
|
||||
return None
|
||||
|
||||
tournament_type = tournament_data.get('tournament_type', '20_targets')
|
||||
num_targets = 40 if tournament_type == '40_targets' else 20
|
||||
|
||||
# Determine target count and shots per target
|
||||
if tournament_type == '40_targets':
|
||||
num_targets = 40
|
||||
shots_per_target = 2
|
||||
elif tournament_type == '4_targets':
|
||||
num_targets = 4
|
||||
shots_per_target = 5
|
||||
else: # 20_targets (default)
|
||||
num_targets = 20
|
||||
shots_per_target = 2
|
||||
|
||||
results = {
|
||||
'tournament_id': tournament_data.get('created_at', datetime.now().isoformat()),
|
||||
@@ -320,9 +330,18 @@ def create_results_structure(tournament_data):
|
||||
|
||||
for player in all_players:
|
||||
player_id = str(player['id'])
|
||||
|
||||
# Create target structure based on tournament type
|
||||
targets = {}
|
||||
for i in range(1, num_targets + 1):
|
||||
target = {}
|
||||
for j in range(1, shots_per_target + 1):
|
||||
target[f'shot{j}'] = None
|
||||
targets[str(i)] = target
|
||||
|
||||
results['participants'][player_id] = {
|
||||
'name': player['name'],
|
||||
'targets': {str(i): {'shot1': None, 'shot2': None} for i in range(1, num_targets + 1)},
|
||||
'targets': targets,
|
||||
'total_score': 0,
|
||||
'completed': False
|
||||
}
|
||||
@@ -333,19 +352,17 @@ def calculate_total_score(targets):
|
||||
"""Calculate total score from targets, treating None as 0"""
|
||||
total = 0
|
||||
for target in targets.values():
|
||||
shot1 = target.get('shot1')
|
||||
shot2 = target.get('shot2')
|
||||
total += (shot1 if shot1 is not None else 0)
|
||||
total += (shot2 if shot2 is not None else 0)
|
||||
for shot_key, shot_value in target.items():
|
||||
if shot_key.startswith('shot') and shot_value is not None:
|
||||
total += shot_value
|
||||
return total
|
||||
|
||||
def is_participant_completed(targets):
|
||||
"""Check if a participant has completed all targets (all shots entered, including 0s)"""
|
||||
for target in targets.values():
|
||||
shot1 = target.get('shot1')
|
||||
shot2 = target.get('shot2')
|
||||
if shot1 is None or shot2 is None:
|
||||
return False
|
||||
for shot_key, shot_value in target.items():
|
||||
if shot_key.startswith('shot') and shot_value is None:
|
||||
return False
|
||||
return True
|
||||
|
||||
def calculate_league_final_scores(league_data):
|
||||
@@ -749,6 +766,8 @@ def get_all_players_from_archives():
|
||||
|
||||
return players_list
|
||||
|
||||
|
||||
|
||||
# Add these routes after the existing routes in app.py
|
||||
|
||||
# Add this to your app.py file to integrate the modern archive system
|
||||
@@ -875,15 +894,17 @@ def api_get_archive_stats():
|
||||
'leagues': [1, 1, 2, 1, 2, 1]
|
||||
}
|
||||
|
||||
# Calculate tournament type distribution
|
||||
type_distribution = {'20_targets': 0, '40_targets': 0}
|
||||
# Calculate tournament type distribution - now includes 4_targets
|
||||
type_distribution = {'20_targets': 0, '40_targets': 0, '4_targets': 0}
|
||||
for tournament in tournaments:
|
||||
tournament_type = tournament.get('tournament_type', '20_targets')
|
||||
type_distribution[tournament_type] += 1
|
||||
if tournament_type in type_distribution:
|
||||
type_distribution[tournament_type] += 1
|
||||
|
||||
for league in leagues:
|
||||
league_type = league.get('tournament_type', '20_targets')
|
||||
type_distribution[league_type] += 1
|
||||
if league_type in type_distribution:
|
||||
type_distribution[league_type] += 1
|
||||
|
||||
stats = {
|
||||
'overview': {
|
||||
@@ -894,15 +915,14 @@ def api_get_archive_stats():
|
||||
},
|
||||
'activity_data': activity_data,
|
||||
'type_distribution': {
|
||||
'labels': ['20 Targets', '40 Targets'],
|
||||
'data': [type_distribution['20_targets'], type_distribution['40_targets']]
|
||||
'labels': ['20 Targets', '40 Targets', '4 Targets'],
|
||||
'data': [type_distribution['20_targets'], type_distribution['40_targets'], type_distribution['4_targets']]
|
||||
}
|
||||
}
|
||||
|
||||
return jsonify({'status': 'success', 'stats': stats})
|
||||
except Exception as e:
|
||||
return jsonify({'status': 'error', 'message': str(e)}), 500
|
||||
|
||||
@app.route('/api/archive/player/<int:player_id>/performance', methods=['GET'])
|
||||
def api_get_player_performance(player_id):
|
||||
"""API endpoint to get player performance data for charts"""
|
||||
@@ -1629,10 +1649,9 @@ def start_league():
|
||||
try:
|
||||
data = request.get_json()
|
||||
tournament_type = data.get('tournament_type', '20_targets')
|
||||
|
||||
if tournament_type not in ['20_targets', '40_targets']:
|
||||
if tournament_type not in ['20_targets', '40_targets', '4_targets']:
|
||||
return jsonify({'status': 'error', 'message': 'Invalid tournament type'}), 400
|
||||
|
||||
|
||||
players_data = load_players()
|
||||
enabled_players = [p for p in players_data['players'] if p['enabled']]
|
||||
|
||||
@@ -1741,7 +1760,7 @@ def start_tournament():
|
||||
data = request.get_json() or {}
|
||||
tournament_type = data.get('tournament_type', '20_targets')
|
||||
|
||||
if tournament_type not in ['20_targets', '40_targets']:
|
||||
if tournament_type not in ['20_targets', '40_targets', '4_targets']:
|
||||
return jsonify({'status': 'error', 'message': 'Invalid tournament type'}), 400
|
||||
|
||||
players_data = load_players()
|
||||
@@ -1869,6 +1888,13 @@ def finish_tournament():
|
||||
results['tournament_finished'] = True
|
||||
results['finished_at'] = datetime.now().isoformat()
|
||||
|
||||
# Define total shots per participant for each tournament type
|
||||
total_shots_per_participant = {
|
||||
'20_targets': 40, # 20 targets × 2 shots
|
||||
'40_targets': 80, # 40 targets × 2 shots
|
||||
'4_targets': 20 # 4 targets × 5 shots
|
||||
}
|
||||
|
||||
league_finished = False # Track if league finished
|
||||
|
||||
# Update league state if this is a league tournament
|
||||
@@ -1901,13 +1927,21 @@ def finish_tournament():
|
||||
'joker': True
|
||||
})
|
||||
|
||||
# Calculate total shots correctly for any tournament type
|
||||
tournament_type = results.get('tournament_type', '20_targets')
|
||||
shots_per_participant = total_shots_per_participant.get(tournament_type, 40)
|
||||
total_shots_fired = len(results['participants']) * shots_per_participant
|
||||
|
||||
# Add to completed tournaments
|
||||
league_state['completed_tournaments'].append({
|
||||
'tournament_number': tournament_number,
|
||||
'tournament_type': tournament_type,
|
||||
'finished_at': datetime.now().isoformat(),
|
||||
'results_summary': {
|
||||
'participants': len(results['participants']),
|
||||
'total_shots': len(results['participants']) * (40 if results.get('tournament_type') == '40_targets' else 20) * 2
|
||||
'shots_per_participant': shots_per_participant,
|
||||
'total_shots': total_shots_fired,
|
||||
'format_description': get_tournament_format_description(tournament_type)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1920,7 +1954,7 @@ def finish_tournament():
|
||||
calculate_league_final_scores(league_state)
|
||||
|
||||
league_finished = True
|
||||
print("League finished!")
|
||||
print(f"League finished! Final tournament was {tournament_type} format.")
|
||||
|
||||
save_league_state(league_state)
|
||||
|
||||
@@ -1928,9 +1962,11 @@ def finish_tournament():
|
||||
archive_success = False
|
||||
if not league_state: # Only archive standalone tournaments
|
||||
archive_success = archive_tournament(tournament_state, results)
|
||||
print(f"Standalone tournament archived: {archive_success}")
|
||||
tournament_type = results.get('tournament_type', '20_targets')
|
||||
print(f"Standalone {tournament_type} tournament archived: {archive_success}")
|
||||
else:
|
||||
print("League tournament - not archiving individual tournament")
|
||||
tournament_type = results.get('tournament_type', '20_targets')
|
||||
print(f"League {tournament_type} tournament - not archiving individual tournament")
|
||||
|
||||
# Archive the league if it just finished
|
||||
league_archive_success = False
|
||||
@@ -1952,7 +1988,9 @@ def finish_tournament():
|
||||
'status': 'success',
|
||||
'results': results,
|
||||
'archived': archive_success,
|
||||
'league_archived': league_archive_success if league_finished else None
|
||||
'league_archived': league_archive_success if league_finished else None,
|
||||
'tournament_type': results.get('tournament_type', '20_targets'),
|
||||
'tournament_format': get_tournament_format_description(results.get('tournament_type', '20_targets'))
|
||||
}
|
||||
|
||||
if league_state:
|
||||
@@ -1967,6 +2005,15 @@ def finish_tournament():
|
||||
print(f"Error finishing tournament: {e}")
|
||||
return jsonify({'status': 'error', 'message': str(e)}), 400
|
||||
|
||||
|
||||
def get_tournament_format_description(tournament_type):
|
||||
"""Get human-readable description of tournament format"""
|
||||
format_descriptions = {
|
||||
'20_targets': '20 Targets (2 shots each)',
|
||||
'40_targets': '40 Targets (2 shots each)',
|
||||
'4_targets': '4 Targets (5 shots each)'
|
||||
}
|
||||
return format_descriptions.get(tournament_type, '20 Targets (2 shots each)')
|
||||
@app.route('/api/results', methods=['GET'])
|
||||
def get_results():
|
||||
"""API endpoint to get current results"""
|
||||
@@ -2115,5 +2162,7 @@ def get_camera_titles():
|
||||
except Exception as e:
|
||||
return jsonify({'status': 'error', 'message': str(e)}), 400
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=5000, debug=True)
|
||||
Reference in New Issue
Block a user