How to resolve the algorithm Knight's tour step by step in the C programming language
How to resolve the algorithm Knight's tour step by step in the C programming language
Table of Contents
Problem Statement
Problem: you have a standard 8x8 chessboard, empty but for a single knight on some square. Your task is to emit a series of legal knight moves that result in the knight visiting every square on the chessboard exactly once. Note that it is not a requirement that the tour be "closed"; that is, the knight need not end within a single move of its start position. Input and output may be textual or graphical, according to the conventions of the programming environment. If textual, squares should be indicated in algebraic notation. The output should indicate the order in which the knight visits the squares, starting with the initial position. The form of the output may be a diagram of the board with the squares numbered according to visitation sequence, or a textual list of algebraic coordinates in order, or even an actual animation of the knight moving around the chessboard. Input: starting square Output: move sequence
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Knight's tour step by step in the C programming language
The C code you provided implements an algorithm to solve a "Knight's Tour" problem. A Knight's Tour is a path for a knight in a chess game that visits all squares of a given board exactly once.
The code defines a few helper functions and a main function:
-
init_board
initializes the game board. It creates a 2D array of cells, with some padding around the edges. The padding is used to represent the "outside" of the board, which the knight cannot move to. -
walk_board
implements the actual Knight's Tour algorithm. It takes a starting position and a game board as input, and tries to find a path that visits all squares of the board exactly once. The algorithm uses a depth-first search approach, and it backtracks if it reaches a dead end. -
solve
is the main function that callsinit_board
andwalk_board
to solve the Knight's Tour problem for a given board size. It also handles user input and provides a visual representation of the solution.
The main function takes two command-line arguments: the width and height of the game board. If no arguments are provided, the default board size is 8x8.
The solve
function initializes the game board and then calls walk_board
to find a solution. If a solution is found, it prints a message to the console and returns 1. If no solution is found, it prints a message to the console and returns 0.
The walk_board
function takes a starting position and a game board as input, and tries to find a path that visits all squares of the board exactly once. It uses a depth-first search approach, and it backtracks if it reaches a dead end.
The algorithm works by first occupying the current cell on the board. Then, it reduces the neighbor count of all of the current cell's neighbors. Next, it finds the neighbor with the lowest neighbor count, and moves to that neighbor. The algorithm repeats this process until it has visited all of the squares on the board.
If the algorithm reaches a dead end, it backtracks to the previous cell and tries a different neighbor. If it backtracks to the starting cell, then there is no solution to the Knight's Tour problem for the given board size.
Source code in the c programming language
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
typedef unsigned char cell;
int dx[] = { -2, -2, -1, 1, 2, 2, 1, -1 };
int dy[] = { -1, 1, 2, 2, 1, -1, -2, -2 };
void init_board(int w, int h, cell **a, cell **b)
{
int i, j, k, x, y, p = w + 4, q = h + 4;
/* b is board; a is board with 2 rows padded at each side */
a[0] = (cell*)(a + q);
b[0] = a[0] + 2;
for (i = 1; i < q; i++) {
a[i] = a[i-1] + p;
b[i] = a[i] + 2;
}
memset(a[0], 255, p * q);
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
for (k = 0; k < 8; k++) {
x = j + dx[k], y = i + dy[k];
if (b[i+2][j] == 255) b[i+2][j] = 0;
b[i+2][j] += x >= 0 && x < w && y >= 0 && y < h;
}
}
}
}
#define E "\033["
int walk_board(int w, int h, int x, int y, cell **b)
{
int i, nx, ny, least;
int steps = 0;
printf(E"H"E"J"E"%d;%dH"E"32m[]"E"m", y + 1, 1 + 2 * x);
while (1) {
/* occupy cell */
b[y][x] = 255;
/* reduce all neighbors' neighbor count */
for (i = 0; i < 8; i++)
b[ y + dy[i] ][ x + dx[i] ]--;
/* find neighbor with lowest neighbor count */
least = 255;
for (i = 0; i < 8; i++) {
if (b[ y + dy[i] ][ x + dx[i] ] < least) {
nx = x + dx[i];
ny = y + dy[i];
least = b[ny][nx];
}
}
if (least > 7) {
printf(E"%dH", h + 2);
return steps == w * h - 1;
}
if (steps++) printf(E"%d;%dH[]", y + 1, 1 + 2 * x);
x = nx, y = ny;
printf(E"%d;%dH"E"31m[]"E"m", y + 1, 1 + 2 * x);
fflush(stdout);
usleep(120000);
}
}
int solve(int w, int h)
{
int x = 0, y = 0;
cell **a, **b;
a = malloc((w + 4) * (h + 4) + sizeof(cell*) * (h + 4));
b = malloc((h + 4) * sizeof(cell*));
while (1) {
init_board(w, h, a, b);
if (walk_board(w, h, x, y, b + 2)) {
printf("Success!\n");
return 1;
}
if (++x >= w) x = 0, y++;
if (y >= h) {
printf("Failed to find a solution\n");
return 0;
}
printf("Any key to try next start position");
getchar();
}
}
int main(int c, char **v)
{
int w, h;
if (c < 2 || (w = atoi(v[1])) <= 0) w = 8;
if (c < 3 || (h = atoi(v[2])) <= 0) h = w;
solve(w, h);
return 0;
}
You may also check:How to resolve the algorithm Blum integer step by step in the Perl programming language
You may also check:How to resolve the algorithm Visualize a tree step by step in the Lua programming language
You may also check:How to resolve the algorithm Strip a set of characters from a string step by step in the Rust programming language
You may also check:How to resolve the algorithm Shoelace formula for polygonal area step by step in the Kotlin programming language
You may also check:How to resolve the algorithm Number names step by step in the HicEst programming language