Either you plan too much ahead and you end up tweaking your design forever, eventually building high-level cruft code that still won't get anything done because you don't dig deep to the ground to find the real culprits of your solution.
Alternatively, you plan nothing at all and end up rewriting your program several times because you just won't see the big picture as you're just digging up dirt from many different spots.
I think it works best if you plan only as much as you initially can and then start coding a proof-of-concept version as quickly as possible. You can only plan what you know of, and it's not much at first but it's something. Quickly getting to coding helps you understand the problem better, and you will throw away a many approaches that turn out to be suboptimal or solutions to the wrong problem, but there's nothing wrong with that. When the coding brings in more knowledge, then you can plan a bit more, and repeat.
If you're good, you can do that most of the most of the time. A conservative estimate might be half the time. More importantly, you will never hit the optimal planning versus coding point but you wave around on the both sides, sometimes planning too much and sometimes coding too much.
Experienced programmers can keep the amplitude of that zigzagging low, inexperienced programmers rush from endpoint to endpoint doing too much either.