The increasing complexity of the problems being tackled with software systems means that in many cases it is no longer cost-effective (or even possible) for the programmer to prescribe the best action in every state of the environment. To meet these new challenges, not only do we need better programming tools and protocols --- we need a new way of thinking about problem solving. Just as when we hire human agents to solve problems for us, we want to specify only high-level preferences to our software agents, and have them figure out the best course of action. This is not only more cost-effective, but also leads to better and more robust performance in real-world, changing, and uncertain environments. In this article we have presented a brief introduction to reinforcement learning, a problem solving method that enables software agents to learn near-optimal solutions to complex problems from a specification of high-level preferences.