C Program to demonstrate 8Queen with simple graphics

C Program to Show 8Queen

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:

  1. Initialization: The program initializes the SDL graphics library and TTF (TrueType Font) for text rendering.
  2. Graphics Setup: It creates a window and renderer for graphics rendering.
  3. 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.
  4. 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.
  5. 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.
  6. Delay and Clear: The program introduces a delay and clears the graphics before proceeding to the next solution.
  7. User Interaction: The user can interact with the program by closing the window or letting the computer explore all possibilities.
  8. 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);
}
M. Saqib: Saqib is Master-level Senior Software Engineer with over 14 years of experience in designing and developing large-scale software and web applications. He has more than eight years experience of leading software development teams. Saqib provides consultancy to develop software systems and web services for Fortune 500 companies. He has hands-on experience in C/C++ Java, JavaScript, PHP and .NET Technologies. Saqib owns and write contents on mycplus.com since 2004.
Related Post