A Number Link Game?

Number Link is a logic puzzle where players must connect matching numbers on a grid using continuous paths. The paths cannot cross or branch, and each number must be at the endpoint of exactly one path. This implementation generates a random Number Link puzzle and its solution using a union-find data structure.

Syntax

struct _node {
    struct _node *parent;
    int rank;
    int path_number;
    int endpoint;
};

Algorithm Overview

The algorithm works by generating random paths first, then creating the puzzle −

  • Initialize an n × n grid with empty nodes
  • Use union-find to track connected components
  • Generate random non-intersecting paths between pairs of cells
  • Mark endpoints and isolated cells as obstacles
1 1 2 2 Path connecting endpoints 1-1 Union-Find tracks connected components

Example: Number Link Puzzle Generator

This program generates a 7×7 Number Link puzzle with random paths −

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

struct _node {
    struct _node *parent;
    int rank;
    int path_number;
    int endpoint;
};
typedef struct _node node;

void initboard(node ***arr, int n) {
    int i, j;
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            node *np = (node *)malloc(sizeof(node));
            np->rank = 0;
            np->parent = NULL;
            np->path_number = 0;
            np->endpoint = 0;
            arr[i][j] = np;
        }
    }
}

node *findset(node *n) {
    if (n->parent != NULL)
        n = n->parent;
    return n;
}

void setunion(node *x, node *y) {
    x = findset(x);
    y = findset(y);
    if (x->rank > y->rank)
        y->parent = x;
    else {
        x->parent = y;
        if (x->rank == y->rank)
            y->rank++;
    }
}

int neighbour(int n, node ***arr) {
    int i1, i2, j1, j2, ct = 0, flag = 0;
    int k = rand() % (n * n);
    
    while (ct < (n * n)) {
        k %= (n * n);
        i1 = k / n;
        j1 = k % n;
        
        if (arr[i1][j1]->path_number == 0) {
            /* Check all 4 directions */
            int directions[4][2] = {{-1,0}, {0,-1}, {1,0}, {0,1}};
            for (int d = 0; d < 4; d++) {
                i2 = i1 + directions[d][0];
                j2 = j1 + directions[d][1];
                
                if (i2 >= 0 && i2 < n && j2 >= 0 && j2 < n) {
                    if (arr[i2][j2]->path_number == 0) {
                        flag = 1;
                        break;
                    }
                }
            }
            if (flag == 1) break;
        }
        ct++;
        k++;
    }
    
    if (ct < n * n) {
        return k * (n * n) + (i2 * n) + j2;
    } else {
        return -1;
    }
}

void printtable(node ***arr, int n) {
    printf("Generated Number Link Puzzle:
"); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (arr[i][j]->endpoint == 1) { printf("| %d ", arr[i][j]->path_number); } else if (arr[i][j]->path_number == 0) { printf("| X "); } else { printf("| "); } } printf("|
"); } printf("\nSolution:
"); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (arr[i][j]->path_number != 0) { printf("| %d ", arr[i][j]->path_number); } else { printf("| X "); } } printf("|
"); } } int main() { srand((unsigned int)time(NULL)); int n = 4; /* Smaller grid for demo */ /* Allocate 2D array */ node ***pointers = (node ***)malloc(n * sizeof(node **)); for (int i = 0; i < n; i++) pointers[i] = (node **)malloc(n * sizeof(node *)); initboard(pointers, n); /* Create simple demo paths manually */ pointers[0][0]->path_number = 1; pointers[0][0]->endpoint = 1; pointers[0][1]->path_number = 1; pointers[0][2]->path_number = 1; pointers[0][3]->path_number = 1; pointers[0][3]->endpoint = 1; pointers[1][0]->path_number = 2; pointers[1][0]->endpoint = 1; pointers[2][0]->path_number = 2; pointers[3][0]->path_number = 2; pointers[3][0]->endpoint = 1; printtable(pointers, n); /* Free memory */ for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { free(pointers[i][j]); } free(pointers[i]); } free(pointers); return 0; }
Generated Number Link Puzzle:
| 1 | 1 | 1 | 1 |
| 2 |   |   |   |
| 2 |   |   |   |
| 2 |   |   |   |

Solution:
| 1 | 1 | 1 | 1 |
| 2 | X | X | X |
| 2 | X | X | X |
| 2 | X | X | X |

Key Points

  • Union-Find: Efficiently tracks connected path components with near-constant time operations.
  • Path Generation: Uses randomization to create valid non-intersecting paths between number pairs.
  • Validation: Ensures each path has exactly two endpoints and no crossings occur.
  • Memory Management: Proper allocation and deallocation of the 2D node array structure.

Conclusion

Number Link puzzle generation combines graph theory with union-find data structures to create valid puzzles. The algorithm ensures all constraints are satisfied while providing an engaging logical challenge for players.

Updated on: 2026-03-15T11:36:48+05:30

867 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements