Yes I know it makes login code much more complex and stateful, but it's probably a bad idea to allow anything with an Internet login more than a certain number of attempts. On a webapp I'm developing I lockout the IP4 or IP6 address sooner than the account based on number of bad attempts. It will still allow a DOS attack by someone with more than enough IP6 addresses to burn through by hitting the per account bad login limit for enough guessable account names. I think the next significant iteration of this code will probably need more entropy included as or with the account name.
In the end I have to strike a balance, between a system which is possible for my users (some of them retired and very recent computer users) to learn and use, and one which is secure under all circumstances. I don't think I can achieve both. Another improvement is not allowing users to choose their own passwords. If they want to change their password generate a new random one for them.