# Complete GUROBIPY implementation - Retry Attempt 4

import gurobipy as gp
from gurobipy import GRB

def optimize_tournament_scheduling():
    # 1. MODEL & DATA SETUP
    model = gp.Model("tournament_scheduling")

    # Data from the problem
    players = [1, 2, 3]
    tournaments = [101, 102, 103]

    # Ranking points for each player in each tournament
    ranking_points = {
        (1, 101): 100,
        (2, 102): 200,
        (3, 103): 300
    }

    # Maximum players per tournament
    max_players_per_tournament = {
        101: 32,
        102: 64,
        103: 128
    }

    # Player availability
    availability = {
        1: True,
        2: False,
        3: True
    }

    # CRITICAL: Validate array lengths before loops
    assert len(players) == 3, "Player array length mismatch"
    assert len(tournaments) == 3, "Tournament array length mismatch"

    # 2. VARIABLES
    # Decision variables: x[p, t] = 1 if player p participates in tournament t, 0 otherwise
    x = model.addVars(players, tournaments, vtype=GRB.BINARY, name="x")

    # 3. OBJECTIVE FUNCTION
    # Maximize total ranking points
    model.setObjective(gp.quicksum(ranking_points[p, t] * x[p, t] for p in players for t in tournaments), GRB.MAXIMIZE)

    # 4. CONSTRAINTS

    # Player Participation Limit: Each player can participate in a maximum of 5 tournaments
    for p in players:
        model.addConstr(gp.quicksum(x[p, t] for t in tournaments) <= 5, name=f"player_limit_{p}")

    # Tournament Capacity Limit: Each tournament has a maximum number of players
    for t in tournaments:
        model.addConstr(gp.quicksum(x[p, t] for p in players) <= max_players_per_tournament[t], name=f"tournament_capacity_{t}")

    # Player Availability: A player can only participate in a tournament if they are available
    for p in players:
        for t in tournaments:
            model.addConstr(x[p, t] <= int(availability[p]), name=f"availability_{p}_{t}")

    # 5. SOLVING & RESULTS
    model.optimize()

    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for p in players:
            for t in tournaments:
                if x[p, t].x > 0.5:
                    print(f"Player {p} participates in tournament {t}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")

    return model

# Execute the optimization
optimize_tournament_scheduling()