The C program is an implementation of the 8-Queens Puzzle, a classic problem in chess. The objective of the puzzle is to place eight chess queens on an 8×8 chessboard in such a way that no two queens threaten each other. In chess, a queen can attack horizontally, vertically, and diagonally.
Here’s a brief overview of how the program works:
- Initialization: The program initializes the SDL graphics library and TTF (TrueType Font) for text rendering.
- Graphics Setup: It creates a window and renderer for graphics rendering.
- User Input: The user is prompted to choose whether they want to manually input the coordinates of the first queen or let the computer explore all possible cases.
- Queen Placement: The program then uses backtracking to find solutions to the 8-Queens Puzzle. It iteratively places queens on the chessboard, checking if the current placement is valid.
- Graphics Display: When a valid placement is found, the program displays the chessboard with queens using SDL graphics. It shows the positions of queens, a counter for the number of solutions found, and the current placement coordinates.
- Delay and Clear: The program introduces a delay and clears the graphics before proceeding to the next solution.
- User Interaction: The user can interact with the program by closing the window or letting the computer explore all possibilities.
- Cleanup: After the program finishes, it closes the graphics window and frees allocated resources.
Please note that the use of SDL and graphics libraries is for visualization purposes, allowing you to see the solutions on a graphical chessboard. The core logic of the 8-Queens Puzzle is implemented in the queen
function, which uses backtracking to find valid queen placements.
#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#define SCREEN_WIDTH 500
#define SCREEN_HEIGHT 500
#define SQUARE_SIZE 50
int x[9];
TTF_Font* font;
SDL_Color textColor;
SDL_Renderer* renderer;
SDL_Window* window;
int place(int);
void queen(int);
void drawBoard(SDL_Renderer*);
void drawQueen(SDL_Renderer*, int, int);
void drawCounter(SDL_Renderer*, int, int, int);
int XYGraphic(int);
SDL_Point convertToSDLPoint(int, int);
int main(void) {
SDL_Init(SDL_INIT_VIDEO);
TTF_Init();
window = SDL_CreateWindow("8 Queens Puzzle", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
font = TTF_OpenFont("summernote.ttf", 16); // Replace with the path to your font file
textColor.r = 255;
textColor.g = 255;
textColor.b = 255;
queen(8);
TTF_CloseFont(font);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
TTF_Quit();
SDL_Quit();
return 0;
}
void queen(int n) {
int k = 1, z, X, Y, counter = 0, x2, y2, loc=0;
char answer;
x[1] = 0;
printf("WHETHER YOU WANT TO CHOOSE A COORDINATE OR\n");
printf("COMPUTER TAKES ALL POSSIBLE CASES: ");
scanf_s(" %c", &answer);
if (answer == 'c' || answer == 'C') {
printf("X, Y: ");
scanf_s("%d%d", &x2, &y2);
}
SDL_Event event;
int quit = 0;
while (!quit) {
while (SDL_PollEvent(&event) != 0) {
if (event.type == SDL_QUIT) {
quit = 1;
}
}
x[k]++;
while (x[k] <= n && !place(k))
x[k]++;
if (x[k] <= n) {
if (k == n) {
if (answer == 'a' || answer == 'A') {
drawBoard(renderer);
counter++;
for (int m = 1; m < 9; m++) {
z = x[m];
X = XYGraphic(m);
Y = XYGraphic(z);
drawQueen(renderer, X, Y);
drawCounter(renderer, m, z, counter);
}
SDL_RenderPresent(renderer);
SDL_Delay(3000);
}
else if (answer == 'c' || answer == 'C') {
for (int i = 1; i < 9; i++)
if (i == x2 && x[i] == y2)
loc = 1;
if (loc == 1) {
drawBoard(renderer);
counter++;
for (int m = 1; m < 9; m++) {
z = x[m];
X = XYGraphic(m);
Y = XYGraphic(z);
drawQueen(renderer, X, Y);
drawCounter(renderer, m, z, counter);
}
loc = 0;
SDL_RenderPresent(renderer);
SDL_Delay(3000);
}
}
SDL_PollEvent(&event);
if (event.type == SDL_QUIT) {
quit = 1;
}
SDL_RenderClear(renderer);
}
else {
k++;
x[k] = 0;
}
}
else
k--;
}
}
int place(int l) {
int i = 1;
while (i < l) {
if ((x[i] == x[l]) || abs(x[i] - x[l]) == abs(i - l))
return 0;
i += 1;
}
return 1;
}
int XYGraphic(int p) {
switch (p) {
case 1:
return 65;
case 2:
return 115;
case 3:
return 165;
case 4:
return 215;
case 5:
return 265;
case 6:
return 315;
case 7:
return 365;
case 8:
return 415;
}
return 0;
}
void drawCounter(SDL_Renderer* renderer, int x3, int y3, int c) {
SDL_Rect rect = { 60, 4, 50, 20 };
SDL_RenderDrawRect(renderer, &rect);
char text[10];
sprintf(text, "[%d]", c);
SDL_Surface* surface = TTF_RenderText_Solid(font, text, textColor);
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_RenderCopy(renderer, texture, NULL, &rect);
SDL_FreeSurface(surface);
SDL_DestroyTexture(texture);
SDL_Rect textRect = { 59, 6 + x3, 50, 20 };
sprintf(text, "(%c,%d)", 96 + x3, y3);
surface = TTF_RenderText_Solid(font, text, textColor);
texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_RenderCopy(renderer, texture, NULL, &textRect);
SDL_FreeSurface(surface);
SDL_DestroyTexture(texture);
}
void drawQueen(SDL_Renderer* renderer, int x1, int y1) {
for (int i = 0; i <= 15; i++) {
SDL_SetRenderDrawColor(renderer, i, i, i, 255);
SDL_RenderDrawPoint(renderer, x1 + i, y1);
SDL_RenderDrawPoint(renderer, x1, y1 + i);
}
}
void drawBoard(SDL_Renderer* renderer) {
for (int j = 0; j < 8; j++) {
for (int i = 0; i < 8; i++) {
SDL_Rect rect = { i * SQUARE_SIZE, j * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE };
if ((i + j) % 2 == 0) {
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); // White
}
else {
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // Black
}
SDL_RenderFillRect(renderer, &rect);
}
}
SDL_RenderPresent(renderer);
}