From 99e99d9233629e8b5ebbf24d0cb6893a5caeab05 Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Sun, 24 Sep 2023 18:17:51 -0500 Subject: [PATCH] Added creation of random initial board and queen threat checking --- src/chess.cpp | 90 +++++++++++++++++++++++++++++++++++++++ src/chess.hpp | 34 +++++++++++++++ src/genetic_algorithm.cpp | 3 -- src/genetic_algorithm.hpp | 2 +- src/n_queens.cpp | 5 +++ 5 files changed, 130 insertions(+), 4 deletions(-) diff --git a/src/chess.cpp b/src/chess.cpp index e69de29..1ae5e59 100644 --- a/src/chess.cpp +++ b/src/chess.cpp @@ -0,0 +1,90 @@ +#include "chess.hpp" +#include +#include + +std::default_random_engine generator; + +void InitializeGenerator(void) { + generator.seed(std::random_device{}()); +} + +int GenerateRandomNumber(int generationLimit) { + int generatedNumber; + std::uniform_int_distribution<> distribution(0, generationLimit - 1); + generatedNumber = distribution(generator); + return generatedNumber; +} + +GeneticDefaults::GeneticDefaults(void) { + size = 8; + length = 8; +} + +GeneticDefaults::GeneticDefaults(unsigned int size, unsigned int length) { + this->size = size; + this->length = length; +} + +GeneticChess::GeneticChess(void) { + generationCount = 0; + InitializeGenerator(); + // population init part of vector resize + board.resize(genetics.size, 0); + for (int i = 0; i < board.size(); ++i) { + board.at(i) = GenerateRandomNumber(genetics.size); + } +} + + +void GeneticChess::Print(void) { + std::cout << generationCount << ':' << std::endl; + for (int i : board) { + std::cout << '['; + for (int j = 0; j < genetics.size; ++j) { + if (j == i) { std::cout << "Q"; } + else { std::cout << ' '; } + } + std::cout << ']'; + std::cout << std::endl; + } +} + +// Gets the fitness of the population +unsigned int GeneticChess::GetFitness(void) { + int fitness = 0; + for (int i : board) { + if (!IsQueenThreatened(i)) { fitness++; } + } + return fitness; +} + +// +void GeneticChess::Selection(void) { + +} + +// Crossover on the population +void GeneticChess::Crossover(void) { + +} + +// Mutates the population +void GeneticChess::Mutation(void) { + +} + +// Checks if the passed in queen is threatened on the board +// Impossible for queens to be threatened by same row +bool GeneticChess::IsQueenThreatened(const unsigned int queenRow) { + int queenCol = board.at(queenRow); + int diffRow, diffCol; + for (int i = 0; i < genetics.size; ++i) { + if (i == queenRow) { continue; } + diffCol = queenCol - board.at(i); + diffRow = queenRow - i; + if (diffCol == 0) { return true; } // Column threat + if (diffCol == diffRow) { return true; } + } + return false; +} + diff --git a/src/chess.hpp b/src/chess.hpp index e69de29..bebbaa9 100644 --- a/src/chess.hpp +++ b/src/chess.hpp @@ -0,0 +1,34 @@ +#ifndef CHESS_HPP +#define CHESS_HPP + +#include + +void InitializeGenerator(void); +int GenerateRandomNumber(int generationLimit); + +struct GeneticDefaults { + const float kProbabilityCrossover = 0.7; //crossover probability (typical val.) + const float kProbabilityMutation = 0.001; //mutation probability (typical val.) + const unsigned int generationLimit = 10000; //number of generations (something huge) + unsigned int size; //population size (change to something even) + unsigned int length; //string length (don't change) + GeneticDefaults(void); + GeneticDefaults(unsigned int size, unsigned int length); //custom generation sizes +}; + +class GeneticChess { +public: + std::vector board; + GeneticDefaults genetics; + int generationCount; + GeneticChess(void); + void Print(void); + unsigned int GetFitness(void); + void Selection(void); + void Crossover(void); + void Mutation(void); +private: + bool IsQueenThreatened(const unsigned int queenRow); +}; + +#endif // CHESS_HPP diff --git a/src/genetic_algorithm.cpp b/src/genetic_algorithm.cpp index 7c95315..e15ca20 100644 --- a/src/genetic_algorithm.cpp +++ b/src/genetic_algorithm.cpp @@ -49,7 +49,6 @@ void init_population(unsigned char* population){ } } - /* Perform selection of population members based on fitness */ void do_selection(unsigned char* population, int* selected){ int fitness[N] = {0}; @@ -81,7 +80,6 @@ void do_selection(unsigned char* population, int* selected){ } } - /* compute a mask to use when crossing over parents*/ unsigned char get_mask(int locus_in){ int i = 0; @@ -130,7 +128,6 @@ void do_crossover(unsigned char* population, int* selected){ } } - void do_mutation(unsigned char* population){ double mutation_roll; int i, j; diff --git a/src/genetic_algorithm.hpp b/src/genetic_algorithm.hpp index fec9132..883b1f2 100644 --- a/src/genetic_algorithm.hpp +++ b/src/genetic_algorithm.hpp @@ -5,7 +5,7 @@ #define P_m 0.001 //mutation probability (typical val.) #define N 8 //population size (change to something even) #define L 8 //string length (don't change) -#define G 10000 //number of generations (something huge) +#define G 10000 //number of generations (something huge) void print_population(unsigned char population_in[]); int get_fitness(unsigned char string_in); diff --git a/src/n_queens.cpp b/src/n_queens.cpp index 8b0fab1..a74930e 100644 --- a/src/n_queens.cpp +++ b/src/n_queens.cpp @@ -5,6 +5,10 @@ #include int main(){ + GeneticChess population; + population.Print(); + + /* unsigned char population[N] = {0}; int selected[N] = {-1}; int generation_count = 0; @@ -30,6 +34,7 @@ int main(){ } generation_count++; } + */ return 0; }