#include <gtk/gtk.h>
#include <math.h>
+#include "loa-board.h"
+
#define BOARD_SIZE 8
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,
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;
+ }
+
+ 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 ||
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);
}
}
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);
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);