Skip to content
Vamshi Jandhyala

Books · Solving Puzzles through Mathematical Programming

Chapter 10

Dobble

Dobble is a card game of fifty-five cards, each bearing eight pictorial symbols drawn from a pool of fifty-seven. It is marketed under the trade names Dobble in Europe and Spot It! in North America, and sold as a speed-matching game: players race to identify a symbol common to two cards. The design guarantees that this common symbol always exists and is always unique — any two cards in the deck share exactly one symbol. The combinatorial feat that makes the game playable conceals a piece of classical finite geometry: a full Dobble deck is a projective plane of order seven (projective planes exist for every prime-power order).

The deck’s parameters are not arbitrary. A projective plane of order nn has n2+n+1n^2 + n + 1 points and the same number of lines; each line passes through n+1n + 1 points, each point lies on n+1n + 1 lines, and any two distinct lines intersect in exactly one point. Setting n=7n = 7 gives 5757 symbols, 5757 cards, 88 symbols per card, and the Dobble guarantee. (Commercial decks trim the full 5757 cards to 5555 for printing reasons; the mathematics works for any subset.) The existence of a plane of order nn is guaranteed when nn is a prime power, in which case the finite-field construction below applies. For n=6n = 6 (not a prime power) no plane exists, by the Bruck–Ryser theorem; for n=10n = 10 the nonexistence is a celebrated result of Lam, Thiel, and Swiercz (19891989).

The Fano plane: n=2n = 2

The smallest projective plane is the Fano plane, PG(2,2)\mathrm{PG}(2, 2): 77 points, 77 lines, 33 points per line. Figure 10.1 shows the standard picture: a triangle, its three medians, and an inscribed circle. The three sides, three medians, and one circle together make seven lines; the three vertices, three edge midpoints, and one centroid make seven points; and any two lines meet in exactly one point.

The Fano plane PG(2,2)\mathrm{PG}(2, 2): seven points (labelled AA through GG) and seven lines (three sides, three medians, one circle). Any two distinct lines meet in exactly one point. Thought of as a Dobble deck, this is seven cards of three symbols each.

A “mini-Dobble” with the Fano plane’s parameters has seven cards, each with three symbols; any two share exactly one symbol. The seven cards are the seven lines of Figure 10.1: the three sides (A,D,B)(A, D, B), (A,F,C)(A, F, C), (B,E,C)(B, E, C), each carrying its edge midpoint; the three medians (A,G,E)(A, G, E), (B,G,F)(B, G, F), (C,G,D)(C, G, D), each through the centre GG; and the inscribed circle (D,E,F)(D, E, F) through the three midpoints.

The programming model

Constructing a projective plane of a given order by pure search is an exact-cover-flavoured problem with a beautifully simple encoding.

Variables

For each card i{0,,N1}i \in \{0, \ldots, N - 1\} and each symbol j{0,,N1}j \in \{0, \ldots, N - 1\} (where N=n2+n+1N = n^2 + n + 1), introduce a Boolean variable xi,jx_{i, j}: one if card ii contains symbol jj, zero otherwise.

Card size

Each card has exactly n+1n + 1 symbols: j=0N1xi,j  =  n+1,i{0,,N1}.\sum_{j = 0}^{N - 1} x_{i, j} \;=\; n + 1, \quad i \in \{0, \ldots, N - 1\}.

Symbol multiplicity

Each symbol appears on exactly n+1n + 1 cards: i=0N1xi,j  =  n+1,j{0,,N1}.\sum_{i = 0}^{N - 1} x_{i, j} \;=\; n + 1, \quad j \in \{0, \ldots, N - 1\}.

Pairwise intersection

For every pair of distinct cards iki \neq k, exactly one symbol is shared. Since xi,jxk,jx_{i, j} x_{k, j} is the indicator that symbol jj lies on both cards, the constraint is j=0N1xi,j  xk,j  =  1,0i<kN1.\sum_{j = 0}^{N - 1} x_{i, j} \; x_{k, j} \;=\; 1, \quad 0 \leq i < k \leq N - 1. In CP-SAT the product is linearised by introducing an auxiliary Boolean yi,k,j=xi,jxk,jy_{i, k, j} = x_{i, j} \wedge x_{k, j} and requiring jyi,k,j=1\sum_j y_{i, k, j} = 1.

Symmetry breaking

The full automorphism group of a projective plane is enormous, so without symmetry breaking the enumerator will revisit many equivalent decks. A common break fixes the contents of card 00: card 0={0,1,,n}0 = \{0, 1, \ldots, n\}. This pins the first card’s symbols and halves or more the search tree.

A solver in forty lines

from ortools.sat.python import cp_model

def dobble(n):
    N = n * n + n + 1
    m = cp_model.CpModel()
    x = [[m.NewBoolVar("")
          for _ in range(N)] for _ in range(N)]
    # Each card has n+1 symbols
    for i in range(N):
        m.Add(sum(x[i][j]
                  for j in range(N)) == n + 1)
    # Each symbol on n+1 cards
    for j in range(N):
        m.Add(sum(x[i][j]
                  for i in range(N)) == n + 1)
    # Any two cards share exactly one symbol
    for i in range(N):
        for k in range(i + 1, N):
            y = [m.NewBoolVar("") for _ in range(N)]
            for j in range(N):
                m.AddBoolAnd(
                    [x[i][j], x[k][j]]
                ).OnlyEnforceIf(y[j])
                m.AddBoolOr(
                    [x[i][j].Not(), x[k][j].Not()]
                ).OnlyEnforceIf(y[j].Not())
            m.Add(sum(y) == 1)
    # Symmetry break: card 0 = {0, 1, ..., n}
    for j in range(N):
        m.Add(x[0][j] == (1 if j <= n else 0))
    s = cp_model.CpSolver()
    s.parameters.max_time_in_seconds = 120
    s.Solve(m)
    return [[j for j in range(N) if s.Value(x[i][j])]
            for i in range(N)]

Timings (on a standard laptop, with the symmetry break above): n=2 (Fano):18 ms;n=3:60 ms;n=4:0.4 s;n = 2 \text{ (Fano)}: 18 \text{ ms}; \quad n = 3: 60 \text{ ms}; \quad n = 4: 0.4 \text{ s}; n=5:1.6 s;n=7 (commercial Dobble):30 s.\quad n = 5: 1.6 \text{ s}; \quad n = 7 \text{ (commercial Dobble)}: \approx 30 \text{ s}. No projective plane of order 66 exists, by the Bruck–Ryser theorem, and the solver confirms this by eventually returning infeasible; note though that proving nonexistence is a genuine exhaustive search, far slower than finding a plane that does exist, so the time it takes is not the fraction of a second the feasible cases enjoy. For n=10n = 10 the model is beyond naive CP-SAT; the nonexistence result is Lam–Thiel–Swiercz’s 19891989 theorem, obtained by a much larger specialised search.

The incidence matrix of PG(2,3)\mathrm{PG}(2, 3): 1313 cards (rows) and 1313 symbols (columns), with a filled cell marking symbol presence. Each row has four filled cells; each column has four filled cells; any two rows share exactly one filled column.

The algebraic construction

For nn a prime power qq, the projective plane PG(2,q)\mathrm{PG}(2, q) is built directly. Points are equivalence classes of (a,b,c)Fq3{0}(a, b, c) \in \mathbb{F}_q^3 \setminus \{\mathbf{0}\} under scaling; lines are the same, with the duality that point (a,b,c)(a, b, c) lies on line (u,v,w)(u, v, w) if and only if au+bv+cw=0au + bv + cw = 0 in the finite field Fq\mathbb{F}_q. When qq is prime this is ordinary arithmetic modulo qq; when qq is a proper prime power the field Fq\mathbb{F}_q is needed, since the ring Z/qZ\mathbb{Z}/q\mathbb{Z} then has zero divisors and is not a field. For q=7q = 7 this assembles a full Dobble deck in microseconds, yielding the same 57×5757 \times 57 incidence matrix that CP-SAT recovers by search (up to permutation of rows and columns).

Sources. Projective planes entered finite geometry in the late nineteenth century through the work of Karl von Staudt and Theodor Reye; the Fano plane is named after Gino Fano (18921892). The classical existence theorem for planes of prime power order is due to Veblen and Wedderburn (19071907). The Bruck–Ryser nonexistence theorem (19491949) rules out orders n1,2(mod4)n \equiv 1, 2 \pmod{4} unless nn is a sum of two squares. The nonexistence for n=10n = 10 is due to Lam, Thiel, and Swiercz (Canadian Journal of Mathematics, 19891989), a major computational result that occupied several Cray years. The Bruck–Ryser theorem also rules out orders 2121 and 2222 (neither is a sum of two squares, and both are 1,2(mod4)\equiv 1, 2 \pmod 4), so the smallest orders whose existence is currently open are n=12,15,18,20,24,n = 12, 15, 18, 20, 24, \ldots. The mapping of finite projective planes to a physical game of cards has a longer history than the commercial product suggests: in 19761976 the French enthusiast Jacques Cottereau devised an unpublished set of 3131 insect cards with the shared-symbol property, and in 20082008 the game designer Denis Blanchot reworked the idea into Dobble, published in 20092009.