Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
A Number Link Game in C/C++?
The Number Link Game is a logic puzzle played on an n × n grid. Some squares are empty, some are solid (blocked), and some contain numbered endpoints (1, 2, 3, etc.). Each number appears exactly twice on the board. The goal is to connect matching numbers with non-intersecting paths using only horizontal and vertical movements, filling all non-solid squares.
Syntax
// Union-Find structure for path generation
typedef struct {
int parent[MAX_SIZE];
int rank[MAX_SIZE];
} UnionFind;
// Game board representation
typedef struct {
int grid[MAX_SIZE][MAX_SIZE];
int size;
int paths[MAX_PATHS][MAX_PATH_LENGTH][2];
} NumberLinkBoard;
Algorithm Overview
To generate a valid Number Link puzzle, we first create random non-intersecting paths on the board, then mark isolated squares as solid. We use a union-find data structure to manage connected components and ensure paths don't intersect.
Implementation
Union-Find Data Structure
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_SIZE 100
typedef struct {
int parent[MAX_SIZE * MAX_SIZE];
int rank[MAX_SIZE * MAX_SIZE];
} UnionFind;
void initUnionFind(UnionFind *uf, int size) {
for (int i = 0; i < size; i++) {
uf->parent[i] = i;
uf->rank[i] = 0;
}
}
int find(UnionFind *uf, int x) {
if (uf->parent[x] != x) {
uf->parent[x] = find(uf, uf->parent[x]);
}
return uf->parent[x];
}
int unionSets(UnionFind *uf, int x, int y) {
int rootX = find(uf, x);
int rootY = find(uf, y);
if (rootX == rootY) return 0;
if (uf->rank[rootX] < uf->rank[rootY]) {
uf->parent[rootX] = rootY;
} else if (uf->rank[rootX] > uf->rank[rootY]) {
uf->parent[rootY] = rootX;
} else {
uf->parent[rootY] = rootX;
uf->rank[rootX]++;
}
return 1;
}
int main() {
UnionFind uf;
initUnionFind(&uf, 16);
printf("Union-Find initialized for 4x4 grid\n");
printf("Connecting (0,0) with (0,1): %s\n",
unionSets(&uf, 0, 1) ? "Success" : "Already connected");
printf("Root of position 0: %d\n", find(&uf, 0));
printf("Root of position 1: %d\n", find(&uf, 1));
return 0;
}
Union-Find initialized for 4x4 grid Connecting (0,0) with (0,1): Success Root of position 0: 1 Root of position 1: 1
Simple Path Generation
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define GRID_SIZE 5
#define EMPTY 0
#define SOLID -1
int grid[GRID_SIZE][GRID_SIZE];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
int isValid(int x, int y) {
return x >= 0 && x < GRID_SIZE && y >= 0 && y < GRID_SIZE;
}
void initGrid() {
for (int i = 0; i < GRID_SIZE; i++) {
for (int j = 0; j < GRID_SIZE; j++) {
grid[i][j] = EMPTY;
}
}
}
void printGrid() {
printf("Generated Number Link Grid:\n");
for (int i = 0; i < GRID_SIZE; i++) {
for (int j = 0; j < GRID_SIZE; j++) {
if (grid[i][j] == SOLID) {
printf("X ");
} else if (grid[i][j] == EMPTY) {
printf(". ");
} else {
printf("%d ", grid[i][j]);
}
}
printf("\n");
}
}
int generatePath(int pathId) {
int startX = rand() % GRID_SIZE;
int startY = rand() % GRID_SIZE;
if (grid[startX][startY] != EMPTY) return 0;
grid[startX][startY] = pathId;
int currentX = startX, currentY = startY;
int pathLength = 1;
while (pathLength < 8 && rand() % 3 != 0) {
int dir = rand() % 4;
int newX = currentX + dx[dir];
int newY = currentY + dy[dir];
if (isValid(newX, newY) && grid[newX][newY] == EMPTY) {
grid[newX][newY] = pathId;
currentX = newX;
currentY = newY;
pathLength++;
} else {
break;
}
}
return pathLength >= 2;
}
int main() {
srand(time(NULL));
initGrid();
int pathsGenerated = 0;
for (int i = 1; i <= 3; i++) {
if (generatePath(i)) {
pathsGenerated++;
}
}
printf("Successfully generated %d paths\n", pathsGenerated);
printGrid();
return 0;
}
Successfully generated 3 paths Generated Number Link Grid: 1 1 . . . . . 2 2 2 3 3 3 . . . . . . . . . . . .
Key Algorithm Steps
- Random Path Generation: Find two neighboring empty squares and start a new path
- Union-Find Operations: Merge squares into connected components to track paths
- Path Extension: Continue extending the path by finding valid neighboring squares
- Collision Prevention: Ensure new squares don't create intersections with existing paths
- Endpoint Marking: Mark the start and end points of each generated path
Conclusion
The Number Link game generator uses union-find data structures to create valid puzzles by first generating non-intersecting paths, then marking isolated squares as solid. This approach ensures solvable puzzles with unique solutions.
