West leads the Spade Queen against your contract of Seven Hearts.
How do you play to win all the tricks?

The program below will determine whether or not a given contract can
succeed against perfect card play.
The single long function consists of

Code to input the hands, number of tricks required, and to designate
the trump suit and opening lead;

Code to echo that input, thus creating a self-sufficient record on
stdout;

A loop to move forward, playing cards;

A backwards loop to undo the cards played in the forward loop; and

Code to print the solution.

Putting everything into a single routine named ``main()''
was excessive, but I did it to emphasize a particular point:
No use of recursion, in the ordinary sense of automatic
stack manipulation is required here.
The ``needed recursion'' collapses into a simple iteration, or
rather a form closely related to tail recusion arises.

Such ``quasi-tail recursions'' are not always available.
Here however, the whole procedural implementation of a forward/backtrack
loop collapses into a simple flow (implemented with a goto!),
arguably best viewed as a variation of the tail-recursion motif.

It seems surprising that this simple program, with such a simple
flow, can solve a seemingly non-trivial problem: Finding best play
in a difficult game.
Complication would arise if we tried to make the program fast,
by developing bridge strategies.
The program isn't that slow as it is, however, and can
even quickly solve an interesting 52-card problem too difficult for
most human experts.
(Try to work the above example yourself before turning it over to the
machine! If you do give up, the software will print out only one variation,
so you'll either have to use that as a hint to come up with the complete
solution, or let the computer print the winning play against other defenses
by inputting the appropriate subsequent positions.
As a last resort, here's the solution.)

The program does apply two heuristics.
When a player has the Nine and Ten of Spades, there is no sense
trying both cards; their effect will be the same.
More generally, if the player has the Five and Ten of Spades,
and each Spade in between the Five and Ten is either out of play,
or is already present in the trick under consideration, then,
provided the Ten of Spades wouldn't be enough to win the trick,
the effect of the Five and Ten will be the same.
There are a few lines of code in the software to implement this
idea.

The other heuristic applied is the alpha-beta heuristic.
In our program, only two game values are ever generated: Success
and Failure.
This makes the alpha-beta heuristic so trivial it almost
goes unnoticed.
An unfortunate consequence of this degenerate form of the heuristic
is that the software will not try for overtricks.
If there is a play which guarantees an overtrick it can be discovered
by rerunning the program with a different contract.
Two such runs will often take less execution time than a single
run would take were the game value modified to recognize overtricks.
(This fact provides a clue towards a general approach for speeding
game-tree searches.)

There is a special reason why I've included this program on the website,
but I'll explain that after giving the source code.

It is not wrong to avoid goto statements when
convenient alternatives exist, but some people carry their
contempt for goto much too far.
There are many, many situations where use of goto is
the least of evils.
A simple example arises in the
Waldo's Nim playing software on this
website:

The people who despise goto base their case on the fact
that programs can always be rewritten to remove any goto.
Well, we could write English without any adverbs if we wanted;
does that make it right?
Here's how the goto Gestapo would rewrite the above
fragment:

Boy, if you think that's an improvement you probably thought
Steve Forbes's tax plan was good for America!

There are many examples where goto is the best approach
in a programming problem, but I'd hate to rely on this simple
example from the Waldo's Nim program to make my point: it's
too tame, and too clearcut for any serious controversy.
That's why I've included the Bridge Double Dummy solver
on this website.

In the Double Dummy Solver there are two independent nested loops,
one plays cards forward, the other undoes those plays, backwards.
A backtracking search involves ``zig-zagging'' through the
forward and backward routines, and in this program that's
accomplished with a goto from the innermost depth of one
loop to the innermost depth of the other!

I do not propose this as a general model for backtracking.
Easier problems can be handled nicely by nesting the backtrack
loop inside the forward loop, or vice versa (attempting that
here would require clumsy switching variables), and harder
problems require more general methods.
But for this particular algorithm the goto works out
just right, and I think that's elegant.

The code contains twogoto's.
One of these is the wonderful goto which cannot be removed
without making the source code dramatically more complex.
The other goto is quite trivial to remove; I've included
it, perhaps perversely,
just because it seems to add an elegant balance: now both
inner loops jump to the other.