9

I have a question about a weird, unknown (and possibly impossible) game a friend of mine has taught me. It is a solitaire game that's played with a regular deck of 52 cards but it is suspiciously difficult to beat. What's more, neither my friend nor I were able to find ANY reference to it in all the Internets.

I am aware that the question is not necessarily interesting to anyone but my friend and I, but I was wondering if someone would be willing to help me calculate the odds of beating this game? I think it would help us decide if this is a real game or if it's just a weird multi-generational prank my friend's father (who taught him the game) is pulling. My current grasp of math and probability does not allow me to undertake the project alone.

Here are the rules:

Nine columns of three overlapping face up cards are laid on the table. The face value of each card is used to calculate a sum with the two closest cards (either on top or on bottom) on the column and the last card can "wrap" with the bottom card (the first one played on the column) to achieve a certain sum if needed. Face cards all are worth 10 points.

Each turn you go to the "next" column (cyclically), place a card from the deck on the top of that column, and then, in the same column, look for potentially three cards one after another (two at the top and one at the bottom, and one at the top and two at the bottom, are also valid) which make up 9, 19 or 29, then, if found, remove those cards and put them at the bottom of the deck, in the same order.

If any other valid combinations are revealed after the removal of a triplet of cards from a column, they are also removed and placed back at the bottom of the deck.

If all the cards of a column are thus picked up, the column is eliminated.

The theoretical goal is to pick up all nine columns before the deck runs out. If the deck does run out, it's game over.

Now... my friend has played thousands of games and has never beat the game even once. He holds on to it only because his own father boasts that he finished it twice in thirty years of playing it... But it really sounds fishy.

Can anyone help?

7
  • 1
    I must be missing something, because it doesn't sound like the player makes any decisions in this game Dec 26, 2021 at 18:27
  • 2
    @ArcanistLupus Basically none, indeed. SOMETIMES, there is more than one combination of cards that form a valid triplet to be removed and you have to choose between the two, but that's it. Dec 26, 2021 at 18:48
  • 2
    If it were a generational prank he would have told you to remove groups that add to 9, 18, or 27 instead. It's easy to prove this game can never be won. The deck's total (measured mod 9) never changes as a result of such removals. So it's impossible to get from any starting configuration (sum 340 or 380 depending how you count aces) to an empty configuration (sum 0).
    – amalloy
    Dec 27, 2021 at 4:22
  • 1
    @amalloy Your reasoning doesn't seem to consider that the deck-total changes by an arbitrary amount mod 9 as one card is dealt onto on a column before removing any triplets. Actually, it's interesting that some games can be won in well under 100 moves, but others require more than 1000 moves!
    – r.e.s.
    Dec 27, 2021 at 5:18
  • 4
    @amalloy We don't need to pick up 52, just however many are in the columns, which changes as cards are added one-at-a-time from the deck and removed three-at-a-time when possible. (Only 27 are in the columns initially.)
    – r.e.s.
    Dec 27, 2021 at 5:29

1 Answer 1

13

Depending on the deck's starting arrangement, your game either ends in a win or loss, or it never ends. To estimate the probabilities, I simulated 10^8 games (using the Python program below), under two different rules:

  1. After a card is added to a column, only the three triplets (using wrap-around) that include the added card are to be considered for removal.
  2. After a card is added to a column, all triplets (using wrap-around) are to be considered for removal.

Following are the results:

                      with rule (1)              with rule (2)
                   --------------------      --------------------           
est.P(win)    =    0.000040 +- 0.000001      0.000043 +- 0.000001
est.P(loss)   =    0.999921 +- 0.000002      0.999914 +- 0.000002
est.P(cycle)  =    0.000039 +- 0.000001      0.000043 +- 0.000001

This suggests that your friend's father, in order to win twice in 30 years, would have had to play about 2/(.00004)= 50000 games in that time, which is more than 4 games per day.

It's interesting that some rare arrangements of the deck allow a win in less than 100 moves, while others (also rare) require more than 1000 moves to win! The games that don't end can be interesting too, as they may not begin cycling until after several hundreds of moves, and the cycles have various lengths (e.g., 51, 96, ...).


Python 3 program (you can try it online, but it takes about 50 seconds for 10^5 games. I ran my 10^8 games using pypy, which is very must faster, but still took about 2 hrs.):

import random

deck0 = [i+1 for i in range(9)]*4 + [10]*16

def game():
# return the list of final columns ( or None if cycle, else [] if win, else nonempty if loss)
    deck = deck0[:]
    random.shuffle(deck)
    #print(f"starting deck = {deck}\n")
    
    # with cards from the deck, make 9 cols of 3 cards each 
    cols = []
    for i in range(9):
        cols += [deck[:3]]
        deck = deck[3:]
    
    nmoves = 0
    max_nmoves = 10**4  # assume cycling if nmoves > max_nmoves  (confirm this works in separate testing)
    #print(f"deck = {deck}\ncols = {cols}\n")
    
    c = -1    
    while cols and deck:
        
        nmoves += 1 
        if nmoves >= max_nmoves:
            return None  # signal that it's cycling
        
        # make the next col (with wrap-around) the current col
        c = (c + 1) % len(cols)
        
        # move one card from deck to current col
        cols[c] += [deck[0]]
        deck = deck[1:]
        
        done_col = False  # a flag for when finished processing the current column
        while not done_col: 
            # in current col, remove the first "good" triple (if any) to the deck (good := sum ends in 9)
            l = len(cols[c])
            if l < 3:
                break
            else:
                found_triple9 = False  # a flag for when a valid triple is found anywhere in this column
                #for triple_indices in [[l-3, l-2, l-1], [l-2, l-1, 0], [l-1, 0, 1]]:   #<-- rule(1)
                for triple_indices in [[i, (i+1) % l, (i+2) % l] for i in range(l)]:   #<-- rule(2)
                    triple = [cols[c][i] for i in triple_indices]
                    if sum(triple) % 10 == 9:
                        found_triple9 = True
                        # remove the triple from the column
                        cols[c] = [e for (i,e) in enumerate(cols[c]) if i not in triple_indices]
                        if cols[c] == []:  # delete the column if it's empty
                            del cols[c]
                            done_col = True
                            c -= 1  # <-- column-index adjustment due to deleting a column (omitted in previous version)
                        deck += triple
                        break 
                if not found_triple9:
                    done_col = True
        #print(f"nmoves={nmoves}\ndeck={deck}\ncols={cols}, c={c}\n")   
    return cols
    
import math

nsamp = 10**8
wins = 0
losses = 0
nonstops = 0
for i in range(nsamp):
    cols = game()
    if cols == None:
        nonstops += 1
    elif len(cols) == 0:
        wins += 1
    else:
        losses += 1

p_win = float(wins/nsamp)
p_loss = float(losses/nsamp)
p_cyc = float(nonstops/nsamp)
print(f"wins     = {wins:>10};  est.P(win)   = {p_win:8.6f} +- {1.96*math.sqrt(p_win*(1-p_win)/nsamp):8.6f}")
print(f"losses   = {losses:>10};  est.P(loss)  = {p_loss:8.6f} +- {1.96*math.sqrt(p_loss*(1-p_loss)/nsamp):8.6f}")
print(f"nonstops = {nonstops:>10};  est.P(cycle) = {p_cyc:8.6f} +- {1.96*math.sqrt(p_cyc*(1-p_cyc)/nsamp):8.6f}")
print(f"total    = {wins + losses + nonstops:>10}")

Note: The program allows simulating either of the rules (1) or (2) by simply commenting out with a "#" the line of code that doesn't apply. (Rule (2) is now the default, but takes almost twice as long to run.) The rules as implemented in the program completely determine the game's outcome once the deck is shuffled.

3
  • 1
    I see that you only consider three triple_indices regardless of the size of the column. E.g. for column sizes 4 and higher, the triple of indices [0,1,2] is never checked for their sum. But in my reading of the rules, they should be: for a column of size n>=3, there are n triples whose sum should be checked.
    – Oliphaunt
    Dec 27, 2021 at 22:13
  • 1
    @Oliphaunt-reinstateMonica Thanks for noting that! I've edited the program so a user can select (by commenting out with #) which of two lines of code they want, with the default now being the version you describe. I've also edited the answer to add results of a fresh simulation, now showing the probability estimates for both versions.
    – r.e.s.
    Dec 28, 2021 at 3:16
  • 2
    Side-note: There was déjà vu when seeing that Pwin ~ 0.000043, because of simulations I once did for variants of One-handed Solitaire (OHS): amazingly, this is the same approx. Pwin as for the variant of OHS that uses a 3-card instead of a 4-card "window", discarding the middle card when the outer two are the same suit and discarding all three when the outer two are the same rank. (The 4-card version has Pwin ~ 0.0071. A different 3-card variant has Pwin ~ 0.0061.)
    – r.e.s.
    Jan 5, 2022 at 16:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .