/* game.c generated by valac 0.16.0, the Vala compiler
 * generated from game.vala, do not modify */


#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <gobject/gvaluecollector.h>


#define TYPE_TILE (tile_get_type ())
#define TILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_TILE, Tile))
#define TILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_TILE, TileClass))
#define IS_TILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_TILE))
#define IS_TILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_TILE))
#define TILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_TILE, TileClass))

typedef struct _Tile Tile;
typedef struct _TileClass TileClass;
typedef struct _TilePrivate TilePrivate;

#define TYPE_SLOT (slot_get_type ())
#define SLOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_SLOT, Slot))
#define SLOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_SLOT, SlotClass))
#define IS_SLOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_SLOT))
#define IS_SLOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_SLOT))
#define SLOT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_SLOT, SlotClass))

typedef struct _Slot Slot;
typedef struct _SlotClass SlotClass;
#define _slot_unref0(var) ((var == NULL) ? NULL : (var = (slot_unref (var), NULL)))
typedef struct _ParamSpecTile ParamSpecTile;

#define TYPE_MATCH (match_get_type ())
#define MATCH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MATCH, Match))
#define MATCH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MATCH, MatchClass))
#define IS_MATCH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MATCH))
#define IS_MATCH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MATCH))
#define MATCH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_MATCH, MatchClass))

typedef struct _Match Match;
typedef struct _MatchClass MatchClass;
typedef struct _MatchPrivate MatchPrivate;
#define _tile_unref0(var) ((var == NULL) ? NULL : (var = (tile_unref (var), NULL)))
typedef struct _ParamSpecMatch ParamSpecMatch;

#define TYPE_GAME (game_get_type ())
#define GAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_GAME, Game))
#define GAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_GAME, GameClass))
#define IS_GAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_GAME))
#define IS_GAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_GAME))
#define GAME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_GAME, GameClass))

typedef struct _Game Game;
typedef struct _GameClass GameClass;
typedef struct _GamePrivate GamePrivate;

#define TYPE_MAP (map_get_type ())
#define MAP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MAP, Map))
#define MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MAP, MapClass))
#define IS_MAP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MAP))
#define IS_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MAP))
#define MAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_MAP, MapClass))

typedef struct _Map Map;
typedef struct _MapClass MapClass;
#define _map_unref0(var) ((var == NULL) ? NULL : (var = (map_unref (var), NULL)))
#define __g_list_free__tile_unref0_0(var) ((var == NULL) ? NULL : (var = (_g_list_free__tile_unref0_ (var), NULL)))
typedef struct _MapPrivate MapPrivate;
#define __g_list_free__match_unref0_0(var) ((var == NULL) ? NULL : (var = (_g_list_free__match_unref0_ (var), NULL)))
#define _match_unref0(var) ((var == NULL) ? NULL : (var = (match_unref (var), NULL)))
typedef struct _SlotPrivate SlotPrivate;
typedef struct _ParamSpecGame ParamSpecGame;

struct _Tile {
	GTypeInstance parent_instance;
	volatile int ref_count;
	TilePrivate * priv;
	gint number;
	Slot* slot;
	gboolean visible;
	gint move_number;
};

struct _TileClass {
	GTypeClass parent_class;
	void (*finalize) (Tile *self);
};

struct _ParamSpecTile {
	GParamSpec parent_instance;
};

struct _Match {
	GTypeInstance parent_instance;
	volatile int ref_count;
	MatchPrivate * priv;
	Tile* tile0;
	Tile* tile1;
};

struct _MatchClass {
	GTypeClass parent_class;
	void (*finalize) (Match *self);
};

struct _ParamSpecMatch {
	GParamSpec parent_instance;
};

struct _Game {
	GTypeInstance parent_instance;
	volatile int ref_count;
	GamePrivate * priv;
	Map* map;
	GList* tiles;
	Tile* hint_tiles[2];
	gint move_number;
	guint hint_blink_counter;
};

struct _GameClass {
	GTypeClass parent_class;
	void (*finalize) (Game *self);
};

struct _GamePrivate {
	guint hint_timer;
	Tile* _selected_tile;
};

struct _Map {
	GTypeInstance parent_instance;
	volatile int ref_count;
	MapPrivate * priv;
	gchar* name;
	gchar* score_name;
	GList* slots;
};

struct _MapClass {
	GTypeClass parent_class;
	void (*finalize) (Map *self);
};

struct _Slot {
	GTypeInstance parent_instance;
	volatile int ref_count;
	SlotPrivate * priv;
	gint x;
	gint y;
	gint layer;
};

struct _SlotClass {
	GTypeClass parent_class;
	void (*finalize) (Slot *self);
};

struct _ParamSpecGame {
	GParamSpec parent_instance;
};


static gpointer tile_parent_class = NULL;
static gpointer match_parent_class = NULL;
static gpointer game_parent_class = NULL;

gpointer tile_ref (gpointer instance);
void tile_unref (gpointer instance);
GParamSpec* param_spec_tile (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_tile (GValue* value, gpointer v_object);
void value_take_tile (GValue* value, gpointer v_object);
gpointer value_get_tile (const GValue* value);
GType tile_get_type (void) G_GNUC_CONST;
gpointer slot_ref (gpointer instance);
void slot_unref (gpointer instance);
GParamSpec* param_spec_slot (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_slot (GValue* value, gpointer v_object);
void value_take_slot (GValue* value, gpointer v_object);
gpointer value_get_slot (const GValue* value);
GType slot_get_type (void) G_GNUC_CONST;
enum  {
	TILE_DUMMY_PROPERTY
};
Tile* tile_new (Slot* slot);
Tile* tile_construct (GType object_type, Slot* slot);
gboolean tile_matches (Tile* self, Tile* tile);
gint tile_get_set (Tile* self);
static void tile_finalize (Tile* obj);
gint compare_tiles (Tile* a, Tile* b);
gint compare_slots (Slot* a, Slot* b);
gpointer match_ref (gpointer instance);
void match_unref (gpointer instance);
GParamSpec* param_spec_match (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_match (GValue* value, gpointer v_object);
void value_take_match (GValue* value, gpointer v_object);
gpointer value_get_match (const GValue* value);
GType match_get_type (void) G_GNUC_CONST;
enum  {
	MATCH_DUMMY_PROPERTY
};
Match* match_new (Tile* tile0, Tile* tile1);
Match* match_construct (GType object_type, Tile* tile0, Tile* tile1);
static void match_finalize (Match* obj);
gpointer game_ref (gpointer instance);
void game_unref (gpointer instance);
GParamSpec* param_spec_game (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_game (GValue* value, gpointer v_object);
void value_take_game (GValue* value, gpointer v_object);
gpointer value_get_game (const GValue* value);
GType game_get_type (void) G_GNUC_CONST;
gpointer map_ref (gpointer instance);
void map_unref (gpointer instance);
GParamSpec* param_spec_map (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_map (GValue* value, gpointer v_object);
void value_take_map (GValue* value, gpointer v_object);
gpointer value_get_map (const GValue* value);
GType map_get_type (void) G_GNUC_CONST;
#define GAME_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_GAME, GamePrivate))
enum  {
	GAME_DUMMY_PROPERTY
};
static void _tile_unref0_ (gpointer var);
static void _g_list_free__tile_unref0_ (GList* self);
Game* game_new (Map* map);
Game* game_construct (GType object_type, Map* map);
static gint _compare_tiles_gcompare_func (gconstpointer a, gconstpointer b);
static gboolean game_shuffle (Game* self, gint* numbers, int numbers_length1, gint depth);
void game_reset (Game* self);
GList* game_find_matches (Game* self, Tile* tile);
static void _match_unref0_ (gpointer var);
static void _g_list_free__match_unref0_ (GList* self);
void game_set_selected_tile (Game* self, Tile* value);
void game_set_hint (Game* self, Tile* tile0, Tile* tile1);
static gboolean game_hint_timeout_cb (Game* self);
static gboolean _game_hint_timeout_cb_gsource_func (gpointer self);
gboolean game_tile_can_move (Game* self, Tile* tile);
gboolean game_remove_pair (Game* self, Tile* tile0, Tile* tile1);
void game_undo (Game* self);
gboolean game_get_can_undo (Game* self);
void game_redo (Game* self);
gboolean game_get_can_redo (Game* self);
gboolean game_get_started (Game* self);
Tile* game_get_selected_tile (Game* self);
gint game_get_visible_tiles (Game* self);
guint game_get_moves_left (Game* self);
gboolean game_get_complete (Game* self);
gboolean game_get_can_move (Game* self);
static void g_cclosure_user_marshal_VOID__TILE (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data);
static void game_finalize (Game* obj);
static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func);


static gpointer _slot_ref0 (gpointer self) {
	return self ? slot_ref (self) : NULL;
}


Tile* tile_construct (GType object_type, Slot* slot) {
	Tile* self = NULL;
	Slot* _tmp0_;
	Slot* _tmp1_;
	g_return_val_if_fail (slot != NULL, NULL);
	self = (Tile*) g_type_create_instance (object_type);
	_tmp0_ = slot;
	_tmp1_ = _slot_ref0 (_tmp0_);
	_slot_unref0 (self->slot);
	self->slot = _tmp1_;
	return self;
}


Tile* tile_new (Slot* slot) {
	return tile_construct (TYPE_TILE, slot);
}


gboolean tile_matches (Tile* self, Tile* tile) {
	gboolean result = FALSE;
	Tile* _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	gint _tmp3_;
	gint _tmp4_;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (tile != NULL, FALSE);
	_tmp0_ = tile;
	_tmp1_ = tile_get_set (_tmp0_);
	_tmp2_ = _tmp1_;
	_tmp3_ = tile_get_set (self);
	_tmp4_ = _tmp3_;
	result = _tmp2_ == _tmp4_;
	return result;
}


gint tile_get_set (Tile* self) {
	gint result;
	gint _tmp0_;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = self->number;
	result = _tmp0_ / 4;
	return result;
}


static void value_tile_init (GValue* value) {
	value->data[0].v_pointer = NULL;
}


static void value_tile_free_value (GValue* value) {
	if (value->data[0].v_pointer) {
		tile_unref (value->data[0].v_pointer);
	}
}


static void value_tile_copy_value (const GValue* src_value, GValue* dest_value) {
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = tile_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}


static gpointer value_tile_peek_pointer (const GValue* value) {
	return value->data[0].v_pointer;
}


static gchar* value_tile_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	if (collect_values[0].v_pointer) {
		Tile* object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = tile_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}


static gchar* value_tile_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	Tile** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = tile_ref (value->data[0].v_pointer);
	}
	return NULL;
}


GParamSpec* param_spec_tile (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
	ParamSpecTile* spec;
	g_return_val_if_fail (g_type_is_a (object_type, TYPE_TILE), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}


gpointer value_get_tile (const GValue* value) {
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_TILE), NULL);
	return value->data[0].v_pointer;
}


void value_set_tile (GValue* value, gpointer v_object) {
	Tile* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_TILE));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_TILE));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		tile_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		tile_unref (old);
	}
}


void value_take_tile (GValue* value, gpointer v_object) {
	Tile* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_TILE));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_TILE));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		tile_unref (old);
	}
}


static void tile_class_init (TileClass * klass) {
	tile_parent_class = g_type_class_peek_parent (klass);
	TILE_CLASS (klass)->finalize = tile_finalize;
}


static void tile_instance_init (Tile * self) {
	self->visible = TRUE;
	self->ref_count = 1;
}


static void tile_finalize (Tile* obj) {
	Tile * self;
	self = TILE (obj);
	_slot_unref0 (self->slot);
}


GType tile_get_type (void) {
	static volatile gsize tile_type_id__volatile = 0;
	if (g_once_init_enter (&tile_type_id__volatile)) {
		static const GTypeValueTable g_define_type_value_table = { value_tile_init, value_tile_free_value, value_tile_copy_value, value_tile_peek_pointer, "p", value_tile_collect_value, "p", value_tile_lcopy_value };
		static const GTypeInfo g_define_type_info = { sizeof (TileClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) tile_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Tile), 0, (GInstanceInitFunc) tile_instance_init, &g_define_type_value_table };
		static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
		GType tile_type_id;
		tile_type_id = g_type_register_fundamental (g_type_fundamental_next (), "Tile", &g_define_type_info, &g_define_type_fundamental_info, 0);
		g_once_init_leave (&tile_type_id__volatile, tile_type_id);
	}
	return tile_type_id__volatile;
}


gpointer tile_ref (gpointer instance) {
	Tile* self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}


void tile_unref (gpointer instance) {
	Tile* self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		TILE_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}


gint compare_tiles (Tile* a, Tile* b) {
	gint result = 0;
	Tile* _tmp0_;
	Slot* _tmp1_;
	Tile* _tmp2_;
	Slot* _tmp3_;
	gint _tmp4_ = 0;
	g_return_val_if_fail (a != NULL, 0);
	g_return_val_if_fail (b != NULL, 0);
	_tmp0_ = a;
	_tmp1_ = _tmp0_->slot;
	_tmp2_ = b;
	_tmp3_ = _tmp2_->slot;
	_tmp4_ = compare_slots (_tmp1_, _tmp3_);
	result = _tmp4_;
	return result;
}


static gpointer _tile_ref0 (gpointer self) {
	return self ? tile_ref (self) : NULL;
}


Match* match_construct (GType object_type, Tile* tile0, Tile* tile1) {
	Match* self = NULL;
	Tile* _tmp0_;
	Tile* _tmp1_;
	Tile* _tmp2_;
	Tile* _tmp3_;
	g_return_val_if_fail (tile0 != NULL, NULL);
	g_return_val_if_fail (tile1 != NULL, NULL);
	self = (Match*) g_type_create_instance (object_type);
	_tmp0_ = tile0;
	_tmp1_ = _tile_ref0 (_tmp0_);
	_tile_unref0 (self->tile0);
	self->tile0 = _tmp1_;
	_tmp2_ = tile1;
	_tmp3_ = _tile_ref0 (_tmp2_);
	_tile_unref0 (self->tile1);
	self->tile1 = _tmp3_;
	return self;
}


Match* match_new (Tile* tile0, Tile* tile1) {
	return match_construct (TYPE_MATCH, tile0, tile1);
}


static void value_match_init (GValue* value) {
	value->data[0].v_pointer = NULL;
}


static void value_match_free_value (GValue* value) {
	if (value->data[0].v_pointer) {
		match_unref (value->data[0].v_pointer);
	}
}


static void value_match_copy_value (const GValue* src_value, GValue* dest_value) {
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = match_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}


static gpointer value_match_peek_pointer (const GValue* value) {
	return value->data[0].v_pointer;
}


static gchar* value_match_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	if (collect_values[0].v_pointer) {
		Match* object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = match_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}


static gchar* value_match_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	Match** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = match_ref (value->data[0].v_pointer);
	}
	return NULL;
}


GParamSpec* param_spec_match (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
	ParamSpecMatch* spec;
	g_return_val_if_fail (g_type_is_a (object_type, TYPE_MATCH), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}


gpointer value_get_match (const GValue* value) {
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_MATCH), NULL);
	return value->data[0].v_pointer;
}


void value_set_match (GValue* value, gpointer v_object) {
	Match* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_MATCH));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_MATCH));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		match_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		match_unref (old);
	}
}


void value_take_match (GValue* value, gpointer v_object) {
	Match* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_MATCH));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_MATCH));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		match_unref (old);
	}
}


static void match_class_init (MatchClass * klass) {
	match_parent_class = g_type_class_peek_parent (klass);
	MATCH_CLASS (klass)->finalize = match_finalize;
}


static void match_instance_init (Match * self) {
	self->ref_count = 1;
}


static void match_finalize (Match* obj) {
	Match * self;
	self = MATCH (obj);
	_tile_unref0 (self->tile0);
	_tile_unref0 (self->tile1);
}


GType match_get_type (void) {
	static volatile gsize match_type_id__volatile = 0;
	if (g_once_init_enter (&match_type_id__volatile)) {
		static const GTypeValueTable g_define_type_value_table = { value_match_init, value_match_free_value, value_match_copy_value, value_match_peek_pointer, "p", value_match_collect_value, "p", value_match_lcopy_value };
		static const GTypeInfo g_define_type_info = { sizeof (MatchClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) match_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Match), 0, (GInstanceInitFunc) match_instance_init, &g_define_type_value_table };
		static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
		GType match_type_id;
		match_type_id = g_type_register_fundamental (g_type_fundamental_next (), "Match", &g_define_type_info, &g_define_type_fundamental_info, 0);
		g_once_init_leave (&match_type_id__volatile, match_type_id);
	}
	return match_type_id__volatile;
}


gpointer match_ref (gpointer instance) {
	Match* self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}


void match_unref (gpointer instance) {
	Match* self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		MATCH_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}


static void _tile_unref0_ (gpointer var) {
	(var == NULL) ? NULL : (var = (tile_unref (var), NULL));
}


static void _g_list_free__tile_unref0_ (GList* self) {
	g_list_foreach (self, (GFunc) _tile_unref0_, NULL);
	g_list_free (self);
}


static gpointer _map_ref0 (gpointer self) {
	return self ? map_ref (self) : NULL;
}


static gint _compare_tiles_gcompare_func (gconstpointer a, gconstpointer b) {
	gint result;
	result = compare_tiles (a, b);
	return result;
}


Game* game_construct (GType object_type, Map* map) {
	Game* self = NULL;
	Map* _tmp0_;
	Map* _tmp1_;
	Map* _tmp2_;
	GList* _tmp3_;
	GList* _tmp10_;
	guint _tmp11_ = 0U;
	gint n_pairs;
	gint _tmp12_;
	gint* _tmp13_ = NULL;
	gint* numbers;
	gint numbers_length1;
	gint _numbers_size_;
	gint* _tmp44_;
	gint _tmp44__length1;
	g_return_val_if_fail (map != NULL, NULL);
	self = (Game*) g_type_create_instance (object_type);
	_tmp0_ = map;
	_tmp1_ = _map_ref0 (_tmp0_);
	_map_unref0 (self->map);
	self->map = _tmp1_;
	self->move_number = 1;
	_tmp2_ = map;
	_tmp3_ = _tmp2_->slots;
	{
		GList* slot_collection = NULL;
		GList* slot_it = NULL;
		slot_collection = _tmp3_;
		for (slot_it = slot_collection; slot_it != NULL; slot_it = slot_it->next) {
			Slot* _tmp4_;
			Slot* slot = NULL;
			_tmp4_ = _slot_ref0 ((Slot*) slot_it->data);
			slot = _tmp4_;
			{
				Slot* _tmp5_;
				Tile* _tmp6_;
				Tile* tile;
				Tile* _tmp7_;
				Tile* _tmp8_;
				Tile* _tmp9_;
				_tmp5_ = slot;
				_tmp6_ = tile_new (_tmp5_);
				tile = _tmp6_;
				_tmp7_ = tile;
				_tmp7_->number = 0;
				_tmp8_ = tile;
				_tmp9_ = _tile_ref0 (_tmp8_);
				self->tiles = g_list_insert_sorted (self->tiles, _tmp9_, _compare_tiles_gcompare_func);
				_tile_unref0 (tile);
				_slot_unref0 (slot);
			}
		}
	}
	_tmp10_ = self->tiles;
	_tmp11_ = g_list_length (_tmp10_);
	n_pairs = ((gint) _tmp11_) / 2;
	_tmp12_ = n_pairs;
	_tmp13_ = g_new0 (gint, _tmp12_);
	numbers = _tmp13_;
	numbers_length1 = _tmp12_;
	_numbers_size_ = numbers_length1;
	{
		gint i;
		i = 0;
		{
			gboolean _tmp14_;
			_tmp14_ = TRUE;
			while (TRUE) {
				gboolean _tmp15_;
				gint _tmp17_;
				gint _tmp18_;
				gint* _tmp19_;
				gint _tmp19__length1;
				gint _tmp20_;
				gint _tmp21_;
				gint _tmp22_;
				_tmp15_ = _tmp14_;
				if (!_tmp15_) {
					gint _tmp16_;
					_tmp16_ = i;
					i = _tmp16_ + 1;
				}
				_tmp14_ = FALSE;
				_tmp17_ = i;
				_tmp18_ = n_pairs;
				if (!(_tmp17_ < _tmp18_)) {
					break;
				}
				_tmp19_ = numbers;
				_tmp19__length1 = numbers_length1;
				_tmp20_ = i;
				_tmp21_ = i;
				_tmp19_[_tmp20_] = _tmp21_ * 2;
				_tmp22_ = _tmp19_[_tmp20_];
			}
		}
	}
	{
		gint i;
		i = 0;
		{
			gboolean _tmp23_;
			_tmp23_ = TRUE;
			while (TRUE) {
				gboolean _tmp24_;
				gint _tmp26_;
				gint _tmp27_;
				gint _tmp28_;
				gint _tmp29_;
				gint32 _tmp30_ = 0;
				gint32 n;
				gint* _tmp31_;
				gint _tmp31__length1;
				gint _tmp32_;
				gint _tmp33_;
				gint t;
				gint* _tmp34_;
				gint _tmp34__length1;
				gint _tmp35_;
				gint* _tmp36_;
				gint _tmp36__length1;
				gint32 _tmp37_;
				gint _tmp38_;
				gint _tmp39_;
				gint* _tmp40_;
				gint _tmp40__length1;
				gint32 _tmp41_;
				gint _tmp42_;
				gint _tmp43_;
				_tmp24_ = _tmp23_;
				if (!_tmp24_) {
					gint _tmp25_;
					_tmp25_ = i;
					i = _tmp25_ + 1;
				}
				_tmp23_ = FALSE;
				_tmp26_ = i;
				_tmp27_ = n_pairs;
				if (!(_tmp26_ < _tmp27_)) {
					break;
				}
				_tmp28_ = i;
				_tmp29_ = n_pairs;
				_tmp30_ = g_random_int_range ((gint32) _tmp28_, (gint32) _tmp29_);
				n = _tmp30_;
				_tmp31_ = numbers;
				_tmp31__length1 = numbers_length1;
				_tmp32_ = i;
				_tmp33_ = _tmp31_[_tmp32_];
				t = _tmp33_;
				_tmp34_ = numbers;
				_tmp34__length1 = numbers_length1;
				_tmp35_ = i;
				_tmp36_ = numbers;
				_tmp36__length1 = numbers_length1;
				_tmp37_ = n;
				_tmp38_ = _tmp36_[_tmp37_];
				_tmp34_[_tmp35_] = _tmp38_;
				_tmp39_ = _tmp34_[_tmp35_];
				_tmp40_ = numbers;
				_tmp40__length1 = numbers_length1;
				_tmp41_ = n;
				_tmp42_ = t;
				_tmp40_[_tmp41_] = _tmp42_;
				_tmp43_ = _tmp40_[_tmp41_];
			}
		}
	}
	_tmp44_ = numbers;
	_tmp44__length1 = numbers_length1;
	game_shuffle (self, _tmp44_, _tmp44__length1, 0);
	game_reset (self);
	numbers = (g_free (numbers), NULL);
	return self;
}


Game* game_new (Map* map) {
	return game_construct (TYPE_GAME, map);
}


static void _match_unref0_ (gpointer var) {
	(var == NULL) ? NULL : (var = (match_unref (var), NULL));
}


static void _g_list_free__match_unref0_ (GList* self) {
	g_list_foreach (self, (GFunc) _match_unref0_, NULL);
	g_list_free (self);
}


static gpointer _match_ref0 (gpointer self) {
	return self ? match_ref (self) : NULL;
}


static gboolean game_shuffle (Game* self, gint* numbers, int numbers_length1, gint depth) {
	gboolean result = FALSE;
	gint _tmp0_;
	GList* _tmp1_;
	guint _tmp2_ = 0U;
	GList* _tmp3_ = NULL;
	GList* matches;
	GList* _tmp4_;
	guint _tmp5_ = 0U;
	guint n_matches;
	guint _tmp6_;
	guint _tmp7_;
	gint32 _tmp8_ = 0;
	gint32 n;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = depth;
	_tmp1_ = self->tiles;
	_tmp2_ = g_list_length (_tmp1_);
	if (((guint) _tmp0_) == (_tmp2_ / 2)) {
		result = TRUE;
		return result;
	}
	_tmp3_ = game_find_matches (self, NULL);
	matches = _tmp3_;
	_tmp4_ = matches;
	_tmp5_ = g_list_length (_tmp4_);
	n_matches = _tmp5_;
	_tmp6_ = n_matches;
	if (_tmp6_ == ((guint) 0)) {
		result = FALSE;
		__g_list_free__match_unref0_0 (matches);
		return result;
	}
	_tmp7_ = n_matches;
	_tmp8_ = g_random_int_range ((gint32) 0, (gint32) ((gint) _tmp7_));
	n = _tmp8_;
	{
		gint i;
		i = 0;
		{
			gboolean _tmp9_;
			_tmp9_ = TRUE;
			while (TRUE) {
				gboolean _tmp10_;
				gint _tmp12_;
				guint _tmp13_;
				GList* _tmp14_;
				gint32 _tmp15_;
				gint _tmp16_;
				guint _tmp17_;
				gconstpointer _tmp18_ = NULL;
				Match* _tmp19_;
				Match* match;
				Match* _tmp20_;
				Tile* _tmp21_;
				gint* _tmp22_;
				gint _tmp22__length1;
				gint _tmp23_;
				gint _tmp24_;
				Match* _tmp25_;
				Tile* _tmp26_;
				Match* _tmp27_;
				Tile* _tmp28_;
				gint* _tmp29_;
				gint _tmp29__length1;
				gint _tmp30_;
				gint _tmp31_;
				Match* _tmp32_;
				Tile* _tmp33_;
				gint* _tmp34_;
				gint _tmp34__length1;
				gint _tmp35_;
				gboolean _tmp36_ = FALSE;
				Match* _tmp37_;
				Tile* _tmp38_;
				Match* _tmp39_;
				Tile* _tmp40_;
				Match* _tmp41_;
				Tile* _tmp42_;
				Match* _tmp43_;
				Tile* _tmp44_;
				_tmp10_ = _tmp9_;
				if (!_tmp10_) {
					gint _tmp11_;
					_tmp11_ = i;
					i = _tmp11_ + 1;
				}
				_tmp9_ = FALSE;
				_tmp12_ = i;
				_tmp13_ = n_matches;
				if (!(((guint) _tmp12_) < _tmp13_)) {
					break;
				}
				_tmp14_ = matches;
				_tmp15_ = n;
				_tmp16_ = i;
				_tmp17_ = n_matches;
				_tmp18_ = g_list_nth_data (_tmp14_, (_tmp15_ + _tmp16_) % _tmp17_);
				_tmp19_ = _match_ref0 ((Match*) _tmp18_);
				match = _tmp19_;
				_tmp20_ = match;
				_tmp21_ = _tmp20_->tile0;
				_tmp22_ = numbers;
				_tmp22__length1 = numbers_length1;
				_tmp23_ = depth;
				_tmp24_ = _tmp22_[_tmp23_];
				_tmp21_->number = _tmp24_;
				_tmp25_ = match;
				_tmp26_ = _tmp25_->tile0;
				_tmp26_->visible = FALSE;
				_tmp27_ = match;
				_tmp28_ = _tmp27_->tile1;
				_tmp29_ = numbers;
				_tmp29__length1 = numbers_length1;
				_tmp30_ = depth;
				_tmp31_ = _tmp29_[_tmp30_];
				_tmp28_->number = _tmp31_ + 1;
				_tmp32_ = match;
				_tmp33_ = _tmp32_->tile1;
				_tmp33_->visible = FALSE;
				_tmp34_ = numbers;
				_tmp34__length1 = numbers_length1;
				_tmp35_ = depth;
				_tmp36_ = game_shuffle (self, _tmp34_, _tmp34__length1, _tmp35_ + 1);
				if (_tmp36_) {
					result = TRUE;
					_match_unref0 (match);
					__g_list_free__match_unref0_0 (matches);
					return result;
				}
				_tmp37_ = match;
				_tmp38_ = _tmp37_->tile0;
				_tmp38_->number = 0;
				_tmp39_ = match;
				_tmp40_ = _tmp39_->tile0;
				_tmp40_->visible = TRUE;
				_tmp41_ = match;
				_tmp42_ = _tmp41_->tile1;
				_tmp42_->number = 0;
				_tmp43_ = match;
				_tmp44_ = _tmp43_->tile1;
				_tmp44_->visible = TRUE;
				_match_unref0 (match);
			}
		}
	}
	result = FALSE;
	__g_list_free__match_unref0_0 (matches);
	return result;
}


void game_reset (Game* self) {
	GList* _tmp0_;
	g_return_if_fail (self != NULL);
	game_set_selected_tile (self, NULL);
	game_set_hint (self, NULL, NULL);
	_tmp0_ = self->tiles;
	{
		GList* tile_collection = NULL;
		GList* tile_it = NULL;
		tile_collection = _tmp0_;
		for (tile_it = tile_collection; tile_it != NULL; tile_it = tile_it->next) {
			Tile* _tmp1_;
			Tile* tile = NULL;
			_tmp1_ = _tile_ref0 ((Tile*) tile_it->data);
			tile = _tmp1_;
			{
				Tile* _tmp2_;
				Tile* _tmp3_;
				_tmp2_ = tile;
				_tmp2_->visible = TRUE;
				_tmp3_ = tile;
				_tmp3_->move_number = 0;
				_tile_unref0 (tile);
			}
		}
	}
}


static gboolean _game_hint_timeout_cb_gsource_func (gpointer self) {
	gboolean result;
	result = game_hint_timeout_cb (self);
	return result;
}


void game_set_hint (Game* self, Tile* tile0, Tile* tile1) {
	Tile* _tmp0_;
	Tile* _tmp2_;
	gboolean _tmp4_ = FALSE;
	Tile* _tmp5_;
	gboolean _tmp7_;
	Tile* _tmp8_;
	Tile* _tmp9_;
	Tile* _tmp10_;
	Tile* _tmp11_;
	Tile* _tmp12_;
	Tile* _tmp13_;
	guint _tmp14_;
	guint _tmp16_ = 0U;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->hint_tiles[0];
	if (_tmp0_ != NULL) {
		Tile* _tmp1_;
		_tmp1_ = self->hint_tiles[0];
		g_signal_emit_by_name (self, "redraw-tile", _tmp1_);
	}
	_tmp2_ = self->hint_tiles[1];
	if (_tmp2_ != NULL) {
		Tile* _tmp3_;
		_tmp3_ = self->hint_tiles[1];
		g_signal_emit_by_name (self, "redraw-tile", _tmp3_);
	}
	_tmp5_ = tile0;
	if (_tmp5_ == NULL) {
		Tile* _tmp6_;
		_tmp6_ = tile1;
		_tmp4_ = _tmp6_ == NULL;
	} else {
		_tmp4_ = FALSE;
	}
	_tmp7_ = _tmp4_;
	if (_tmp7_) {
		self->hint_blink_counter = (guint) 0;
		game_hint_timeout_cb (self);
		return;
	}
	_tmp8_ = tile0;
	_tmp9_ = _tile_ref0 (_tmp8_);
	_tile_unref0 (self->hint_tiles[0]);
	self->hint_tiles[0] = _tmp9_;
	_tmp10_ = self->hint_tiles[0];
	_tmp11_ = tile1;
	_tmp12_ = _tile_ref0 (_tmp11_);
	_tile_unref0 (self->hint_tiles[1]);
	self->hint_tiles[1] = _tmp12_;
	_tmp13_ = self->hint_tiles[1];
	self->hint_blink_counter = (guint) 6;
	_tmp14_ = self->priv->hint_timer;
	if (_tmp14_ != ((guint) 0)) {
		guint _tmp15_;
		_tmp15_ = self->priv->hint_timer;
		g_source_remove (_tmp15_);
	}
	_tmp16_ = g_timeout_add_full (G_PRIORITY_DEFAULT, (guint) 250, _game_hint_timeout_cb_gsource_func, game_ref (self), game_unref);
	self->priv->hint_timer = _tmp16_;
	game_hint_timeout_cb (self);
}


static gboolean game_hint_timeout_cb (Game* self) {
	gboolean result = FALSE;
	guint _tmp0_;
	guint _tmp3_;
	Tile* _tmp4_;
	Tile* _tmp6_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->hint_blink_counter;
	if (_tmp0_ == ((guint) 0)) {
		guint _tmp1_;
		_tmp1_ = self->priv->hint_timer;
		if (_tmp1_ != ((guint) 0)) {
			guint _tmp2_;
			_tmp2_ = self->priv->hint_timer;
			g_source_remove (_tmp2_);
		}
		self->priv->hint_timer = (guint) 0;
		result = FALSE;
		return result;
	}
	_tmp3_ = self->hint_blink_counter;
	self->hint_blink_counter = _tmp3_ - 1;
	_tmp4_ = self->hint_tiles[0];
	if (_tmp4_ != NULL) {
		Tile* _tmp5_;
		_tmp5_ = self->hint_tiles[0];
		g_signal_emit_by_name (self, "redraw-tile", _tmp5_);
	}
	_tmp6_ = self->hint_tiles[1];
	if (_tmp6_ != NULL) {
		Tile* _tmp7_;
		_tmp7_ = self->hint_tiles[1];
		g_signal_emit_by_name (self, "redraw-tile", _tmp7_);
	}
	result = TRUE;
	return result;
}


gboolean game_tile_can_move (Game* self, Tile* tile) {
	gboolean result = FALSE;
	Tile* _tmp0_;
	gboolean _tmp1_;
	gboolean blocked_left;
	gboolean blocked_right;
	Tile* _tmp2_;
	Slot* _tmp3_;
	Slot* _tmp4_;
	Slot* slot;
	GList* _tmp5_;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (tile != NULL, FALSE);
	_tmp0_ = tile;
	_tmp1_ = _tmp0_->visible;
	if (!_tmp1_) {
		result = FALSE;
		return result;
	}
	blocked_left = FALSE;
	blocked_right = FALSE;
	_tmp2_ = tile;
	_tmp3_ = _tmp2_->slot;
	_tmp4_ = _slot_ref0 (_tmp3_);
	slot = _tmp4_;
	_tmp5_ = self->tiles;
	{
		GList* t_collection = NULL;
		GList* t_it = NULL;
		t_collection = _tmp5_;
		for (t_it = t_collection; t_it != NULL; t_it = t_it->next) {
			Tile* _tmp6_;
			Tile* t = NULL;
			_tmp6_ = _tile_ref0 ((Tile*) t_it->data);
			t = _tmp6_;
			{
				gboolean _tmp7_ = FALSE;
				Tile* _tmp8_;
				Tile* _tmp9_;
				gboolean _tmp12_;
				Tile* _tmp13_;
				Slot* _tmp14_;
				Slot* _tmp15_;
				Slot* s;
				gboolean _tmp16_ = FALSE;
				gboolean _tmp17_ = FALSE;
				Slot* _tmp18_;
				gint _tmp19_;
				Slot* _tmp20_;
				gint _tmp21_;
				gboolean _tmp32_;
				gboolean _tmp43_;
				gboolean _tmp44_ = FALSE;
				Slot* _tmp45_;
				gint _tmp46_;
				Slot* _tmp47_;
				gint _tmp48_;
				gboolean _tmp59_;
				_tmp8_ = t;
				_tmp9_ = tile;
				if (_tmp8_ == _tmp9_) {
					_tmp7_ = TRUE;
				} else {
					Tile* _tmp10_;
					gboolean _tmp11_;
					_tmp10_ = t;
					_tmp11_ = _tmp10_->visible;
					_tmp7_ = !_tmp11_;
				}
				_tmp12_ = _tmp7_;
				if (_tmp12_) {
					_tile_unref0 (t);
					continue;
				}
				_tmp13_ = t;
				_tmp14_ = _tmp13_->slot;
				_tmp15_ = _slot_ref0 (_tmp14_);
				s = _tmp15_;
				_tmp18_ = s;
				_tmp19_ = _tmp18_->layer;
				_tmp20_ = slot;
				_tmp21_ = _tmp20_->layer;
				if (_tmp19_ == (_tmp21_ + 1)) {
					gboolean _tmp22_ = FALSE;
					Slot* _tmp23_;
					gint _tmp24_;
					Slot* _tmp25_;
					gint _tmp26_;
					gboolean _tmp31_;
					_tmp23_ = s;
					_tmp24_ = _tmp23_->x;
					_tmp25_ = slot;
					_tmp26_ = _tmp25_->x;
					if (_tmp24_ >= (_tmp26_ - 1)) {
						Slot* _tmp27_;
						gint _tmp28_;
						Slot* _tmp29_;
						gint _tmp30_;
						_tmp27_ = s;
						_tmp28_ = _tmp27_->x;
						_tmp29_ = slot;
						_tmp30_ = _tmp29_->x;
						_tmp22_ = _tmp28_ <= (_tmp30_ + 1);
					} else {
						_tmp22_ = FALSE;
					}
					_tmp31_ = _tmp22_;
					_tmp17_ = _tmp31_;
				} else {
					_tmp17_ = FALSE;
				}
				_tmp32_ = _tmp17_;
				if (_tmp32_) {
					gboolean _tmp33_ = FALSE;
					Slot* _tmp34_;
					gint _tmp35_;
					Slot* _tmp36_;
					gint _tmp37_;
					gboolean _tmp42_;
					_tmp34_ = s;
					_tmp35_ = _tmp34_->y;
					_tmp36_ = slot;
					_tmp37_ = _tmp36_->y;
					if (_tmp35_ >= (_tmp37_ - 1)) {
						Slot* _tmp38_;
						gint _tmp39_;
						Slot* _tmp40_;
						gint _tmp41_;
						_tmp38_ = s;
						_tmp39_ = _tmp38_->y;
						_tmp40_ = slot;
						_tmp41_ = _tmp40_->y;
						_tmp33_ = _tmp39_ <= (_tmp41_ + 1);
					} else {
						_tmp33_ = FALSE;
					}
					_tmp42_ = _tmp33_;
					_tmp16_ = _tmp42_;
				} else {
					_tmp16_ = FALSE;
				}
				_tmp43_ = _tmp16_;
				if (_tmp43_) {
					result = FALSE;
					_slot_unref0 (s);
					_tile_unref0 (t);
					_slot_unref0 (slot);
					return result;
				}
				_tmp45_ = s;
				_tmp46_ = _tmp45_->layer;
				_tmp47_ = slot;
				_tmp48_ = _tmp47_->layer;
				if (_tmp46_ == _tmp48_) {
					gboolean _tmp49_ = FALSE;
					Slot* _tmp50_;
					gint _tmp51_;
					Slot* _tmp52_;
					gint _tmp53_;
					gboolean _tmp58_;
					_tmp50_ = s;
					_tmp51_ = _tmp50_->y;
					_tmp52_ = slot;
					_tmp53_ = _tmp52_->y;
					if (_tmp51_ >= (_tmp53_ - 1)) {
						Slot* _tmp54_;
						gint _tmp55_;
						Slot* _tmp56_;
						gint _tmp57_;
						_tmp54_ = s;
						_tmp55_ = _tmp54_->y;
						_tmp56_ = slot;
						_tmp57_ = _tmp56_->y;
						_tmp49_ = _tmp55_ <= (_tmp57_ + 1);
					} else {
						_tmp49_ = FALSE;
					}
					_tmp58_ = _tmp49_;
					_tmp44_ = _tmp58_;
				} else {
					_tmp44_ = FALSE;
				}
				_tmp59_ = _tmp44_;
				if (_tmp59_) {
					Slot* _tmp60_;
					gint _tmp61_;
					Slot* _tmp62_;
					gint _tmp63_;
					Slot* _tmp64_;
					gint _tmp65_;
					Slot* _tmp66_;
					gint _tmp67_;
					gboolean _tmp68_ = FALSE;
					gboolean _tmp69_;
					gboolean _tmp71_;
					_tmp60_ = s;
					_tmp61_ = _tmp60_->x;
					_tmp62_ = slot;
					_tmp63_ = _tmp62_->x;
					if (_tmp61_ == (_tmp63_ - 2)) {
						blocked_left = TRUE;
					}
					_tmp64_ = s;
					_tmp65_ = _tmp64_->x;
					_tmp66_ = slot;
					_tmp67_ = _tmp66_->x;
					if (_tmp65_ == (_tmp67_ + 2)) {
						blocked_right = TRUE;
					}
					_tmp69_ = blocked_left;
					if (_tmp69_) {
						gboolean _tmp70_;
						_tmp70_ = blocked_right;
						_tmp68_ = _tmp70_;
					} else {
						_tmp68_ = FALSE;
					}
					_tmp71_ = _tmp68_;
					if (_tmp71_) {
						result = FALSE;
						_slot_unref0 (s);
						_tile_unref0 (t);
						_slot_unref0 (slot);
						return result;
					}
				}
				_slot_unref0 (s);
				_tile_unref0 (t);
			}
		}
	}
	result = TRUE;
	_slot_unref0 (slot);
	return result;
}


GList* game_find_matches (Game* self, Tile* tile) {
	GList* result = NULL;
	GList* matches;
	gboolean _tmp0_ = FALSE;
	Tile* _tmp1_;
	gboolean _tmp4_;
	Tile* _tmp5_;
	g_return_val_if_fail (self != NULL, NULL);
	matches = NULL;
	_tmp1_ = tile;
	if (_tmp1_ != NULL) {
		Tile* _tmp2_;
		gboolean _tmp3_ = FALSE;
		_tmp2_ = tile;
		_tmp3_ = game_tile_can_move (self, _tmp2_);
		_tmp0_ = !_tmp3_;
	} else {
		_tmp0_ = FALSE;
	}
	_tmp4_ = _tmp0_;
	if (_tmp4_) {
		result = matches;
		return result;
	}
	_tmp5_ = tile;
	if (_tmp5_ == NULL) {
		GList* _tmp6_;
		_tmp6_ = self->tiles;
		{
			GList* t_collection = NULL;
			GList* t_it = NULL;
			t_collection = _tmp6_;
			for (t_it = t_collection; t_it != NULL; t_it = t_it->next) {
				Tile* _tmp7_;
				Tile* t = NULL;
				_tmp7_ = _tile_ref0 ((Tile*) t_it->data);
				t = _tmp7_;
				{
					Tile* _tmp8_;
					GList* _tmp9_ = NULL;
					_tmp8_ = t;
					_tmp9_ = game_find_matches (self, _tmp8_);
					{
						GList* match_collection = NULL;
						GList* match_it = NULL;
						match_collection = _tmp9_;
						for (match_it = match_collection; match_it != NULL; match_it = match_it->next) {
							Match* _tmp10_;
							Match* match = NULL;
							_tmp10_ = _match_ref0 ((Match*) match_it->data);
							match = _tmp10_;
							{
								gboolean already_matched;
								GList* _tmp11_;
								gboolean _tmp23_;
								already_matched = FALSE;
								_tmp11_ = matches;
								{
									GList* existing_match_collection = NULL;
									GList* existing_match_it = NULL;
									existing_match_collection = _tmp11_;
									for (existing_match_it = existing_match_collection; existing_match_it != NULL; existing_match_it = existing_match_it->next) {
										Match* _tmp12_;
										Match* existing_match = NULL;
										_tmp12_ = _match_ref0 ((Match*) existing_match_it->data);
										existing_match = _tmp12_;
										{
											gboolean _tmp13_ = FALSE;
											Match* _tmp14_;
											Tile* _tmp15_;
											Match* _tmp16_;
											Tile* _tmp17_;
											gboolean _tmp22_;
											_tmp14_ = existing_match;
											_tmp15_ = _tmp14_->tile0;
											_tmp16_ = match;
											_tmp17_ = _tmp16_->tile1;
											if (_tmp15_ == _tmp17_) {
												Match* _tmp18_;
												Tile* _tmp19_;
												Match* _tmp20_;
												Tile* _tmp21_;
												_tmp18_ = existing_match;
												_tmp19_ = _tmp18_->tile1;
												_tmp20_ = match;
												_tmp21_ = _tmp20_->tile0;
												_tmp13_ = _tmp19_ == _tmp21_;
											} else {
												_tmp13_ = FALSE;
											}
											_tmp22_ = _tmp13_;
											if (_tmp22_) {
												already_matched = TRUE;
												_match_unref0 (existing_match);
												break;
											}
											_match_unref0 (existing_match);
										}
									}
								}
								_tmp23_ = already_matched;
								if (!_tmp23_) {
									Match* _tmp24_;
									Match* _tmp25_;
									_tmp24_ = match;
									_tmp25_ = _match_ref0 (_tmp24_);
									matches = g_list_append (matches, _tmp25_);
								}
								_match_unref0 (match);
							}
						}
						__g_list_free__match_unref0_0 (match_collection);
					}
					_tile_unref0 (t);
				}
			}
		}
	} else {
		GList* _tmp26_;
		_tmp26_ = self->tiles;
		{
			GList* t_collection = NULL;
			GList* t_it = NULL;
			t_collection = _tmp26_;
			for (t_it = t_collection; t_it != NULL; t_it = t_it->next) {
				Tile* _tmp27_;
				Tile* t = NULL;
				_tmp27_ = _tile_ref0 ((Tile*) t_it->data);
				t = _tmp27_;
				{
					gboolean _tmp28_ = FALSE;
					Tile* _tmp29_;
					Tile* _tmp30_;
					gboolean _tmp33_;
					Tile* _tmp34_;
					Tile* _tmp35_;
					gboolean _tmp36_ = FALSE;
					_tmp29_ = t;
					_tmp30_ = tile;
					if (_tmp29_ == _tmp30_) {
						_tmp28_ = TRUE;
					} else {
						Tile* _tmp31_;
						gboolean _tmp32_ = FALSE;
						_tmp31_ = t;
						_tmp32_ = game_tile_can_move (self, _tmp31_);
						_tmp28_ = !_tmp32_;
					}
					_tmp33_ = _tmp28_;
					if (_tmp33_) {
						_tile_unref0 (t);
						continue;
					}
					_tmp34_ = t;
					_tmp35_ = tile;
					_tmp36_ = tile_matches (_tmp34_, _tmp35_);
					if (_tmp36_) {
						Tile* _tmp37_;
						Tile* _tmp38_;
						Match* _tmp39_;
						_tmp37_ = t;
						_tmp38_ = tile;
						_tmp39_ = match_new (_tmp37_, _tmp38_);
						matches = g_list_append (matches, _tmp39_);
					}
					_tile_unref0 (t);
				}
			}
		}
	}
	result = matches;
	return result;
}


gboolean game_remove_pair (Game* self, Tile* tile0, Tile* tile1) {
	gboolean result = FALSE;
	gboolean _tmp0_ = FALSE;
	Tile* _tmp1_;
	gboolean _tmp2_;
	gboolean _tmp5_;
	Tile* _tmp6_;
	gint _tmp7_;
	gint _tmp8_;
	Tile* _tmp9_;
	gint _tmp10_;
	gint _tmp11_;
	Tile* _tmp12_;
	Tile* _tmp13_;
	gint _tmp14_;
	Tile* _tmp15_;
	Tile* _tmp16_;
	gint _tmp17_;
	gint _tmp18_;
	Tile* _tmp19_;
	Tile* _tmp20_;
	GList* _tmp21_;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (tile0 != NULL, FALSE);
	g_return_val_if_fail (tile1 != NULL, FALSE);
	_tmp1_ = tile0;
	_tmp2_ = _tmp1_->visible;
	if (!_tmp2_) {
		_tmp0_ = TRUE;
	} else {
		Tile* _tmp3_;
		gboolean _tmp4_;
		_tmp3_ = tile1;
		_tmp4_ = _tmp3_->visible;
		_tmp0_ = !_tmp4_;
	}
	_tmp5_ = _tmp0_;
	if (_tmp5_) {
		result = FALSE;
		return result;
	}
	_tmp6_ = tile0;
	_tmp7_ = tile_get_set (_tmp6_);
	_tmp8_ = _tmp7_;
	_tmp9_ = tile1;
	_tmp10_ = tile_get_set (_tmp9_);
	_tmp11_ = _tmp10_;
	if (_tmp8_ != _tmp11_) {
		result = FALSE;
		return result;
	}
	game_set_selected_tile (self, NULL);
	game_set_hint (self, NULL, NULL);
	_tmp12_ = tile0;
	_tmp12_->visible = FALSE;
	_tmp13_ = tile0;
	_tmp14_ = self->move_number;
	_tmp13_->move_number = _tmp14_;
	_tmp15_ = tile1;
	_tmp15_->visible = FALSE;
	_tmp16_ = tile1;
	_tmp17_ = self->move_number;
	_tmp16_->move_number = _tmp17_;
	_tmp18_ = self->move_number;
	self->move_number = _tmp18_ + 1;
	_tmp19_ = tile0;
	g_signal_emit_by_name (self, "redraw-tile", _tmp19_);
	_tmp20_ = tile1;
	g_signal_emit_by_name (self, "redraw-tile", _tmp20_);
	_tmp21_ = self->tiles;
	{
		GList* tile_collection = NULL;
		GList* tile_it = NULL;
		tile_collection = _tmp21_;
		for (tile_it = tile_collection; tile_it != NULL; tile_it = tile_it->next) {
			Tile* _tmp22_;
			Tile* tile = NULL;
			_tmp22_ = _tile_ref0 ((Tile*) tile_it->data);
			tile = _tmp22_;
			{
				Tile* _tmp23_;
				gint _tmp24_;
				gint _tmp25_;
				_tmp23_ = tile;
				_tmp24_ = _tmp23_->move_number;
				_tmp25_ = self->move_number;
				if (_tmp24_ >= _tmp25_) {
					Tile* _tmp26_;
					_tmp26_ = tile;
					_tmp26_->move_number = 0;
				}
				_tile_unref0 (tile);
			}
		}
	}
	g_signal_emit_by_name (self, "moved");
	result = TRUE;
	return result;
}


void game_undo (Game* self) {
	gboolean _tmp0_;
	gboolean _tmp1_;
	gint _tmp2_;
	GList* _tmp3_;
	g_return_if_fail (self != NULL);
	_tmp0_ = game_get_can_undo (self);
	_tmp1_ = _tmp0_;
	if (!_tmp1_) {
		return;
	}
	game_set_selected_tile (self, NULL);
	game_set_hint (self, NULL, NULL);
	_tmp2_ = self->move_number;
	self->move_number = _tmp2_ - 1;
	_tmp3_ = self->tiles;
	{
		GList* tile_collection = NULL;
		GList* tile_it = NULL;
		tile_collection = _tmp3_;
		for (tile_it = tile_collection; tile_it != NULL; tile_it = tile_it->next) {
			Tile* _tmp4_;
			Tile* tile = NULL;
			_tmp4_ = _tile_ref0 ((Tile*) tile_it->data);
			tile = _tmp4_;
			{
				Tile* _tmp5_;
				gint _tmp6_;
				gint _tmp7_;
				_tmp5_ = tile;
				_tmp6_ = _tmp5_->move_number;
				_tmp7_ = self->move_number;
				if (_tmp6_ == _tmp7_) {
					Tile* _tmp8_;
					Tile* _tmp9_;
					_tmp8_ = tile;
					_tmp8_->visible = TRUE;
					_tmp9_ = tile;
					g_signal_emit_by_name (self, "redraw-tile", _tmp9_);
				}
				_tile_unref0 (tile);
			}
		}
	}
}


void game_redo (Game* self) {
	gboolean _tmp0_;
	gboolean _tmp1_;
	GList* _tmp2_;
	gint _tmp9_;
	g_return_if_fail (self != NULL);
	_tmp0_ = game_get_can_redo (self);
	_tmp1_ = _tmp0_;
	if (!_tmp1_) {
		return;
	}
	game_set_selected_tile (self, NULL);
	game_set_hint (self, NULL, NULL);
	_tmp2_ = self->tiles;
	{
		GList* tile_collection = NULL;
		GList* tile_it = NULL;
		tile_collection = _tmp2_;
		for (tile_it = tile_collection; tile_it != NULL; tile_it = tile_it->next) {
			Tile* _tmp3_;
			Tile* tile = NULL;
			_tmp3_ = _tile_ref0 ((Tile*) tile_it->data);
			tile = _tmp3_;
			{
				Tile* _tmp4_;
				gint _tmp5_;
				gint _tmp6_;
				_tmp4_ = tile;
				_tmp5_ = _tmp4_->move_number;
				_tmp6_ = self->move_number;
				if (_tmp5_ == _tmp6_) {
					Tile* _tmp7_;
					Tile* _tmp8_;
					_tmp7_ = tile;
					_tmp7_->visible = FALSE;
					_tmp8_ = tile;
					g_signal_emit_by_name (self, "redraw-tile", _tmp8_);
				}
				_tile_unref0 (tile);
			}
		}
	}
	_tmp9_ = self->move_number;
	self->move_number = _tmp9_ + 1;
}


gboolean game_get_started (Game* self) {
	gboolean result;
	gint _tmp0_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->move_number;
	result = _tmp0_ > 1;
	return result;
}


Tile* game_get_selected_tile (Game* self) {
	Tile* result;
	Tile* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_selected_tile;
	result = _tmp0_;
	return result;
}


void game_set_selected_tile (Game* self, Tile* value) {
	Tile* _tmp0_;
	Tile* _tmp2_;
	Tile* _tmp3_;
	Tile* _tmp4_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_selected_tile;
	if (_tmp0_ != NULL) {
		Tile* _tmp1_;
		_tmp1_ = self->priv->_selected_tile;
		g_signal_emit_by_name (self, "redraw-tile", _tmp1_);
	}
	_tmp2_ = value;
	_tmp3_ = _tile_ref0 (_tmp2_);
	_tile_unref0 (self->priv->_selected_tile);
	self->priv->_selected_tile = _tmp3_;
	_tmp4_ = value;
	if (_tmp4_ != NULL) {
		Tile* _tmp5_;
		_tmp5_ = value;
		g_signal_emit_by_name (self, "redraw-tile", _tmp5_);
	}
}


gint game_get_visible_tiles (Game* self) {
	gint result;
	gint n;
	GList* _tmp0_;
	gint _tmp5_;
	g_return_val_if_fail (self != NULL, 0);
	n = 0;
	_tmp0_ = self->tiles;
	{
		GList* tile_collection = NULL;
		GList* tile_it = NULL;
		tile_collection = _tmp0_;
		for (tile_it = tile_collection; tile_it != NULL; tile_it = tile_it->next) {
			Tile* _tmp1_;
			Tile* tile = NULL;
			_tmp1_ = _tile_ref0 ((Tile*) tile_it->data);
			tile = _tmp1_;
			{
				Tile* _tmp2_;
				gboolean _tmp3_;
				_tmp2_ = tile;
				_tmp3_ = _tmp2_->visible;
				if (_tmp3_) {
					gint _tmp4_;
					_tmp4_ = n;
					n = _tmp4_ + 1;
				}
				_tile_unref0 (tile);
			}
		}
	}
	_tmp5_ = n;
	result = _tmp5_;
	return result;
}


guint game_get_moves_left (Game* self) {
	guint result;
	GList* _tmp0_ = NULL;
	GList* _tmp1_;
	guint _tmp2_ = 0U;
	guint _tmp3_;
	g_return_val_if_fail (self != NULL, 0U);
	_tmp0_ = game_find_matches (self, NULL);
	_tmp1_ = _tmp0_;
	_tmp2_ = g_list_length (_tmp1_);
	_tmp3_ = _tmp2_;
	__g_list_free__match_unref0_0 (_tmp1_);
	result = _tmp3_;
	return result;
}


gboolean game_get_complete (Game* self) {
	gboolean result;
	gint _tmp0_;
	gint _tmp1_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = game_get_visible_tiles (self);
	_tmp1_ = _tmp0_;
	result = _tmp1_ == 0;
	return result;
}


gboolean game_get_can_move (Game* self) {
	gboolean result;
	guint _tmp0_;
	guint _tmp1_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = game_get_moves_left (self);
	_tmp1_ = _tmp0_;
	result = _tmp1_ != ((guint) 0);
	return result;
}


gboolean game_get_can_undo (Game* self) {
	gboolean result;
	gint _tmp0_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->move_number;
	result = _tmp0_ > 1;
	return result;
}


gboolean game_get_can_redo (Game* self) {
	gboolean result;
	GList* _tmp0_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->tiles;
	{
		GList* tile_collection = NULL;
		GList* tile_it = NULL;
		tile_collection = _tmp0_;
		for (tile_it = tile_collection; tile_it != NULL; tile_it = tile_it->next) {
			Tile* _tmp1_;
			Tile* tile = NULL;
			_tmp1_ = _tile_ref0 ((Tile*) tile_it->data);
			tile = _tmp1_;
			{
				Tile* _tmp2_;
				gint _tmp3_;
				gint _tmp4_;
				_tmp2_ = tile;
				_tmp3_ = _tmp2_->move_number;
				_tmp4_ = self->move_number;
				if (_tmp3_ >= _tmp4_) {
					result = TRUE;
					_tile_unref0 (tile);
					return result;
				}
				_tile_unref0 (tile);
			}
		}
	}
	result = FALSE;
	return result;
}


static void g_cclosure_user_marshal_VOID__TILE (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) {
	typedef void (*GMarshalFunc_VOID__TILE) (gpointer data1, gpointer arg_1, gpointer data2);
	register GMarshalFunc_VOID__TILE callback;
	register GCClosure * cc;
	register gpointer data1;
	register gpointer data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 2);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__TILE) (marshal_data ? marshal_data : cc->callback);
	callback (data1, value_get_tile (param_values + 1), data2);
}


static void value_game_init (GValue* value) {
	value->data[0].v_pointer = NULL;
}


static void value_game_free_value (GValue* value) {
	if (value->data[0].v_pointer) {
		game_unref (value->data[0].v_pointer);
	}
}


static void value_game_copy_value (const GValue* src_value, GValue* dest_value) {
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = game_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}


static gpointer value_game_peek_pointer (const GValue* value) {
	return value->data[0].v_pointer;
}


static gchar* value_game_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	if (collect_values[0].v_pointer) {
		Game* object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = game_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}


static gchar* value_game_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	Game** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = game_ref (value->data[0].v_pointer);
	}
	return NULL;
}


GParamSpec* param_spec_game (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
	ParamSpecGame* spec;
	g_return_val_if_fail (g_type_is_a (object_type, TYPE_GAME), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}


gpointer value_get_game (const GValue* value) {
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_GAME), NULL);
	return value->data[0].v_pointer;
}


void value_set_game (GValue* value, gpointer v_object) {
	Game* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_GAME));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_GAME));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		game_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		game_unref (old);
	}
}


void value_take_game (GValue* value, gpointer v_object) {
	Game* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_GAME));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_GAME));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		game_unref (old);
	}
}


static void game_class_init (GameClass * klass) {
	game_parent_class = g_type_class_peek_parent (klass);
	GAME_CLASS (klass)->finalize = game_finalize;
	g_type_class_add_private (klass, sizeof (GamePrivate));
	g_signal_new ("redraw_tile", TYPE_GAME, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__TILE, G_TYPE_NONE, 1, TYPE_TILE);
	g_signal_new ("moved", TYPE_GAME, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}


static void game_instance_init (Game * self) {
	self->priv = GAME_GET_PRIVATE (self);
	self->tiles = NULL;
	self->priv->hint_timer = (guint) 0;
	self->hint_blink_counter = (guint) 0;
	self->priv->_selected_tile = NULL;
	self->ref_count = 1;
}


static void game_finalize (Game* obj) {
	Game * self;
	self = GAME (obj);
	_map_unref0 (self->map);
	__g_list_free__tile_unref0_0 (self->tiles);
	_vala_array_destroy (self->hint_tiles, 2, (GDestroyNotify) tile_unref);
	_tile_unref0 (self->priv->_selected_tile);
}


GType game_get_type (void) {
	static volatile gsize game_type_id__volatile = 0;
	if (g_once_init_enter (&game_type_id__volatile)) {
		static const GTypeValueTable g_define_type_value_table = { value_game_init, value_game_free_value, value_game_copy_value, value_game_peek_pointer, "p", value_game_collect_value, "p", value_game_lcopy_value };
		static const GTypeInfo g_define_type_info = { sizeof (GameClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) game_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Game), 0, (GInstanceInitFunc) game_instance_init, &g_define_type_value_table };
		static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
		GType game_type_id;
		game_type_id = g_type_register_fundamental (g_type_fundamental_next (), "Game", &g_define_type_info, &g_define_type_fundamental_info, 0);
		g_once_init_leave (&game_type_id__volatile, game_type_id);
	}
	return game_type_id__volatile;
}


gpointer game_ref (gpointer instance) {
	Game* self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}


void game_unref (gpointer instance) {
	Game* self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		GAME_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}


static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) {
	if ((array != NULL) && (destroy_func != NULL)) {
		int i;
		for (i = 0; i < array_length; i = i + 1) {
			if (((gpointer*) array)[i] != NULL) {
				destroy_func (((gpointer*) array)[i]);
			}
		}
	}
}


static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func) {
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}



