You need to be able to think abstractly about what is happening during the recursion process to understand what is going on.
Let's say you have a list [], and we're going to limit the things you can do with that list. You can add items to it by list.append(). You can process
and remove the last item with list.pop().
This is called a last-in-first-out stack, and it's a simple concept to understand how recursion is processed.
You call some function, and a copy of that is appended to an in memory stack. [f_copy(x, y)]
As you append more copies, [f_copy_(x, y), f_copy_1(a, b), f_copy_2(c, d)], and then ultimately begin the computations, you pop() the last item, and
continue until one of your win/lose conditions are met.
stack = []
# iter 1 starts
f(x, y)
stack.append(f_copy(a,b)) # calls itself
stack = [f_copy(a, b)]
# iter 2 starts
stack.pop() = f_copy(a, b)
stack.append(f_copy_1(c, d)) # calls itself
stack = [f_copy_1(c, d)]
# iter 3 starts
stack.pop() = f_copy_1(c, d)
# iter 3 returns, some condition met
stack = [] # never called itself during iter 3
# iter 2 returns, statisfied
# iter 1 returns, satisfied
That's not exactly how recursion works, mind you, but that's kind of the idea.
edit on 17-2-2023 by rounda because: (no reason given)