The standard NP-Complete routine I use (when lacking a problem or domain specific optimization) is a recursive solution that tries to cover all combinatorial possibilities, but will short circuit (prune the tree) in the case where the fitness function would never succeed from that point on.
I have something similar with a variation of fitness() except that the function does all the heavy-lifting of driving the moves: