5 #include <librsvg/rsvg.h>
6 #include <librsvg/rsvg-cairo.h>
9 * TILE_NUMBER_X_OFFSET = 3
11 * || TILE_NUMBER_WIDTH = 34
13 * || | TILE_WIDTH = 40
16 * +-----+ - TILE_NUMBER_Y_OFFSET = 3 -
19 * || || TILE_NUMBER_HEIGHT = 24 |
21 * | _ | _ |-TILE_HEIGHT = 50
23 * || || TILE_SUN_HEIGHT = 20 |
25 * | | TILE_SUN_Y_OFFSET = 3 |
27 * || | TILE_SUN_WIDTH = 20
29 * || TILE_SUN_X_OFFSET = 10
32 #define TILE_HEIGHT 50
34 #define TILE_NUMBER_X_OFFSET 3
35 #define TILE_NUMBER_Y_OFFSET 3
36 #define TILE_NUMBER_WIDTH 34
37 #define TILE_NUMBER_HEIGHT 24
39 #define TILE_SUN_X_OFFSET 10
40 #define TILE_SUN_Y_OFFSET 3
41 #define TILE_SUN_WIDTH 20
42 #define TILE_SUN_HEIGHT 20
44 #define FATAL_ERROR(msg) \
45 do { fprintf (stderr, "Error: %s\n", msg); exit (1); } while (0)
47 char *colors[] = {"Black", "Blue", "Red", "Yellow"};
49 typedef enum {BLACK, BLUE, RED, YELLOW} color_t;
60 #define DECK_MAX_TILES 104
63 tile_t tiles[DECK_MAX_TILES];
67 #define TILE_GROUP_MAX_TILES DECK_MAX_TILES
69 typedef struct tile_group {
70 tile_t tiles[TILE_GROUP_MAX_TILES];
74 #define BOARD_MAX_TILE_GROUPS (DECK_MAX_TILES / 3)
76 typedef struct board {
77 tile_group_t groups[BOARD_MAX_TILE_GROUPS];
81 typedef struct player {
85 typedef struct selection_box {
86 int x1, x2, y1, y2, visible;
89 #define GAME_MAX_PLAYERS 4
90 #define GAME_WINDOW_DEFAULT_WIDTH 800
91 #define GAME_WINDOW_DEFAULT_HEIGHT 600
93 typedef struct state {
94 player_t players[GAME_MAX_PLAYERS];
100 player_t players[GAME_MAX_PLAYERS];
104 selection_box_t selection_box;
106 RsvgHandle *blanktile;
107 RsvgHandle *selectedtile;
108 RsvgHandle *ownedtile;
111 tile_t *current_tile;
116 int click_x, click_y;
117 int release_x, release_y; /*Currently unused*/
120 static void selection_box_init(selection_box_t *box)
129 static void selection_box_draw(selection_box_t *box, cairo_t *cr)
131 cairo_rectangle (cr, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1);
132 cairo_set_source_rgba(cr, 0.0, 0.1, 0.2, 0.5);
136 static void tile_init (tile_t *tile, color_t color, int number)
139 tile->number = number;
146 static void tile_set_x_y (tile_t *tile, int x, int y)
152 static void tile_print(tile_t tile)
154 printf("%6s %2d\n", colors[tile.color], tile.number + 1);
157 static void tile_draw(game_t *game, tile_t *tile, cairo_t *cr, GdkRegion *region)
159 char number_string[3];
161 GdkRectangle rectangle;
163 rectangle.x = tile->x - 1;
164 rectangle.y = tile->y - 1;
165 rectangle.width = TILE_WIDTH + 2;
166 rectangle.height = TILE_HEIGHT + 2;
167 if (gdk_region_rect_in (region, &rectangle) == GDK_OVERLAP_RECTANGLE_OUT)
170 len = snprintf (number_string, 3, "%d", tile->number + 1);
171 if (len < 0 || len >= 3)
172 FATAL_ERROR ("snprintf failed");
175 cairo_translate(cr, tile->x, tile->y);
178 rsvg_handle_render_cairo (game->selectedtile, cr);
180 rsvg_handle_render_cairo (game->ownedtile, cr);
182 rsvg_handle_render_cairo (game->blanktile, cr);
184 if (tile->color == BLACK)
185 cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
186 if (tile->color == BLUE)
187 cairo_set_source_rgb (cr, 0.0, 0.0, 1.0);
188 if (tile->color == RED)
189 cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
190 if (tile->color == YELLOW)
191 cairo_set_source_rgb (cr, 1.0, .843, 0.0);
192 if (tile->number + 1 > 9)
193 cairo_move_to (cr, 1, 25);
195 cairo_move_to (cr, 10, 25);
196 cairo_set_font_size(cr, 25);
197 cairo_show_text (cr, number_string);
202 static void tile_group_init(tile_group_t *tile_group)
204 tile_group->num_tiles = 0;
207 static void board_init(board_t *board)
210 board->num_groups = 0;
212 for (i = 0; i <= BOARD_MAX_TILE_GROUPS; ++i)
214 tile_group_init(&board->groups[i]);
218 static void player_init(player_t *player)
220 tile_group_init(&player->hand);
224 /* If tile_one < tile_two, then return value will be negative
225 if they are equal, 0 will be returned,
226 if tile_one > tile_two, then return value will be positive */
227 static int tile_compare(const void *one, const void *two)
229 const tile_t *tile_one = one;
230 const tile_t *tile_two = two;
231 return tile_one->number - tile_two->number; //Sort lowest to highest
234 static int int_compare(const void *vx, const void *vy)
236 const int *x = vx, *y = vy;
237 return *y - *x; //Sort highest to lowest
241 static int tile_in_box(game_t *game, tile_t *tile)
247 static int tile_group_is_run_one(tile_group_t *tile_group)
250 qsort (&tile_group->tiles[0], tile_group->num_tiles,
251 sizeof (tile_t), tile_compare);
253 if (tile_group->num_tiles > 13 || tile_group->num_tiles < 3)
255 printf("fail run - invalid num tiles; ");
258 for (i = 0; i < tile_group->num_tiles - 1; ++i)
260 if(tile_group->tiles[i].color != tile_group->tiles[i + 1].color)
262 printf("fail run - colors don't match; ");
265 if( tile_group->tiles[i].number != tile_group->tiles[i + 1].number -1 &&
266 i+1 != tile_group->num_tiles)
268 printf("fail run - invalid number sequence; ");
276 static int tile_group_is_run_two(tile_group_t *tile_group)
279 int lowest = 14, highest = 0;
282 /* By definition, a run must have at least 3 tiles. Also, it's
283 * impossible for any group of tiles with more than 13 tiles to be
284 * a run, (there are only 13 unique numbers so a group with more
285 * than 13 tiles must have some duplicates).
287 if (tile_group->num_tiles < 3 || tile_group->num_tiles > 13)
292 /* Loop through all tiles in the group, ensuring that they are all
293 * the same color and finding the highest and lowest number in the
295 run_color = tile_group->tiles[0].color;
297 for (i = 0; i < tile_group->num_tiles; i++)
299 if (tile_group->tiles[i].color != run_color)
301 if (tile_group->tiles[i].number > highest)
303 highest = tile_group->tiles[i].number;
305 if (tile_group->tiles[i].number < lowest)
307 lowest = tile_group->tiles[i].number;
311 /* For a run, the difference between the highest and lowest tiles
312 * will always be one less than the number of tiles in the
313 * group. If not then we know it's not a run.
315 if (highest - lowest != tile_group->num_tiles - 1)
320 /* XXX: There's a bug here. We're guessing that at this point
321 * anything we're looking at must be a run. This would be correct
322 * if there were no duplicate tiles, but since there are
323 * duplicates this us quite broken. For example consider two
324 * sequences of entirely red tiles:
326 * This is a run: 1, 2, 3, 4
327 * But this is not: 1, 3, 4, 4
329 * As currently written, this function will consider both of these
330 * groups to be a run. One possible fix is to throw away the
331 * highest - lowest heuristic and instead simply sort the tiles up
332 * front and ensure the difference between each adjacent pair is
338 static int tile_group_is_set(tile_group_t *tile_group)
341 color_t seen_color[4];
342 for (i = 0; i < 4; i++)
345 if (tile_group->num_tiles > 4 || tile_group->num_tiles < 3)
347 printf("fail set - invalid num tiles; ");
350 for (i = 0; i <= tile_group->num_tiles - 1; ++i)
352 if (tile_group->tiles[i].number != tile_group->tiles[i + 1].number &&
353 i+1 != tile_group->num_tiles)
355 printf("fail set - numbers don't match; ");
358 seen_color[tile_group->tiles[i].color] += 1;
360 for (i = 0; i < 4; i++)
362 if (seen_color[i] > 1)
364 printf("fail set - repeat color; ");
371 static gboolean board_valid(board_t *board)
374 gboolean valid = TRUE;
375 for (i = 0; i < board->num_groups; ++i)
377 if (!(tile_group_is_run_one(&board->groups[i])) &&
378 !(tile_group_is_set(&board->groups[i])))
386 static void deck_deal(game_t *game, deck_t *deck)
392 printf ("How many players(1-4) should I deal in? ");
393 game->num_players = getchar();
394 if (game->num_players == EOF)
396 printf ("\nGoodbye.\n");
400 game->num_players -= '0';
402 for (i = 0; i < game->num_players; ++i)
404 for (j = 0; j < 14; ++j)
406 rand_tile = ((deck->num_tiles + 1.0) * rand()) / (RAND_MAX + 1.0);
407 temp = deck->tiles[rand_tile];
408 deck->tiles[rand_tile] = deck->tiles[deck->num_tiles - 1];
409 game->players[i].hand.tiles[j] = temp;
410 game->players[i].hand.tiles[j].owned = 1;
411 deck->num_tiles -= 1;
412 game->players[i].hand.num_tiles += 1;
415 printf ("Game dealt for %d player(s)\n", game->num_players);
418 static void deck_init(deck_t *deck)
422 for (h = 0; h <= 1; ++h)
424 for (i = 0; i <= 3; ++i)
426 for (j = 0; j <= 12; ++j)
428 tile_init (&deck->tiles[deck->num_tiles++], i, j);
429 printf ("There are %d tiles in the deck\n", deck->num_tiles);
435 static void deck_shuffle(deck_t *deck)
440 for (last = deck->num_tiles; last > 0; --last)
442 rand_tile = ((last + 1.0) * rand()) / (RAND_MAX + 1.0);
443 temp = deck->tiles[rand_tile];
444 deck->tiles[rand_tile] = deck->tiles[last - 1];
445 deck->tiles[last - 1] = temp;
449 static void deck_print(deck_t *deck)
452 for (h = 0; h < 2; ++h)
454 for (i = 0; i < 4; ++i)
456 for (j = 0; j < 13; ++j)
458 tile_print(deck->tiles[j + (i * 13) + (h * 52)]);
462 printf ("There are %d tiles in the deck\n" , deck->num_tiles);
465 static void deck_spread(deck_t *deck)
468 for (i = 0; i < 8; i++)
470 for (j = 0; j < 13; j++)
472 deck->tiles[j + (i * 13)].x = j * 50;
473 deck->tiles[j + (i * 13)].y = i * 60;
478 static void deck_draw(game_t *game, cairo_t *cr, GdkRegion *region)
481 for (i = 0; i < game->deck.num_tiles; i++)
483 tile_draw(game, &game->deck.tiles[i], cr, region);
487 static void board_draw(game_t *game, cairo_t *cr, GdkRegion *region)
490 for (i = 0; i < game->board.num_groups; i++)
492 for (j = 0; j < game->board.groups[i].num_tiles; j++)
494 tile_draw(game, &game->board.groups[i].tiles[j], cr, region);
495 //tile_print(game->board.groups[i].tiles[j]);
500 static void board_print(game_t *game)
503 printf("\tBegin board print\n");
504 for (i = 0; i < game->board.num_groups; i++)
506 printf("\tBegin group %d\n", i);
507 for (j = 0; j < game->board.groups[i].num_tiles; j++)
509 tile_print(game->board.groups[i].tiles[j]);
511 printf("\tEnd group %d\n", i);
515 static void hand_print(game_t *game, int player)
518 for (i = 0; i < game->players[player].hand.num_tiles; i++)
520 tile_print(game->players[player].hand.tiles[i]);
524 static void hand_draw(game_t *game, int player, cairo_t *cr, GdkRegion *region, GtkWidget *widget)
527 int window_width = widget->allocation.width;
528 // int window_width = GAME_WINDOW_DEFAULT_WIDTH;
529 int window_height = widget->allocation.height;
530 // int window_height = GAME_WINDOW_DEFAULT_HEIGHT;
531 for (i = 0; i < game->players[player].hand.num_tiles; i++)
533 tile_set_x_y(&game->players[player].hand.tiles[i],
534 ((window_width / game->players[player].hand.num_tiles)) * i,
535 (window_height - TILE_HEIGHT - 6) );
537 for (i = 0; i < game->players[player].hand.num_tiles; i++)
539 tile_draw(game, &game->players[player].hand.tiles[i], cr, region);
543 static void save_state(game_t *game)
545 game->state.board = game->board;
546 game->state.deck = game->deck;
547 //game->state.players = game->players;
550 static void restore_state(game_t *game)
552 game->board = game->state.board;
553 game->deck = game->state.deck;
554 //game->players = game->state.players;
557 static void game_init(game_t *game)
560 GError *error = NULL;
562 game->num_players = 0;
564 for (i = 0; i < GAME_MAX_PLAYERS; ++i)
566 player_init(&game->players[i]);
567 game->num_players += 1;
569 game->current_player = 0;
571 selection_box_init(&game->selection_box);
572 board_init(&game->board);
573 deck_init(&game->deck);
574 deck_shuffle(&game->deck);
576 game->selectedtile = rsvg_handle_new_from_file ("tiles/selected_tile.svg", &error);
578 FATAL_ERROR (error->message);
580 game->ownedtile = rsvg_handle_new_from_file ("tiles/owned_tile.svg", &error);
582 FATAL_ERROR (error->message);
584 game->blanktile = rsvg_handle_new_from_file ("tiles/blank_tile.svg", &error);
586 FATAL_ERROR (error->message);
588 // game->current_tile = game->deck.num_tiles - 1;
589 game->current_tile = &game->deck.tiles[0];
590 game->select_mode = 1;
591 game->drag_group_mode = 0;
593 game->diff_x = game->diff_y = 0;
596 static gboolean on_expose_event (GtkWidget *widget, GdkEventExpose *event, game_t *game)
600 cr = gdk_cairo_create (widget->window);
602 deck_draw(game, cr, event->region);
603 board_draw(game, cr, event->region);
605 if (game->selection_box.visible)
606 selection_box_draw(&game->selection_box, cr);
608 hand_draw(game, game->current_player, cr, event->region, widget);
609 //hand_draw(game, 0, cr, event->region);
616 static gboolean on_configure_event (GtkWidget *widget, GdkEventConfigure *event, game_t *game)
620 cr = gdk_cairo_create (event->window);
622 hand_draw(game, game->current_player, cr, event->window, widget);
623 // gtk_widget_queue_draw(widget);
626 static gboolean on_key_press_event (GtkWidget *widget, GdkEventKey *event, game_t *game)
630 cr = gdk_cairo_create (widget->window);
632 printf ("You pressed key %d\n", event->keyval);
634 if (event->keyval == 65293) //HIT ENTER
637 printf ("\tEnd of player %d's turn\n", game->current_player + 1);
638 if (game->current_player == game->num_players - 1)
639 game->current_player = 0;
641 game->current_player += 1;
642 gtk_widget_queue_draw(widget);
645 if (event->keyval == 65307) //HIT ESCAPE
648 printf ("\tChanges Reverted\n");
649 gtk_widget_queue_draw(widget);
652 if (event->keyval == 65474) //HIT "F5"
654 gtk_widget_queue_draw(widget);
658 if (event->keyval == 65505 || event->keyval == 65506)
659 game->drag_group_mode = 1;
664 static gboolean on_button_press_event (GtkWidget *widget, GdkEventButton *event, game_t *game)
666 int i, tile_x, tile_y;
668 player_t *curr_player = &game->players[0];
670 /*Handle tiles in player's hand */
671 for (i = 0; i < curr_player->hand.num_tiles; i++)
673 curr_tile = &curr_player->hand.tiles[i];
674 if (curr_tile->selected)
676 curr_tile->selected = 0;
677 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
679 tile_x = curr_player->hand.tiles[i].x;
680 tile_y = curr_player->hand.tiles[i].y;
681 if (event->x >= tile_x && event->x <= (tile_x + TILE_WIDTH) &&
682 event->y >= tile_y && event->y <= (tile_y + TILE_HEIGHT) )
684 game->select_mode = 0;
686 game->current_tile = curr_tile;
688 if (!curr_tile->selected)
689 curr_tile->selected = 1;
691 curr_tile->selected = 0;
692 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
694 game->diff_x = event->x - tile_x;
695 game->diff_y = event->y - tile_y;
699 /*Handle tiles in deck */
700 for (i = 0; i < game->deck.num_tiles; i++)
702 curr_tile = &game->deck.tiles[i];
703 if (curr_tile->selected)
705 curr_tile->selected = 0;
706 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
709 tile_x = game->deck.tiles[i].x;
710 tile_y = game->deck.tiles[i].y;
711 if (event->x >= tile_x && event->x <= (tile_x + TILE_WIDTH) &&
712 event->y >= tile_y && event->y <= (tile_y + TILE_HEIGHT) )
714 game->select_mode = 0;
716 // game->current_tile = i;
717 game->current_tile = curr_tile;
719 //delete_this? curr_tile = &game->deck.tiles[game->current_tile];
720 if (!curr_tile->selected)
721 curr_tile->selected = 1;
723 curr_tile->selected = 0;
724 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
726 game->diff_x = event->x - tile_x;
727 game->diff_y = event->y - tile_y;
730 if (game->select_mode)
732 // game->deck.tiles[game->current_tile].selected = 0;
733 game->current_tile->selected = 0;
734 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
736 game->selection_box.visible = 1;
737 /*These next two lines appear to be dead
738 game->click_x = event->x;
739 game->click_y = event->y;*/
741 game->selection_box.x1 = event->x;
742 game->selection_box.x2 = event->x;
743 game->selection_box.y1 = event->y;
744 game->selection_box.y2 = event->y;
749 static gboolean on_button_release_event (GtkWidget *widget, GdkEventButton *event, game_t *game)
751 if (game->select_mode)
753 game->select_mode = 0;
754 selection_box_t *box;
755 box = &game->selection_box;
757 int x_min = MIN(box->x1, box->x2);
758 int x_max = MAX(box->x1, box->x2);
759 int y_min = MIN(box->y1, box->y2);
760 int y_max = MAX(box->y1, box->y2);
761 int width = abs(box->x2 - box->x1);
762 int height = abs(box->y2 - box->y1);
765 gtk_widget_queue_draw_area (widget, x_min, y_min, width, height);
770 int i, tile_x, tile_y, tile_x2, tile_y2;
771 int tiles_to_remove[game->deck.num_tiles];
772 for (i = 0; i < game->deck.num_tiles; i++)
774 tile_x = game->deck.tiles[i].x;
775 tile_y = game->deck.tiles[i].y;
776 tile_x2 = tile_x + TILE_WIDTH;
777 tile_y2 = tile_y + TILE_HEIGHT;
778 if (/*If top-left corner*/
779 (tile_x >= x_min && tile_x <= x_max &&
780 tile_y >= y_min && tile_y <= y_max) ||
781 /*or bottom-right corner*/
782 (tile_x2 >= x_min && tile_x2 <= x_max &&
783 tile_y2 >= y_min && tile_y2 <= y_max) ||
784 /*or bottom-left corner*/
785 (tile_x >= x_min && tile_x <= x_max &&
786 tile_y2 >= y_min && tile_y2 <= y_max) ||
787 /*or top-right corner*/
788 (tile_x2 >= x_min && tile_x2 <= x_max &&
789 tile_y >= y_min && tile_y <= y_max) ||
791 (y_min >= tile_y && y_min <= tile_y2 &&
792 x_min <= tile_x && x_max >= tile_x) ||
794 (x_min >= tile_x && x_min <= tile_x2 &&
795 y_min <= tile_y && y_max >= tile_y) ||
797 (y_min >= tile_y && y_min <= tile_y2 &&
798 x_min >= tile_x && x_min <= tile_x2) ||
799 /*or bottom edge of tile selected*/
800 (x_min >= tile_x && x_min <= tile_x2 &&
801 y_min >= tile_y && y_min <= tile_y) )
803 tiles_to_remove[group.num_tiles] = i;
805 group.tiles[group.num_tiles] = game->deck.tiles[i];
809 printf("is run %d\n", tile_group_is_run_one(&group) );
810 printf("is set %d\n", tile_group_is_set(&group) );
812 qsort (tiles_to_remove, group.num_tiles, sizeof (int), int_compare);
814 for (i = 0; i < group.num_tiles; i++)
816 tile_print(group.tiles[i]);
817 gtk_widget_queue_draw_area (widget, group.tiles[i].x - 1,
818 group.tiles[i].y - 1, TILE_WIDTH + 1,
821 group.tiles[i].x = x_min + (i * (TILE_WIDTH));
822 group.tiles[i].y = y_min;
824 gtk_widget_queue_draw_area (widget, group.tiles[i].x - 1,
825 group.tiles[i].y - 1, TILE_WIDTH + 1,
828 //Remove tile from deck
829 if (tiles_to_remove[i] != game->deck.num_tiles - 1)
830 game->deck.tiles[tiles_to_remove[i]] = game->deck.tiles[game->deck.num_tiles-1];
831 game->deck.num_tiles--;
834 if (group.num_tiles > 0)
836 game->board.groups[game->board.num_groups] = group;
837 game->board.num_groups++;
840 printf("\nBut is the board valid?\t\t%s\n", board_valid(&game->board) ? "yes" : "no");
842 game->select_mode = 1;
847 static gboolean on_button_motion_event (GtkWidget *widget, GdkEventMotion *event,
848 game_t *game, cairo_t *cr)
850 if (game->select_mode)
852 selection_box_t *box;
853 box = &game->selection_box;
856 int x_min = MIN(box->x1, box->x2);
857 int x_max = MAX(box->x1, box->x2);
858 int y_min = MIN(box->y1, box->y2);
859 int y_max = MAX(box->y1, box->y2);
860 int width = abs(box->x2 - box->x1);
861 int height = abs(box->y2 - box->y1);
863 gtk_widget_queue_draw_area ( widget, x_min, y_min, width, height );
868 gtk_widget_queue_draw_area ( widget, MIN(box->x1, box->x2), MIN(box->y1, box->y2), abs(box->x2 - box->x1), abs(box->y2 - box->y1) );
870 int i, tile_x, tile_y, tile_x2, tile_y2;
872 for (i = 0; i < game->deck.num_tiles; i++)
874 curr_tile = &game->deck.tiles[i];
876 tile_x = game->deck.tiles[i].x;
877 tile_y = game->deck.tiles[i].y;
878 tile_x2 = tile_x + TILE_WIDTH;
879 tile_y2 = tile_y + TILE_HEIGHT;
880 if (/*If top-left corner*/
881 (tile_x >= x_min && tile_x <= x_max &&
882 tile_y >= y_min && tile_y <= y_max) ||
883 /*or bottom-right corner*/
884 (tile_x2 >= x_min && tile_x2 <= x_max &&
885 tile_y2 >= y_min && tile_y2 <= y_max) ||
886 /*or bottom-left corner*/
887 (tile_x >= x_min && tile_x <= x_max &&
888 tile_y2 >= y_min && tile_y2 <= y_max) ||
889 /*or top-right corner*/
890 (tile_x2 >= x_min && tile_x2 <= x_max &&
891 tile_y >= y_min && tile_y <= y_max) ||
893 (y_min >= tile_y && y_min <= tile_y2 &&
894 x_min <= tile_x && x_max >= tile_x) ||
896 (x_min >= tile_x && x_min <= tile_x2 &&
897 y_min <= tile_y && y_max >= tile_y) ||
899 (y_min >= tile_y && y_min <= tile_y2 &&
900 x_min >= tile_x && x_min <= tile_x2) ||
901 /*or bottom edge of tile selected*/
902 (x_min >= tile_x && x_min <= tile_x2 &&
903 y_min >= tile_y && y_min <= tile_y) )
905 curr_tile->selected = 1;
906 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
911 if (curr_tile->selected)
913 curr_tile->selected = 0;
914 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
921 if (game->drag_group_mode)
927 // tile = &game->deck.tiles[game->current_tile];
928 tile = game->current_tile;
930 /* First, invalidate the region where the tile currently is. */
931 gtk_widget_queue_draw_area (widget, tile->x - 1, tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
933 /* Then, move the tile */
934 tile->x = event->x - game->diff_x;
935 tile->y = event->y - game->diff_y;
937 /* Finally, invalidate the region where the tile is now. */
938 gtk_widget_queue_draw_area (widget, tile->x - 1, tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
943 int main(int argc, char *argv[])
950 gtk_init (&argc, &argv);
953 deck_print(&game.deck);
954 deck_spread(&game.deck);
955 deck_deal(&game, &game.deck);
957 game.state.board = game.board;
958 game.state.deck = game.deck;
959 //game->state.players = game.players;
961 //hand_print(&game, 0); //With Zero being passed, will print hand for player 1(players[0])
962 //deck_print(&game.deck);
964 /* Create a new window */
965 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
966 gtk_window_set_default_size (GTK_WINDOW (window),
967 GAME_WINDOW_DEFAULT_WIDTH,
968 GAME_WINDOW_DEFAULT_HEIGHT);
970 gtk_widget_set_events (window,
973 GDK_BUTTON_MOTION_MASK |
974 GDK_BUTTON_PRESS_MASK |
975 GDK_BUTTON_RELEASE_MASK);
977 g_signal_connect (G_OBJECT (window), "delete_event",
978 G_CALLBACK (gtk_main_quit), NULL);
979 g_signal_connect (G_OBJECT (window), "expose_event",
980 G_CALLBACK (on_expose_event), &game);
981 // g_signal_connect (G_OBJECT (window), "configure_event",
982 // G_CALLBACK (on_configure_event), &game);
983 g_signal_connect (G_OBJECT (window), "key_press_event",
984 G_CALLBACK (on_key_press_event), &game);
985 g_signal_connect (G_OBJECT (window), "button_press_event",
986 G_CALLBACK (on_button_press_event), &game);
987 g_signal_connect (G_OBJECT (window), "button_release_event",
988 G_CALLBACK (on_button_release_event), &game);
989 g_signal_connect (G_OBJECT (window), "motion_notify_event",
990 G_CALLBACK (on_button_motion_event), &game);
993 gtk_widget_show_all (window);