Here's a few tips from my experiences.
Try www.projecteuler.net Yes, they're problems with a well defined goal. But it's always up to you how to go about doing them.
It's probably one of the best sites to help you develop problem solving skills using programming and forces you to delve into the often vast pool of predefined classes and methods that you will undoubtedly use again in your future if you're a dedicated programmer.
I'd also suggest trying to recreate programs you've used before. One of the first things I tried to recreate was minesweeper; a project that vastly improved my recursive function programming, frame organization, and event listening.
The point I'm trying to make is, the best way to improve your skills and put the knowledge you already have to good use is to just program. Go out (Well, since we're talking programming, I guess we'll stay in) and just experiment. You don't even need to have a goal in mind. Experiment with the limits of a language. Go see how well arrays handle redefinition. Find instances where you prefer one method over another. Try to improve on your past work and examples that you've been given.
Just do it.