} // Error /// <summary> /// This creates a new random solution and maps that solution onto provided problem /// </summary> /// <param name="problem">int[][]</param> /// <param name="rand">pass in your random object if you got one</param> /// <returns></returns> public static int[][] GetRandomMatrix(int[][] problem, Random rand = null) { Random rnd = rand ?? new Random(); // make a copy of the current puzzle var newRandomMatrix = SudokuTool.DuplicateMatrix(problem); for (var block = 0; block < Constants.BoardSize; ++block) { // fill them with 1 through 9 var corners = SudokuTool.Corner(block); var vals = new List <int>(Constants.BoardSize); for (var i = 1; i <= Constants.BoardSize; ++i) { vals.Add(i); } // shuffle each cell with a value from another cell for (var k = 0; k < vals.Count; ++k) { var ri = rnd.Next(k, vals.Count); var tmp = vals[k]; vals[k] = vals[ri]; vals[ri] = tmp; } // remove the random cell values from the known cell values var r = corners[0]; var c = corners[1]; for (var i = r; i < r + 3; ++i) { for (var j = c; j < c + 3; ++j) { var v = problem[i][j]; if (v != 0) // a fixed starting number is assumed correct { vals.Remove(v); } } } // walk thru block and add the new values to the random solution output var ptr = 0; // pointer into List for (var i = r; i < r + 3; ++i) { for (var j = c; j < c + 3; ++j) { if (newRandomMatrix[i][j] == 0) // not occupied { var v = vals[ptr]; // get value from List newRandomMatrix[i][j] = v; ++ptr; // move to next value in List } } } } // each block, k return(newRandomMatrix); } // RandomMatrix
} // RandomMatrix /// <summary> /// Randomly swap the values in two cells of a random block of the supplied matrix /// </summary> /// <param name="problem">the original puzzle </param> /// <param name="matrix">the current working solution</param> /// <param name="rand">pass in your random object if you got one</param> /// <returns></returns> public static int[][] EvolveMatrixAsync(int[][] problem, int[][] matrix, Random rand = null) { Random rnd = rand ?? new Random(); // pick a random 3x3 block, // pick two random cells in block // swap values var result = SudokuTool.DuplicateMatrix(matrix); var block = rnd.Next(0, 9); // [0,8] //Console.WriteLine("block = " + block); var corners = SudokuTool.Corner(block); //Console.WriteLine("corners = " + corners[0] + " " + corners[1]); // look for at minimum 2 cells in the neighbor matrix that might be useful in the problem var cells = new List <int[]>(); for (var i = corners[0]; i < corners[0] + 3; ++i) { for (var j = corners[1]; j < corners[1] + 3; ++j) { //Console.WriteLine("problem " + i + " " + j + " = " + problem[i][j]); if (problem[i][j] == 0) // a non-fixed value { cells.Add(new[] { i, j }); } } } if (cells.Count < 2) { // _sb.AppendLine($"Found only {cells.Count} useful cell in the neighbor."); throw new Exception("block " + block + " doesn't have two values to swap!"); } // pick two. suppose there are 4 possible cells 0,1,2,3 var k1 = rnd.Next(0, cells.Count); // 0,1,2,3 var inc = rnd.Next(1, cells.Count); // 1,2,3 var k2 = (k1 + inc) % cells.Count; //Console.WriteLine("k1 k2 = " + k1 + " " + k2); var r1 = cells[k1][0]; var c1 = cells[k1][1]; var r2 = cells[k2][0]; var c2 = cells[k2][1]; //Console.WriteLine("r1 c1 = " + r1 + " " + c1); //Console.WriteLine("r2 c2 = " + r2 + " " + c2); var tmp = result[r1][c1]; result[r1][c1] = result[r2][c2]; result[r2][c2] = tmp; return(result); } // NeighborMatrix
} // NeighborMatrix /// <summary> /// for each block (3x3) in matrix2, there's a 50% chance to be added into matrix1 /// </summary> /// <param name="matrix1">mating partner 1</param> /// <param name="matrix2">mating partner 2</param> /// <param name="chance">0.50 or some percential double value</param> /// <param name="rand">pass in your random object if you got one</param> /// <returns>a single matrix with some relationships between both provided</returns> public static int[][] MatingResult(int[][] matrix1, int[][] matrix2, double chance = 0.50, Random rand = null) { Random rnd = rand ?? new Random(); var result = SudokuTool.DuplicateMatrix(matrix1); for (var block = 0; block < 9; ++block) { if (rnd.NextDouble() < chance) { var corners = SudokuTool.Corner(block); for (var i = corners[0]; i < corners[0] + 3; ++i) { for (var j = corners[1]; j < corners[1] + 3; ++j) { result[i][j] = matrix2[i][j]; } } } } return(result);// Task.FromResult(result); }