]> git.cworth.org Git - loa/blobdiff - loa.c
Fix compilation by putting dependent libraries at the end
[loa] / loa.c
diff --git a/loa.c b/loa.c
index 48b5b045c3fdf76e4418a03e773eb4157581fd3e..355c66744df9dba359db3b54c2ed2801683b41ce 100644 (file)
--- a/loa.c
+++ b/loa.c
@@ -20,6 +20,8 @@
 #include <gtk/gtk.h>
 #include <math.h>
 
+#include "loa-board.h"
+
 #define BOARD_SIZE 8
 
 typedef struct {
@@ -30,6 +32,14 @@ typedef struct {
     int cell_size;
 } layout_t;
 
+typedef struct {
+    layout_t layout;
+    loa_board_t board;
+    loa_bool_t has_selected;
+    int selected_x;
+    int selected_y;
+} loa_game_t;
+
 static gboolean
 on_delete_event_quit (GtkWidget  *widget,
                      GdkEvent   *event,
@@ -42,13 +52,76 @@ on_delete_event_quit (GtkWidget  *widget,
     return FALSE;
 }
 
+/* Something like buff */
+#define LIGHT_SQUARE_COLOR 0.89, 0.70, 0.40
+/* Something like mahogany */
+#define DARK_SQUARE_COLOR  0.26, 0.02, 0.01
+
+static gboolean
+on_button_press_event (GtkWidget       *widget,
+                      GdkEventButton   *event,
+                      gpointer          user_data)
+{
+    loa_game_t *game = user_data;
+    layout_t *layout = &game->layout;
+    int x, y;
+    char *error;
+
+    x = (event->x - layout->x_offset) / layout->cell_size;
+    y = (event->y - layout->y_offset) / layout->cell_size;
+
+    if (! game->has_selected) {
+       if (game->board.cells[x][y] == game->board.player) {
+           game->has_selected = TRUE;
+           game->selected_x = x;
+           game->selected_y = y;
+           gtk_widget_queue_draw (widget);
+       }
+       return TRUE;
+    }
+
+    /* Do nothing for out-of-bounds clicks */
+    if (x < 0 || x >= LOA_BOARD_SIZE ||
+       y < 0 || y >= LOA_BOARD_SIZE)
+    {
+       return TRUE;
+    }
+
+    if (x == game->selected_x &&
+       y == game->selected_y)
+    {
+       game->has_selected = FALSE;
+       gtk_widget_queue_draw (widget);
+       return TRUE;
+    }
+       
+    if (loa_board_move (&game->board,
+                       game->selected_x, game->selected_y,
+                       x, y, &error))
+    {
+       game->has_selected = FALSE;
+       gtk_widget_queue_draw (widget);
+       return TRUE;
+    } else {
+       printf ("Illegal move %c%d%c%d: %s\n",
+               'a' + game->selected_x,
+               LOA_BOARD_SIZE - game->selected_y,
+               'a' + x,
+               LOA_BOARD_SIZE - y,
+               error);
+    }
+
+    return TRUE;
+}
+
 static gboolean
 on_expose_event_draw (GtkWidget                *widget,
                      GdkEventExpose    *event,
                      gpointer           user_data)
 {
+    loa_game_t *game = user_data;
+    layout_t *layout = &game->layout;
     cairo_t *cr;
-    layout_t *layout = user_data;
     int x, y;
 
     if (layout->width != widget->allocation.width ||
@@ -74,14 +147,45 @@ on_expose_event_draw (GtkWidget            *widget,
 
     for (y = 0; y < BOARD_SIZE; y++) {
        for (x = 0; x < BOARD_SIZE; x++) {
+           loa_cell_t cell;
+           cairo_save (cr);
+           cairo_translate(cr, x * layout->cell_size, y * layout->cell_size);
            if ((x + y) % 2 == 0)
-               cairo_set_source_rgb (cr, 0.89, 0.70, 0.40);
+               cairo_set_source_rgb (cr, LIGHT_SQUARE_COLOR);
            else
-               cairo_set_source_rgb (cr, 0.26, 0.02, 0.01);
-           cairo_rectangle (cr,
-                            x * layout->cell_size, y * layout->cell_size,
-                            layout->cell_size, layout->cell_size);
+               cairo_set_source_rgb (cr, DARK_SQUARE_COLOR);
+           cairo_rectangle (cr, 0, 0, layout->cell_size, layout->cell_size);
            cairo_fill (cr);
+           cell = game->board.cells[x][y];
+           if (cell != LOA_CELL_EMPTY) {
+               cairo_arc (cr,
+                          layout->cell_size / 2.0, layout->cell_size / 2.0,
+                          layout->cell_size / 2.5,
+                          0, 2 * M_PI);
+               if (cell == LOA_CELL_BLACK)
+                   cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+               else
+                   cairo_set_source_rgb (cr, 1, 1, 1); /* white */
+               cairo_fill_preserve (cr);
+               cairo_set_line_width (cr, 2.0);
+               if (cell == LOA_CELL_BLACK)
+                   cairo_set_source_rgb (cr, LIGHT_SQUARE_COLOR);
+               else
+                   cairo_set_source_rgb (cr, DARK_SQUARE_COLOR);
+               cairo_stroke (cr);
+           }
+           if (game->has_selected &&
+               x == game->selected_x &&
+               y == game->selected_y)
+           {
+               cairo_arc (cr,
+                          layout->cell_size / 2.0, layout->cell_size / 2.0,
+                          layout->cell_size / 2.5,
+                          0, 2 * M_PI);
+               cairo_set_source_rgba (cr, 0.2, 0.2, 1.0, 0.4);
+               cairo_fill (cr);
+           }
+           cairo_restore (cr);
        }
     }
 
@@ -90,21 +194,31 @@ on_expose_event_draw (GtkWidget            *widget,
     return TRUE;
 }
 
+static void
+loa_game_init (loa_game_t *game)
+{
+    game->layout.width = 0;
+    game->layout.height = 0;
+
+    game->has_selected = FALSE;
+
+    loa_board_init (&game->board);
+}
+
 int
 main (int argc, char *argv[])
 {
     GtkWidget *window;
     GtkWidget *drawing_area;
-    layout_t layout;
+    loa_game_t game;
 
-    layout.width = 0;
-    layout.height = 0;
+    loa_game_init (&game);
 
     gtk_init (&argc, &argv);
 
     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 
-    gtk_window_set_default_size (GTK_WINDOW (window), 100, 100);
+    gtk_window_set_default_size (GTK_WINDOW (window), 256, 256);
 
     g_signal_connect (window, "delete-event",
                      G_CALLBACK (on_delete_event_quit), NULL);
@@ -114,7 +228,11 @@ main (int argc, char *argv[])
     gtk_container_add (GTK_CONTAINER (window), drawing_area);
 
     g_signal_connect (drawing_area, "expose-event",  
-                     G_CALLBACK (on_expose_event_draw), &layout);
+                     G_CALLBACK (on_expose_event_draw), &game);
+
+    gtk_widget_add_events (drawing_area, GDK_BUTTON_PRESS_MASK);
+    g_signal_connect (drawing_area, "button-press-event",
+                     G_CALLBACK (on_button_press_event), &game);
 
     gtk_widget_show_all (window);