Heh. If that annoys you, maybe programming isn't right for you. There will ALWAYS be code rework due to changing requirements. What the pros do (well what I do anyway) is to code accordingly; make stuff as generic as possible; if something's written for one item, write it as you would for n items where n currently = 1. Use symbols instead of constants for as much as possible. Writing a chess program? Think the board is only ever going to be 8x8? Some arsehole will come along sooner or later and ask you to make it do Chinese chess (I think) that requires a 10x10 board. Make sure BOARD_X and BOARD_Y are separate, cos if you don't you can guarantee some idiot will think up some bizarre rectangular form of chess.
However you're correct that you should always do as much preparation as possible. You'll never do enough to avoid all rework though. What you have to prepare partially comes from experience, which you can gain just by making stuff generic.