Package: qqwing
Version: 1.3.4-1.1+b1
Severity: important
Tags: patch
X-Debbugs-Cc: krzpyrk...@gmail.com

Dear Maintainer,

Current version of qqwing uses srand(time(0)) and rand() as a way to
generate the board. It makes running multiple instances of the program
in parallel for faster sudoku generation impossible, because all are
started in the same second, generating exactly the same sequence of
numbers, and as a result, sequence of boards.

The solution is to replace the randomness based on time with one based on
a truly random seed, and rand() with a random generator that does not
rely on a global state like srand.

My patch makes use of several C++11 features such as std::random_device,
std::uniform_int_distribution and std::shuffle that are state of the art
solutions to the aforementioned issue.
diff --git a/main.cpp b/main.cpp
index 13a4355..ae1def7 100644
--- a/main.cpp
+++ b/main.cpp
@@ -200,9 +200,6 @@ int main(int argc, char *argv[]){
                        return 1;
                }
 
-               // Initialize the random number generator
-               srand ( unsigned ( time(0) ) );
-
                // If printing out CSV, print a header
                if (printStyle == SudokuBoard::CSV){
                        if (printPuzzle) cout << "Puzzle,";
diff --git a/qqwing.cpp b/qqwing.cpp
index ed18ff0..a923398 100644
--- a/qqwing.cpp
+++ b/qqwing.cpp
@@ -23,6 +23,7 @@
 
 #include <cstdlib>
 #include <iostream>
+#include <algorithm>
 
 #include "qqwing.hpp"
 
@@ -109,6 +110,7 @@ namespace qqwing {
         * Create a new Sudoku board
         */
        SudokuBoard::SudokuBoard() :
+               rand_generator(random_device{}()),
                puzzle ( new int[BOARD_SIZE] ),
                solution ( new int[BOARD_SIZE] ),
                solutionRound ( new int[BOARD_SIZE] ),
@@ -1528,18 +1530,13 @@ namespace qqwing {
        /**
         * Shuffle the values in an array of integers.
         */
-       void shuffleArray(int* array, int size){
-               {for (int i=0; i<size; i++){
-                       int tailSize = size-i;
-                       int randTailPos = rand()%tailSize+i;
-                       int temp = array[i];
-                       array[i] = array[randTailPos];
-                       array[randTailPos] = temp;
-               }}
+       void SudokuBoard::shuffleArray(int* array, int size){
+               std::shuffle(array, array + size, rand_generator);
        }
 
-       SudokuBoard::Symmetry getRandomSymmetry(){
-               switch (rand()%4){
+       SudokuBoard::Symmetry SudokuBoard::getRandomSymmetry(){
+               std::uniform_int_distribution<int> dist(0, 3);
+               switch (dist(rand_generator)){
                        case 0: return SudokuBoard::ROTATE90;
                        case 1: return SudokuBoard::ROTATE180;
                        case 2: return SudokuBoard::MIRROR;
diff --git a/qqwing.hpp b/qqwing.hpp
index 54a7872..9a9c752 100644
--- a/qqwing.hpp
+++ b/qqwing.hpp
@@ -24,6 +24,7 @@
 
        #include <string>
        #include <vector>
+       #include <random>
 
        namespace qqwing {
 
@@ -120,6 +121,13 @@
                                ~SudokuBoard();
 
                        private:
+                               /**
+                                * Random number generator seeded with true 
randomness
+                                * in the constructor. Replacement for 
srand(time(0)).
+                                * Now, multiple instances of the program 
running
+                                * in parallel generate different boards.
+                                */
+                               std::mt19937 rand_generator;
                                /**
                                 * The 81 integers that make up a sudoku puzzle.
                                 * Givens are 1-9, unknowns are 0.
@@ -230,6 +238,8 @@
                                bool arePossibilitiesSame(int position1, int 
position2);
                                void addHistoryItem(LogItem* l);
                                void shuffleRandomArrays();
+                               void shuffleArray(int* array, int size);
+                               SudokuBoard::Symmetry getRandomSymmetry();
                                void print(int* sudoku);
                                void rollbackNonGuesses();
                                void clearPuzzle();

Reply via email to