Stefanauss

The Knight Round in C

Jul 31st, 2012
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.96 KB | None | 0 0
  1. /* Deitel & Deitel: C - How To Program.                     *
  2.  * Italian, 2000 Edition.                                       *
  3.  * Exercise 6.24c - "Knight's Tour"                         *
  4.  * http://it.wikipedia.org/wiki/Percorso_del_cavallo        *
  5.  */
  6.  
  7. #include <stdio.h>
  8.  
  9. /* PROTOTIPI DI FUNZIONE */
  10. void promptStartPosition();
  11. int legalMovesThisRound();
  12. int stayOnBoard(int, int, int);
  13. int isUnvisited(int, int, int);
  14. void printBoard();
  15. int selectBestMove();
  16. int getAccessibility(int, int, int);
  17. void setAccessibility(int, int);
  18. void printAccessibility();
  19.  
  20. /* VARIABILI GLOBALI */
  21. int board[8][8] = {0};
  22. int horizontal[8] = {2, 1, -1, -2, -2, -1, 1, 2};
  23. int vertical[8] = {-1, -2, -2, -1, 1, 2, 2, 1};
  24. int counter = 1;
  25. int currentRow, currentColumn;
  26. int legalMoves[8] = {-1};
  27. /* Index for legalMoves[] */
  28. /* Can have value = 8, so watch out for -1 or +1 errors. */
  29. int legalMovesAvalaible = 0;
  30. int moveNumber = 0;
  31. /* Accessibility Heuristic: for each square, the number stands for the amount   *
  32.  * of other squares it can be reached from. */
  33. int accessibility[8][8] = { {2, 3, 4, 4, 4, 4, 3, 2},
  34.                 {3, 4, 6, 6, 6, 6, 4, 3},
  35.                 {4, 6, 8, 8, 8, 8, 6, 4},
  36.                 {4, 6, 8, 8, 8, 8, 6, 4},
  37.                 {4, 6, 8, 8, 8, 8, 6, 4},
  38.                 {4, 6, 8, 8, 8, 8, 6, 4},
  39.                 {3, 4, 6, 6, 6, 6, 4, 3},
  40.                 {2, 3, 4, 4, 4, 4, 3, 2} };
  41.  
  42. int main(void) {
  43.  
  44.     promptStartPosition();
  45.     board[currentRow][currentColumn] = 0;
  46.    
  47.     while (legalMovesThisRound()) {
  48.        
  49.         /* Randomly select the move to execute among those that are legal. */
  50.         moveNumber = selectBestMove();
  51.         /* Executing move. */
  52.         currentRow += vertical[moveNumber];
  53.         currentColumn += horizontal[moveNumber];
  54.         board[currentRow][currentColumn] = counter++;
  55.         /* Setting new accessibility value for the squares accessible from the  *
  56.          * newly reached square. */
  57.         setAccessibility(currentRow, currentColumn);
  58.  
  59.     }
  60.    
  61.     printBoard();
  62.    
  63. }
  64.  
  65. /* Ask the user for where to start the Knight Round. */
  66. /* Input NOT sanitized. */
  67. void promptStartPosition() {
  68.    
  69.     printf("\nInsert the row number from which you wish the knight to start its round: ");
  70.     scanf("%d", &currentRow);
  71.     printf("\nInsert the column number from which you wish the knight to start its round: ");
  72.     scanf("%d", &currentColumn);
  73.    
  74. }
  75.  
  76. /* Fill an array with the IDs of the legal moves for the current position.      *
  77.  * The array has been initialized with -1, which is the sentinel value.             *
  78.  * This array needs to be re-initialized before making the next move.               */
  79. int legalMovesThisRound() {
  80.    
  81.     int move;
  82.     legalMoves[0] = -1;
  83.     legalMoves[1] = -1;
  84.     legalMoves[2] = -1;
  85.     legalMoves[3] = -1;
  86.     legalMoves[4] = -1;
  87.     legalMoves[5] = -1;
  88.     legalMoves[6] = -1;
  89.     legalMoves[7] = -1;
  90.    
  91.     for (legalMovesAvalaible = 0, move = 0; move < 8; move++) {
  92.        
  93.         if (stayOnBoard(currentRow, currentColumn, move)
  94.             && isUnvisited(currentRow, currentColumn, move))
  95.             legalMoves[legalMovesAvalaible++] = move;
  96.        
  97.     }
  98.    
  99.     if (legalMovesAvalaible > 0)
  100.         return 1;
  101.     else
  102.         return 0;
  103.    
  104. }
  105.  
  106. /* Check if the move is forbidden. */
  107. int stayOnBoard(int cR, int cC, int m) {
  108.    
  109.     if (cR + vertical[m] >= 0 && cR + vertical[m] < 8
  110.         &&  cC + horizontal[m] >= 0 && cC +  horizontal[m] < 8)
  111.         return 1;
  112.     else
  113.         return 0;
  114.    
  115. }
  116.  
  117. /* Check if the knight has already been on the landing square. */
  118. int isUnvisited(int cR, int cC, int m) {
  119.    
  120.     if (board[cR + vertical[m]][cC + horizontal[m]] == 0)
  121.         return 1;
  122.     else
  123.         return 0;
  124.    
  125. }
  126.  
  127. /* Print the current round on standard output. */
  128. void printBoard() {
  129.    
  130.     int i, j;
  131.    
  132.     printf("\nCURRENT POSITION [%d][%d]", currentRow, currentColumn);
  133.     printf("\n=============== BOARD =================");
  134.     for (i = 0; i < 8; i++) {
  135.         printf("\n");
  136.         for (j = 0; j < 8; j++) {
  137.             printf("%4d", board[i][j]);
  138.         }
  139.     }
  140.     printf("\n=============== BOARD =================\n");
  141.    
  142. }
  143.  
  144. /* Among the legal moves, select the one with the highest accessibility. */
  145. int selectBestMove() {
  146.    
  147.     /* None initially set. It will be, because any accessibility will be better *
  148.      * than the initialized value 0. */
  149.     int bestMove = -1;
  150.     int worstAccessibility = 8;
  151.     int i;
  152.    
  153.     for (i = 0; i < legalMovesAvalaible; i++) {
  154.         if (getAccessibility(currentRow, currentColumn, legalMoves[i]) <= worstAccessibility) {
  155.             bestMove = legalMoves[i];
  156.             worstAccessibility = getAccessibility(currentRow, currentColumn, legalMoves[i]);
  157.         }
  158.     }
  159.    
  160.     return bestMove;
  161.    
  162. }
  163.  
  164. /* Retrieves the accessibility of the possible landing square. */
  165. int getAccessibility(int cR, int cC, int m) {
  166.    
  167.     return accessibility[cR + vertical[m]][cC + horizontal[m]];
  168.    
  169. }
  170.  
  171. void setAccessibility(int cR, int cC) {
  172.    
  173.     int move;
  174.    
  175.     for (move = 0; move < 8; move++)
  176.         if (stayOnBoard(cR, cC, move))
  177.             --accessibility[cR + vertical[move]][cC + horizontal[move]];
  178.        
  179. }
  180.  
  181. void printAccessibility() {
  182.    
  183.     int i, j;
  184.    
  185.     printf("\n============ ACCESSIBILITY =============");
  186.     for (i = 0; i < 8; i++) {
  187.         printf("\n");
  188.         for (j = 0; j < 8; j++) {
  189.             printf("%4d", accessibility[i][j]);
  190.         }
  191.     }
  192.     printf("\n============ ACCESSIBILITY =============");
  193.    
  194. }
Advertisement
Add Comment
Please, Sign In to add comment