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;
234 static int tile_compare_1(tile_t *tile_one, tile_t *tile_two)
236 return tile_one->number - tile_two->number; //Sort lowest to highest
239 static int int_compare(int *x, int *y)
241 return y - x; //Sort highest to lowest
245 static int tile_in_box(game_t *game, tile_t *tile)
251 static int tile_group_is_run_one(tile_group_t *tile_group)
254 qsort (&tile_group->tiles[0], tile_group->num_tiles,
255 sizeof (tile_t), tile_compare);
257 if (tile_group->num_tiles > 13 || tile_group->num_tiles < 3)
259 printf("fail run - invalid num tiles; ");
262 for (i = 0; i < tile_group->num_tiles - 1; ++i)
264 if(tile_group->tiles[i].color != tile_group->tiles[i + 1].color)
266 printf("fail run - colors don't match; ");
269 if( tile_group->tiles[i].number != tile_group->tiles[i + 1].number -1 &&
270 i+1 != tile_group->num_tiles)
272 printf("fail run - invalid number sequence; ");
280 static int tile_group_is_run_two(tile_group_t *tile_group)
283 int lowest = 14, highest = 0;
286 /* By definition, a run must have at least 3 tiles. Also, it's
287 * impossible for any group of tiles with more than 13 tiles to be
288 * a run, (there are only 13 unique numbers so a group with more
289 * than 13 tiles must have some duplicates).
291 if (tile_group->num_tiles < 3 || tile_group->num_tiles > 13)
296 /* Loop through all tiles in the group, ensuring that they are all
297 * the same color and finding the highest and lowest number in the
299 run_color = tile_group->tiles[0].color;
301 for (i = 0; i < tile_group->num_tiles; i++)
303 if (tile_group->tiles[i].color != run_color)
305 if (tile_group->tiles[i].number > highest)
307 highest = tile_group->tiles[i].number;
309 if (tile_group->tiles[i].number < lowest)
311 lowest = tile_group->tiles[i].number;
315 /* For a run, the difference between the highest and lowest tiles
316 * will always be one less than the number of tiles in the
317 * group. If not then we know it's not a run.
319 if (highest - lowest != tile_group->num_tiles - 1)
324 /* XXX: There's a bug here. We're guessing that at this point
325 * anything we're looking at must be a run. This would be correct
326 * if there were no duplicate tiles, but since there are
327 * duplicates this us quite broken. For example consider two
328 * sequences of entirely red tiles:
330 * This is a run: 1, 2, 3, 4
331 * But this is not: 1, 3, 4, 4
333 * As currently written, this function will consider both of these
334 * groups to be a run. One possible fix is to throw away the
335 * highest - lowest heuristic and instead simply sort the tiles up
336 * front and ensure the difference between each adjacent pair is
342 static int tile_group_is_set(tile_group_t *tile_group)
345 color_t seen_color[4];
346 for (i = 0; i < 4; i++)
349 if (tile_group->num_tiles > 4 || tile_group->num_tiles < 3)
351 printf("fail set - invalid num tiles; ");
354 for (i = 0; i <= tile_group->num_tiles - 1; ++i)
356 if (tile_group->tiles[i].number != tile_group->tiles[i + 1].number &&
357 i+1 != tile_group->num_tiles)
359 printf("fail set - numbers don't match; ");
362 seen_color[tile_group->tiles[i].color] += 1;
364 for (i = 0; i < 4; i++)
366 if (seen_color[i] > 1)
368 printf("fail set - repeat color; ");
375 static gboolean board_valid(board_t *board)
378 gboolean valid = TRUE;
379 for (i = 0; i < board->num_groups; ++i)
381 if (!(tile_group_is_run_one(&board->groups[i])) &&
382 !(tile_group_is_set(&board->groups[i])))
390 static void deck_deal(game_t *game, deck_t *deck)
396 printf ("How many players(1-4) should I deal in? ");
397 game->num_players = getchar();
398 if (game->num_players == EOF)
400 printf ("\nGoodbye.\n");
404 game->num_players -= '0';
406 for (i = 0; i < game->num_players; ++i)
408 for (j = 0; j < 14; ++j)
410 rand_tile = ((deck->num_tiles + 1.0) * rand()) / (RAND_MAX + 1.0);
411 temp = deck->tiles[rand_tile];
412 deck->tiles[rand_tile] = deck->tiles[deck->num_tiles - 1];
413 game->players[i].hand.tiles[j] = temp;
414 game->players[i].hand.tiles[j].owned = 1;
415 deck->num_tiles -= 1;
416 game->players[i].hand.num_tiles += 1;
419 printf ("Game dealt for %d player(s)\n", game->num_players);
422 static void deck_init(deck_t *deck)
426 for (h = 0; h <= 1; ++h)
428 for (i = 0; i <= 3; ++i)
430 for (j = 0; j <= 12; ++j)
432 tile_init (&deck->tiles[deck->num_tiles++], i, j);
433 printf ("There are %d tiles in the deck\n", deck->num_tiles);
439 static void deck_shuffle(deck_t *deck)
444 for (last = deck->num_tiles; last > 0; --last)
446 rand_tile = ((last + 1.0) * rand()) / (RAND_MAX + 1.0);
447 temp = deck->tiles[rand_tile];
448 deck->tiles[rand_tile] = deck->tiles[last - 1];
449 deck->tiles[last - 1] = temp;
453 static void deck_print(deck_t *deck)
456 for (h = 0; h < 2; ++h)
458 for (i = 0; i < 4; ++i)
460 for (j = 0; j < 13; ++j)
462 tile_print(deck->tiles[j + (i * 13) + (h * 52)]);
466 printf ("There are %d tiles in the deck\n" , deck->num_tiles);
469 static void deck_spread(deck_t *deck)
472 for (i = 0; i < 8; i++)
474 for (j = 0; j < 13; j++)
476 deck->tiles[j + (i * 13)].x = j * 50;
477 deck->tiles[j + (i * 13)].y = i * 60;
482 static void deck_draw(game_t *game, cairo_t *cr, GdkRegion *region)
485 for (i = 0; i < game->deck.num_tiles; i++)
487 tile_draw(game, &game->deck.tiles[i], cr, region);
491 static void board_draw(game_t *game, cairo_t *cr, GdkRegion *region)
494 for (i = 0; i < game->board.num_groups; i++)
496 for (j = 0; j < game->board.groups[i].num_tiles; j++)
498 tile_draw(game, &game->board.groups[i].tiles[j], cr, region);
499 //tile_print(game->board.groups[i].tiles[j]);
504 static void board_print(game_t *game)
507 printf("\tBegin board print\n");
508 for (i = 0; i < game->board.num_groups; i++)
510 printf("\tBegin group %d\n", i);
511 for (j = 0; j < game->board.groups[i].num_tiles; j++)
513 tile_print(game->board.groups[i].tiles[j]);
515 printf("\tEnd group %d\n", i);
519 static void hand_print(game_t *game, int player)
522 for (i = 0; i < game->players[player].hand.num_tiles; i++)
524 tile_print(game->players[player].hand.tiles[i]);
528 static void hand_draw(game_t *game, int player, cairo_t *cr, GdkRegion *region, GtkWidget *widget)
531 int window_width = widget->allocation.width;
532 // int window_width = GAME_WINDOW_DEFAULT_WIDTH;
533 int window_height = widget->allocation.height;
534 // int window_height = GAME_WINDOW_DEFAULT_HEIGHT;
535 for (i = 0; i < game->players[player].hand.num_tiles; i++)
537 tile_set_x_y(&game->players[player].hand.tiles[i],
538 ((window_width / game->players[player].hand.num_tiles)) * i,
539 (window_height - TILE_HEIGHT - 6) );
541 for (i = 0; i < game->players[player].hand.num_tiles; i++)
543 tile_draw(game, &game->players[player].hand.tiles[i], cr, region);
547 static void save_state(game_t *game)
549 game->state.board = game->board;
550 game->state.deck = game->deck;
551 //game->state.players = game->players;
554 static void restore_state(game_t *game)
556 game->board = game->state.board;
557 game->deck = game->state.deck;
558 //game->players = game->state.players;
561 static void game_init(game_t *game)
564 GError *error = NULL;
566 game->num_players = 0;
568 for (i = 0; i < GAME_MAX_PLAYERS; ++i)
570 player_init(&game->players[i]);
571 game->num_players += 1;
573 game->current_player = 0;
575 selection_box_init(&game->selection_box);
576 board_init(&game->board);
577 deck_init(&game->deck);
578 deck_shuffle(&game->deck);
580 game->selectedtile = rsvg_handle_new_from_file ("tiles/selected_tile.svg", &error);
582 FATAL_ERROR (error->message);
584 game->ownedtile = rsvg_handle_new_from_file ("tiles/owned_tile.svg", &error);
586 FATAL_ERROR (error->message);
588 game->blanktile = rsvg_handle_new_from_file ("tiles/blank_tile.svg", &error);
590 FATAL_ERROR (error->message);
592 // game->current_tile = game->deck.num_tiles - 1;
593 game->current_tile = &game->deck.tiles[0];
594 game->select_mode = 1;
595 game->drag_group_mode = 0;
597 game->diff_x = game->diff_y = 0;
600 static gboolean on_expose_event (GtkWidget *widget, GdkEventExpose *event, game_t *game)
604 cr = gdk_cairo_create (widget->window);
606 deck_draw(game, cr, event->region);
607 board_draw(game, cr, event->region);
609 if (game->selection_box.visible)
610 selection_box_draw(&game->selection_box, cr);
612 hand_draw(game, game->current_player, cr, event->region, widget);
613 //hand_draw(game, 0, cr, event->region);
620 static gboolean on_configure_event (GtkWidget *widget, GdkEventConfigure *event, game_t *game)
624 cr = gdk_cairo_create (event->window);
626 hand_draw(game, game->current_player, cr, event->window, widget);
627 // gtk_widget_queue_draw(widget);
630 static gboolean on_key_press_event (GtkWidget *widget, GdkEventKey *event, game_t *game)
634 cr = gdk_cairo_create (widget->window);
636 printf ("You pressed key %d\n", event->keyval);
638 if (event->keyval == 65293) //HIT ENTER
641 printf ("\tEnd of player %d's turn\n", game->current_player + 1);
642 if (game->current_player == game->num_players - 1)
643 game->current_player = 0;
645 game->current_player += 1;
646 gtk_widget_queue_draw(widget);
649 if (event->keyval == 65307) //HIT ESCAPE
652 printf ("\tChanges Reverted\n");
653 gtk_widget_queue_draw(widget);
656 if (event->keyval == 65474) //HIT "F5"
658 gtk_widget_queue_draw(widget);
662 if (event->keyval == 65505 || event->keyval == 65506)
663 game->drag_group_mode = 1;
668 static gboolean on_button_press_event (GtkWidget *widget, GdkEventButton *event, game_t *game)
670 int i, tile_x, tile_y;
672 player_t *curr_player = &game->players[0];
674 /*Handle tiles in player's hand */
675 for (i = 0; i < curr_player->hand.num_tiles; i++)
677 curr_tile = &curr_player->hand.tiles[i];
678 if (curr_tile->selected)
680 curr_tile->selected = 0;
681 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
683 tile_x = curr_player->hand.tiles[i].x;
684 tile_y = curr_player->hand.tiles[i].y;
685 if (event->x >= tile_x && event->x <= (tile_x + TILE_WIDTH) &&
686 event->y >= tile_y && event->y <= (tile_y + TILE_HEIGHT) )
688 game->select_mode = 0;
690 game->current_tile = curr_tile;
692 if (!curr_tile->selected)
693 curr_tile->selected = 1;
695 curr_tile->selected = 0;
696 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
698 game->diff_x = event->x - tile_x;
699 game->diff_y = event->y - tile_y;
703 /*Handle tiles in deck */
704 for (i = 0; i < game->deck.num_tiles; i++)
706 curr_tile = &game->deck.tiles[i];
707 if (curr_tile->selected)
709 curr_tile->selected = 0;
710 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
713 tile_x = game->deck.tiles[i].x;
714 tile_y = game->deck.tiles[i].y;
715 if (event->x >= tile_x && event->x <= (tile_x + TILE_WIDTH) &&
716 event->y >= tile_y && event->y <= (tile_y + TILE_HEIGHT) )
718 game->select_mode = 0;
720 // game->current_tile = i;
721 game->current_tile = curr_tile;
723 //delete_this? curr_tile = &game->deck.tiles[game->current_tile];
724 if (!curr_tile->selected)
725 curr_tile->selected = 1;
727 curr_tile->selected = 0;
728 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
730 game->diff_x = event->x - tile_x;
731 game->diff_y = event->y - tile_y;
734 if (game->select_mode)
736 // game->deck.tiles[game->current_tile].selected = 0;
737 game->current_tile->selected = 0;
738 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
740 game->selection_box.visible = 1;
741 /*These next two lines appear to be dead
742 game->click_x = event->x;
743 game->click_y = event->y;*/
745 game->selection_box.x1 = event->x;
746 game->selection_box.x2 = event->x;
747 game->selection_box.y1 = event->y;
748 game->selection_box.y2 = event->y;
753 static gboolean on_button_release_event (GtkWidget *widget, GdkEventButton *event, game_t *game)
755 if (game->select_mode)
757 game->select_mode = 0;
758 selection_box_t *box;
759 box = &game->selection_box;
761 int x_min = MIN(box->x1, box->x2);
762 int x_max = MAX(box->x1, box->x2);
763 int y_min = MIN(box->y1, box->y2);
764 int y_max = MAX(box->y1, box->y2);
765 int width = abs(box->x2 - box->x1);
766 int height = abs(box->y2 - box->y1);
769 gtk_widget_queue_draw_area (widget, x_min, y_min, width, height);
774 int i, tile_x, tile_y, tile_x2, tile_y2;
775 int tiles_to_remove[game->deck.num_tiles];
776 for (i = 0; i < game->deck.num_tiles; i++)
778 tile_x = game->deck.tiles[i].x;
779 tile_y = game->deck.tiles[i].y;
780 tile_x2 = tile_x + TILE_WIDTH;
781 tile_y2 = tile_y + TILE_HEIGHT;
782 if (/*If top-left corner*/
783 (tile_x >= x_min && tile_x <= x_max &&
784 tile_y >= y_min && tile_y <= y_max) ||
785 /*or bottom-right corner*/
786 (tile_x2 >= x_min && tile_x2 <= x_max &&
787 tile_y2 >= y_min && tile_y2 <= y_max) ||
788 /*or bottom-left corner*/
789 (tile_x >= x_min && tile_x <= x_max &&
790 tile_y2 >= y_min && tile_y2 <= y_max) ||
791 /*or top-right corner*/
792 (tile_x2 >= x_min && tile_x2 <= x_max &&
793 tile_y >= y_min && tile_y <= y_max) ||
795 (y_min >= tile_y && y_min <= tile_y2 &&
796 x_min <= tile_x && x_max >= tile_x) ||
798 (x_min >= tile_x && x_min <= tile_x2 &&
799 y_min <= tile_y && y_max >= tile_y) ||
801 (y_min >= tile_y && y_min <= tile_y2 &&
802 x_min >= tile_x && x_min <= tile_x2) ||
803 /*or bottom edge of tile selected*/
804 (x_min >= tile_x && x_min <= tile_x2 &&
805 y_min >= tile_y && y_min <= tile_y) )
807 tiles_to_remove[group.num_tiles] = i;
809 group.tiles[group.num_tiles] = game->deck.tiles[i];
813 printf("is run %d\n", tile_group_is_run_one(&group) );
814 printf("is set %d\n", tile_group_is_set(&group) );
816 qsort (tiles_to_remove, group.num_tiles, sizeof (int), int_compare);
818 for (i = 0; i < group.num_tiles; i++)
820 tile_print(group.tiles[i]);
821 gtk_widget_queue_draw_area (widget, group.tiles[i].x - 1,
822 group.tiles[i].y - 1, TILE_WIDTH + 1,
825 group.tiles[i].x = x_min + (i * (TILE_WIDTH));
826 group.tiles[i].y = y_min;
828 gtk_widget_queue_draw_area (widget, group.tiles[i].x - 1,
829 group.tiles[i].y - 1, TILE_WIDTH + 1,
832 //Remove tile from deck
833 if (tiles_to_remove[i] != game->deck.num_tiles - 1)
834 game->deck.tiles[tiles_to_remove[i]] = game->deck.tiles[game->deck.num_tiles-1];
835 game->deck.num_tiles--;
838 if (group.num_tiles > 0)
840 game->board.groups[game->board.num_groups] = group;
841 game->board.num_groups++;
844 printf("\nBut is the board valid?\t\t%s\n", board_valid(&game->board));
846 game->select_mode = 1;
851 static gboolean on_button_motion_event (GtkWidget *widget, GdkEventMotion *event,
852 game_t *game, cairo_t *cr)
854 if (game->select_mode)
856 selection_box_t *box;
857 box = &game->selection_box;
860 int x_min = MIN(box->x1, box->x2);
861 int x_max = MAX(box->x1, box->x2);
862 int y_min = MIN(box->y1, box->y2);
863 int y_max = MAX(box->y1, box->y2);
864 int width = abs(box->x2 - box->x1);
865 int height = abs(box->y2 - box->y1);
867 gtk_widget_queue_draw_area ( widget, x_min, y_min, width, height );
872 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) );
874 int i, tile_x, tile_y, tile_x2, tile_y2;
876 for (i = 0; i < game->deck.num_tiles; i++)
878 curr_tile = &game->deck.tiles[i];
880 tile_x = game->deck.tiles[i].x;
881 tile_y = game->deck.tiles[i].y;
882 tile_x2 = tile_x + TILE_WIDTH;
883 tile_y2 = tile_y + TILE_HEIGHT;
884 if (/*If top-left corner*/
885 (tile_x >= x_min && tile_x <= x_max &&
886 tile_y >= y_min && tile_y <= y_max) ||
887 /*or bottom-right corner*/
888 (tile_x2 >= x_min && tile_x2 <= x_max &&
889 tile_y2 >= y_min && tile_y2 <= y_max) ||
890 /*or bottom-left corner*/
891 (tile_x >= x_min && tile_x <= x_max &&
892 tile_y2 >= y_min && tile_y2 <= y_max) ||
893 /*or top-right corner*/
894 (tile_x2 >= x_min && tile_x2 <= x_max &&
895 tile_y >= y_min && tile_y <= y_max) ||
897 (y_min >= tile_y && y_min <= tile_y2 &&
898 x_min <= tile_x && x_max >= tile_x) ||
900 (x_min >= tile_x && x_min <= tile_x2 &&
901 y_min <= tile_y && y_max >= tile_y) ||
903 (y_min >= tile_y && y_min <= tile_y2 &&
904 x_min >= tile_x && x_min <= tile_x2) ||
905 /*or bottom edge of tile selected*/
906 (x_min >= tile_x && x_min <= tile_x2 &&
907 y_min >= tile_y && y_min <= tile_y) )
909 curr_tile->selected = 1;
910 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
915 if (curr_tile->selected)
917 curr_tile->selected = 0;
918 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
925 if (game->drag_group_mode)
931 // tile = &game->deck.tiles[game->current_tile];
932 tile = game->current_tile;
934 /* First, invalidate the region where the tile currently is. */
935 gtk_widget_queue_draw_area (widget, tile->x - 1, tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
937 /* Then, move the tile */
938 tile->x = event->x - game->diff_x;
939 tile->y = event->y - game->diff_y;
941 /* Finally, invalidate the region where the tile is now. */
942 gtk_widget_queue_draw_area (widget, tile->x - 1, tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
947 int main(int argc, char *argv[])
954 gtk_init (&argc, &argv);
957 deck_print(&game.deck);
958 deck_spread(&game.deck);
959 deck_deal(&game, &game.deck);
961 game.state.board = game.board;
962 game.state.deck = game.deck;
963 //game->state.players = game.players;
965 //hand_print(&game, 0); //With Zero being passed, will print hand for player 1(players[0])
966 //deck_print(&game.deck);
968 /* Create a new window */
969 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
970 gtk_window_set_default_size (GTK_WINDOW (window),
971 GAME_WINDOW_DEFAULT_WIDTH,
972 GAME_WINDOW_DEFAULT_HEIGHT);
974 gtk_widget_set_events (window,
977 GDK_BUTTON_MOTION_MASK |
978 GDK_BUTTON_PRESS_MASK |
979 GDK_BUTTON_RELEASE_MASK);
981 g_signal_connect (G_OBJECT (window), "delete_event",
982 G_CALLBACK (gtk_main_quit), NULL);
983 g_signal_connect (G_OBJECT (window), "expose_event",
984 G_CALLBACK (on_expose_event), &game);
985 // g_signal_connect (G_OBJECT (window), "configure_event",
986 // G_CALLBACK (on_configure_event), &game);
987 g_signal_connect (G_OBJECT (window), "key_press_event",
988 G_CALLBACK (on_key_press_event), &game);
989 g_signal_connect (G_OBJECT (window), "button_press_event",
990 G_CALLBACK (on_button_press_event), &game);
991 g_signal_connect (G_OBJECT (window), "button_release_event",
992 G_CALLBACK (on_button_release_event), &game);
993 g_signal_connect (G_OBJECT (window), "motion_notify_event",
994 G_CALLBACK (on_button_motion_event), &game);
997 gtk_widget_show_all (window);