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;
58 int in_hand;//Draw the tile in the hand, or elsewhere on the board?
61 #define DECK_MAX_TILES 104
64 tile_t tiles[DECK_MAX_TILES];
68 #define TILE_GROUP_MAX_TILES DECK_MAX_TILES
70 typedef struct tile_group {
71 tile_t tiles[TILE_GROUP_MAX_TILES];
75 #define BOARD_MAX_TILE_GROUPS DECK_MAX_TILES
77 typedef struct board {
78 tile_group_t groups[BOARD_MAX_TILE_GROUPS];
82 typedef struct player {
86 typedef struct selection_box {
87 int x1, x2, y1, y2, visible;
90 #define GAME_MAX_PLAYERS 4
91 #define GAME_WINDOW_DEFAULT_WIDTH 800
92 #define GAME_WINDOW_DEFAULT_HEIGHT 600
94 typedef struct state {
95 player_t players[GAME_MAX_PLAYERS];
100 typedef struct game {
101 player_t players[GAME_MAX_PLAYERS];
105 selection_box_t selection_box;
107 RsvgHandle *blanktile;
108 RsvgHandle *selectedtile;
109 RsvgHandle *ownedtile;
112 tile_t *current_tile;
117 int click_x, click_y;
118 int release_x, release_y; /*Currently unused*/
121 static void selection_box_init(selection_box_t *box)
130 static void selection_box_draw(selection_box_t *box, cairo_t *cr)
132 cairo_rectangle (cr, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1);
133 cairo_set_source_rgba(cr, 0.0, 0.1, 0.2, 0.5);
137 static void tile_init (tile_t *tile, color_t color, int number)
140 tile->number = number;
148 static void tile_set_x_y (tile_t *tile, int x, int y)
154 static void tile_print(tile_t tile)
156 printf("%6s %2d\n", colors[tile.color], tile.number + 1);
159 static void tile_draw(game_t *game, tile_t *tile, cairo_t *cr, GdkRegion *region)
161 char number_string[3];
163 GdkRectangle rectangle;
165 rectangle.x = tile->x - 1;
166 rectangle.y = tile->y - 1;
167 rectangle.width = TILE_WIDTH + 2;
168 rectangle.height = TILE_HEIGHT + 2;
169 if (gdk_region_rect_in (region, &rectangle) == GDK_OVERLAP_RECTANGLE_OUT)
172 len = snprintf (number_string, 3, "%d", tile->number + 1);
173 if (len < 0 || len >= 3)
174 FATAL_ERROR ("snprintf failed");
177 cairo_translate(cr, tile->x, tile->y);
180 rsvg_handle_render_cairo (game->selectedtile, cr);
182 rsvg_handle_render_cairo (game->ownedtile, cr);
184 rsvg_handle_render_cairo (game->blanktile, cr);
186 if (tile->color == BLACK)
187 cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
188 if (tile->color == BLUE)
189 cairo_set_source_rgb (cr, 0.0, 0.0, 1.0);
190 if (tile->color == RED)
191 cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
192 if (tile->color == YELLOW)
193 cairo_set_source_rgb (cr, 1.0, .843, 0.0);
194 if (tile->number + 1 > 9)
195 cairo_move_to (cr, 1, 25);
197 cairo_move_to (cr, 10, 25);
198 cairo_set_font_size(cr, 25);
199 cairo_show_text (cr, number_string);
204 static void tile_group_init(tile_group_t *tile_group)
206 tile_group->num_tiles = 0;
209 static void board_init(board_t *board)
212 board->num_groups = 0;
214 for (i = 0; i <= BOARD_MAX_TILE_GROUPS; ++i)
216 tile_group_init(&board->groups[i]);
220 static void player_init(player_t *player)
222 tile_group_init(&player->hand);
226 /* If tile_one < tile_two, then return value will be negative
227 if they are equal, 0 will be returned,
228 if tile_one > tile_two, then return value will be positive */
229 static int tile_compare(const void *one, const void *two)
231 const tile_t *tile_one = one;
232 const tile_t *tile_two = two;
233 return tile_one->number - tile_two->number; //Sort lowest to highest
236 static int int_compare(const void *vx, const void *vy)
238 const int *x = vx, *y = vy;
239 return *y - *x; //Sort highest to lowest
243 static int tile_in_box(game_t *game, tile_t *tile)
249 static int tile_group_is_run_one(tile_group_t *tile_group)
252 qsort (&tile_group->tiles[0], tile_group->num_tiles,
253 sizeof (tile_t), tile_compare);
255 if (tile_group->num_tiles > 13 || tile_group->num_tiles < 3)
257 printf("fail run - invalid num tiles; ");
260 for (i = 0; i < tile_group->num_tiles - 1; ++i)
262 if(tile_group->tiles[i].color != tile_group->tiles[i + 1].color)
264 printf("fail run - colors don't match; ");
267 if( tile_group->tiles[i].number != tile_group->tiles[i + 1].number -1 &&
268 i+1 != tile_group->num_tiles)
270 printf("fail run - invalid number sequence; ");
278 static int tile_group_is_run_two(tile_group_t *tile_group)
281 int lowest = 14, highest = 0;
284 /* By definition, a run must have at least 3 tiles. Also, it's
285 * impossible for any group of tiles with more than 13 tiles to be
286 * a run, (there are only 13 unique numbers so a group with more
287 * than 13 tiles must have some duplicates).
289 if (tile_group->num_tiles < 3 || tile_group->num_tiles > 13)
294 /* Loop through all tiles in the group, ensuring that they are all
295 * the same color and finding the highest and lowest number in the
297 run_color = tile_group->tiles[0].color;
299 for (i = 0; i < tile_group->num_tiles; i++)
301 if (tile_group->tiles[i].color != run_color)
303 if (tile_group->tiles[i].number > highest)
305 highest = tile_group->tiles[i].number;
307 if (tile_group->tiles[i].number < lowest)
309 lowest = tile_group->tiles[i].number;
313 /* For a run, the difference between the highest and lowest tiles
314 * will always be one less than the number of tiles in the
315 * group. If not then we know it's not a run.
317 if (highest - lowest != tile_group->num_tiles - 1)
322 /* XXX: There's a bug here. We're guessing that at this point
323 * anything we're looking at must be a run. This would be correct
324 * if there were no duplicate tiles, but since there are
325 * duplicates this us quite broken. For example consider two
326 * sequences of entirely red tiles:
328 * This is a run: 1, 2, 3, 4
329 * But this is not: 1, 3, 4, 4
331 * As currently written, this function will consider both of these
332 * groups to be a run. One possible fix is to throw away the
333 * highest - lowest heuristic and instead simply sort the tiles up
334 * front and ensure the difference between each adjacent pair is
340 static int tile_group_is_set(tile_group_t *tile_group)
343 color_t seen_color[4];
344 for (i = 0; i < 4; i++)
347 if (tile_group->num_tiles > 4 || tile_group->num_tiles < 3)
349 printf("fail set - invalid num tiles; ");
352 for (i = 0; i <= tile_group->num_tiles - 1; ++i)
354 if (tile_group->tiles[i].number != tile_group->tiles[i + 1].number &&
355 i+1 != tile_group->num_tiles)
357 printf("fail set - numbers don't match; ");
360 seen_color[tile_group->tiles[i].color] += 1;
362 for (i = 0; i < 4; i++)
364 if (seen_color[i] > 1)
366 printf("fail set - repeat color; ");
373 static gboolean board_valid(board_t *board)
376 gboolean valid = TRUE;
377 for (i = 0; i < board->num_groups; ++i)
379 if (!(tile_group_is_run_one(&board->groups[i])) &&
380 !(tile_group_is_set(&board->groups[i])))
388 static void deck_deal(game_t *game, deck_t *deck)
394 printf ("How many players(1-4) should I deal in? ");
395 game->num_players = getchar();
396 if (game->num_players == EOF)
398 printf ("\nGoodbye.\n");
402 game->num_players -= '0';
404 for (i = 0; i < game->num_players; ++i)
406 for (j = 0; j < 14; ++j)
408 rand_tile = ((deck->num_tiles + 1.0) * rand()) / (RAND_MAX + 1.0);
409 temp = deck->tiles[rand_tile];
410 deck->tiles[rand_tile] = deck->tiles[deck->num_tiles - 1];
411 game->players[i].hand.tiles[j] = temp;
412 game->players[i].hand.tiles[j].owned = 1;
413 deck->num_tiles -= 1;
414 game->players[i].hand.num_tiles += 1;
417 printf ("Game dealt for %d player(s)\n", game->num_players);
420 static void deck_init(deck_t *deck)
424 for (h = 0; h <= 1; ++h)
426 for (i = 0; i <= 3; ++i)
428 for (j = 0; j <= 12; ++j)
430 tile_init (&deck->tiles[deck->num_tiles++], i, j);
431 printf ("There are %d tiles in the deck\n", deck->num_tiles);
437 static void deck_shuffle(deck_t *deck)
442 for (last = deck->num_tiles; last > 0; --last)
444 rand_tile = ((last + 1.0) * rand()) / (RAND_MAX + 1.0);
445 temp = deck->tiles[rand_tile];
446 deck->tiles[rand_tile] = deck->tiles[last - 1];
447 deck->tiles[last - 1] = temp;
451 static void deck_print(deck_t *deck)
454 for (h = 0; h < 2; ++h)
456 for (i = 0; i < 4; ++i)
458 for (j = 0; j < 13; ++j)
460 tile_print(deck->tiles[j + (i * 13) + (h * 52)]);
464 printf ("There are %d tiles in the deck\n" , deck->num_tiles);
467 static void deck_spread(deck_t *deck)
470 for (i = 0; i < 8; i++)
472 for (j = 0; j < 13; j++)
474 deck->tiles[j + (i * 13)].x = j * 50;
475 deck->tiles[j + (i * 13)].y = i * 60;
480 static void deck_draw(game_t *game, cairo_t *cr, GdkRegion *region)
483 for (i = 0; i < game->deck.num_tiles; i++)
485 tile_draw(game, &game->deck.tiles[i], cr, region);
489 static void board_draw(game_t *game, cairo_t *cr, GdkRegion *region)
492 for (i = 0; i < game->board.num_groups; i++)
494 for (j = 0; j < game->board.groups[i].num_tiles; j++)
496 tile_draw(game, &game->board.groups[i].tiles[j], cr, region);
497 //tile_print(game->board.groups[i].tiles[j]);
502 static void board_print(game_t *game)
505 printf("\tBegin board print\n");
506 for (i = 0; i < game->board.num_groups; i++)
508 printf("\tBegin group %d\n", i);
509 for (j = 0; j < game->board.groups[i].num_tiles; j++)
511 tile_print(game->board.groups[i].tiles[j]);
513 printf("\tEnd group %d\n", i);
517 static void hand_print(game_t *game, int player)
520 for (i = 0; i < game->players[player].hand.num_tiles; i++)
522 tile_print(game->players[player].hand.tiles[i]);
526 static void hand_draw(game_t *game, int player, cairo_t *cr, GdkRegion *region, GtkWidget *widget)
529 int width = widget->allocation.width;
530 // int width = GAME_WINDOW_DEFAULT_WIDTH;
531 int height = widget->allocation.height;
532 // int height = GAME_WINDOW_DEFAULT_HEIGHT;
533 int num_tiles = game->players[player].hand.num_tiles;
534 for (i = 0; i < num_tiles; i++)
536 if (game->players[player].hand.tiles[i].in_hand)
537 tile_set_x_y(&game->players[player].hand.tiles[i],
538 ((width/num_tiles)) * i, (height - TILE_HEIGHT - 6) );
540 for (i = 0; i < game->players[player].hand.num_tiles; i++)
542 // if (game->players[player].hand.tiles[i].in_hand)
543 tile_draw(game, &game->players[player].hand.tiles[i], cr, region);
547 static void save_state(game_t *game)
549 printf("State saved\n");
550 game->state.board = game->board;
551 game->state.deck = game->deck;
553 for (i=0; i < game->num_players; i++)
554 game->state.players[i] = game->players[i];
557 static void restore_state(game_t *game)
559 game->board = game->state.board;
560 game->deck = game->state.deck;
562 for (i=0; i < game->num_players; i++)
563 game->players[i] = game->state.players[i];
566 static void game_init(game_t *game)
569 GError *error = NULL;
571 game->num_players = 0;
573 for (i = 0; i < GAME_MAX_PLAYERS; ++i)
575 player_init(&game->players[i]);
576 game->num_players += 1;
578 game->current_player = 0;
580 selection_box_init(&game->selection_box);
581 board_init(&game->board);
582 deck_init(&game->deck);
583 deck_shuffle(&game->deck);
585 game->selectedtile = rsvg_handle_new_from_file ("tiles/selected_tile.svg", &error);
587 FATAL_ERROR (error->message);
589 game->ownedtile = rsvg_handle_new_from_file ("tiles/owned_tile.svg", &error);
591 FATAL_ERROR (error->message);
593 game->blanktile = rsvg_handle_new_from_file ("tiles/blank_tile.svg", &error);
595 FATAL_ERROR (error->message);
597 // game->current_tile = game->deck.num_tiles - 1;
598 game->current_tile = &game->deck.tiles[0];
599 game->select_mode = 1;
600 game->drag_group_mode = 0;
602 game->diff_x = game->diff_y = 0;
605 static gboolean on_expose_event (GtkWidget *widget, GdkEventExpose *event, game_t *game)
609 cr = gdk_cairo_create (widget->window);
611 deck_draw(game, cr, event->region);
612 board_draw(game, cr, event->region);
614 if (game->selection_box.visible)
615 selection_box_draw(&game->selection_box, cr);
617 hand_draw(game, game->current_player, cr, event->region, widget);
618 //hand_draw(game, 0, cr, event->region);
625 static gboolean on_configure_event (GtkWidget *widget, GdkEventConfigure *event, game_t *game)
629 cr = gdk_cairo_create (event->window);
631 hand_draw(game, game->current_player, cr, event->window, widget);
632 // gtk_widget_queue_draw(widget);
635 static gboolean on_key_press_event (GtkWidget *widget, GdkEventKey *event, game_t *game)
637 player_t *player = &game->players[game->current_player];
639 cr = gdk_cairo_create (widget->window);
640 printf ("You pressed key %d\n", event->keyval);
642 if (event->keyval == 100) //HIT "d"
644 //Draw(take) top tile from deck and put in hand
645 if (game->deck.num_tiles > 0)
647 tile_t top_tile = game->deck.tiles[game->deck.num_tiles-1];
648 game->deck.num_tiles--;
649 player->hand.tiles[player->hand.num_tiles] = top_tile;
650 player->hand.tiles[player->hand.num_tiles].owned=1;
651 player->hand.num_tiles++;
652 printf("Tile added to hand\n");
653 gtk_widget_queue_draw(widget);
656 else if (event->keyval == 115) //HIT "s"
658 else if (event->keyval == 65293) //HIT ENTER
660 player_t *player = &game->players[game->current_player];
662 for (i = 0; i < player->hand.num_tiles; i++)
663 player->hand.tiles[i].in_hand = 1;
665 printf ("\tEnd of player %d's turn\n", game->current_player+1);
666 if (game->current_player == game->num_players-1)
667 game->current_player = 0;
669 game->current_player += 1;
670 gtk_widget_queue_draw(widget);
672 else if (event->keyval == 65307) //HIT ESCAPE
675 printf ("\tChanges Reverted\n");
676 gtk_widget_queue_draw(widget);
678 else if (event->keyval == 65474) //HIT "F5"
680 gtk_widget_queue_draw(widget);
682 else if (event->keyval == 65505 || event->keyval == 65506)
683 game->drag_group_mode = 1;
687 static gboolean on_button_press_event (GtkWidget *widget, GdkEventButton *event, game_t *game)
689 int i, tile_x, tile_y;
691 player_t *curr_player = &game->players[game->current_player];
693 /*Handle tiles in player's hand */
694 for (i = 0; i < curr_player->hand.num_tiles; i++)
696 curr_tile = &curr_player->hand.tiles[i];
697 if (curr_tile->selected)
699 curr_tile->selected = 0;
700 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
702 tile_x = curr_player->hand.tiles[i].x;
703 tile_y = curr_player->hand.tiles[i].y;
704 if (event->x >= tile_x && event->x <= (tile_x + TILE_WIDTH) &&
705 event->y >= tile_y && event->y <= (tile_y + TILE_HEIGHT) )
707 game->select_mode = 0;
708 game->current_tile = curr_tile;
709 curr_tile->in_hand = 0;
710 if (!curr_tile->selected)
711 curr_tile->selected = 1;
713 curr_tile->selected = 0;
714 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
715 game->diff_x = event->x - tile_x;
716 game->diff_y = event->y - tile_y;
720 /*Handle tiles in deck */
721 for (i = 0; i < game->deck.num_tiles; i++)
723 curr_tile = &game->deck.tiles[i];
724 if (curr_tile->selected)
726 curr_tile->selected = 0;
727 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
730 tile_x = game->deck.tiles[i].x;
731 tile_y = game->deck.tiles[i].y;
732 if (event->x >= tile_x && event->x <= (tile_x + TILE_WIDTH) &&
733 event->y >= tile_y && event->y <= (tile_y + TILE_HEIGHT) )
735 game->select_mode = 0;
737 // game->current_tile = i;
738 game->current_tile = curr_tile;
740 //delete_this? curr_tile = &game->deck.tiles[game->current_tile];
741 if (!curr_tile->selected)
742 curr_tile->selected = 1;
744 curr_tile->selected = 0;
745 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
747 game->diff_x = event->x - tile_x;
748 game->diff_y = event->y - tile_y;
751 if (game->select_mode)
753 // game->deck.tiles[game->current_tile].selected = 0;
754 game->current_tile->selected = 0;
755 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
757 game->selection_box.visible = 1;
758 /*These next two lines appear to be dead
759 game->click_x = event->x;
760 game->click_y = event->y;*/
762 game->selection_box.x1 = event->x;
763 game->selection_box.x2 = event->x;
764 game->selection_box.y1 = event->y;
765 game->selection_box.y2 = event->y;
770 static gboolean on_button_release_event (GtkWidget *widget, GdkEventButton *event, game_t *game)
772 if (game->select_mode)
774 game->select_mode = 0;
775 selection_box_t *box;
776 box = &game->selection_box;
778 int x_min = MIN(box->x1, box->x2);
779 int x_max = MAX(box->x1, box->x2);
780 int y_min = MIN(box->y1, box->y2);
781 int y_max = MAX(box->y1, box->y2);
782 int width = abs(box->x2 - box->x1);
783 int height = abs(box->y2 - box->y1);
786 gtk_widget_queue_draw_area (widget, x_min, y_min, width, height);
791 int i, tile_x, tile_y, tile_x2, tile_y2;
792 int tiles_to_remove[game->deck.num_tiles];
793 for (i = 0; i < game->deck.num_tiles; i++)
795 tile_x = game->deck.tiles[i].x;
796 tile_y = game->deck.tiles[i].y;
797 tile_x2 = tile_x + TILE_WIDTH;
798 tile_y2 = tile_y + TILE_HEIGHT;
799 if (/*If top-left corner*/
800 (tile_x >= x_min && tile_x <= x_max &&
801 tile_y >= y_min && tile_y <= y_max) ||
802 /*or bottom-right corner*/
803 (tile_x2 >= x_min && tile_x2 <= x_max &&
804 tile_y2 >= y_min && tile_y2 <= y_max) ||
805 /*or bottom-left corner*/
806 (tile_x >= x_min && tile_x <= x_max &&
807 tile_y2 >= y_min && tile_y2 <= y_max) ||
808 /*or top-right corner*/
809 (tile_x2 >= x_min && tile_x2 <= x_max &&
810 tile_y >= y_min && tile_y <= y_max) ||
812 (y_min >= tile_y && y_min <= tile_y2 &&
813 x_min <= tile_x && x_max >= tile_x) ||
815 (x_min >= tile_x && x_min <= tile_x2 &&
816 y_min <= tile_y && y_max >= tile_y) ||
818 (y_min >= tile_y && y_min <= tile_y2 &&
819 x_min >= tile_x && x_min <= tile_x2) ||
820 /*or bottom edge of tile selected*/
821 (x_min >= tile_x && x_min <= tile_x2 &&
822 y_min >= tile_y && y_min <= tile_y) )
824 tiles_to_remove[group.num_tiles] = i;
826 group.tiles[group.num_tiles] = game->deck.tiles[i];
830 printf("is run %d\n", tile_group_is_run_one(&group) );
831 printf("is set %d\n", tile_group_is_set(&group) );
833 qsort (tiles_to_remove, group.num_tiles, sizeof (int), int_compare);
835 for (i = 0; i < group.num_tiles; i++)
837 tile_print(group.tiles[i]);
838 gtk_widget_queue_draw_area (widget, group.tiles[i].x - 1,
839 group.tiles[i].y - 1, TILE_WIDTH + 1,
842 group.tiles[i].x = x_min + (i * (TILE_WIDTH));
843 group.tiles[i].y = y_min;
845 gtk_widget_queue_draw_area (widget, group.tiles[i].x - 1,
846 group.tiles[i].y - 1, TILE_WIDTH + 1,
849 //Remove tile from deck
850 if (tiles_to_remove[i] != game->deck.num_tiles - 1)
851 game->deck.tiles[tiles_to_remove[i]] = game->deck.tiles[game->deck.num_tiles-1];
852 game->deck.num_tiles--;
855 if (group.num_tiles > 0)
857 game->board.groups[game->board.num_groups] = group;
858 game->board.num_groups++;
861 printf("\nBut is the board valid?\t\t%s\n", board_valid(&game->board) ? "yes" : "no");
863 game->select_mode = 1;
868 static gboolean on_button_motion_event (GtkWidget *widget, GdkEventMotion *event,
869 game_t *game, cairo_t *cr)
871 if (game->select_mode)
873 selection_box_t *box;
874 box = &game->selection_box;
877 int x_min = MIN(box->x1, box->x2);
878 int x_max = MAX(box->x1, box->x2);
879 int y_min = MIN(box->y1, box->y2);
880 int y_max = MAX(box->y1, box->y2);
881 int width = abs(box->x2 - box->x1);
882 int height = abs(box->y2 - box->y1);
884 gtk_widget_queue_draw_area ( widget, x_min, y_min, width, height );
889 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) );
891 int i, tile_x, tile_y, tile_x2, tile_y2;
893 for (i = 0; i < game->deck.num_tiles; i++)
895 curr_tile = &game->deck.tiles[i];
897 tile_x = game->deck.tiles[i].x;
898 tile_y = game->deck.tiles[i].y;
899 tile_x2 = tile_x + TILE_WIDTH;
900 tile_y2 = tile_y + TILE_HEIGHT;
901 if (/*If top-left corner*/
902 (tile_x >= x_min && tile_x <= x_max &&
903 tile_y >= y_min && tile_y <= y_max) ||
904 /*or bottom-right corner*/
905 (tile_x2 >= x_min && tile_x2 <= x_max &&
906 tile_y2 >= y_min && tile_y2 <= y_max) ||
907 /*or bottom-left corner*/
908 (tile_x >= x_min && tile_x <= x_max &&
909 tile_y2 >= y_min && tile_y2 <= y_max) ||
910 /*or top-right corner*/
911 (tile_x2 >= x_min && tile_x2 <= x_max &&
912 tile_y >= y_min && tile_y <= y_max) ||
914 (y_min >= tile_y && y_min <= tile_y2 &&
915 x_min <= tile_x && x_max >= tile_x) ||
917 (x_min >= tile_x && x_min <= tile_x2 &&
918 y_min <= tile_y && y_max >= tile_y) ||
920 (y_min >= tile_y && y_min <= tile_y2 &&
921 x_min >= tile_x && x_min <= tile_x2) ||
922 /*or bottom edge of tile selected*/
923 (x_min >= tile_x && x_min <= tile_x2 &&
924 y_min >= tile_y && y_min <= tile_y) )
926 curr_tile->selected = 1;
927 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
932 if (curr_tile->selected)
934 curr_tile->selected = 0;
935 gtk_widget_queue_draw_area (widget, curr_tile->x - 1, curr_tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
942 if (game->drag_group_mode)
948 // tile = &game->deck.tiles[game->current_tile];
949 tile = game->current_tile;
951 /* First, invalidate the region where the tile currently is. */
952 gtk_widget_queue_draw_area (widget, tile->x - 1, tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
954 /* Then, move the tile */
955 tile->x = event->x - game->diff_x;
956 tile->y = event->y - game->diff_y;
958 /* Finally, invalidate the region where the tile is now. */
959 gtk_widget_queue_draw_area (widget, tile->x - 1, tile->y - 1, TILE_WIDTH + 1, TILE_HEIGHT + 2);
964 int main(int argc, char *argv[])
971 gtk_init (&argc, &argv);
974 deck_print(&game.deck);
975 deck_spread(&game.deck);
976 deck_deal(&game, &game.deck);
978 game.state.board = game.board;
979 game.state.deck = game.deck;
981 for (i=0; i < game.num_players; i++)
982 game.state.players[i] = game.players[i];
984 //hand_print(&game, 0); //With Zero being passed, will print hand for player 1(players[0])
985 //deck_print(&game.deck);
987 /* Create a new window */
988 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
989 gtk_window_set_default_size (GTK_WINDOW (window),
990 GAME_WINDOW_DEFAULT_WIDTH,
991 GAME_WINDOW_DEFAULT_HEIGHT);
993 gtk_widget_set_events (window,
996 GDK_BUTTON_MOTION_MASK |
997 GDK_BUTTON_PRESS_MASK |
998 GDK_BUTTON_RELEASE_MASK);
1000 g_signal_connect (G_OBJECT (window), "delete_event",
1001 G_CALLBACK (gtk_main_quit), NULL);
1002 g_signal_connect (G_OBJECT (window), "expose_event",
1003 G_CALLBACK (on_expose_event), &game);
1004 // g_signal_connect (G_OBJECT (window), "configure_event",
1005 // G_CALLBACK (on_configure_event), &game);
1006 g_signal_connect (G_OBJECT (window), "key_press_event",
1007 G_CALLBACK (on_key_press_event), &game);
1008 g_signal_connect (G_OBJECT (window), "button_press_event",
1009 G_CALLBACK (on_button_press_event), &game);
1010 g_signal_connect (G_OBJECT (window), "button_release_event",
1011 G_CALLBACK (on_button_release_event), &game);
1012 g_signal_connect (G_OBJECT (window), "motion_notify_event",
1013 G_CALLBACK (on_button_motion_event), &game);
1016 gtk_widget_show_all (window);