Priorities for your bot
In 2014, I think that the best bots were the best because they did three things well: combat micro, pathfinding, and strategy.
I list these in order of importance. To win, you absolutely need top tier combat micro. You can't afford to fall behind in this area, or a better team will wipe your robots off the map regardless of your strategy.
Almost as important, you need robust pathfinding. Many games were lost because one team got some or all of their robots stuck behind a convoluted obstacle, allowing the other team to pick up a free win. Note that I say "robust" and not "optimal." It's much more important that you not get stuck than that you get to the destination as fast as possible. A well-implemented bug nav is much, much better than a buggy A*.
Finally, you need good strategy. While you do need to keep up with the metagame, robust execution is again most important. My bots made some suboptimal strategic choices in the final tournament but managed to claw back many of those games because the other teams' bots got confused or distracted and stopped making progress toward the goal of collecting milk. Your robots always have to being doing something sensible even if you are losing or the enemy is doing something unexpected.
At least, that's how it was in 2014! If the game doesn't change too much, I expect that these will continue to be important priorities in the future.
How to write a winning bot
So how can you write a bot that wins? The most important rule is: copy other teams! If you lose a scimmage match, don't be proud. Copy the technique that beat you, whether it's a new strategy or a combat micro refinement, and start using it. This will also let you start developing counters to that technique, using your implementation as a test opponent.
Make it easy to write lots of code fast. You are going to have to write (and rewrite, and rewrite) a few thousand lines of code in just a few weeks. This is not a lot of time, so you need to make it as easy as possible to write code efficiently. Use a nice IDE. Wrap the API in easy-to-use interfaces. I found it particularly useful to wrap the communications functions and debugging functions in nicer interfaces.
Don't do premature bytecode optimization. Try to have a sense of which parts of your code cost a lot of bytecodes, but don't work too hard on optimizing them early on when they are still likely to change.
Test a lot. Keep a lot of versions of your bot around and play your current version against others to test your improvements. Implement other strategies and test your strategy against those. I probably spent similar amounts of time coding and watching test matches between different versions of my bots. By the end of Battlecode 2014 I had 46 different versions lying around that I had used for testing at various points. The most rigorous testing ground is the scrimmage server because other teams' bots will behave in unexpected ways and you get to see whether your code can handle it. Keep in mind that the goal of testing is to see your bot lose: losing tells you what you need to fix and improve. So prefer to play scrimmages on your weakest maps. Fix all the bugs and problems you find in your testing, unless you make a careful and considered decision that the bug is too rare or minor to matter. Unfixed bugs will come back to bite you in tournaments.