Following is my implementation of a 8-Queen Problem Solver using Genetic Algorithm. The program is written in C.
The program can be used as an N-Queen Solver by changing the number of queens in the parameters.
The parameters of the genetic algorithm can also be changed by tweaking the parameters.

/**
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
/**
 * Author: Pratanu Mandal
 * Date:   24-11-2017
 * Desc:   N-Queens problem using genetic algorithm
 *
 * Copyright © Pratanu Mandal, 2017
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>


/** parameters */
#define NQUEENS      8   // no. of queens
#define POP        100   // count of population
#define M_RATE      10   // mutation rate
#define LIMIT       -1   // limit - maximum no. of iterations, -1 = infinity

#define SHOW_GEN     0   // show generations 0 = FALSE, 1 = TRUE


/** global variables */
int ** genX;     // generation X
int ** genY;     // generation Y or X+1
float * fitness; // fitness values for generation X

void display();
void calcFitness();


/**
 * method to initialize variables
 */
void init()
{
    // initialize random seed
    srand(time(NULL));

    // initialize generations
    genX = (int **) malloc(sizeof(int *) * POP);
    genY = (int **) malloc(sizeof(int *) * POP);

    // randomly generate initial population
    for (int i = 0; i < POP; i++) {
        genX[i] = (int *) malloc(sizeof(int) * NQUEENS);
        genY[i] = (int *) malloc(sizeof(int) * NQUEENS);

        for (int j = 0; j < NQUEENS; j++) {
            int flag, val;
            do {
                flag = 0;
                val = rand() % NQUEENS;
                for (int k = 0; k < j; k++) {
                    if (val == genX[i][k]) {
                        flag = 1;
                        break;
                    }
                }
            } while(flag);
            genX[i][j] = val;
        }
    }

    // initialize fitness array
    fitness = (float *) malloc(sizeof(float) * POP);
}


/**
 * method to calculate the fitness of population of generation X
 */
void calcFitness()
{
    for (int i = 0; i < POP; i++) {

        int clash = 0;

        // check horizontally
        for (int j = 0; j < NQUEENS; j++) {
            for (int k = j+1; k < NQUEENS; k++) {
                if (genX[i][j] == genX[i][k]) {
                    clash++;
                }
            }
        }

        // check diagonally
        for (int j = 0; j < NQUEENS; j++) {
            for (int k = 0; k < NQUEENS; k++) {
                if (j != k) {
                    int dx = abs(j - k);
                    int dy = abs(genX[i][j] - genX[i][k]);
                    if (dx == dy)
                        clash++;
                }
            }
        }

        // if goal, fitness is 1.0
        fitness[i] = 1.0f / (1.0f + clash);
    }
}


/**
 * method to select one parent
 */
int selectParent()
{
    // using tournament selection - much faster, and suitable for floating values
    int sz = (int)(POP * 0.2), c;

    int candidate[sz];

    for (int i = 0; i < sz; i++) {
        int flag = 0;
        do {
            c = rand() % POP;
            flag = 0;
            for (int j = 0; j < i; j++) {
                if (candidate[j] == c) {
                    flag = 1;
                    break;
                }
            }
        } while (flag);

        candidate[i] = c;
    }

    int index = 0;

    for (int i = 1; i < sz; i++) {
        if (fitness[candidate[i]] > fitness[candidate[index]]) {
            index = i;
        }
    }

    return index;
}


/**
 * method to perform crossover on generation X
 */
void crossover()
{
    for (int i = 0; i < POP; i++) {
        int p1 = selectParent();
        int p2 = selectParent();

        if (p1 == p2) {     // single parent
            memcpy(genY[i], genX[p1], sizeof(int) * NQUEENS);
        }
        else {  // crossover
            // take a gene from either parent based on a 50% chance
            // once a gene is taken, it cannot be repeated
            for (int j = 0; j < NQUEENS; j++) {
                int px;
                if (rand() % 2) px = p1;
                else px = p2;

                int k;
                for (k = 0; k < NQUEENS; k++) {
                    int flag = 0;
                    for (int m = 0; m < j; m++) {
                        if (genX[px][k] == genY[i][m]) {
                            flag = 1;
                            break;
                        }
                    }
                    if (!flag) break;
                }

                if (k == NQUEENS) {
                    // we have exhausted parent px
                    j--;
                    continue;
                }

                genY[i][j] = genX[px][k];
            }
        }
    }

    // swap generations
    int ** temp = genX;
    genX = genY;
    genY = temp;
}


/**
 * perform mutation on generation Y (now stored in generation X)
 */
void mutation()
{
    // using swapping mutation
    for (int i = 0; i < POP; i++) {
        int r = rand() % 100;

        if (r <= M_RATE) {
            int j = rand() % NQUEENS;
            int k;
            do {
                k = rand() % NQUEENS;
            } while (j == k);

            int temp = genX[i][j];
            genX[i][j] = genX[i][k];
            genX[i][k] = temp;
        }
    }
}


/**
 * method to free all variables
 */
void destroy()
{
    for (int i = 0; i < POP; i++) {
        free(genX[i]);
        free(genY[i]);
    }

    free(genX);
    free(genY);
}


/**
 * utility method to display the population of a generation X
 */
void display()
{
    for (int i = 0; i < POP; i++) {
        for (int j = 0; j < NQUEENS; j++) {
            printf(" %d ", genX[i][j]);
        }
        printf("| %f %d\n", fitness[i], i);
    }
}


/**
 * utility method to display the solution
 */
void displayQueens(int index)
{
    for (int i = 0; i < NQUEENS; i++) {
        for (int j = 0; j < NQUEENS; j++) {
            if (genX[index][i] == j)
                printf(" Q ");
            else
                printf(" . ");
        }
        printf("\n\n");
    }
}


/**
 * method implementing the genetic algorithm
 *
 * limit: the maximum no. of generations to be searched for a solution
 *        if set to -1, the limit is infinity
 *
 * found (return): -1 if not found, non-negative int otherwise
 */
int geneticAlgorithm(int limit)
{
    int found = -1;

    for (int i = 0; limit == -1 || i <= limit; i++) {
        // calculate fitness of generation X
        calcFitness();

        if (SHOW_GEN) {
            printf("[Generation %d]\n", i);
            display();
            printf("\n\n");
        }

        // find the fittest candidate of generation i
        int index = 0;  // assuming that fitness[0] contains largest value
        for (int j = 1; j < POP; j++) {
            if (fitness[j] > fitness[index])
                index = j;
        }

        // if fittest candidate has reached desired fitness, terminate
        if (fitness[index] == 1.0f) {
            found = index;
            break;
        }

        crossover();    // perform crossover
        mutation();     // perform mutation
    }

    return found;
}


/**
 * method that is to be used as an entry-point
 * initializes, executes GA, displays results, and cleans up
 */
void run()
{
    init();

    int found = geneticAlgorithm(LIMIT);

    if (found == -1) {
        printf("\nSolution not found\n");
    }
    else {
        printf("\nSolution: ");
        for (int i = 0; i < NQUEENS; i++) {
            printf("%d ", genX[found][i]);
        }
        printf("\n\n\n");

        displayQueens(found);
    }

    destroy();
}


/**
 * main - entry point to program
 * dispatch execution to other methods
 */
int main()
{
    run();

    printf("\n\nPress [ENTER] to continue ...");
    getchar();

    return 0;
}

The following video explains the process used in the program very well.