Advertisement
mixster

mixster

Jul 15th, 2010
462
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.17 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>
  4. #include <time.h>
  5.  
  6. #define PIECE_NP 0
  7. #define PIECE_P1 1
  8. #define PIECE_P2 2
  9. #define PIECE_P3 3
  10. #define PIECE_P4 4
  11. #define PIECE_PB 5
  12. #define PIECE_PR 6
  13. #define PIECE_PK 7
  14. #define PIECE_PQ 8
  15. #define PIECE_PJ 9
  16.  
  17. #define BOARD_WIDTH 6
  18. #define BOARD_HEIGHT 6
  19.  
  20. struct Tile {
  21.   int x;
  22.   int y;
  23.   int piece;
  24.   int valid;
  25.   struct Tile **child;
  26.   int num_child;
  27. };
  28.  
  29. int high_moves = 0;
  30. struct Tile *best_moves;
  31. unsigned long long counter = 0;
  32.  
  33. char piece_to_chr(int piece) {
  34.   switch(piece) {
  35.     case PIECE_NP: return ' ';
  36.     case PIECE_P1: return '1';
  37.     case PIECE_P2: return '2';
  38.     case PIECE_P3: return '3';
  39.     case PIECE_P4: return '4';
  40.     case PIECE_PB: return 'B';
  41.     case PIECE_PR: return 'R';
  42.     case PIECE_PK: return 'K';
  43.     case PIECE_PQ: return 'Q';
  44.     case PIECE_PJ: return 'J';
  45.     default      : return 'E';
  46.   }
  47. }
  48.  
  49. int chr_to_piece(char piece) {
  50.   switch(piece) {
  51.     case '0': return PIECE_NP;
  52.     case '1': return PIECE_P1;
  53.     case '2': return PIECE_P2;
  54.     case '3': return PIECE_P3;
  55.     case '4': return PIECE_P4;
  56.     case 'B': return PIECE_PB;
  57.     case 'R': return PIECE_PR;
  58.     case 'K': return PIECE_PK;
  59.     case 'Q': return PIECE_PQ;
  60.     case 'J': return PIECE_PJ;
  61.     default : return PIECE_NP;
  62.   }
  63. }
  64.  
  65. int tile_valid(int a, int b) {
  66.   return ((b >= 0) && (b < BOARD_HEIGHT) && (a >= 0) && (a < BOARD_WIDTH));
  67. }
  68.  
  69. void append_tile(struct Tile ***board, struct Tile *tile, int x, int y, int a, int b) {
  70.   if (((b != y) || (a != x)) && tile_valid(a, b)) {
  71.     tile->child[tile->num_child] = &((*board)[b][a]);
  72.     tile->num_child++;
  73.   }
  74. }
  75.  
  76. void assign_normal_move(struct Tile ***board, int x, int y) {
  77.   int n = 0;
  78.   int b;
  79.   int a;
  80.   struct Tile *tile = &((*board)[y][x]);
  81.  
  82.   switch (tile->piece) {
  83.     case PIECE_P1: n = 1;
  84.                    break;
  85.     case PIECE_P2: n = 2;
  86.                    break;
  87.     case PIECE_P3: n = 3;
  88.                    break;
  89.     case PIECE_P4: n = 4;
  90.                    break;
  91.   }
  92.  
  93.   tile->num_child = 0;
  94.  
  95.   for (b = y - n; b <= y + n; b += n) {
  96.     for (a = x - n; a <= x + n; a += n) {
  97.       append_tile(board, tile, x, y, a, b);
  98.     }
  99.   }
  100. }
  101.  
  102. void assign_bishop_move(struct Tile ***board, int x, int y) {
  103.   int a = 0;
  104.   int b = 0;
  105.   struct Tile *tile = &((*board)[y][x]);
  106.  
  107.   b = y - x;
  108.   append_tile(board, tile, x, y, a, b);
  109.  
  110.   b = y + x;
  111.   append_tile(board, tile, x, y, a, b);
  112.  
  113.   a = BOARD_WIDTH - 1;
  114.   b = (y + BOARD_WIDTH) - (x + 1);
  115.   append_tile(board, tile, x, y, a, b);
  116.  
  117.   b = (y + x + 1) - BOARD_WIDTH;
  118.   append_tile(board, tile, x, y, a, b);
  119.  
  120.   a = x - y;
  121.   b = 0;
  122.   append_tile(board, tile, x, y, a, b);
  123.  
  124.   a = x + y;
  125.   append_tile(board, tile, x, y, a, b);
  126.  
  127.   a = (x + BOARD_HEIGHT) - (y + 1);
  128.   b = BOARD_HEIGHT - 1;
  129.   append_tile(board, tile, x, y, a, b);
  130.  
  131.   a = (x + y + 1) - BOARD_HEIGHT;
  132.   append_tile(board, tile, x, y, a, b);
  133. }
  134.  
  135. void assign_rook_move(struct Tile ***board, int x, int y) {
  136.   int a;
  137.   int b;
  138.   struct Tile *tile = &((*board)[y][x]);
  139.  
  140.   a = 0;
  141.   b = y;
  142.   append_tile(board, tile, x, y, a, b);
  143.  
  144.   a = BOARD_WIDTH - 1;
  145.   append_tile(board, tile, x, y, a, b);
  146.  
  147.   a = x;
  148.   b = 0;
  149.   append_tile(board, tile, x, y, a, b);
  150.  
  151.   b = BOARD_HEIGHT - 1;
  152.   append_tile(board, tile, x, y, a, b);
  153. }
  154.  
  155. void assign_knight_move(struct Tile ***board, int x, int y) {
  156.   int a;
  157.   int b;
  158.   struct Tile *tile = &((*board)[y][x]);
  159.  
  160.   a = x - 2;
  161.   b = y - 1;
  162.   append_tile(board, tile, x, y, a, b);
  163.  
  164.   b = y + 1;
  165.   append_tile(board, tile, x, y, a, b);
  166.  
  167.   a = x + 2;
  168.   b = y - 1;
  169.   append_tile(board, tile, x, y, a, b);
  170.  
  171.   b = y + 1;
  172.   append_tile(board, tile, x, y, a, b);
  173.  
  174.   a = x - 1;
  175.   b = y - 2;
  176.   append_tile(board, tile, x, y, a, b);
  177.  
  178.   a = x + 1;
  179.   append_tile(board, tile, x, y, a, b);
  180.  
  181.   a = x - 1;
  182.   b = y + 2;
  183.   append_tile(board, tile, x, y, a, b);
  184.  
  185.   a = x + 1;
  186.   append_tile(board, tile, x, y, a, b);
  187. }
  188.  
  189. void assign_queen_move(struct Tile ***board, int x, int y) {
  190.   int a;
  191.   int b;
  192.  
  193.   assign_bishop_move(board, x, y);
  194.   assign_rook_move(board, x, y);
  195. }
  196.  
  197. void assign_joker_move(struct Tile ***board, int x, int y) {
  198.   int a;
  199.   int b;
  200.   struct Tile *tile = &((*board)[y][x]);
  201.  
  202.   tile->num_child = 0;
  203.  
  204.   for (b = 0; b < BOARD_HEIGHT; b++) {
  205.     for (a = 0; a < BOARD_WIDTH; a++) {
  206.       append_tile(board, tile, x, y, a, b);
  207.     }
  208.   }
  209. }
  210.  
  211. void assign_possible_moves(struct Tile ***board, int x, int y) {
  212.   struct Tile *tile = &((*board)[y][x]);
  213.  
  214.   switch (tile->piece) {
  215.     case PIECE_P1:
  216.     case PIECE_P2:
  217.     case PIECE_P3:
  218.     case PIECE_P4: assign_normal_move(board, x, y);
  219.                    break;
  220.     case PIECE_PB: assign_bishop_move(board, x, y);
  221.                    break;
  222.     case PIECE_PR: assign_rook_move(board, x, y);
  223.                    break;
  224.     case PIECE_PK: assign_knight_move(board, x, y);
  225.                    break;
  226.     case PIECE_PQ: assign_queen_move(board, x, y);
  227.                    break;
  228.     case PIECE_PJ: assign_joker_move(board, x, y);
  229.                    break;
  230.     default      : printf("Unknown piece\n");
  231.   }
  232. }
  233.  
  234. void print_board(struct Tile **board) {
  235.   int x;
  236.   int y;
  237.  
  238.   printf("   |");
  239.   for (x = 0; x < BOARD_WIDTH; x++) {
  240.     printf(" %d |", x);
  241.   }
  242.   printf("\n---");
  243.   for (x = 0; x < BOARD_WIDTH; x++) {
  244.     printf("+---");
  245.   }
  246.   printf("+\n");
  247.  
  248.   for (y = 0; y < BOARD_HEIGHT; y++) {
  249.     printf(" %d |", y);
  250.     for (x = 0; x < BOARD_WIDTH; x++) {
  251.       printf(" %c |", piece_to_chr(board[y][x].piece));
  252.     }
  253.     printf("\n---");
  254.     for (x = 0; x < BOARD_WIDTH; x++) {
  255.       printf("+---");
  256.     }
  257.     printf("+\n");
  258.   }
  259. }
  260.  
  261. void parse_board(struct Tile ***board) {
  262.   char inp [BOARD_WIDTH];
  263.   int x;
  264.   int y;
  265.  
  266.   for (y = 0; y < BOARD_HEIGHT; y++) {
  267.     scanf("%s", inp);
  268.     for (x = 0; x < BOARD_WIDTH; x++) {
  269.       (*board)[y][x].piece = chr_to_piece(inp[x]);
  270.       assign_possible_moves(board, x, y);
  271.     }
  272.   }
  273. }
  274.  
  275. int get_move(struct Tile ***board, int x, int y, int depth, struct Tile *res[BOARD_HEIGHT * BOARD_WIDTH]) {
  276.   int m;
  277.   res[depth] = &((*board)[y][x]);
  278.   counter += 1;
  279.  
  280.   if (depth > high_moves) {
  281.     high_moves = depth;
  282.     for (m = 0; m <= depth; m++) {
  283.       best_moves[m] = *(res[m]);
  284.     }
  285.  
  286.     //printf("Best now %d moves\n", (depth + 1));
  287.   }
  288.  
  289.   if ((depth + 1) == (BOARD_HEIGHT * BOARD_WIDTH)) {
  290.     return 1; // Should be 1
  291.   }
  292.  
  293.   for (m = 0; m < (*board)[y][x].num_child; m++) {
  294.     if ((*board)[y][x].child[m]->valid) {
  295.       (*board)[y][x].child[m]->valid = 0;
  296.       if (get_move(board, (*board)[y][x].child[m]->x, (*board)[y][x].child[m]->y, depth + 1, res)) {
  297.         return 1;
  298.       }
  299.       res[depth]->child[m]->valid = 1;
  300.     }
  301.   }
  302.   return 0;
  303. }
  304.  
  305. void find_move(struct Tile **board) {
  306.   int x;
  307.   int y;
  308.   struct Tile *res[BOARD_HEIGHT * BOARD_WIDTH];
  309.  
  310.   srand((unsigned)(time(0)));
  311.   x = rand() % BOARD_WIDTH;
  312.   y = rand() % BOARD_HEIGHT;
  313.  
  314.   printf(">> %d, %d\n", x, y);
  315.  
  316.   if (board[y][x].valid) {
  317.     board[y][x].valid = 0;
  318.     if (get_move(&board, x, y, 0, res)) {
  319.       return;
  320.     }
  321.     board[y][x].valid = 1;
  322.   }
  323. }
  324.  
  325. void find_new_move(struct Tile **board, int x, int y, int pie) {
  326.   struct Tile temp = board[y][x];
  327.   struct Tile temp2;
  328.   struct Tile **res;
  329.   int m;
  330.  
  331.   res = (struct Tile**) malloc(BOARD_WIDTH * BOARD_HEIGHT * sizeof(struct Tile*));
  332.  
  333.   board[y][x].piece = pie;
  334.   assign_possible_moves(&board, x, y);
  335.  
  336.   temp2 = board[y][x];
  337.   board[y][x] = temp;
  338.  
  339.   for (m = 0; m < temp2.num_child; m++) {
  340.     if (temp2.child[m]->valid) {
  341.       temp2.child[m]->valid = 0;
  342.       if (get_move(&board, temp2.child[m]->x, temp2.child[m]->y, 0, res)) {
  343.         free(res);
  344.         return;
  345.       }
  346.       temp2.child[m]->valid = 1;
  347.     }
  348.   }
  349. }
  350.  
  351. void print_moves(struct Tile *res, int depth) {
  352.   int m;
  353.  
  354.   for (m = 0; m <= depth; m++) {
  355.     printf("%d: %c - %d, %d\n", (m + 1), piece_to_chr(res[m].piece), res[m].x, res[m].y);
  356.   }
  357. }
  358.  
  359. void ex_program(int sig) {
  360.   printf("Cought signal: %d\n", sig);
  361.   printf("Best solution came to %d moves\n", (high_moves + 1));
  362.   print_moves(best_moves, high_moves);
  363.   printf("Counter says % llu\n", counter);
  364.   (void) signal(SIGINT, SIG_DFL);
  365. }
  366.  
  367. int main()
  368. {
  369.   struct Tile **board;
  370.   int x;
  371.   int y;
  372.   int a;
  373.   int b;
  374.  (void) signal(SIGINT, ex_program);
  375.  
  376.   best_moves = (struct Tile*) malloc(BOARD_WIDTH * BOARD_HEIGHT * sizeof(struct Tile));
  377.  
  378.   board = (struct Tile**) malloc(BOARD_HEIGHT * sizeof(struct Tile*));
  379.   for (y = 0; y < BOARD_HEIGHT; y++) {
  380.       board[y] = (struct Tile*) malloc(BOARD_WIDTH * sizeof(struct Tile));
  381.       for (x = 0; x < BOARD_WIDTH; x++) {
  382.         board[y][x].x = x;
  383.         board[y][x].y = y;
  384.         board[y][x].piece = PIECE_NP;
  385.         board[y][x].valid = 1;
  386.         board[y][x].num_child = 0;
  387.         board[y][x].child = (struct Tile**) malloc(BOARD_WIDTH * BOARD_HEIGHT * sizeof(struct Tile*));
  388.       }
  389.   }
  390.  
  391.   parse_board(&board);
  392.   print_board(board);
  393.  
  394.   find_move(board);
  395.   //find_new_move(board, 4, 2, PIECE_P4);
  396.   print_moves(best_moves, high_moves);
  397.  
  398.   free(best_moves);
  399.   for (y = 0; y < BOARD_HEIGHT; y++) {
  400.     free(board[y]);
  401.   }
  402.  
  403.   printf("Counter says % llu\n", counter);
  404.   return 0;
  405. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement