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

/*
 * Color lines for GNOME
 * Copyright © 1999 Free Software Foundation
 * Authors: Robert Szokovacs <szo@szo.hu>
 *          Szabolcs Ban <shooby@gnome.hu>
 *          Karuna Grewal <karunagrewal98@gmail.com>
 *          Ruxandra Simion <ruxandra.simion93@gmail.com>
 * Copyright © 2007 Christian Persch
 *
 * This game is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
 */

#include <glib-object.h>
#include <glib.h>
#include <gee.h>
#include <stdlib.h>
#include <string.h>
#include <glib/gi18n-lib.h>
#include <math.h>

#define GAME_N_TYPES 7
#define GAME_N_ANIMATIONS 4
#define GAME_N_MATCH 5
#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif
#if !defined(VALA_EXTERN)
#if defined(_MSC_VER)
#define VALA_EXTERN __declspec(dllexport) extern
#elif __GNUC__ >= 4
#define VALA_EXTERN __attribute__((visibility("default"))) extern
#else
#define VALA_EXTERN extern
#endif
#endif

#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_BOARD (board_get_type ())
#define BOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_BOARD, Board))
#define BOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_BOARD, BoardClass))
#define IS_BOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_BOARD))
#define IS_BOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_BOARD))
#define BOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_BOARD, BoardClass))

typedef struct _Board Board;
typedef struct _BoardClass BoardClass;

#define TYPE_CELL (cell_get_type ())
#define CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CELL, Cell))
#define CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CELL, CellClass))
#define IS_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CELL))
#define IS_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CELL))
#define CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CELL, CellClass))

typedef struct _Cell Cell;
typedef struct _CellClass CellClass;

#define TYPE_PIECE (piece_get_type ())
#define PIECE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PIECE, Piece))
#define PIECE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_PIECE, PieceClass))
#define IS_PIECE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PIECE))
#define IS_PIECE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PIECE))
#define PIECE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PIECE, PieceClass))

typedef struct _Piece Piece;
typedef struct _PieceClass PieceClass;

#define TYPE_NEXT_PIECES_GENERATOR (next_pieces_generator_get_type ())
#define NEXT_PIECES_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_NEXT_PIECES_GENERATOR, NextPiecesGenerator))
#define NEXT_PIECES_GENERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_NEXT_PIECES_GENERATOR, NextPiecesGeneratorClass))
#define IS_NEXT_PIECES_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_NEXT_PIECES_GENERATOR))
#define IS_NEXT_PIECES_GENERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_NEXT_PIECES_GENERATOR))
#define NEXT_PIECES_GENERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_NEXT_PIECES_GENERATOR, NextPiecesGeneratorClass))

typedef struct _NextPiecesGenerator NextPiecesGenerator;
typedef struct _NextPiecesGeneratorClass NextPiecesGeneratorClass;
typedef enum  {
	STATUS_MESSAGE_DESCRIPTION,
	STATUS_MESSAGE_NO_PATH,
	STATUS_MESSAGE_GAME_OVER,
	STATUS_MESSAGE_NONE
} StatusMessage;

#define TYPE_STATUS_MESSAGE (status_message_get_type ())
enum  {
	GAME_0_PROPERTY,
	GAME_SIZE_PROPERTY,
	GAME_N_ROWS_PROPERTY,
	GAME_N_COLS_PROPERTY,
	GAME_SCORE_PROPERTY,
	GAME_CURRENT_PATH_CELL_POS_PROPERTY,
	GAME_NEXT_PIECES_QUEUE_PROPERTY,
	GAME_IS_GAME_OVER_PROPERTY,
	GAME_STATUS_MESSAGE_PROPERTY,
	GAME_NUM_PROPERTIES
};
static GParamSpec* game_properties[GAME_NUM_PROPERTIES];

#define TYPE_GAME_DIFFICULTY (game_difficulty_get_type ())
typedef struct _GameDifficulty GameDifficulty;

#define TYPE_KEY_VALUE (key_value_get_type ())
typedef struct _KeyValue KeyValue;
#define _next_pieces_generator_unref0(var) ((var == NULL) ? NULL : (var = (next_pieces_generator_unref (var), NULL)))
#define _board_unref0(var) ((var == NULL) ? NULL : (var = (board_unref (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _piece_unref0(var) ((var == NULL) ? NULL : (var = (piece_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _cell_unref0(var) ((var == NULL) ? NULL : (var = (cell_unref (var), NULL)))
typedef struct _CellPrivate CellPrivate;
enum  {
	GAME_CURRENT_PATH_CELL_POS_CHANGED_SIGNAL,
	GAME_QUEUE_CHANGED_SIGNAL,
	GAME_GAME_OVER_SIGNAL,
	GAME_NUM_SIGNALS
};
static guint game_signals[GAME_NUM_SIGNALS] = {0};
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);

struct _Game {
	GObject parent_instance;
	GamePrivate * priv;
	Board* board;
	gint n_next_pieces;
	gint n_filled_cells;
	GeeArrayList* current_path;
	gboolean animating;
	Piece* animating_piece;
	gint n_categories;
	gchar* score_current_category;
};

struct _GameClass {
	GObjectClass parent_class;
};

struct _GamePrivate {
	gint _size;
	NextPiecesGenerator* next_pieces_generator;
	gint n_cells;
	gint _score;
	gint _current_path_cell_pos;
	GeeArrayList* _next_pieces_queue;
	gboolean _is_game_over;
	StatusMessage _status_message;
};

struct _GameDifficulty {
	gint n_cols;
	gint n_rows;
	gint n_types;
	gint n_next_pieces;
};

struct _KeyValue {
	gchar* key;
	gchar* name;
};

struct _Cell {
	GTypeInstance parent_instance;
	volatile int ref_count;
	CellPrivate * priv;
	gint row;
	gint col;
	Cell* parent;
	Piece* piece;
	gint cost;
};

struct _CellClass {
	GTypeClass parent_class;
	void (*finalize) (Cell *self);
};

static gint Game_private_offset;
static gpointer game_parent_class = NULL;

VALA_EXTERN GType game_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (Game, g_object_unref)
VALA_EXTERN gpointer board_ref (gpointer instance);
VALA_EXTERN void board_unref (gpointer instance);
VALA_EXTERN GParamSpec* param_spec_board (const gchar* name,
                              const gchar* nick,
                              const gchar* blurb,
                              GType object_type,
                              GParamFlags flags);
VALA_EXTERN void value_set_board (GValue* value,
                      gpointer v_object);
VALA_EXTERN void value_take_board (GValue* value,
                       gpointer v_object);
VALA_EXTERN gpointer value_get_board (const GValue* value);
VALA_EXTERN GType board_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (Board, board_unref)
VALA_EXTERN gpointer cell_ref (gpointer instance);
VALA_EXTERN void cell_unref (gpointer instance);
VALA_EXTERN GParamSpec* param_spec_cell (const gchar* name,
                             const gchar* nick,
                             const gchar* blurb,
                             GType object_type,
                             GParamFlags flags);
VALA_EXTERN void value_set_cell (GValue* value,
                     gpointer v_object);
VALA_EXTERN void value_take_cell (GValue* value,
                      gpointer v_object);
VALA_EXTERN gpointer value_get_cell (const GValue* value);
VALA_EXTERN GType cell_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (Cell, cell_unref)
VALA_EXTERN gpointer piece_ref (gpointer instance);
VALA_EXTERN void piece_unref (gpointer instance);
VALA_EXTERN GParamSpec* param_spec_piece (const gchar* name,
                              const gchar* nick,
                              const gchar* blurb,
                              GType object_type,
                              GParamFlags flags);
VALA_EXTERN void value_set_piece (GValue* value,
                      gpointer v_object);
VALA_EXTERN void value_take_piece (GValue* value,
                       gpointer v_object);
VALA_EXTERN gpointer value_get_piece (const GValue* value);
VALA_EXTERN GType piece_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (Piece, piece_unref)
VALA_EXTERN gpointer next_pieces_generator_ref (gpointer instance);
VALA_EXTERN void next_pieces_generator_unref (gpointer instance);
VALA_EXTERN GParamSpec* param_spec_next_pieces_generator (const gchar* name,
                                              const gchar* nick,
                                              const gchar* blurb,
                                              GType object_type,
                                              GParamFlags flags);
VALA_EXTERN void value_set_next_pieces_generator (GValue* value,
                                      gpointer v_object);
VALA_EXTERN void value_take_next_pieces_generator (GValue* value,
                                       gpointer v_object);
VALA_EXTERN gpointer value_get_next_pieces_generator (const GValue* value);
VALA_EXTERN GType next_pieces_generator_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (NextPiecesGenerator, next_pieces_generator_unref)
VALA_EXTERN GType status_message_get_type (void) G_GNUC_CONST ;
VALA_EXTERN GType game_difficulty_get_type (void) G_GNUC_CONST ;
VALA_EXTERN GameDifficulty* game_difficulty_dup (const GameDifficulty* self);
VALA_EXTERN void game_difficulty_free (GameDifficulty* self);
VALA_EXTERN GType key_value_get_type (void) G_GNUC_CONST ;
VALA_EXTERN KeyValue* key_value_dup (const KeyValue* self);
VALA_EXTERN void key_value_free (KeyValue* self);
VALA_EXTERN void key_value_copy (const KeyValue* self,
                     KeyValue* dest);
VALA_EXTERN void key_value_destroy (KeyValue* self);
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (KeyValue, key_value_destroy)
VALA_EXTERN Game* game_new (gint size);
VALA_EXTERN Game* game_construct (GType object_type,
                      gint size);
static void game_init_game (Game* self);
static void game_set_is_game_over (Game* self,
                            gboolean value);
static gint game_get_size (Game* self);
static void game_set_score (Game* self,
                     gint value);
VALA_EXTERN void game_set_status_message (Game* self,
                              StatusMessage value);
VALA_EXTERN NextPiecesGenerator* next_pieces_generator_new (gint n_next_pieces,
                                                gint n_types);
VALA_EXTERN NextPiecesGenerator* next_pieces_generator_construct (GType object_type,
                                                      gint n_next_pieces,
                                                      gint n_types);
VALA_EXTERN void game_generate_next_pieces (Game* self);
VALA_EXTERN Board* board_new (gint n_rows,
                  gint n_cols);
VALA_EXTERN Board* board_construct (GType object_type,
                        gint n_rows,
                        gint n_cols);
VALA_EXTERN void board_reset (Board* self,
                  gint n_rows,
                  gint n_cols);
static void game_fill_board (Game* self,
                      gint n_rows,
                      gint n_cols);
VALA_EXTERN GeeArrayList* next_pieces_generator_yield_next_pieces (NextPiecesGenerator* self);
VALA_EXTERN void game_set_next_pieces_queue (Game* self,
                                 GeeArrayList* value);
VALA_EXTERN GeeArrayList* game_get_next_pieces_queue (Game* self);
VALA_EXTERN Piece* board_get_piece (Board* self,
                        gint row,
                        gint col);
VALA_EXTERN void board_set_piece (Board* self,
                      gint row,
                      gint col,
                      Piece* piece);
VALA_EXTERN Cell* board_get_cell (Board* self,
                      gint row,
                      gint col);
VALA_EXTERN GeeHashSet* cell_get_all_directions (Cell* self,
                                     Cell** board,
                                     gint board_length1,
                                     gint board_length2);
VALA_EXTERN Cell** board_get_grid (Board* self,
                       gint* result_length1,
                       gint* result_length2);
static void game_update_score (Game* self,
                        gint n_matched);
static gboolean game_check_game_over (Game* self);
VALA_EXTERN gint game_get_score (Game* self);
VALA_EXTERN void game_next_step (Game* self);
VALA_EXTERN gint game_get_n_rows (Game* self);
VALA_EXTERN gint game_get_n_cols (Game* self);
VALA_EXTERN gboolean game_make_move (Game* self,
                         gint start_row,
                         gint start_col,
                         gint end_row,
                         gint end_col);
VALA_EXTERN GeeArrayList* board_find_path (Board* self,
                               gint start_row,
                               gint start_col,
                               gint end_row,
                               gint end_col);
VALA_EXTERN void game_set_current_path_cell_pos (Game* self,
                                     gint value);
VALA_EXTERN gint game_get_current_path_cell_pos (Game* self);
VALA_EXTERN gboolean game_animate (Game* self);
static gboolean _game_animate_gsource_func (gpointer self);
VALA_EXTERN void game_new_game (Game* self,
                    gint _size);
VALA_EXTERN void game_set_size (Game* self,
                    gint value);
VALA_EXTERN gint board_get_n_rows (Board* self);
VALA_EXTERN gint board_get_n_cols (Board* self);
VALA_EXTERN gboolean game_get_is_game_over (Game* self);
VALA_EXTERN StatusMessage game_get_status_message (Game* self);
static void game_finalize (GObject * obj);
static GType game_get_type_once (void);
static void _vala_game_get_property (GObject * object,
                              guint property_id,
                              GValue * value,
                              GParamSpec * pspec);
static void _vala_game_set_property (GObject * object,
                              guint property_id,
                              const GValue * value,
                              GParamSpec * pspec);
static void _vala_array_destroy (gpointer array,
                          gssize array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gssize array_length,
                       GDestroyNotify destroy_func);

const GameDifficulty GAME_game_difficulty[4] = {{-1, -1, -1, -1}, {7, 7, 5, 3}, {9, 9, 7, 3}, {20, 15, 7, 7}};
const KeyValue GAME_scorecats[3] = {{"Small", NC_ ("board size", "Small")}, {"Medium", NC_ ("board size", "Medium")}, {"Large", NC_ ("board size", "Large")}};

static inline gpointer
game_get_instance_private (Game* self)
{
	return G_STRUCT_MEMBER_P (self, Game_private_offset);
}

Game*
game_construct (GType object_type,
                gint size)
{
	Game * self = NULL;
	self = (Game*) g_object_new (object_type, "size", size, NULL);
	game_init_game (self);
	return self;
}

Game*
game_new (gint size)
{
	return game_construct (TYPE_GAME, size);
}

static void
game_init_game (Game* self)
{
	gint n_rows = 0;
	gint _tmp0_;
	GameDifficulty _tmp1_;
	gint n_cols = 0;
	gint _tmp2_;
	GameDifficulty _tmp3_;
	gint _tmp4_;
	GameDifficulty _tmp5_;
	gint _tmp6_;
	KeyValue _tmp7_;
	const gchar* _tmp8_;
	gchar* _tmp9_;
	gint _tmp10_;
	GameDifficulty _tmp11_;
	gint _tmp12_;
	GameDifficulty _tmp13_;
	NextPiecesGenerator* _tmp14_;
	Board* _tmp15_;
	g_return_if_fail (self != NULL);
	game_set_is_game_over (self, FALSE);
	_tmp0_ = self->priv->_size;
	_tmp1_ = GAME_game_difficulty[_tmp0_];
	n_rows = _tmp1_.n_rows;
	_tmp2_ = self->priv->_size;
	_tmp3_ = GAME_game_difficulty[_tmp2_];
	n_cols = _tmp3_.n_cols;
	_tmp4_ = self->priv->_size;
	_tmp5_ = GAME_game_difficulty[_tmp4_];
	self->n_next_pieces = _tmp5_.n_next_pieces;
	self->priv->n_cells = n_rows * n_cols;
	self->n_filled_cells = 0;
	game_set_score (self, 0);
	_tmp6_ = self->priv->_size;
	_tmp7_ = GAME_scorecats[_tmp6_ - 1];
	_tmp8_ = _tmp7_.key;
	_tmp9_ = g_strdup (_tmp8_);
	_g_free0 (self->score_current_category);
	self->score_current_category = _tmp9_;
	game_set_status_message (self, STATUS_MESSAGE_DESCRIPTION);
	_tmp10_ = self->priv->_size;
	_tmp11_ = GAME_game_difficulty[_tmp10_];
	_tmp12_ = self->priv->_size;
	_tmp13_ = GAME_game_difficulty[_tmp12_];
	_tmp14_ = next_pieces_generator_new (_tmp11_.n_next_pieces, _tmp13_.n_types);
	_next_pieces_generator_unref0 (self->priv->next_pieces_generator);
	self->priv->next_pieces_generator = _tmp14_;
	game_generate_next_pieces (self);
	_tmp15_ = self->board;
	if (_tmp15_ == NULL) {
		Board* _tmp16_;
		_tmp16_ = board_new (n_rows, n_cols);
		_board_unref0 (self->board);
		self->board = _tmp16_;
	} else {
		Board* _tmp17_;
		_tmp17_ = self->board;
		board_reset (_tmp17_, n_rows, n_cols);
	}
	game_fill_board (self, n_rows, n_cols);
	game_generate_next_pieces (self);
}

void
game_generate_next_pieces (Game* self)
{
	NextPiecesGenerator* _tmp0_;
	GeeArrayList* _tmp1_;
	GeeArrayList* _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->next_pieces_generator;
	_tmp1_ = next_pieces_generator_yield_next_pieces (_tmp0_);
	_tmp2_ = _tmp1_;
	game_set_next_pieces_queue (self, _tmp2_);
	_g_object_unref0 (_tmp2_);
}

static void
game_fill_board (Game* self,
                 gint n_rows,
                 gint n_cols)
{
	gint row = 0;
	gint col = 0;
	g_return_if_fail (self != NULL);
	row = -1;
	col = -1;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				GeeArrayList* _tmp2_;
				GeeArrayList* _tmp3_;
				gint _tmp4_;
				gint _tmp5_;
				Board* _tmp11_;
				GeeArrayList* _tmp12_;
				GeeArrayList* _tmp13_;
				gpointer _tmp14_;
				Piece* _tmp15_;
				GeeHashSet* inactivate = NULL;
				Board* _tmp16_;
				Cell* _tmp17_;
				Cell* _tmp18_;
				Board* _tmp19_;
				gint _tmp20_ = 0;
				gint _tmp21_ = 0;
				Cell** _tmp22_;
				Cell** _tmp23_;
				gint _tmp23__length1;
				gint _tmp23__length2;
				GeeHashSet* _tmp24_;
				GeeHashSet* _tmp25_;
				GeeHashSet* _tmp26_;
				gint _tmp27_;
				gint _tmp28_;
				Board* _tmp43_;
				gint _tmp44_;
				if (!_tmp0_) {
					gint _tmp1_;
					_tmp1_ = i;
					i = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				_tmp2_ = game_get_next_pieces_queue (self);
				_tmp3_ = _tmp2_;
				_tmp4_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp3_);
				_tmp5_ = _tmp4_;
				if (!(i < _tmp5_)) {
					break;
				}
				{
					gboolean _tmp6_ = FALSE;
					_tmp6_ = TRUE;
					while (TRUE) {
						if (!_tmp6_) {
							Board* _tmp7_;
							Piece* _tmp8_;
							Piece* _tmp9_;
							gboolean _tmp10_;
							_tmp7_ = self->board;
							_tmp8_ = board_get_piece (_tmp7_, row, col);
							_tmp9_ = _tmp8_;
							_tmp10_ = !(_tmp9_ != NULL);
							_piece_unref0 (_tmp9_);
							if (_tmp10_) {
								break;
							}
						}
						_tmp6_ = FALSE;
						row = (gint) g_random_int_range ((gint32) 0, (gint32) n_rows);
						col = (gint) g_random_int_range ((gint32) 0, (gint32) n_cols);
					}
				}
				_tmp11_ = self->board;
				_tmp12_ = game_get_next_pieces_queue (self);
				_tmp13_ = _tmp12_;
				_tmp14_ = gee_abstract_list_get ((GeeAbstractList*) _tmp13_, i);
				_tmp15_ = (Piece*) _tmp14_;
				board_set_piece (_tmp11_, row, col, _tmp15_);
				_piece_unref0 (_tmp15_);
				_tmp16_ = self->board;
				_tmp17_ = board_get_cell (_tmp16_, row, col);
				_tmp18_ = _tmp17_;
				_tmp19_ = self->board;
				_tmp22_ = board_get_grid (_tmp19_, &_tmp20_, &_tmp21_);
				_tmp23_ = _tmp22_;
				_tmp23__length1 = _tmp20_;
				_tmp23__length2 = _tmp21_;
				_tmp24_ = cell_get_all_directions (_tmp18_, _tmp23_, (gint) _tmp20_, (gint) _tmp21_);
				_tmp25_ = _tmp24_;
				_tmp23_ = (_vala_array_free (_tmp23_, _tmp23__length1 * _tmp23__length2, (GDestroyNotify) cell_unref), NULL);
				_cell_unref0 (_tmp18_);
				inactivate = _tmp25_;
				_tmp26_ = inactivate;
				_tmp27_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp26_);
				_tmp28_ = _tmp27_;
				if (_tmp28_ > 0) {
					GeeHashSet* _tmp29_;
					gint _tmp30_;
					gint _tmp31_;
					GeeHashSet* _tmp40_;
					gint _tmp41_;
					gint _tmp42_;
					_tmp29_ = inactivate;
					_tmp30_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp29_);
					_tmp31_ = _tmp30_;
					self->n_filled_cells = self->n_filled_cells - _tmp31_;
					{
						GeeIterator* _cell_it = NULL;
						GeeHashSet* _tmp32_;
						GeeIterator* _tmp33_;
						_tmp32_ = inactivate;
						_tmp33_ = gee_abstract_collection_iterator ((GeeAbstractCollection*) _tmp32_);
						_cell_it = _tmp33_;
						while (TRUE) {
							GeeIterator* _tmp34_;
							Cell* cell = NULL;
							GeeIterator* _tmp35_;
							gpointer _tmp36_;
							Board* _tmp37_;
							Cell* _tmp38_;
							Cell* _tmp39_;
							_tmp34_ = _cell_it;
							if (!gee_iterator_next (_tmp34_)) {
								break;
							}
							_tmp35_ = _cell_it;
							_tmp36_ = gee_iterator_get (_tmp35_);
							cell = (Cell*) _tmp36_;
							_tmp37_ = self->board;
							_tmp38_ = cell;
							_tmp39_ = cell;
							board_set_piece (_tmp37_, _tmp38_->row, _tmp39_->col, NULL);
							_cell_unref0 (cell);
						}
						_g_object_unref0 (_cell_it);
					}
					_tmp40_ = inactivate;
					_tmp41_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp40_);
					_tmp42_ = _tmp41_;
					game_update_score (self, _tmp42_);
				}
				_tmp43_ = self->board;
				g_signal_emit_by_name (_tmp43_, "grid-changed");
				_tmp44_ = self->n_filled_cells;
				self->n_filled_cells = _tmp44_ + 1;
				if (game_check_game_over (self)) {
					Board* _tmp45_;
					game_set_status_message (self, STATUS_MESSAGE_GAME_OVER);
					_tmp45_ = self->board;
					g_signal_emit_by_name (_tmp45_, "grid-changed");
					_g_object_unref0 (inactivate);
					return;
				}
				_g_object_unref0 (inactivate);
			}
		}
	}
}

static void
game_update_score (Game* self,
                   gint n_matched)
{
	gint _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_score;
	game_set_score (self, _tmp0_ + ((gint) (45 * log (0.25 * n_matched))));
}

static gboolean
game_check_game_over (Game* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if ((self->priv->n_cells - self->n_filled_cells) == 0) {
		game_set_is_game_over (self, TRUE);
		g_signal_emit (self, game_signals[GAME_GAME_OVER_SIGNAL], 0);
		result = TRUE;
		return result;
	}
	result = FALSE;
	return result;
}

void
game_next_step (Game* self)
{
	gint _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	gint _tmp3_;
	g_return_if_fail (self != NULL);
	_tmp0_ = game_get_n_rows (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = game_get_n_cols (self);
	_tmp3_ = _tmp2_;
	game_fill_board (self, _tmp1_, _tmp3_);
	game_generate_next_pieces (self);
}

static gpointer
_piece_ref0 (gpointer self)
{
	return self ? piece_ref (self) : NULL;
}

static gboolean
_game_animate_gsource_func (gpointer self)
{
	gboolean result;
	result = game_animate ((Game*) self);
	return result;
}

gboolean
game_make_move (Game* self,
                gint start_row,
                gint start_col,
                gint end_row,
                gint end_col)
{
	Board* _tmp0_;
	GeeArrayList* _tmp1_;
	gboolean _tmp2_ = FALSE;
	GeeArrayList* _tmp3_;
	GeeArrayList* _tmp7_;
	gint _tmp8_;
	gint _tmp9_;
	gpointer _tmp10_;
	Cell* _tmp11_;
	Piece* _tmp12_;
	Piece* _tmp13_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->board;
	_tmp1_ = board_find_path (_tmp0_, start_row, start_col, end_row, end_col);
	_g_object_unref0 (self->current_path);
	self->current_path = _tmp1_;
	_tmp3_ = self->current_path;
	if (_tmp3_ == NULL) {
		_tmp2_ = TRUE;
	} else {
		GeeArrayList* _tmp4_;
		gint _tmp5_;
		gint _tmp6_;
		_tmp4_ = self->current_path;
		_tmp5_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp4_);
		_tmp6_ = _tmp5_;
		_tmp2_ = _tmp6_ == 0;
	}
	if (_tmp2_) {
		game_set_status_message (self, STATUS_MESSAGE_NO_PATH);
		result = FALSE;
		return result;
	}
	game_set_current_path_cell_pos (self, 0);
	_tmp7_ = self->current_path;
	_tmp8_ = game_get_current_path_cell_pos (self);
	_tmp9_ = _tmp8_;
	_tmp10_ = gee_abstract_list_get ((GeeAbstractList*) _tmp7_, _tmp9_);
	_tmp11_ = (Cell*) _tmp10_;
	_tmp12_ = _tmp11_->piece;
	_tmp13_ = _piece_ref0 (_tmp12_);
	_piece_unref0 (self->animating_piece);
	self->animating_piece = _tmp13_;
	_cell_unref0 (_tmp11_);
	g_timeout_add_full (G_PRIORITY_DEFAULT, (guint) 20, _game_animate_gsource_func, g_object_ref (self), g_object_unref);
	result = TRUE;
	return result;
}

gboolean
game_animate (Game* self)
{
	Cell* curr_cell = NULL;
	GeeArrayList* _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	gpointer _tmp3_;
	gint _tmp4_;
	gint _tmp5_;
	gint _tmp9_;
	gint _tmp10_;
	GeeArrayList* _tmp11_;
	gint _tmp12_;
	gint _tmp13_;
	gint _tmp47_;
	gint _tmp48_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	self->animating = TRUE;
	_tmp0_ = self->current_path;
	_tmp1_ = game_get_current_path_cell_pos (self);
	_tmp2_ = _tmp1_;
	_tmp3_ = gee_abstract_list_get ((GeeAbstractList*) _tmp0_, _tmp2_);
	curr_cell = (Cell*) _tmp3_;
	_tmp4_ = game_get_current_path_cell_pos (self);
	_tmp5_ = _tmp4_;
	if (_tmp5_ == 0) {
		Board* _tmp6_;
		Cell* _tmp7_;
		Cell* _tmp8_;
		_tmp6_ = self->board;
		_tmp7_ = curr_cell;
		_tmp8_ = curr_cell;
		board_set_piece (_tmp6_, _tmp7_->row, _tmp8_->col, NULL);
	}
	_tmp9_ = game_get_current_path_cell_pos (self);
	_tmp10_ = _tmp9_;
	_tmp11_ = self->current_path;
	_tmp12_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp11_);
	_tmp13_ = _tmp12_;
	if (_tmp10_ == (_tmp13_ - 1)) {
		Board* _tmp14_;
		Cell* _tmp15_;
		Cell* _tmp16_;
		Piece* _tmp17_;
		GeeHashSet* inactivate = NULL;
		Cell* _tmp18_;
		Board* _tmp19_;
		gint _tmp20_ = 0;
		gint _tmp21_ = 0;
		Cell** _tmp22_;
		Cell** _tmp23_;
		gint _tmp23__length1;
		gint _tmp23__length2;
		GeeHashSet* _tmp24_;
		GeeHashSet* _tmp25_;
		GeeHashSet* _tmp26_;
		gint _tmp27_;
		gint _tmp28_;
		GeeHashSet* _tmp43_;
		gint _tmp44_;
		gint _tmp45_;
		Board* _tmp46_;
		_tmp14_ = self->board;
		_tmp15_ = curr_cell;
		_tmp16_ = curr_cell;
		_tmp17_ = self->animating_piece;
		board_set_piece (_tmp14_, _tmp15_->row, _tmp16_->col, _tmp17_);
		_g_object_unref0 (self->current_path);
		self->current_path = NULL;
		_tmp18_ = curr_cell;
		_tmp19_ = self->board;
		_tmp22_ = board_get_grid (_tmp19_, &_tmp20_, &_tmp21_);
		_tmp23_ = _tmp22_;
		_tmp23__length1 = _tmp20_;
		_tmp23__length2 = _tmp21_;
		_tmp24_ = cell_get_all_directions (_tmp18_, _tmp23_, (gint) _tmp20_, (gint) _tmp21_);
		_tmp25_ = _tmp24_;
		_tmp23_ = (_vala_array_free (_tmp23_, _tmp23__length1 * _tmp23__length2, (GDestroyNotify) cell_unref), NULL);
		inactivate = _tmp25_;
		_tmp26_ = inactivate;
		_tmp27_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp26_);
		_tmp28_ = _tmp27_;
		if (_tmp28_ > 0) {
			GeeHashSet* _tmp29_;
			gint _tmp30_;
			gint _tmp31_;
			GeeHashSet* _tmp40_;
			gint _tmp41_;
			gint _tmp42_;
			_tmp29_ = inactivate;
			_tmp30_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp29_);
			_tmp31_ = _tmp30_;
			self->n_filled_cells = self->n_filled_cells - _tmp31_;
			{
				GeeIterator* _cell_it = NULL;
				GeeHashSet* _tmp32_;
				GeeIterator* _tmp33_;
				_tmp32_ = inactivate;
				_tmp33_ = gee_abstract_collection_iterator ((GeeAbstractCollection*) _tmp32_);
				_cell_it = _tmp33_;
				while (TRUE) {
					GeeIterator* _tmp34_;
					Cell* cell = NULL;
					GeeIterator* _tmp35_;
					gpointer _tmp36_;
					Board* _tmp37_;
					Cell* _tmp38_;
					Cell* _tmp39_;
					_tmp34_ = _cell_it;
					if (!gee_iterator_next (_tmp34_)) {
						break;
					}
					_tmp35_ = _cell_it;
					_tmp36_ = gee_iterator_get (_tmp35_);
					cell = (Cell*) _tmp36_;
					_tmp37_ = self->board;
					_tmp38_ = cell;
					_tmp39_ = cell;
					board_set_piece (_tmp37_, _tmp38_->row, _tmp39_->col, NULL);
					_cell_unref0 (cell);
				}
				_g_object_unref0 (_cell_it);
			}
			_tmp40_ = inactivate;
			_tmp41_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp40_);
			_tmp42_ = _tmp41_;
			game_update_score (self, _tmp42_);
		}
		_tmp43_ = inactivate;
		_tmp44_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp43_);
		_tmp45_ = _tmp44_;
		if (_tmp45_ < GAME_N_MATCH) {
			game_next_step (self);
		}
		_tmp46_ = self->board;
		g_signal_emit_by_name (_tmp46_, "grid-changed");
		self->animating = FALSE;
		result = G_SOURCE_REMOVE;
		_g_object_unref0 (inactivate);
		_cell_unref0 (curr_cell);
		return result;
	}
	_tmp47_ = game_get_current_path_cell_pos (self);
	_tmp48_ = _tmp47_;
	game_set_current_path_cell_pos (self, _tmp48_ + 1);
	result = G_SOURCE_CONTINUE;
	_cell_unref0 (curr_cell);
	return result;
}

void
game_new_game (Game* self,
               gint _size)
{
	g_return_if_fail (self != NULL);
	game_set_size (self, _size);
	game_init_game (self);
}

static gint
game_get_size (Game* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, 0);
	result = self->priv->_size;
	return result;
}

void
game_set_size (Game* self,
               gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = game_get_size (self);
	if (old_value != value) {
		self->priv->_size = value;
		g_object_notify_by_pspec ((GObject *) self, game_properties[GAME_SIZE_PROPERTY]);
	}
}

gint
game_get_n_rows (Game* self)
{
	gint result;
	Board* _tmp0_;
	Board* _tmp1_;
	gint _tmp2_;
	gint _tmp3_;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = self->board;
	_vala_assert (_tmp0_ != NULL, "board != null");
	_tmp1_ = self->board;
	_tmp2_ = board_get_n_rows (_tmp1_);
	_tmp3_ = _tmp2_;
	result = _tmp3_;
	return result;
}

gint
game_get_n_cols (Game* self)
{
	gint result;
	Board* _tmp0_;
	Board* _tmp1_;
	gint _tmp2_;
	gint _tmp3_;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = self->board;
	_vala_assert (_tmp0_ != NULL, "board != null");
	_tmp1_ = self->board;
	_tmp2_ = board_get_n_cols (_tmp1_);
	_tmp3_ = _tmp2_;
	result = _tmp3_;
	return result;
}

gint
game_get_score (Game* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, 0);
	result = self->priv->_score;
	return result;
}

static void
game_set_score (Game* self,
                gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = game_get_score (self);
	if (old_value != value) {
		self->priv->_score = value;
		g_object_notify_by_pspec ((GObject *) self, game_properties[GAME_SCORE_PROPERTY]);
	}
}

gint
game_get_current_path_cell_pos (Game* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, 0);
	result = self->priv->_current_path_cell_pos;
	return result;
}

void
game_set_current_path_cell_pos (Game* self,
                                gint value)
{
	g_return_if_fail (self != NULL);
	self->priv->_current_path_cell_pos = value;
	g_signal_emit (self, game_signals[GAME_CURRENT_PATH_CELL_POS_CHANGED_SIGNAL], 0);
	g_object_notify_by_pspec ((GObject *) self, game_properties[GAME_CURRENT_PATH_CELL_POS_PROPERTY]);
}

GeeArrayList*
game_get_next_pieces_queue (Game* self)
{
	GeeArrayList* result;
	GeeArrayList* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_next_pieces_queue;
	result = _tmp0_;
	return result;
}

static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

void
game_set_next_pieces_queue (Game* self,
                            GeeArrayList* value)
{
	GeeArrayList* _tmp0_;
	GeeArrayList* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = _g_object_ref0 (value);
	_g_object_unref0 (self->priv->_next_pieces_queue);
	self->priv->_next_pieces_queue = _tmp0_;
	_tmp1_ = self->priv->_next_pieces_queue;
	g_signal_emit (self, game_signals[GAME_QUEUE_CHANGED_SIGNAL], 0, _tmp1_);
	g_object_notify_by_pspec ((GObject *) self, game_properties[GAME_NEXT_PIECES_QUEUE_PROPERTY]);
}

gboolean
game_get_is_game_over (Game* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_is_game_over;
	return result;
}

static void
game_set_is_game_over (Game* self,
                       gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = game_get_is_game_over (self);
	if (old_value != value) {
		self->priv->_is_game_over = value;
		g_object_notify_by_pspec ((GObject *) self, game_properties[GAME_IS_GAME_OVER_PROPERTY]);
	}
}

StatusMessage
game_get_status_message (Game* self)
{
	StatusMessage result;
	g_return_val_if_fail (self != NULL, 0);
	result = self->priv->_status_message;
	return result;
}

void
game_set_status_message (Game* self,
                         StatusMessage value)
{
	StatusMessage old_value;
	g_return_if_fail (self != NULL);
	old_value = game_get_status_message (self);
	if (old_value != value) {
		self->priv->_status_message = value;
		g_object_notify_by_pspec ((GObject *) self, game_properties[GAME_STATUS_MESSAGE_PROPERTY]);
	}
}

static void
game_class_init (GameClass * klass,
                 gpointer klass_data)
{
	game_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &Game_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_game_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_game_set_property;
	G_OBJECT_CLASS (klass)->finalize = game_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), GAME_SIZE_PROPERTY, game_properties[GAME_SIZE_PROPERTY] = g_param_spec_int ("size", "size", "size", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GAME_N_ROWS_PROPERTY, game_properties[GAME_N_ROWS_PROPERTY] = g_param_spec_int ("n-rows", "n-rows", "n-rows", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GAME_N_COLS_PROPERTY, game_properties[GAME_N_COLS_PROPERTY] = g_param_spec_int ("n-cols", "n-cols", "n-cols", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GAME_SCORE_PROPERTY, game_properties[GAME_SCORE_PROPERTY] = g_param_spec_int ("score", "score", "score", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GAME_CURRENT_PATH_CELL_POS_PROPERTY, game_properties[GAME_CURRENT_PATH_CELL_POS_PROPERTY] = g_param_spec_int ("current-path-cell-pos", "current-path-cell-pos", "current-path-cell-pos", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GAME_NEXT_PIECES_QUEUE_PROPERTY, game_properties[GAME_NEXT_PIECES_QUEUE_PROPERTY] = g_param_spec_object ("next-pieces-queue", "next-pieces-queue", "next-pieces-queue", GEE_TYPE_ARRAY_LIST, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GAME_IS_GAME_OVER_PROPERTY, game_properties[GAME_IS_GAME_OVER_PROPERTY] = g_param_spec_boolean ("is-game-over", "is-game-over", "is-game-over", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GAME_STATUS_MESSAGE_PROPERTY, game_properties[GAME_STATUS_MESSAGE_PROPERTY] = g_param_spec_enum ("status-message", "status-message", "status-message", TYPE_STATUS_MESSAGE, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	game_signals[GAME_CURRENT_PATH_CELL_POS_CHANGED_SIGNAL] = g_signal_new ("current-path-cell-pos-changed", TYPE_GAME, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	game_signals[GAME_QUEUE_CHANGED_SIGNAL] = g_signal_new ("queue-changed", TYPE_GAME, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GEE_TYPE_ARRAY_LIST);
	game_signals[GAME_GAME_OVER_SIGNAL] = g_signal_new ("game-over", 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,
                    gpointer klass)
{
	self->priv = game_get_instance_private (self);
	self->board = NULL;
	self->current_path = NULL;
	self->animating = FALSE;
	self->priv->_current_path_cell_pos = -1;
	self->priv->_is_game_over = FALSE;
	self->n_categories = 3;
	self->score_current_category = NULL;
}

static void
game_finalize (GObject * obj)
{
	Game * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_GAME, Game);
	_next_pieces_generator_unref0 (self->priv->next_pieces_generator);
	_board_unref0 (self->board);
	_g_object_unref0 (self->current_path);
	_piece_unref0 (self->animating_piece);
	_g_object_unref0 (self->priv->_next_pieces_queue);
	_g_free0 (self->score_current_category);
	G_OBJECT_CLASS (game_parent_class)->finalize (obj);
}

static GType
game_get_type_once (void)
{
	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, NULL };
	GType game_type_id;
	game_type_id = g_type_register_static (G_TYPE_OBJECT, "Game", &g_define_type_info, 0);
	Game_private_offset = g_type_add_instance_private (game_type_id, sizeof (GamePrivate));
	return game_type_id;
}

GType
game_get_type (void)
{
	static volatile gsize game_type_id__once = 0;
	if (g_once_init_enter (&game_type_id__once)) {
		GType game_type_id;
		game_type_id = game_get_type_once ();
		g_once_init_leave (&game_type_id__once, game_type_id);
	}
	return game_type_id__once;
}

static void
_vala_game_get_property (GObject * object,
                         guint property_id,
                         GValue * value,
                         GParamSpec * pspec)
{
	Game * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_GAME, Game);
	switch (property_id) {
		case GAME_SIZE_PROPERTY:
		g_value_set_int (value, game_get_size (self));
		break;
		case GAME_N_ROWS_PROPERTY:
		g_value_set_int (value, game_get_n_rows (self));
		break;
		case GAME_N_COLS_PROPERTY:
		g_value_set_int (value, game_get_n_cols (self));
		break;
		case GAME_SCORE_PROPERTY:
		g_value_set_int (value, game_get_score (self));
		break;
		case GAME_CURRENT_PATH_CELL_POS_PROPERTY:
		g_value_set_int (value, game_get_current_path_cell_pos (self));
		break;
		case GAME_NEXT_PIECES_QUEUE_PROPERTY:
		g_value_set_object (value, game_get_next_pieces_queue (self));
		break;
		case GAME_IS_GAME_OVER_PROPERTY:
		g_value_set_boolean (value, game_get_is_game_over (self));
		break;
		case GAME_STATUS_MESSAGE_PROPERTY:
		g_value_set_enum (value, game_get_status_message (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_game_set_property (GObject * object,
                         guint property_id,
                         const GValue * value,
                         GParamSpec * pspec)
{
	Game * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_GAME, Game);
	switch (property_id) {
		case GAME_SIZE_PROPERTY:
		game_set_size (self, g_value_get_int (value));
		break;
		case GAME_SCORE_PROPERTY:
		game_set_score (self, g_value_get_int (value));
		break;
		case GAME_CURRENT_PATH_CELL_POS_PROPERTY:
		game_set_current_path_cell_pos (self, g_value_get_int (value));
		break;
		case GAME_NEXT_PIECES_QUEUE_PROPERTY:
		game_set_next_pieces_queue (self, g_value_get_object (value));
		break;
		case GAME_IS_GAME_OVER_PROPERTY:
		game_set_is_game_over (self, g_value_get_boolean (value));
		break;
		case GAME_STATUS_MESSAGE_PROPERTY:
		game_set_status_message (self, g_value_get_enum (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

GameDifficulty*
game_difficulty_dup (const GameDifficulty* self)
{
	GameDifficulty* dup;
	dup = g_new0 (GameDifficulty, 1);
	memcpy (dup, self, sizeof (GameDifficulty));
	return dup;
}

void
game_difficulty_free (GameDifficulty* self)
{
	g_free (self);
}

static GType
game_difficulty_get_type_once (void)
{
	GType game_difficulty_type_id;
	game_difficulty_type_id = g_boxed_type_register_static ("GameDifficulty", (GBoxedCopyFunc) game_difficulty_dup, (GBoxedFreeFunc) game_difficulty_free);
	return game_difficulty_type_id;
}

GType
game_difficulty_get_type (void)
{
	static volatile gsize game_difficulty_type_id__once = 0;
	if (g_once_init_enter (&game_difficulty_type_id__once)) {
		GType game_difficulty_type_id;
		game_difficulty_type_id = game_difficulty_get_type_once ();
		g_once_init_leave (&game_difficulty_type_id__once, game_difficulty_type_id);
	}
	return game_difficulty_type_id__once;
}

void
key_value_copy (const KeyValue* self,
                KeyValue* dest)
{
	const gchar* _tmp0_;
	gchar* _tmp1_;
	const gchar* _tmp2_;
	gchar* _tmp3_;
	_tmp0_ = (*self).key;
	_tmp1_ = g_strdup (_tmp0_);
	_g_free0 ((*dest).key);
	(*dest).key = _tmp1_;
	_tmp2_ = (*self).name;
	_tmp3_ = g_strdup (_tmp2_);
	_g_free0 ((*dest).name);
	(*dest).name = _tmp3_;
}

void
key_value_destroy (KeyValue* self)
{
	_g_free0 ((*self).key);
	_g_free0 ((*self).name);
}

KeyValue*
key_value_dup (const KeyValue* self)
{
	KeyValue* dup;
	dup = g_new0 (KeyValue, 1);
	key_value_copy (self, dup);
	return dup;
}

void
key_value_free (KeyValue* self)
{
	key_value_destroy (self);
	g_free (self);
}

static GType
key_value_get_type_once (void)
{
	GType key_value_type_id;
	key_value_type_id = g_boxed_type_register_static ("KeyValue", (GBoxedCopyFunc) key_value_dup, (GBoxedFreeFunc) key_value_free);
	return key_value_type_id;
}

GType
key_value_get_type (void)
{
	static volatile gsize key_value_type_id__once = 0;
	if (g_once_init_enter (&key_value_type_id__once)) {
		GType key_value_type_id;
		key_value_type_id = key_value_get_type_once ();
		g_once_init_leave (&key_value_type_id__once, key_value_type_id);
	}
	return key_value_type_id__once;
}

static GType
status_message_get_type_once (void)
{
	static const GEnumValue values[] = {{STATUS_MESSAGE_DESCRIPTION, "STATUS_MESSAGE_DESCRIPTION", "description"}, {STATUS_MESSAGE_NO_PATH, "STATUS_MESSAGE_NO_PATH", "no-path"}, {STATUS_MESSAGE_GAME_OVER, "STATUS_MESSAGE_GAME_OVER", "game-over"}, {STATUS_MESSAGE_NONE, "STATUS_MESSAGE_NONE", "none"}, {0, NULL, NULL}};
	GType status_message_type_id;
	status_message_type_id = g_enum_register_static ("StatusMessage", values);
	return status_message_type_id;
}

GType
status_message_get_type (void)
{
	static volatile gsize status_message_type_id__once = 0;
	if (g_once_init_enter (&status_message_type_id__once)) {
		GType status_message_type_id;
		status_message_type_id = status_message_get_type_once ();
		g_once_init_leave (&status_message_type_id__once, status_message_type_id);
	}
	return status_message_type_id__once;
}

static void
_vala_array_destroy (gpointer array,
                     gssize array_length,
                     GDestroyNotify destroy_func)
{
	if ((array != NULL) && (destroy_func != NULL)) {
		gssize 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,
                  gssize array_length,
                  GDestroyNotify destroy_func)
{
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}

