Knight's Tour and Maze Path Problems: Backtracking on Grids

Sanjeev SharmaSanjeev Sharma
2 min read

Advertisement

Knight's Tour and Maze Problems

Knight's Tour

Visit every cell on n×n board exactly once using knight moves.

def knights_tour(n):
    board = [[-1]*n for _ in range(n)]
    moves = [(2,1),(2,-1),(-2,1),(-2,-1),(1,2),(1,-2),(-1,2),(-1,-2)]

    def get_degree(x, y):
        count = 0
        for dx, dy in moves:
            nx, ny = x+dx, y+dy
            if 0<=nx<n and 0<=ny<n and board[nx][ny]==-1:
                count += 1
        return count

    def bt(x, y, move_num):
        board[x][y] = move_num
        if move_num == n*n - 1: return True
        # Warnsdorff's heuristic: sort by degree (fewest onward moves)
        neighbors = []
        for dx, dy in moves:
            nx, ny = x+dx, y+dy
            if 0<=nx<n and 0<=ny<n and board[nx][ny]==-1:
                neighbors.append((get_degree(nx,ny), nx, ny))
        neighbors.sort()
        for _, nx, ny in neighbors:
            if bt(nx, ny, move_num+1): return True
        board[x][y] = -1  # backtrack
        return False

    bt(0, 0, 0)
    return board

# Maze Solver (find any path)
def solve_maze(maze):
    rows, cols = len(maze), len(maze[0])
    path = []
    visited = [[False]*cols for _ in range(rows)]

    def bt(r, c):
        if r == rows-1 and c == cols-1:
            path.append((r, c))
            return True
        if r<0 or r>=rows or c<0 or c>=cols: return False
        if maze[r][c] == 1 or visited[r][c]: return False
        visited[r][c] = True
        path.append((r, c))
        if bt(r+1,c) or bt(r,c+1) or bt(r-1,c) or bt(r,c-1):
            return True
        path.pop()
        visited[r][c] = False
        return False

    bt(0, 0)
    return path

# Count all paths in maze
def count_paths(maze):
    rows, cols = len(maze), len(maze[0])
    visited = [[False]*cols for _ in range(rows)]
    def bt(r, c):
        if r==rows-1 and c==cols-1: return 1
        if r<0 or r>=rows or c<0 or c>=cols or maze[r][c]==1 or visited[r][c]: return 0
        visited[r][c] = True
        count = sum(bt(r+dr, c+dc) for dr,dc in [(1,0),(-1,0),(0,1),(0,-1)])
        visited[r][c] = False
        return count
    return bt(0, 0)

C++ Implementation

#include <bits/stdc++.h>
using namespace std;

bool solveMaze(vector<vector<int>>& maze, int r, int c, vector<pair<int,int>>& path) {
    int rows = maze.size(), cols = maze[0].size();
    if (r < 0||r>=rows||c<0||c>=cols||maze[r][c]==1) return false;
    path.push_back({r, c});
    if (r==rows-1 && c==cols-1) return true;
    maze[r][c] = 1; // mark visited
    int dr[] = {1,-1,0,0}, dc[] = {0,0,1,-1};
    for (int d = 0; d < 4; d++) {
        if (solveMaze(maze, r+dr[d], c+dc[d], path)) return true;
    }
    path.pop_back();
    maze[r][c] = 0; // unmark
    return false;
}

Warnsdorff Heuristic

Choose the next cell with the fewest onward moves. Converts O(8^(n^2)) to near-linear in practice for the knight's tour.

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro