A couple of other things to help your mind moving:
- draw pictures, diagrams, scribbles, ... it doesn't matter if its a picture or squares representing memory, with lines for pointers ... or if its a UML diagram of an activity, a flowchart, or just a scribble with 5 circles and some lines representing your logical state machine. Mental and physical visualization can help you think clearly and keep your thoughts focused.
As said before - pause and review
- take the time to think before you code, while you code, and after you code. You can vary the amount and the ratio based on your success and how repetitive your task is: when doing something similar over and over again the up-front thought needed is nearly zero, the coding is fast, so half the time will be in simple review / double-check, when solving a problem you've never even completely understood before, with ramifications you may not yet have noticed, you'll need a lot of up front time, and also a lot of coding time (where half the problem will show up) ... then a CAREFUL review when you think you are done, to identify what you have missed.
Know the difference between what you KNOW (for sure), what you THINK you know, and what you know you DON'T KNOW. As you plan, or read and review code - this distinction guides how much focus you need to bring to the table.
Also - the longer you spend debugging the same issue ... the more likely it is something "stupid" ... which really means, something in an area you are making an assumption about, that for whatever reason is not currently true (like a problem with code you thought was working yesterday).
Decompose ... separate ... divide and conquer.
When solving a problem, break it down into smaller chunks .. but just as important as chunk size or complexity is how SENSIBLE and therefore understandable and memorable a chunk is. 4 chunks for - parsing the file into memory, validating the contents for validity, reconciling the contents against the previous day, and updating the processing statistics - might be easier to code and debug for a really complex algorithm, then for instance something that parses a header and updates statistics, then parses the body, reconciles it and updates statistics, then parses the footer, validates the whole, and saves a copy ... for a simple algorithm Even though the first might have 1000 lines of code and the later 200 ... the brain can only handle so many thoughts at any given time ...
and you can take chunk 1 of the 1000 line idea ... and further break it down ...
which leads to the last suggestion
NAME everything ... CLEARLY ... and name it well. And as your design changes KEEP YOU NAME UP TO DATE. a function "UpdatePlayerPosition" that moves the player, unless it is under AI control, and then if raises an event for the AI which will do the update later in the "HandleAI" function instead - suggests someone grew the design without making sure the names and layers still fit together right. And a function called "ComputeTaxAndUpdateOrder" is in fact better than "ComputeTax" or "UpdateOrder" if in fact it does both things, regardless of what the function USED to do. Taking the time to name things well, means you also take the time to understand them correctly. Which pays huge dividends in reducing the number and severity of stupid errors.