Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <stdbool.h>
- #include <inttypes.h>
- #include <xcb/xcb.h>
- #define WIN_W 550
- #define WIN_H 550
- #define BOARD_W 32
- #define BOARD_H 32
- #define TILE_W 16
- #define TILE_H 16
- #define START_DR_X 20
- #define START_DR_Y 20
- #define FORWIN 4
- #define CROSS 1
- #define CIRCLE 0
- typedef void (*draw_func) (xcb_connection_t *,
- xcb_drawable_t, xcb_gcontext_t, xcb_point_t);
- typedef struct
- {
- draw_func func;
- xcb_point_t point;
- } draw_this;
- typedef struct
- {
- draw_func func;
- int figure;
- xcb_point_t last_move;
- } Player;
- typedef struct
- {
- xcb_point_t *line;
- int size;
- int last_elem;
- } Line;
- const char const *names[2] = { "circle", "cross" };
- int check_collide(int x,
- int y,
- int oWidth,
- int oHeight, int xTwo, int yTwo, int oTwoWidth,
- int oTwoHeight)
- {
- if ((x + oWidth <= xTwo || x > xTwo + oTwoWidth) ||
- (y + oHeight <= yTwo || y > yTwo + oTwoHeight))
- return 0;
- return 1;
- }
- xcb_point_t coord_to_num(int x, int y)
- {
- x -= START_DR_X;
- y -= START_DR_Y;
- if ((x < 0) || (x >= (BOARD_W * TILE_W)) ||
- (y < 0) || (y >= (BOARD_H * TILE_H)))
- {
- return (xcb_point_t) {-1, -1};
- }
- printf("%i %i\n", x, y);
- return (xcb_point_t){(x / TILE_W), (y / TILE_H)};
- }
- xcb_point_t get_cell(int x, int y)
- {
- xcb_point_t cell = {-1, -1};
- if (
- (x > START_DR_X) && (x < (START_DR_X + BOARD_W * TILE_W)) &&
- (y > START_DR_Y) && (y < (START_DR_Y + BOARD_H * TILE_H))
- )
- return cell;
- x -= START_DR_X;
- y -= START_DR_Y;
- x /= TILE_W;
- y /= TILE_H;
- cell.x = x;
- cell.y = y;
- return cell;
- }
- void
- draw_board(xcb_connection_t * connection,
- xcb_drawable_t window, xcb_gcontext_t foreground)
- {
- int shell_w = TILE_W * BOARD_W;
- int shell_h = TILE_H * BOARD_H;
- int shell_x = START_DR_X; //(WIN_W - shell_w) / 2;
- int shell_y = START_DR_Y; //(WIN_H - shell_h) / 2;
- xcb_rectangle_t shell[] =
- {
- {shell_x, shell_y, shell_w, shell_h},
- };
- uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
- uint32_t color[2] = { 0x000000, 0 };
- xcb_change_gc(connection, foreground, mask, color);
- xcb_poly_rectangle(connection, window, foreground, 1, shell);
- for (int i = 1; i < BOARD_W; ++i)
- {
- xcb_point_t line[] =
- { {shell_x + i * TILE_W, shell_y}, {0, shell_h} };
- xcb_poly_line(connection, XCB_COORD_MODE_PREVIOUS, window,
- foreground, 2, line);
- }
- for (int i = 1; i < BOARD_H; ++i)
- {
- xcb_point_t line[] =
- { {shell_x, shell_y + i * TILE_H}, {shell_w, 0} };
- xcb_poly_line(connection, XCB_COORD_MODE_PREVIOUS, window,
- foreground, 2, line);
- }
- }
- void
- draw_smth(draw_this drw,
- xcb_connection_t * connection,
- xcb_drawable_t window, xcb_gcontext_t foreground)
- {
- drw.func(connection, window, foreground, drw.point);
- }
- void
- draw_all_figures(draw_this * drw,
- size_t num_figures,
- xcb_connection_t * connection,
- xcb_drawable_t window, xcb_gcontext_t foreground)
- {
- for (size_t i = 0; i < num_figures; i++)
- {
- draw_smth(drw[i], connection, window, foreground);
- }
- }
- void
- draw_circle(xcb_connection_t * connection,
- xcb_drawable_t window, xcb_gcontext_t foreground, xcb_point_t point)
- {
- xcb_arc_t arcs[] =
- {
- {point.x, point.y, TILE_W, TILE_H, 0, (360 << 6)}
- };
- xcb_poly_arc(connection, window, foreground, 1, arcs);
- }
- void
- draw_cross(xcb_connection_t * connection,
- xcb_drawable_t window, xcb_gcontext_t foreground, xcb_point_t point)
- {
- xcb_point_t line[] = { {point.x, point.y}, {TILE_W, TILE_H} };
- xcb_point_t line2[] = { {point.x, point.y + TILE_H}, {TILE_W, -TILE_H} };
- xcb_poly_line(connection, XCB_COORD_MODE_PREVIOUS, window, foreground,
- 2, line);
- xcb_poly_line(connection, XCB_COORD_MODE_PREVIOUS, window, foreground,
- 2, line2);
- }
- void *create_board()
- {
- int (*board)[BOARD_H][BOARD_W] = malloc(sizeof(int) * BOARD_W * BOARD_H);
- if (board)
- {
- for (size_t i = 0; i < BOARD_W; ++i)
- {
- for (size_t j = 0; j < BOARD_H; ++j)
- {
- (*board)[i][j] = -1; // empty tile
- }
- }
- }
- return board;
- }
- int check_win(int (*board)[][BOARD_W], Player player)
- {
- xcb_point_t try[] = { {1, 0}, {1, 1}, {0, 1}, {-1, 1} };
- for (size_t tries = 0; tries < 4; tries++)
- {
- bool tryforward = true;
- bool trybackward = true;
- int counter_in_row = 0;
- for (size_t num_in_row = 0; num_in_row < FORWIN; num_in_row++)
- {
- if (tryforward)
- {
- xcb_point_t forward =
- {
- player.last_move.x +
- (try[tries].x) * (num_in_row + 1),
- player.last_move.y +
- (try[tries].y) * (num_in_row + 1)
- };
- if ((forward.x > BOARD_W - 1) ||
- (forward.y > BOARD_H - 1) ||
- (forward.x < 0) ||
- (forward.y < 0))
- {
- tryforward = false;
- }
- else
- {
- if ((*board)[forward.x][forward.y] ==
- player.figure)
- {
- counter_in_row++;
- }
- else
- {
- tryforward = false;
- }
- }
- }
- if (trybackward)
- {
- xcb_point_t backward =
- {
- player.last_move.x +
- (-try[tries].x) * (num_in_row + 1),
- player.last_move.y +
- (-try[tries].y) * (num_in_row + 1)
- };
- if ((backward.x > BOARD_W - 1) ||
- (backward.y > BOARD_H - 1) ||
- (backward.x < 0) || (backward.y < 0))
- {
- trybackward = false;
- }
- else
- {
- if ((*board)[backward.x][backward.y] ==
- player.figure)
- {
- counter_in_row++; // это значит что при хождении назад мы увидили ту же фигуру что на нашем ходе
- }
- else
- {
- trybackward = false;
- }
- }
- }
- if (counter_in_row >= FORWIN - 1)
- {
- printf ("\n%s is winner!!\n", names[player.figure]);
- return 0;
- }
- if (!trybackward && !tryforward)
- {
- break; // если ни влево ни вправо нельзя идти, завершаем попытки проверить ряд
- }
- }
- }
- return 1;
- }
- int main(int argc, char *argv[], char *envp[])
- {
- xcb_connection_t *connection = xcb_connect(NULL, NULL);
- /* Get the first screen */
- xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data;
- /* Create black (foreground) graphic context */
- xcb_drawable_t window = screen->root;
- xcb_gcontext_t foreground = xcb_generate_id(connection);
- uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
- uint32_t values[2] = { 0xff0000, 0 };
- xcb_create_gc(connection, foreground, window, mask, values);
- window = xcb_generate_id(connection);
- mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
- values[0] = screen->white_pixel;
- values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS;
- xcb_create_window(connection,
- XCB_COPY_FROM_PARENT,
- window,
- screen->root,
- 0, 0,
- WIN_W, WIN_H,
- 10,
- XCB_WINDOW_CLASS_INPUT_OUTPUT,
- screen->root_visual, mask, values);
- xcb_map_window(connection, window);
- xcb_flush(connection);
- int (*board)[BOARD_H][BOARD_W] = create_board();
- xcb_generic_event_t *event;
- draw_this figures[BOARD_W * BOARD_H];
- size_t num_figures = 0;
- xcb_point_t point;
- bool turn = false;
- Player players[2] = { {draw_cross, CROSS}, {draw_circle, CIRCLE} };
- while ((event = xcb_wait_for_event(connection)))
- {
- switch (event->response_type & ~0x80)
- {
- case XCB_EXPOSE:
- draw_board(connection, window, foreground);
- draw_all_figures(figures, num_figures, connection,
- window, foreground);
- xcb_flush(connection);
- case XCB_BUTTON_PRESS:
- {
- xcb_button_press_event_t *bp =
- (xcb_button_press_event_t *) event;
- /*printf ("Button %"PRIu8" pressed in window %"PRIu32", at coordinates (%"PRIi16",%"PRIi16")\n",
- bp->detail, bp->event, bp->event_x, bp->event_y ); */
- xcb_point_t click =
- coord_to_num(bp->event_x, bp->event_y);
- if (click.x != -1 && click.y != -1)
- {
- if ((*board)[click.x][click.y] == -1)
- {
- printf("%" PRId16 " %" PRId16
- " -- %" PRId16 " %"
- PRId16 "\n", click.x,
- click.y, bp->event_x,
- bp->event_y);
- (*board)[click.x][click.y] = turn;
- figures[num_figures] =
- (draw_this)
- {
- players[turn].func,
- {
- click.x * TILE_W + START_DR_X, click.y * TILE_H + START_DR_Y
- }
- };
- num_figures++;
- players[turn].func(
- connection,
- window,
- foreground,
- (xcb_point_t)
- {
- click.x * TILE_W + START_DR_Y, click.y * TILE_H + START_DR_Y
- }
- );
- xcb_flush(connection);
- (*board)[click.x][click.y] = players[turn].figure;
- players[turn].last_move =
- (xcb_point_t)
- {
- click.x, click.y
- };
- check_win(board, players[turn]);
- turn = !turn;
- }
- }
- }
- default:
- break;
- }
- free(event);
- }
- xcb_disconnect(connection);
- free(board);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement