class GoalDetector {
public:
    // Use the RocketSim Team type for consistency
    using Team = RocketSim::Team;

    // Constructor
    GoalDetector() {}

    /**
     * @brief Resets the internal previous game state
     * @param initialState The initial state to set as the previous state
     */
    void Reset(const GameState& initialState) {
        previousState = initialState;
    }

    /**
     * @brief Determines if the latest goal was caused by a player or by random state changes.
     *
     * @param currentState The current game state after the latest update.
     * @return true if the goal was caused by a player, false otherwise.
     */
    bool WasGoalScoredByPlayer(const GameState& currentState) {
        Team scoringTeam;

        // Step 1: Detect if a goal has been scored by comparing score lines
        bool goalScored = false;

        if (currentState.scoreLine[0] > previousState.scoreLine[0]) {
            goalScored = true;
            scoringTeam = Team::BLUE;
        }
        else if (currentState.scoreLine[1] > previousState.scoreLine[1]) {
            goalScored = true;
            scoringTeam = Team::ORANGE;
        }

        if (!goalScored) {
            // No goal scored in this update
            previousState = currentState;  // Update previousState
            return false;
        }

        // Step 2: Check if any player on the scoring team touched the ball before the goal
        bool playerTouched = false;
        for (const auto& player : currentState.players) {
            if (player.team != scoringTeam) {
                continue; // Only consider players on the scoring team
            }

            if (player.ballTouchedStep || player.ballTouchedTick) {
                playerTouched = true;
                break;
            }
        }

        if (playerTouched) {
            previousState = currentState;  // Update previousState
            return true; // Goal was caused by a player
        }

        // Step 3: Alternatively, check if lastTouchCarID corresponds to a player on the scoring team
        int lastTouchID = currentState.lastTouchCarID;
        if (lastTouchID != -1) {
            for (const auto& player : currentState.players) {
                if (player.carId == static_cast<uint32_t>(lastTouchID) && player.team == scoringTeam) {
                    previousState = currentState;  // Update previousState
                    return true; // Goal was caused by a player
                }
            }
        }

        // If no player on the scoring team touched the ball, attribute to random
        previousState = currentState;  // Update previousState
        return false;
    }

private:
    GameState previousState;  // Store the previous state of the game
};

static GoalDetector goalDetector;

rlbot::Controller RLBotBot::GetOutput(rlbot::GameTickPacket gameTickPacket) {
    float curTime = gameTickPacket->gameInfo()->secondsElapsed();
    float deltaTime = curTime - prevTime;
    prevTime = curTime;
    int ticksElapsed = roundf(deltaTime * 120);
    ticks += ticksElapsed;

    std::vector<RocketSim::Car*> rocketSimCars;
    if (predictionArena != nullptr) {
        auto cars = predictionArena->GetCars();
        rocketSimCars.assign(cars.begin(), cars.end());
    }

    GameState gs = ToGameState(gameTickPacket, ticksElapsed, params.tickSkip, rocketSimCars, ticks, controls);
    auto& localPlayer = gs.players[index];

    // Initial goal detector setup
    if (ticks == 0) {
        // Reset the goal detector with the initial state
        goalDetector.Reset(gs);
    }

    // Goal detection logic
    bool goalByPlayer = goalDetector.WasGoalScoredByPlayer(gs);
    if (goalByPlayer) {
        std::cout << "Goal was scored by a player!" << std::endl;
    }
    else {
        std::cout << "Goal was random!" << std::endl;
    }

    ListenAndPrintKeys();

    //ResetToDefaultKickoff();  // Call the reset function

    //RenderBallInfo(gs);

    //RenderCarInfo(gs);

    if (renderRewardEnabled) {
        RenderReward(gs);
    }
    if (renderCarStateTableEnabled) {
        //RenderCarStateTable(gs);
        //RenderCarStateTable(gs);
    }
    if (renderBallPredictionsEnabled) {
        //RenderBallPredictions(gs);
    }
    if (updatePredictionArenaEnabled) {
        UpdatePredictionArena(gs);
    }
    if (renderTimeToReachBallEnabled) {
        //RenderTimeToReachBall(gs);
    }
    gs.lastArena = predictionArena;

    if (g_RLBotParams.userInputMode) {
        controls = ConvertToAction(g_RLBotParams.userControls);
    }
    else {
        if (updateAction) {
            updateAction = false;
            action = policyInferUnit->InferPolicySingle(localPlayer, gs, controls, true);
        }
        if (ticks >= params.tickSkip || ticks == -1) {
            controls = action;
            ticks = 0;
            updateAction = true;
        }
    }

    auto rc = rlbot::Controller();
    rc.throttle = controls.throttle;
    rc.steer = controls.steer;
    rc.pitch = controls.pitch;
    rc.yaw = controls.yaw;
    rc.roll = controls.roll;
    rc.boost = controls.boost;
    rc.jump = controls.jump;
    rc.handbrake = controls.handbrake;

    return rc;
} make that the goal scored gets activated if the ball is within 100 distance from the goal