Advertisement
Guest User

Untitled

a guest
Feb 18th, 2011
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.40 KB | None | 0 0
  1.  
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5.  
  6. //trackers
  7. int solutions[92][64];
  8. int found_sltns = 0;
  9.  
  10. //data structure to store args for the find_queen fn
  11. struct queens_arg {
  12. int board[64];
  13. int focus_idx;
  14. };
  15.  
  16. /*
  17. * Counts the number of queens that exists on a board
  18. */
  19. int no_of_queens(int board[64]) {
  20. int idx;
  21. int total = 0;
  22. for (idx = 0;idx < 64;idx++) {
  23. if (board[idx] == 1) total++;
  24. }
  25. return total;
  26. }
  27.  
  28. /*
  29. * Counts the number of queens in a row
  30. */
  31. int on_row(int board[64], int x, int y) {
  32. int count = 0;
  33. int i;
  34. for (i = (y * 8); i < ((y * 8)+8) ;i++) {
  35. if (board[i] == 1)
  36. count++;
  37. }
  38. return count;
  39. }
  40.  
  41. /*
  42. * Counts the number of queens in a column
  43. */
  44. int on_col(int board[64], int x, int y) {
  45. int count = 0;
  46. int i;
  47. for (i = x; i < 64 ;i=i+8) {
  48. if (board[i] == 1)
  49. count++;
  50. }
  51. return count;
  52. }
  53.  
  54. /*
  55. * Counts the number of queens in diagonals that run both ways.
  56. */
  57. int on_diagonal(int board[64], int x, int y) {
  58. int count = 1;
  59. int idx = coord_to_idx(x,y);
  60. int i;
  61.  
  62. //northwest direction
  63. if ((y > 0) && (x > 0))
  64. for (i = idx - 9; (i >= 0) && (i <= 64) ; i = i - 9) {
  65. if ((board[i] == 1) && (i != idx))
  66. count++;
  67. if (on_edge(i))
  68. break;
  69. }
  70. //northeast direction
  71. if ((y < 7) && (x > 0))
  72. for (i = idx - 7; (i >= 0) && (i <= 64) ;i = i - 7) {
  73. if ((board[i] == 1) && (i != idx))
  74. count++;
  75. if (on_edge(i))
  76. break;
  77. }
  78. //southwest direction
  79. if ((y > 0) && (x < 7))
  80. for (i = idx + 7; (i >= 0) && (i <= 64) ;i = i + 7) {
  81. if ((board[i] == 1) && (i != idx))
  82. count++;
  83. if (on_edge(i))
  84. break;
  85. }
  86. //southeast direction
  87. if ((y < 7) && (x < 7))
  88. for (i = idx + 9; (i >= 0) && (i <= 64) ;i = i + 9) {
  89. if ((board[i] == 1) && (i != idx))
  90. count++;
  91. if (on_edge(i))
  92. break;
  93. }
  94.  
  95. return count;
  96. }
  97.  
  98. /*
  99. * Converts a coordinate to an array index. For example (1,1) refers to index 9.
  100. */
  101. int coord_to_idx(int x, int y) {
  102. return (y*8)+x;
  103. }
  104.  
  105. /*
  106. * Checks if an index positioning lies on the edge of the board
  107. */
  108. int on_edge(int idx) {
  109. int x = idx % 8;
  110. int y = idx / 8;
  111. if ((x == 0) || (x == 7) || (y == 0) || (y == 7))
  112. return 1;
  113. return 0;
  114. }
  115.  
  116. /*
  117. * Checks if all the existing queens (irregardless if it has < 9 or not) are in a good position that prevents them from attacking each other.
  118. * If so, returns false (0), else return true.
  119. */
  120. int good_board(int board[64]) {
  121. int i;
  122. for (i = 0;i<64;i++)
  123. if (board[i] == 1) {
  124. int x = i % 8;
  125. int y = i / 8;
  126. if ((on_row(board,x,y) != 1) || (on_col(board,x,y) != 1) || (on_diagonal(board, x, y) != 1))
  127. return 0;
  128. }
  129. return 1;
  130. }
  131.  
  132. /*
  133. * Adds a board to the solution array
  134. */
  135. void add_solution(int board[64]) {
  136. int i;
  137. //check if sltn already exist
  138. for (i = 0;i<92;i++) {
  139. if (solutions[i] == board) return;
  140. }
  141. #pragma omp critical
  142. for (i = 0;i<64;i++) {
  143. solutions[found_sltns][i] = board[i];
  144. }
  145. found_sltns++;
  146. #pragma end critical
  147. }
  148.  
  149. /*
  150. * Prints a board
  151. */
  152. void print_board(int board[64]) {
  153. printf("\n");
  154. int i;
  155. for (i = 0;i<64;i++) {
  156. if (i % 8 == 0) printf("\n");
  157. printf("%d ", board[i]);
  158. }
  159. printf("\n");
  160. }
  161.  
  162. /*
  163. * Copies an array from one to another.
  164. */
  165. void copy_array(int from[64], int to[64]) {
  166. int i;
  167. for (i = 0; i<64;i++) {
  168. if (from[i]) to[i] = 1;
  169. else to[i] = 0;
  170. }
  171. }
  172.  
  173. /*
  174. * Recursive function using backtracking algorithm to find all possible solutions. Solutions are saved with add_solution() method.
  175. */
  176. void *find_queens(void *args) {
  177.  
  178. //vars
  179. struct queens_arg *data = (struct queens_arg *) args;
  180. int board[64];
  181. copy_array(data->board, board);
  182. int focus_idx = data -> focus_idx;
  183.  
  184. //backtracking base cases
  185. if (found_sltns == 92) return;
  186. if (focus_idx == 64) return;
  187. if (!good_board(board)) return;
  188.  
  189. if (no_of_queens(board) == 8) {
  190. //found solution
  191. add_solution(board);
  192. return;
  193. }
  194.  
  195. //begin the recursion
  196. if (no_of_queens(board) < 8) {
  197. //spawn 2 new boards for recursion
  198. int new_board1[64];
  199. int new_board2[64];
  200. int i;
  201. copy_array(board,new_board1);
  202. copy_array(board,new_board2);
  203. //add a queen one of them
  204. new_board1[focus_idx] = 1;
  205.  
  206. //construct the args
  207. struct queens_arg *args1 = malloc(sizeof (struct queens_arg));
  208. struct queens_arg *args2 = malloc(sizeof (struct queens_arg));
  209. (*args1).focus_idx = focus_idx+1;
  210. (*args2).focus_idx = focus_idx+1;
  211. copy_array(new_board1, args1->board);
  212. copy_array(new_board2, args2->board);
  213.  
  214. #pragma omp task
  215. (*find_queens)(args1);
  216. #pragma omp task
  217. (*find_queens)(args2);
  218. #pragma omp taskwait
  219. free(args1);
  220. free(args2);
  221. }
  222. }
  223.  
  224. main() {
  225.  
  226. //build the board
  227. int board[64] = {
  228. 0,0,0,0,0,0,0,0,
  229. 0,0,0,0,0,0,0,0,
  230. 0,0,0,0,0,0,0,0,
  231. 0,0,0,0,0,0,0,0,
  232. 0,0,0,0,0,0,0,0,
  233. 0,0,0,0,0,0,0,0,
  234. 0,0,0,0,0,0,0,0,
  235. 0,0,0,0,0,0,0,0,
  236. };
  237.  
  238. //begin recursion
  239. struct queens_arg *args = malloc(sizeof (struct queens_arg));
  240. args->focus_idx = 0;
  241. copy_array(board,args->board);
  242. #pragma omp task
  243. (*find_queens)(args);
  244.  
  245. //prints all possible solutions
  246. int i;
  247. for (i = 0;i<found_sltns;i++) {
  248. //print_board(solutions[i]);
  249. }
  250.  
  251. //say goodbye :)
  252. return 0;
  253. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement