One of the skills that distinguishes a winning poker player is that they only play when they are feeling at their best. In poker, like many things, the line between good decisions and bad can be very thin. A player must be at their mental and physical peak in order to successfully juggle all of the factors required to come out ahead in a tough game. Tommy Angelo, a professional poker player, wrote extensively on this subject in his excellent book Elements of Poker. All the following quotes are from the book, with some word substitutions made to make them more applicable to programming.
The first big idea is that we are not always working at our best. Mr. Angelo defines some terms for this:
"Your A-game is when you [program] your best and feel your best at the same time. You can move in and out of your A-game many times in a session. The idea is not to."
"Your C-game is when you [program] poorly according to you. You might [program] bad and know you are [programming] bad. You might [program] bad and wait until tomorrow to tell yourself that you did actually [program] bad...In any case, if you know you [programmed] bad, that's your C-game."
Programming at our A-game is when we introduce great abstractions that help clarify a domain model. It is when we remember to write all the tests we should be writing. The goal then, is to try to increase the percentage of time that we are working at our A-game.
"To improve the consistency of A-game - we turn to C-game. To play your A-game more often, and then more often, and then even more often that that, the essential act is to apply effort, during sessions and in between, forever, to lopping off your C-game. You have a new worst that isn't quite as bad as your old worst was. Wouldn't it be great to have a great C-game? Lop. Lop. Lop."
"Whenever you lop off some C-game, you increase the percentage of time you spend playing your A-game. This means that work you put into your A-game will pay a higher return by being put into play more often."
Mr. Angelo makes a very important point here. Programming (and poker) are very complicated activities that require us to balance a lot of competing ideas in our heads. When you are mentally sharp and on your A-game, you are more likely to remember all the different rules of thumb for picking a good design (SOLID, DRY, Design Patterns, etc). It took years to learn these concepts, but I'm sure that like me you find that sometimes you spend a whole programming session as if you had never heard of them. That's programming at your C-game.
"From the instant each of us learned that [abstraction is important], we have been working on our A-game. When we think about how we [program], we are working on our A-game. When we read a book, we are working on our A-game. When we write about [code] or talk about [code], we are working on our A-game. Have you ever thought about a [design] situation and made plans for how you would handle it the next time it comes up?...That is A-game practice. Have you ever [done a code kata]?. That is A-game practice. A-game practice is what we default to. That's because when we project a future reality, we are the hero. Of course we are at our best! Of course we do not practice the times we aren't. We do not think to add conditions to our fantasies such as 'I can barely keep my eyes open'. If we did, that would be C-game practice. Sound crazy? Try it a few times and see what happens. Lop. Lop. Lop."
As simple as it sounds, one of the best ways to reduce your C-game is to take more control of when you decide to end a programming session.
"When is C-game most likely to occur? At the beginning of a session? Or at the end? It's not surprise that the most important skill for lopping off C-game is quitting"
"In order to quit well, you must be in control of yourself at the end of a session. It can be no other way. To achieve your [best possible code], you must be at your A-performance and your A-mindset all the way to the end, especially to the very end, of every session, not only so that you will make your best [design] decisions, but also so you will make your best quitting decisions"
I'm sure you have had the experience of being stuck on a problem for hours only to solve it once you have stepped away for a while. It's like your subconscious just needed a little time to work through the problem on its own. Getting better at quitting can help you avoid a lot of frustration.
"Being able to quit well when you are stuck is an essential skill for long-term [success]. You can improve it by practicing it, just like any other skill or talent. The talent I'm talking about here is standing up and walking away at the moment when you know you really should, but you really don't want to. There is a way to practice this skill. Take a lot of breaks. If you take a lot of breaks...then you will build up quitting strength much more quickly than if you think of quitting as something that happens only once per session"
The first step, of course, in applying these lessons is to work on improving your self-awareness. It can be difficult to identify when you have slipped out of your A-game. Mr. Angelo's suggestion to take regular breaks is a powerful one. Try setting a timer for every 30 minutes and take a short stretch break. In addition to being better for your health, you can take this opportunity to check in with yourself about whether you are still focused and sharp, or if you have slipped into C-game.
A possible objection that salaried professionals may have is that if they are being paid for "a full day's" worth of programming, then quitting early for the day may not be an option, even if they know they aren't at their A-game. I have a few thoughts on this.
It is entirely possible for someone at their C-game to wreak enough damage on a codebase in a few hours that it could take weeks to recover from. Bad decisions made in complex systems can have nonlinear effects. You are probably creating more value by taking a nap or going for a jog than by forging ahead. Your manager may be more understanding of this than you think.
Furthermore, it may be that the source of the problem is your sleep, exercise, or eating habits. If you find it hard to achieve A-game performance in the morning, maybe you should be going to bed earlier. If you are consistently slipping into C-game after lunch, maybe you need to reconsider what you eat.
"For example, let's say you are ordering dinner at a restaurant. After dinner, you plan for a long night of [programming]. You have a choice. You can order steak and potatoes and wine and dessert, and maximize the likelihood that you will be drowsy, which in turn will maximize the likelihood that your late-session weaknesses will get the best of you. Or, you can order fish and salad, no wine, and no dessert, and maximize the chances that you will be fresh and focused at midnight."
Sometimes though, I absolutely have to keep working, even when I'm not feeling great. Maybe there is a crisis in production that needs an immediate fix, or a make-or-break deadline is fast approaching. One thing that I find helpful in these situations is to use the buddy system. While poker is always a solitary activity, programmers can work in pairs to help keep themselves at an aggregate A-game. You might find that your combined A-game is even higher than either of you could achieve alone. This is why some programmers prefer to work in pairs all or most of the time.
At the very least, I hope that this article will help raise your mindfulness during programming sessions, now that you know about A-game and C-game. And knowing is half the battle.