Advertisement
Guest User

Untitled

a guest
Oct 17th, 2016
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.04 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <stdbool.h>
  4. #include <inttypes.h>
  5.  
  6. #include <xcb/xcb.h>
  7.  
  8. #define WIN_W 550
  9. #define WIN_H 550
  10. #define BOARD_W 32
  11. #define BOARD_H 32
  12. #define TILE_W 16
  13. #define TILE_H 16
  14. #define START_DR_X 20
  15. #define START_DR_Y 20
  16. #define FORWIN 4
  17. #define CROSS 1
  18. #define CIRCLE 0
  19.  
  20.  
  21. typedef void (*draw_func) (xcb_connection_t *,
  22.                            xcb_drawable_t, xcb_gcontext_t, xcb_point_t);
  23.  
  24.  
  25.  
  26. typedef struct
  27. {
  28.   draw_func func;
  29.   xcb_point_t point;
  30. } draw_this;
  31.  
  32. typedef struct
  33. {
  34.   draw_func func;
  35.   int figure;
  36.   xcb_point_t last_move;
  37. } Player;
  38.  
  39. typedef struct
  40. {
  41.   xcb_point_t *line;
  42.   int size;
  43.   int last_elem;
  44. } Line;
  45.  
  46. const char const *names[2] = { "circle", "cross" };
  47.  
  48. int check_collide(int x,
  49.                   int y,
  50.                   int oWidth,
  51.                   int oHeight, int xTwo, int yTwo, int oTwoWidth,
  52.                   int oTwoHeight)
  53. {
  54.   if ((x + oWidth <= xTwo || x > xTwo + oTwoWidth) ||
  55.       (y + oHeight <= yTwo || y > yTwo + oTwoHeight))
  56.     return 0;
  57.   return 1;
  58. }
  59.  
  60. xcb_point_t coord_to_num(int x, int y)
  61. {
  62.   x -= START_DR_X;
  63.   y -= START_DR_Y;
  64.   if ((x < 0) || (x >= (BOARD_W * TILE_W)) ||
  65.       (y < 0) || (y >= (BOARD_H * TILE_H)))
  66.   {
  67.     return (xcb_point_t) {-1, -1};
  68.   }
  69.   printf("%i %i\n", x, y);
  70.   return (xcb_point_t){(x / TILE_W), (y / TILE_H)};
  71. }
  72.  
  73. xcb_point_t get_cell(int x, int y)
  74. {
  75.   xcb_point_t cell = {-1, -1};
  76.  
  77.   if (
  78.        (x > START_DR_X) && (x < (START_DR_X + BOARD_W * TILE_W)) &&
  79.        (y > START_DR_Y) && (y < (START_DR_Y + BOARD_H * TILE_H))
  80.      )
  81.     return cell;
  82.  
  83.   x -= START_DR_X;
  84.   y -= START_DR_Y;
  85.   x /= TILE_W;
  86.   y /= TILE_H;
  87.   cell.x = x;
  88.   cell.y = y;
  89.   return cell;
  90.  
  91. }
  92.  
  93. void
  94. draw_board(xcb_connection_t * connection,
  95.            xcb_drawable_t window, xcb_gcontext_t foreground)
  96. {
  97.   int shell_w = TILE_W * BOARD_W;
  98.   int shell_h = TILE_H * BOARD_H;
  99.   int shell_x = START_DR_X;     //(WIN_W - shell_w) / 2;
  100.   int shell_y = START_DR_Y;     //(WIN_H - shell_h) / 2;
  101.   xcb_rectangle_t shell[] =
  102.   {
  103.     {shell_x, shell_y, shell_w, shell_h},
  104.   };
  105.  
  106.   uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
  107.   uint32_t color[2] = { 0x000000, 0 };
  108.   xcb_change_gc(connection, foreground, mask, color);
  109.   xcb_poly_rectangle(connection, window, foreground, 1, shell);
  110.  
  111.   for (int i = 1; i < BOARD_W; ++i)
  112.   {
  113.     xcb_point_t line[] =
  114.     { {shell_x + i * TILE_W, shell_y}, {0, shell_h} };
  115.     xcb_poly_line(connection, XCB_COORD_MODE_PREVIOUS, window,
  116.                   foreground, 2, line);
  117.   }
  118.  
  119.   for (int i = 1; i < BOARD_H; ++i)
  120.   {
  121.     xcb_point_t line[] =
  122.     { {shell_x, shell_y + i * TILE_H}, {shell_w, 0} };
  123.     xcb_poly_line(connection, XCB_COORD_MODE_PREVIOUS, window,
  124.                   foreground, 2, line);
  125.   }
  126. }
  127.  
  128.  
  129. void
  130. draw_smth(draw_this drw,
  131.           xcb_connection_t * connection,
  132.           xcb_drawable_t window, xcb_gcontext_t foreground)
  133. {
  134.   drw.func(connection, window, foreground, drw.point);
  135. }
  136.  
  137. void
  138. draw_all_figures(draw_this * drw,
  139.                  size_t num_figures,
  140.                  xcb_connection_t * connection,
  141.                  xcb_drawable_t window, xcb_gcontext_t foreground)
  142. {
  143.   for (size_t i = 0; i < num_figures; i++)
  144.   {
  145.     draw_smth(drw[i], connection, window, foreground);
  146.   }
  147. }
  148.  
  149. void
  150. draw_circle(xcb_connection_t * connection,
  151.             xcb_drawable_t window, xcb_gcontext_t foreground, xcb_point_t point)
  152. {
  153.   xcb_arc_t arcs[] =
  154.   {
  155.     {point.x, point.y, TILE_W, TILE_H, 0, (360 << 6)}
  156.   };
  157.   xcb_poly_arc(connection, window, foreground, 1, arcs);
  158. }
  159.  
  160. void
  161. draw_cross(xcb_connection_t * connection,
  162.            xcb_drawable_t window, xcb_gcontext_t foreground, xcb_point_t point)
  163. {
  164.   xcb_point_t line[] = { {point.x, point.y}, {TILE_W, TILE_H} };
  165.   xcb_point_t line2[] = { {point.x, point.y + TILE_H}, {TILE_W, -TILE_H} };
  166.  
  167.   xcb_poly_line(connection, XCB_COORD_MODE_PREVIOUS, window, foreground,
  168.                 2, line);
  169.   xcb_poly_line(connection, XCB_COORD_MODE_PREVIOUS, window, foreground,
  170.                 2, line2);
  171. }
  172.  
  173. void *create_board()
  174. {
  175.   int (*board)[BOARD_H][BOARD_W] = malloc(sizeof(int) * BOARD_W * BOARD_H);
  176.  
  177.   if (board)
  178.   {
  179.     for (size_t i = 0; i < BOARD_W; ++i)
  180.     {
  181.       for (size_t j = 0; j < BOARD_H; ++j)
  182.       {
  183.         (*board)[i][j] = -1;    // empty tile
  184.       }
  185.     }
  186.   }
  187.   return board;
  188. }
  189.  
  190. int check_win(int (*board)[][BOARD_W], Player player)
  191. {
  192.   xcb_point_t try[] = { {1, 0}, {1, 1}, {0, 1}, {-1, 1} };
  193.  
  194.   for (size_t tries = 0; tries < 4; tries++)
  195.   {
  196.     bool tryforward = true;
  197.     bool trybackward = true;
  198.     int counter_in_row = 0;
  199.     for (size_t num_in_row = 0; num_in_row < FORWIN; num_in_row++)
  200.     {
  201.       if (tryforward)
  202.       {
  203.         xcb_point_t forward =
  204.         {
  205.           player.last_move.x +
  206.           (try[tries].x) * (num_in_row + 1),
  207.             player.last_move.y +
  208.             (try[tries].y) * (num_in_row + 1)
  209.             };
  210.         if ((forward.x > BOARD_W - 1) ||
  211.             (forward.y > BOARD_H - 1) ||
  212.             (forward.x < 0) ||
  213.             (forward.y < 0))
  214.         {
  215.           tryforward = false;
  216.         }
  217.         else
  218.         {
  219.  
  220.           if ((*board)[forward.x][forward.y] ==
  221.               player.figure)
  222.           {
  223.             counter_in_row++;
  224.           }
  225.           else
  226.           {
  227.             tryforward = false;
  228.           }
  229.         }
  230.       }
  231.  
  232.       if (trybackward)
  233.       {
  234.         xcb_point_t backward =
  235.         {
  236.           player.last_move.x +
  237.           (-try[tries].x) * (num_in_row + 1),
  238.             player.last_move.y +
  239.             (-try[tries].y) * (num_in_row + 1)
  240.             };
  241.         if ((backward.x > BOARD_W - 1) ||
  242.             (backward.y > BOARD_H - 1) ||
  243.             (backward.x < 0) || (backward.y < 0))
  244.         {
  245.           trybackward = false;
  246.         }
  247.         else
  248.         {
  249.           if ((*board)[backward.x][backward.y] ==
  250.               player.figure)
  251.           {
  252.             counter_in_row++;   // это значит что при хождении назад мы увидили ту же фигуру что на нашем ходе
  253.           }
  254.           else
  255.           {
  256.             trybackward = false;
  257.           }
  258.         }
  259.       }
  260.       if (counter_in_row >= FORWIN - 1)
  261.       {
  262.         printf ("\n%s is winner!!\n", names[player.figure]);
  263.         return 0;
  264.       }
  265.       if (!trybackward && !tryforward)
  266.       {
  267.         break;  // если ни влево ни вправо нельзя идти, завершаем попытки проверить ряд
  268.       }
  269.     }
  270.   }
  271.   return 1;
  272. }
  273.  
  274. int main(int argc, char *argv[], char *envp[])
  275. {
  276.   xcb_connection_t *connection = xcb_connect(NULL, NULL);
  277.   /* Get the first screen */
  278.   xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data;
  279.  
  280.   /* Create black (foreground) graphic context */
  281.   xcb_drawable_t window = screen->root;
  282.   xcb_gcontext_t foreground = xcb_generate_id(connection);
  283.   uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
  284.   uint32_t values[2] = { 0xff0000, 0 };
  285.  
  286.   xcb_create_gc(connection, foreground, window, mask, values);
  287.   window = xcb_generate_id(connection);
  288.   mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
  289.   values[0] = screen->white_pixel;
  290.   values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS;
  291.  
  292.   xcb_create_window(connection,
  293.                     XCB_COPY_FROM_PARENT,
  294.                     window,
  295.                     screen->root,
  296.                     0, 0,
  297.                     WIN_W, WIN_H,
  298.                     10,
  299.                     XCB_WINDOW_CLASS_INPUT_OUTPUT,
  300.                     screen->root_visual, mask, values);
  301.  
  302.   xcb_map_window(connection, window);
  303.   xcb_flush(connection);
  304.   int (*board)[BOARD_H][BOARD_W] = create_board();
  305.  
  306.   xcb_generic_event_t *event;
  307.  
  308.   draw_this figures[BOARD_W * BOARD_H];
  309.   size_t num_figures = 0;
  310.   xcb_point_t point;
  311.   bool turn = false;
  312.  
  313.  
  314.   Player players[2] = { {draw_cross, CROSS}, {draw_circle, CIRCLE} };
  315.  
  316.   while ((event = xcb_wait_for_event(connection)))
  317.   {
  318.     switch (event->response_type & ~0x80)
  319.     {
  320.     case XCB_EXPOSE:
  321.       draw_board(connection, window, foreground);
  322.       draw_all_figures(figures, num_figures, connection,
  323.                        window, foreground);
  324.       xcb_flush(connection);
  325.  
  326.     case XCB_BUTTON_PRESS:
  327.     {
  328.       xcb_button_press_event_t *bp =
  329.         (xcb_button_press_event_t *) event;
  330.  
  331.       /*printf ("Button %"PRIu8" pressed in window %"PRIu32", at coordinates (%"PRIi16",%"PRIi16")\n",
  332.          bp->detail, bp->event, bp->event_x, bp->event_y ); */
  333.  
  334.       xcb_point_t click =
  335.         coord_to_num(bp->event_x, bp->event_y);
  336.       if (click.x != -1 && click.y != -1)
  337.       {
  338.         if ((*board)[click.x][click.y] == -1)
  339.         {
  340.           printf("%" PRId16 " %" PRId16
  341.                  " -- %" PRId16 " %"
  342.                  PRId16 "\n", click.x,
  343.                  click.y, bp->event_x,
  344.                  bp->event_y);
  345.           (*board)[click.x][click.y] = turn;
  346.  
  347.           figures[num_figures] =
  348.           (draw_this)
  349.           {
  350.             players[turn].func,
  351.             {
  352.               click.x * TILE_W + START_DR_X, click.y * TILE_H + START_DR_Y
  353.             }
  354.           };
  355.  
  356.           num_figures++;
  357.           players[turn].func(
  358.                               connection,
  359.                               window,
  360.                               foreground,
  361.                               (xcb_point_t)
  362.                               {
  363.                                 click.x * TILE_W + START_DR_Y, click.y * TILE_H + START_DR_Y
  364.                               }
  365.                             );
  366.  
  367.           xcb_flush(connection);
  368.  
  369.           (*board)[click.x][click.y] = players[turn].figure;
  370.  
  371.           players[turn].last_move =
  372.           (xcb_point_t)
  373.           {
  374.             click.x, click.y
  375.           };
  376.  
  377.           check_win(board, players[turn]);
  378.           turn = !turn;
  379.         }
  380.       }
  381.     }
  382.     default:
  383.       break;
  384.     }
  385.     free(event);
  386.   }
  387.   xcb_disconnect(connection);
  388.   free(board);
  389.   return 0;
  390. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement