Tracking number of attempts via Form API I'd like to track the number of times a user has failed a form validation.

It doesn't necessarily matter if the end user has access to the variable, or even the ability to manipulate it client side, as the purpose is to provide additional help to the user by detecting when they might not be in trouble. 

At this point I think I'm leaning towards adding a hidden field and incrementing that value, but I'm interested to know if there's a cleaner method that does prevent access and manipulation in my quest for knowledge :)

Thanks for any advice.

UPDATE

As per tunic's advice below, I'm trying the $form_state route but this doesn't appear to be persisting. In my form validation function I have:

// Track the number of attempts.
if (!isset($form_state['mymodule']['attempts'])) {
  drupal_set_message('attempts not set');
  $form_state['mymodule']['attempts'] = 0;
}
$form_state['mymodule']['attempts']++;
drupal_set_message($form_state['mymodule']['attempts'] . ' attempts');


However repeatedly submitting a form with errors results in the following output each time:

attempts not set
1 attempts


SOLUTION

Having difficulty arguing with $form_state I instead went for the core flood module as suggested below, with the following code, in my validator:

function mymodule_booking_register_online_form_validate($form, &amp;$form_state) {
  if (form_get_errors()) {
    form_set_error('', 'There was a problem registering your online account, please try again.');
    flood_register_event('mymodule_booking_register');
  }
}


And then to handle the result of this event, back in my form definition:

function mymodule_booking_register_online_form($form, &amp;$form_state) {
  if (flood_is_allowed('mymodule_booking_register', 5, 3600)) {
    ...
  else {
    drupal_set_message('You have incorrectly entered your personal details too many times. Please call us on 12345678 to ask for your user code and then enter it in the form below.');
    ...
  }
}
Just use a variable insider $form_state.

In validate function

if ($validation_failed) {
  $form_state['error_count']++
  $form_state['cache'] = TRUE;
}


Then, in your form function just check $form_state['error_count'].

$form_state will be persistent between page petitions while validation fails thanks to $form_state['cache'].

You can also check for errors using form_get_errors().