/* board.c generated by valac 0.56.18, the Vala compiler
 * generated from board.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 <gee.h>
#include <glib.h>
#include <stdlib.h>
#include <gobject/gvaluecollector.h>

#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_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;
typedef struct _BoardPrivate BoardPrivate;

#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 _cell_unref0(var) ((var == NULL) ? NULL : (var = (cell_unref (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

#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;
typedef struct _CellPrivate CellPrivate;
#define _piece_unref0(var) ((var == NULL) ? NULL : (var = (piece_unref (var), NULL)))
typedef struct _ParamSpecBoard ParamSpecBoard;
enum  {
	BOARD_GRID_CHANGED_SIGNAL,
	BOARD_BOARD_CHANGED_SIGNAL,
	BOARD_NUM_SIGNALS
};
static guint board_signals[BOARD_NUM_SIGNALS] = {0};
typedef enum  {
	DIRECTION_RIGHT,
	DIRECTION_LEFT,
	DIRECTION_UP,
	DIRECTION_DOWN,
	DIRECTION_UPPER_RIGHT,
	DIRECTION_LOWER_LEFT,
	DIRECTION_UPPER_LEFT,
	DIRECTION_LOWER_RIGHT
} Direction;

#define TYPE_DIRECTION (direction_get_type ())
typedef struct _ParamSpecCell ParamSpecCell;
#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 _Board {
	GTypeInstance parent_instance;
	volatile int ref_count;
	BoardPrivate * priv;
	GeeArrayList* closed;
	GeeArrayList* path;
};

struct _BoardClass {
	GTypeClass parent_class;
	void (*finalize) (Board *self);
};

struct _BoardPrivate {
	Cell** grid;
	gint grid_length1;
	gint grid_length2;
	Cell* src;
	Cell* dst;
	GeeArrayList* open;
};

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);
};

struct _ParamSpecBoard {
	GParamSpec parent_instance;
};

struct _ParamSpecCell {
	GParamSpec parent_instance;
};

static gint Board_private_offset;
static gpointer board_parent_class = NULL;
static gpointer cell_parent_class = NULL;

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 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 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 Cell* cell_new (gint row,
                gint col,
                Cell* parent,
                Piece* piece);
VALA_EXTERN Cell* cell_construct (GType object_type,
                      gint row,
                      gint col,
                      Cell* parent,
                      Piece* piece);
VALA_EXTERN void board_reset (Board* self,
                  gint n_rows,
                  gint n_cols);
VALA_EXTERN Cell** board_get_grid (Board* self,
                       gint* result_length1,
                       gint* result_length2);
static Cell** _vala_array_dup1 (Cell** self,
                         gssize length);
VALA_EXTERN void board_set_piece (Board* self,
                      gint row,
                      gint col,
                      Piece* piece);
VALA_EXTERN Piece* board_get_piece (Board* self,
                        gint row,
                        gint col);
VALA_EXTERN Cell* board_get_cell (Board* self,
                      gint row,
                      gint col);
VALA_EXTERN GeeArrayList* board_find_path (Board* self,
                               gint start_row,
                               gint start_col,
                               gint end_row,
                               gint end_col);
static void board_reset_path_search (Board* self);
static gboolean board_cell_equal (Board* self,
                           Cell* a,
                           Cell* b);
static gboolean _board_cell_equal_gee_equal_data_func (gconstpointer a,
                                                gconstpointer b,
                                                gpointer self);
static Cell* board_best_candidate (Board* self,
                            GeeArrayList* neighbours,
                            gint current_cost,
                            Cell* end);
VALA_EXTERN GeeArrayList* cell_get_neighbours (Cell* self,
                                   Cell** board,
                                   gint board_length1,
                                   gint board_length2);
static gint board_total_cost (Board* self,
                       Cell* start,
                       Cell* end,
                       gint current_cost);
VALA_EXTERN gboolean cell_equal (Cell* self,
                     Cell* cell);
static gint board_manhattan (Board* self,
                      gint start_x,
                      gint start_y,
                      gint end_x,
                      gint end_y);
VALA_EXTERN gint board_get_n_rows (Board* self);
VALA_EXTERN gint board_get_n_cols (Board* self);
static void board_finalize (Board * obj);
static GType board_get_type_once (void);
VALA_EXTERN GType direction_get_type (void) G_GNUC_CONST ;
static Cell* cell_get_neighbour (Cell* self,
                          Cell** board,
                          gint board_length1,
                          gint board_length2,
                          Direction dir);
static void cell_get_direction (Cell* self,
                         Cell** board,
                         gint board_length1,
                         gint board_length2,
                         Direction dir,
                         GeeArrayList** list);
VALA_EXTERN gboolean piece_equal (Piece* self,
                      Piece* piece);
static GeeArrayList* cell_get_horizontal (Cell* self,
                                   Cell** board,
                                   gint board_length1,
                                   gint board_length2);
static GeeArrayList* cell_get_vertical (Cell* self,
                                 Cell** board,
                                 gint board_length1,
                                 gint board_length2);
static GeeArrayList* cell_get_first_diagonal (Cell* self,
                                       Cell** board,
                                       gint board_length1,
                                       gint board_length2);
static GeeArrayList* cell_get_second_diagonal (Cell* self,
                                        Cell** board,
                                        gint board_length1,
                                        gint board_length2);
VALA_EXTERN GeeHashSet* cell_get_all_directions (Cell* self,
                                     Cell** board,
                                     gint board_length1,
                                     gint board_length2);
static void cell_finalize (Cell * obj);
static GType cell_get_type_once (void);
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);

static inline gpointer
board_get_instance_private (Board* self)
{
	return G_STRUCT_MEMBER_P (self, Board_private_offset);
}

Board*
board_construct (GType object_type,
                 gint n_rows,
                 gint n_cols)
{
	Board* self = NULL;
	Cell** _tmp0_;
	self = (Board*) g_type_create_instance (object_type);
	_tmp0_ = g_new0 (Cell*, (n_rows * n_cols) + 1);
	self->priv->grid = (_vala_array_free (self->priv->grid, self->priv->grid_length1 * self->priv->grid_length2, (GDestroyNotify) cell_unref), NULL);
	self->priv->grid = _tmp0_;
	self->priv->grid_length1 = n_rows;
	self->priv->grid_length2 = n_cols;
	{
		gint col = 0;
		col = 0;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				if (!_tmp1_) {
					gint _tmp2_;
					_tmp2_ = col;
					col = _tmp2_ + 1;
				}
				_tmp1_ = FALSE;
				if (!(col < n_cols)) {
					break;
				}
				{
					gint row = 0;
					row = 0;
					{
						gboolean _tmp3_ = FALSE;
						_tmp3_ = TRUE;
						while (TRUE) {
							Cell** _tmp5_;
							gint _tmp5__length1;
							gint _tmp5__length2;
							Cell* _tmp6_;
							if (!_tmp3_) {
								gint _tmp4_;
								_tmp4_ = row;
								row = _tmp4_ + 1;
							}
							_tmp3_ = FALSE;
							if (!(row < n_rows)) {
								break;
							}
							_tmp5_ = self->priv->grid;
							_tmp5__length1 = self->priv->grid_length1;
							_tmp5__length2 = self->priv->grid_length2;
							_tmp6_ = cell_new (row, col, NULL, NULL);
							_cell_unref0 (_tmp5_[(row * _tmp5__length2) + col]);
							_tmp5_[(row * _tmp5__length2) + col] = _tmp6_;
						}
					}
				}
			}
		}
	}
	return self;
}

Board*
board_new (gint n_rows,
           gint n_cols)
{
	return board_construct (TYPE_BOARD, n_rows, n_cols);
}

void
board_reset (Board* self,
             gint n_rows,
             gint n_cols)
{
	Cell** _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = g_new0 (Cell*, (n_rows * n_cols) + 1);
	self->priv->grid = (_vala_array_free (self->priv->grid, self->priv->grid_length1 * self->priv->grid_length2, (GDestroyNotify) cell_unref), NULL);
	self->priv->grid = _tmp0_;
	self->priv->grid_length1 = n_rows;
	self->priv->grid_length2 = n_cols;
	{
		gint col = 0;
		col = 0;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				if (!_tmp1_) {
					gint _tmp2_;
					_tmp2_ = col;
					col = _tmp2_ + 1;
				}
				_tmp1_ = FALSE;
				if (!(col < n_cols)) {
					break;
				}
				{
					gint row = 0;
					row = 0;
					{
						gboolean _tmp3_ = FALSE;
						_tmp3_ = TRUE;
						while (TRUE) {
							Cell** _tmp5_;
							gint _tmp5__length1;
							gint _tmp5__length2;
							Cell* _tmp6_;
							if (!_tmp3_) {
								gint _tmp4_;
								_tmp4_ = row;
								row = _tmp4_ + 1;
							}
							_tmp3_ = FALSE;
							if (!(row < n_rows)) {
								break;
							}
							_tmp5_ = self->priv->grid;
							_tmp5__length1 = self->priv->grid_length1;
							_tmp5__length2 = self->priv->grid_length2;
							_tmp6_ = _tmp5_[(row * _tmp5__length2) + col];
							if (_tmp6_ != NULL) {
								Cell** _tmp7_;
								gint _tmp7__length1;
								gint _tmp7__length2;
								Cell* _tmp8_;
								Cell** _tmp9_;
								gint _tmp9__length1;
								gint _tmp9__length2;
								Cell* _tmp10_;
								Cell** _tmp11_;
								gint _tmp11__length1;
								gint _tmp11__length2;
								Cell* _tmp12_;
								_tmp7_ = self->priv->grid;
								_tmp7__length1 = self->priv->grid_length1;
								_tmp7__length2 = self->priv->grid_length2;
								_tmp8_ = _tmp7_[(row * _tmp7__length2) + col];
								_cell_unref0 (_tmp8_->parent);
								_tmp8_->parent = NULL;
								_tmp9_ = self->priv->grid;
								_tmp9__length1 = self->priv->grid_length1;
								_tmp9__length2 = self->priv->grid_length2;
								_tmp10_ = _tmp9_[(row * _tmp9__length2) + col];
								_piece_unref0 (_tmp10_->piece);
								_tmp10_->piece = NULL;
								_tmp11_ = self->priv->grid;
								_tmp11__length1 = self->priv->grid_length1;
								_tmp11__length2 = self->priv->grid_length2;
								_tmp12_ = _tmp11_[(row * _tmp11__length2) + col];
								_tmp12_->cost = G_MAXINT;
							} else {
								Cell** _tmp13_;
								gint _tmp13__length1;
								gint _tmp13__length2;
								Cell* _tmp14_;
								_tmp13_ = self->priv->grid;
								_tmp13__length1 = self->priv->grid_length1;
								_tmp13__length2 = self->priv->grid_length2;
								_tmp14_ = cell_new (row, col, NULL, NULL);
								_cell_unref0 (_tmp13_[(row * _tmp13__length2) + col]);
								_tmp13_[(row * _tmp13__length2) + col] = _tmp14_;
							}
						}
					}
				}
			}
		}
	}
	g_signal_emit (self, board_signals[BOARD_BOARD_CHANGED_SIGNAL], 0);
}

static gpointer
_cell_ref0 (gpointer self)
{
	return self ? cell_ref (self) : NULL;
}

static Cell**
_vala_array_dup1 (Cell** self,
                  gssize length)
{
	if (length >= 0) {
		Cell** result;
		gssize i;
		result = g_new0 (Cell*, length + 1);
		for (i = 0; i < length; i++) {
			Cell* _tmp0_;
			_tmp0_ = _cell_ref0 (self[i]);
			result[i] = _tmp0_;
		}
		return result;
	}
	return NULL;
}

Cell**
board_get_grid (Board* self,
                gint* result_length1,
                gint* result_length2)
{
	Cell** _tmp0_;
	gint _tmp0__length1;
	gint _tmp0__length2;
	Cell** _tmp1_;
	gint _tmp1__length1;
	gint _tmp1__length2;
	Cell** _tmp2_;
	gint _tmp2__length1;
	gint _tmp2__length2;
	Cell** result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->grid;
	_tmp0__length1 = self->priv->grid_length1;
	_tmp0__length2 = self->priv->grid_length2;
	_tmp1_ = (_tmp0_ != NULL) ? _vala_array_dup1 (_tmp0_, _tmp0__length1 * _tmp0__length2) : _tmp0_;
	_tmp1__length1 = _tmp0__length1;
	_tmp1__length2 = _tmp0__length2;
	_tmp2_ = _tmp1_;
	_tmp2__length1 = _tmp1__length1;
	_tmp2__length2 = _tmp1__length2;
	if (result_length1) {
		*result_length1 = _tmp2__length1;
	}
	if (result_length2) {
		*result_length2 = _tmp2__length2;
	}
	result = _tmp2_;
	return result;
}

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

void
board_set_piece (Board* self,
                 gint row,
                 gint col,
                 Piece* piece)
{
	Cell** _tmp0_;
	gint _tmp0__length1;
	gint _tmp0__length2;
	Cell* _tmp1_;
	Piece* _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->grid;
	_tmp0__length1 = self->priv->grid_length1;
	_tmp0__length2 = self->priv->grid_length2;
	_tmp1_ = _tmp0_[(row * _tmp0__length2) + col];
	_tmp2_ = _piece_ref0 (piece);
	_piece_unref0 (_tmp1_->piece);
	_tmp1_->piece = _tmp2_;
}

Piece*
board_get_piece (Board* self,
                 gint row,
                 gint col)
{
	Cell** _tmp0_;
	gint _tmp0__length1;
	gint _tmp0__length2;
	Cell* _tmp1_;
	Piece* _tmp2_;
	Piece* _tmp3_;
	Piece* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->grid;
	_tmp0__length1 = self->priv->grid_length1;
	_tmp0__length2 = self->priv->grid_length2;
	_tmp1_ = _tmp0_[(row * _tmp0__length2) + col];
	_tmp2_ = _tmp1_->piece;
	_tmp3_ = _piece_ref0 (_tmp2_);
	result = _tmp3_;
	return result;
}

Cell*
board_get_cell (Board* self,
                gint row,
                gint col)
{
	Cell** _tmp0_;
	gint _tmp0__length1;
	gint _tmp0__length2;
	Cell* _tmp1_;
	Cell* _tmp2_;
	Cell* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->grid;
	_tmp0__length1 = self->priv->grid_length1;
	_tmp0__length2 = self->priv->grid_length2;
	_tmp1_ = _tmp0_[(row * _tmp0__length2) + col];
	_tmp2_ = _cell_ref0 (_tmp1_);
	result = _tmp2_;
	return result;
}

static gboolean
_board_cell_equal_gee_equal_data_func (gconstpointer a,
                                       gconstpointer b,
                                       gpointer self)
{
	gboolean result;
	result = board_cell_equal ((Board*) self, (Cell*) a, (Cell*) b);
	return result;
}

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

GeeArrayList*
board_find_path (Board* self,
                 gint start_row,
                 gint start_col,
                 gint end_row,
                 gint end_col)
{
	Cell** _tmp0_;
	gint _tmp0__length1;
	gint _tmp0__length2;
	Cell* _tmp1_;
	Cell* _tmp2_;
	Cell** _tmp3_;
	gint _tmp3__length1;
	gint _tmp3__length2;
	Cell* _tmp4_;
	Cell* _tmp5_;
	GeeArrayList* _tmp6_;
	GeeArrayList* _tmp7_;
	GeeArrayList* _tmp8_;
	Cell* _tmp9_;
	Cell* current_cell = NULL;
	gint current_cost = 0;
	GeeArrayList* neighbours = NULL;
	GeeArrayList* _tmp66_;
	GeeArrayList* _tmp67_;
	GeeArrayList* result;
	g_return_val_if_fail (self != NULL, NULL);
	board_reset_path_search (self);
	_tmp0_ = self->priv->grid;
	_tmp0__length1 = self->priv->grid_length1;
	_tmp0__length2 = self->priv->grid_length2;
	_tmp1_ = _tmp0_[(start_row * _tmp0__length2) + start_col];
	_tmp2_ = _cell_ref0 (_tmp1_);
	_cell_unref0 (self->priv->src);
	self->priv->src = _tmp2_;
	_tmp3_ = self->priv->grid;
	_tmp3__length1 = self->priv->grid_length1;
	_tmp3__length2 = self->priv->grid_length2;
	_tmp4_ = _tmp3_[(end_row * _tmp3__length2) + end_col];
	_tmp5_ = _cell_ref0 (_tmp4_);
	_cell_unref0 (self->priv->dst);
	self->priv->dst = _tmp5_;
	_tmp6_ = gee_array_list_new (TYPE_CELL, (GBoxedCopyFunc) cell_ref, (GDestroyNotify) cell_unref, _board_cell_equal_gee_equal_data_func, board_ref (self), board_unref);
	_g_object_unref0 (self->closed);
	self->closed = _tmp6_;
	_tmp7_ = gee_array_list_new (TYPE_CELL, (GBoxedCopyFunc) cell_ref, (GDestroyNotify) cell_unref, _board_cell_equal_gee_equal_data_func, board_ref (self), board_unref);
	_g_object_unref0 (self->priv->open);
	self->priv->open = _tmp7_;
	_tmp8_ = self->priv->open;
	_tmp9_ = self->priv->src;
	gee_abstract_collection_add ((GeeAbstractCollection*) _tmp8_, _tmp9_);
	current_cell = NULL;
	current_cost = 0;
	{
		gboolean _tmp10_ = FALSE;
		_tmp10_ = TRUE;
		while (TRUE) {
			GeeArrayList* _tmp14_;
			gint _tmp15_;
			gint _tmp16_;
			GeeArrayList* _tmp17_;
			Cell* _tmp18_;
			Cell* _tmp19_;
			GeeArrayList* _tmp20_;
			Cell* _tmp21_;
			GeeArrayList* _tmp22_;
			Cell* _tmp23_;
			GeeArrayList* _tmp24_;
			Cell* _tmp25_;
			Cell* _tmp37_;
			Cell** _tmp38_;
			gint _tmp38__length1;
			gint _tmp38__length2;
			GeeArrayList* _tmp39_;
			if (!_tmp10_) {
				GeeArrayList* _tmp11_;
				gint _tmp12_;
				gint _tmp13_;
				_tmp11_ = self->priv->open;
				_tmp12_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp11_);
				_tmp13_ = _tmp12_;
				if (!(_tmp13_ != 0)) {
					break;
				}
			}
			_tmp10_ = FALSE;
			_tmp14_ = self->closed;
			_tmp15_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp14_);
			_tmp16_ = _tmp15_;
			current_cost = _tmp16_;
			_tmp17_ = self->priv->open;
			_tmp18_ = self->priv->dst;
			_tmp19_ = board_best_candidate (self, _tmp17_, current_cost, _tmp18_);
			_cell_unref0 (current_cell);
			current_cell = _tmp19_;
			_tmp20_ = self->closed;
			_tmp21_ = current_cell;
			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp20_, _tmp21_);
			_tmp22_ = self->priv->open;
			_tmp23_ = current_cell;
			gee_abstract_collection_remove ((GeeAbstractCollection*) _tmp22_, _tmp23_);
			_tmp24_ = self->closed;
			_tmp25_ = self->priv->dst;
			if (gee_abstract_collection_contains ((GeeAbstractCollection*) _tmp24_, _tmp25_)) {
				GeeArrayList* _tmp35_;
				GeeArrayList* _tmp36_;
				{
					Cell* p = NULL;
					Cell* _tmp26_;
					Cell* _tmp27_;
					_tmp26_ = self->priv->dst;
					_tmp27_ = _cell_ref0 (_tmp26_);
					p = _tmp27_;
					{
						gboolean _tmp28_ = FALSE;
						_tmp28_ = TRUE;
						while (TRUE) {
							Cell* _tmp32_;
							GeeArrayList* _tmp33_;
							Cell* _tmp34_;
							if (!_tmp28_) {
								Cell* _tmp29_;
								Cell* _tmp30_;
								Cell* _tmp31_;
								_tmp29_ = p;
								_tmp30_ = _tmp29_->parent;
								_tmp31_ = _cell_ref0 (_tmp30_);
								_cell_unref0 (p);
								p = _tmp31_;
							}
							_tmp28_ = FALSE;
							_tmp32_ = p;
							if (!(_tmp32_ != NULL)) {
								break;
							}
							_tmp33_ = self->path;
							_tmp34_ = p;
							gee_abstract_list_insert ((GeeAbstractList*) _tmp33_, 0, _tmp34_);
						}
					}
					_cell_unref0 (p);
				}
				_tmp35_ = self->path;
				_tmp36_ = _g_object_ref0 (_tmp35_);
				result = _tmp36_;
				_g_object_unref0 (neighbours);
				_cell_unref0 (current_cell);
				return result;
			}
			_tmp37_ = current_cell;
			_tmp38_ = self->priv->grid;
			_tmp38__length1 = self->priv->grid_length1;
			_tmp38__length2 = self->priv->grid_length2;
			_tmp39_ = cell_get_neighbours (_tmp37_, _tmp38_, (gint) _tmp38__length1, (gint) _tmp38__length2);
			_g_object_unref0 (neighbours);
			neighbours = _tmp39_;
			{
				GeeArrayList* _neighbour_list = NULL;
				GeeArrayList* _tmp40_;
				gint _neighbour_size = 0;
				GeeArrayList* _tmp41_;
				gint _tmp42_;
				gint _tmp43_;
				gint _neighbour_index = 0;
				_tmp40_ = neighbours;
				_neighbour_list = _tmp40_;
				_tmp41_ = _neighbour_list;
				_tmp42_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp41_);
				_tmp43_ = _tmp42_;
				_neighbour_size = _tmp43_;
				_neighbour_index = -1;
				while (TRUE) {
					gint _tmp44_;
					gint _tmp45_;
					Cell* neighbour = NULL;
					GeeArrayList* _tmp46_;
					gpointer _tmp47_;
					GeeArrayList* _tmp48_;
					Cell* _tmp49_;
					GeeArrayList* _tmp50_;
					Cell* _tmp51_;
					_neighbour_index = _neighbour_index + 1;
					_tmp44_ = _neighbour_index;
					_tmp45_ = _neighbour_size;
					if (!(_tmp44_ < _tmp45_)) {
						break;
					}
					_tmp46_ = _neighbour_list;
					_tmp47_ = gee_abstract_list_get ((GeeAbstractList*) _tmp46_, _neighbour_index);
					neighbour = (Cell*) _tmp47_;
					_tmp48_ = self->closed;
					_tmp49_ = neighbour;
					if (gee_abstract_collection_contains ((GeeAbstractCollection*) _tmp48_, _tmp49_)) {
						_cell_unref0 (neighbour);
						continue;
					}
					_tmp50_ = self->priv->open;
					_tmp51_ = neighbour;
					if (!gee_abstract_collection_contains ((GeeAbstractCollection*) _tmp50_, _tmp51_)) {
						Cell* _tmp52_;
						Cell* _tmp53_;
						Cell* _tmp54_;
						GeeArrayList* _tmp55_;
						Cell* _tmp56_;
						_tmp52_ = neighbour;
						_tmp53_ = current_cell;
						_tmp54_ = _cell_ref0 (_tmp53_);
						_cell_unref0 (_tmp52_->parent);
						_tmp52_->parent = _tmp54_;
						_tmp55_ = self->priv->open;
						_tmp56_ = neighbour;
						gee_abstract_collection_add ((GeeAbstractCollection*) _tmp55_, _tmp56_);
					} else {
						Cell* _tmp57_;
						Cell* _tmp58_;
						Cell* _tmp59_;
						_tmp57_ = neighbour;
						_tmp58_ = self->priv->dst;
						_tmp59_ = neighbour;
						if (board_total_cost (self, _tmp57_, _tmp58_, current_cost) < _tmp59_->cost) {
							Cell* _tmp60_;
							Cell* _tmp61_;
							Cell* _tmp62_;
							Cell* _tmp63_;
							Cell* _tmp64_;
							Cell* _tmp65_;
							_tmp60_ = neighbour;
							_tmp61_ = current_cell;
							_tmp62_ = _cell_ref0 (_tmp61_);
							_cell_unref0 (_tmp60_->parent);
							_tmp60_->parent = _tmp62_;
							_tmp63_ = neighbour;
							_tmp64_ = neighbour;
							_tmp65_ = self->priv->dst;
							_tmp63_->cost = board_total_cost (self, _tmp64_, _tmp65_, current_cost);
						}
					}
					_cell_unref0 (neighbour);
				}
			}
		}
	}
	_tmp66_ = self->path;
	_tmp67_ = _g_object_ref0 (_tmp66_);
	result = _tmp67_;
	_g_object_unref0 (neighbours);
	_cell_unref0 (current_cell);
	return result;
}

static gboolean
board_cell_equal (Board* self,
                  Cell* a,
                  Cell* b)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (a != NULL) {
		_tmp1_ = b != NULL;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		_tmp0_ = cell_equal (a, b);
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

static void
board_reset_path_search (Board* self)
{
	GeeArrayList* _tmp0_;
	Cell** _tmp3_;
	gint _tmp3__length1;
	gint _tmp3__length2;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->path;
	if (_tmp0_ != NULL) {
		GeeArrayList* _tmp1_;
		_tmp1_ = self->path;
		gee_abstract_collection_clear ((GeeAbstractCollection*) _tmp1_);
	} else {
		GeeArrayList* _tmp2_;
		_tmp2_ = gee_array_list_new (TYPE_CELL, (GBoxedCopyFunc) cell_ref, (GDestroyNotify) cell_unref, NULL, NULL, NULL);
		_g_object_unref0 (self->path);
		self->path = _tmp2_;
	}
	_tmp3_ = self->priv->grid;
	_tmp3__length1 = self->priv->grid_length1;
	_tmp3__length2 = self->priv->grid_length2;
	{
		Cell** cell_collection = NULL;
		gint cell_collection_length1 = 0;
		gint cell_collection_length2 = 0;
		gint cell_it = 0;
		cell_collection = _tmp3_;
		cell_collection_length1 = _tmp3__length1 * _tmp3__length2;
		for (cell_it = 0; cell_it < cell_collection_length1; cell_it = cell_it + 1) {
			Cell* _tmp4_;
			Cell* cell = NULL;
			_tmp4_ = _cell_ref0 (cell_collection[cell_it]);
			cell = _tmp4_;
			{
				Cell* _tmp5_;
				Cell* _tmp6_;
				_tmp5_ = cell;
				_cell_unref0 (_tmp5_->parent);
				_tmp5_->parent = NULL;
				_tmp6_ = cell;
				_tmp6_->cost = G_MAXINT;
				_cell_unref0 (cell);
			}
		}
	}
}

static Cell*
board_best_candidate (Board* self,
                      GeeArrayList* neighbours,
                      gint current_cost,
                      Cell* end)
{
	gint lowest_f = 0;
	Cell* best_candidate = NULL;
	Cell* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (neighbours != NULL, NULL);
	g_return_val_if_fail (end != NULL, NULL);
	lowest_f = G_MAXINT;
	best_candidate = NULL;
	{
		GeeArrayList* _neighbour_list = NULL;
		gint _neighbour_size = 0;
		GeeArrayList* _tmp0_;
		gint _tmp1_;
		gint _tmp2_;
		gint _neighbour_index = 0;
		_neighbour_list = neighbours;
		_tmp0_ = _neighbour_list;
		_tmp1_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp0_);
		_tmp2_ = _tmp1_;
		_neighbour_size = _tmp2_;
		_neighbour_index = -1;
		while (TRUE) {
			gint _tmp3_;
			gint _tmp4_;
			Cell* neighbour = NULL;
			GeeArrayList* _tmp5_;
			gpointer _tmp6_;
			Cell* _tmp7_;
			Cell* _tmp8_;
			Cell* _tmp9_;
			_neighbour_index = _neighbour_index + 1;
			_tmp3_ = _neighbour_index;
			_tmp4_ = _neighbour_size;
			if (!(_tmp3_ < _tmp4_)) {
				break;
			}
			_tmp5_ = _neighbour_list;
			_tmp6_ = gee_abstract_list_get ((GeeAbstractList*) _tmp5_, _neighbour_index);
			neighbour = (Cell*) _tmp6_;
			_tmp7_ = neighbour;
			_tmp8_ = neighbour;
			_tmp7_->cost = board_total_cost (self, _tmp8_, end, current_cost);
			_tmp9_ = neighbour;
			if (_tmp9_->cost < lowest_f) {
				Cell* _tmp10_;
				Cell* _tmp11_;
				Cell* _tmp12_;
				_tmp10_ = neighbour;
				lowest_f = _tmp10_->cost;
				_tmp11_ = neighbour;
				_tmp12_ = _cell_ref0 (_tmp11_);
				_cell_unref0 (best_candidate);
				best_candidate = _tmp12_;
			}
			_cell_unref0 (neighbour);
		}
	}
	result = best_candidate;
	return result;
}

static gint
board_manhattan (Board* self,
                 gint start_x,
                 gint start_y,
                 gint end_x,
                 gint end_y)
{
	gint result;
	g_return_val_if_fail (self != NULL, 0);
	result = abs (start_x - end_x) + abs (start_y - end_y);
	return result;
}

static gint
board_total_cost (Board* self,
                  Cell* start,
                  Cell* end,
                  gint current_cost)
{
	gint f = 0;
	gint g = 0;
	gint h = 0;
	gint result;
	g_return_val_if_fail (self != NULL, 0);
	g_return_val_if_fail (start != NULL, 0);
	g_return_val_if_fail (end != NULL, 0);
	g = current_cost + 1;
	h = board_manhattan (self, start->row, start->col, end->row, end->col);
	f = g + h;
	result = f;
	return result;
}

gint
board_get_n_rows (Board* self)
{
	gint result;
	Cell** _tmp0_;
	gint _tmp0__length1;
	gint _tmp0__length2;
	Cell** _tmp1_;
	gint _tmp1__length1;
	gint _tmp1__length2;
	gint _tmp2_;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = self->priv->grid;
	_tmp0__length1 = self->priv->grid_length1;
	_tmp0__length2 = self->priv->grid_length2;
	_vala_assert (_tmp0_ != NULL, "grid != null");
	_tmp1_ = self->priv->grid;
	_tmp1__length1 = self->priv->grid_length1;
	_tmp1__length2 = self->priv->grid_length2;
	_tmp2_ = _tmp1__length1;
	result = _tmp2_;
	return result;
}

gint
board_get_n_cols (Board* self)
{
	gint result;
	Cell** _tmp0_;
	gint _tmp0__length1;
	gint _tmp0__length2;
	Cell** _tmp1_;
	gint _tmp1__length1;
	gint _tmp1__length2;
	gint _tmp2_;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = self->priv->grid;
	_tmp0__length1 = self->priv->grid_length1;
	_tmp0__length2 = self->priv->grid_length2;
	_vala_assert (_tmp0_ != NULL, "grid != null");
	_tmp1_ = self->priv->grid;
	_tmp1__length1 = self->priv->grid_length1;
	_tmp1__length2 = self->priv->grid_length2;
	_tmp2_ = _tmp1__length2;
	result = _tmp2_;
	return result;
}

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

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

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

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

static gchar*
value_board_collect_value (GValue* value,
                           guint n_collect_values,
                           GTypeCValue* collect_values,
                           guint collect_flags)
{
	if (collect_values[0].v_pointer) {
		Board * 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 = board_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}

static gchar*
value_board_lcopy_value (const GValue* value,
                         guint n_collect_values,
                         GTypeCValue* collect_values,
                         guint collect_flags)
{
	Board ** 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 = board_ref (value->data[0].v_pointer);
	}
	return NULL;
}

GParamSpec*
param_spec_board (const gchar* name,
                  const gchar* nick,
                  const gchar* blurb,
                  GType object_type,
                  GParamFlags flags)
{
	ParamSpecBoard* spec;
	g_return_val_if_fail (g_type_is_a (object_type, TYPE_BOARD), 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_board (const GValue* value)
{
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_BOARD), NULL);
	return value->data[0].v_pointer;
}

void
value_set_board (GValue* value,
                 gpointer v_object)
{
	Board * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_BOARD));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_BOARD));
		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;
		board_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		board_unref (old);
	}
}

void
value_take_board (GValue* value,
                  gpointer v_object)
{
	Board * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_BOARD));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_BOARD));
		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) {
		board_unref (old);
	}
}

static void
board_class_init (BoardClass * klass,
                  gpointer klass_data)
{
	board_parent_class = g_type_class_peek_parent (klass);
	((BoardClass *) klass)->finalize = board_finalize;
	g_type_class_adjust_private_offset (klass, &Board_private_offset);
	board_signals[BOARD_GRID_CHANGED_SIGNAL] = g_signal_new ("grid-changed", TYPE_BOARD, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	board_signals[BOARD_BOARD_CHANGED_SIGNAL] = g_signal_new ("board-changed", TYPE_BOARD, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}

static void
board_instance_init (Board * self,
                     gpointer klass)
{
	self->priv = board_get_instance_private (self);
	self->priv->grid = NULL;
	self->priv->grid_length1 = 0;
	self->priv->grid_length2 = 0;
	self->priv->open = NULL;
	self->closed = NULL;
	self->path = NULL;
	self->ref_count = 1;
}

static void
board_finalize (Board * obj)
{
	Board * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_BOARD, Board);
	g_signal_handlers_destroy (self);
	self->priv->grid = (_vala_array_free (self->priv->grid, self->priv->grid_length1 * self->priv->grid_length2, (GDestroyNotify) cell_unref), NULL);
	_cell_unref0 (self->priv->src);
	_cell_unref0 (self->priv->dst);
	_g_object_unref0 (self->priv->open);
	_g_object_unref0 (self->closed);
	_g_object_unref0 (self->path);
}

static GType
board_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { value_board_init, value_board_free_value, value_board_copy_value, value_board_peek_pointer, "p", value_board_collect_value, "p", value_board_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (BoardClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) board_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Board), 0, (GInstanceInitFunc) board_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 board_type_id;
	board_type_id = g_type_register_fundamental (g_type_fundamental_next (), "Board", &g_define_type_info, &g_define_type_fundamental_info, 0);
	Board_private_offset = g_type_add_instance_private (board_type_id, sizeof (BoardPrivate));
	return board_type_id;
}

GType
board_get_type (void)
{
	static volatile gsize board_type_id__once = 0;
	if (g_once_init_enter (&board_type_id__once)) {
		GType board_type_id;
		board_type_id = board_get_type_once ();
		g_once_init_leave (&board_type_id__once, board_type_id);
	}
	return board_type_id__once;
}

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

void
board_unref (gpointer instance)
{
	Board * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		BOARD_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

Cell*
cell_construct (GType object_type,
                gint row,
                gint col,
                Cell* parent,
                Piece* piece)
{
	Cell* self = NULL;
	Cell* _tmp0_;
	Piece* _tmp1_;
	self = (Cell*) g_type_create_instance (object_type);
	self->row = row;
	self->col = col;
	_tmp0_ = _cell_ref0 (parent);
	_cell_unref0 (self->parent);
	self->parent = _tmp0_;
	_tmp1_ = _piece_ref0 (piece);
	_piece_unref0 (self->piece);
	self->piece = _tmp1_;
	self->cost = G_MAXINT;
	return self;
}

Cell*
cell_new (gint row,
          gint col,
          Cell* parent,
          Piece* piece)
{
	return cell_construct (TYPE_CELL, row, col, parent, piece);
}

gboolean
cell_equal (Cell* self,
            Cell* cell)
{
	gboolean _tmp0_ = FALSE;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (cell != NULL, FALSE);
	if (self->row == cell->row) {
		_tmp0_ = self->col == cell->col;
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

static Cell*
cell_get_neighbour (Cell* self,
                    Cell** board,
                    gint board_length1,
                    gint board_length2,
                    Direction dir)
{
	Cell* neighbour = NULL;
	gint row = 0;
	gint col = 0;
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	Cell* result;
	g_return_val_if_fail (self != NULL, NULL);
	neighbour = NULL;
	row = -1;
	col = -1;
	switch (dir) {
		case DIRECTION_RIGHT:
		{
			row = self->row;
			col = self->col + 1;
			break;
		}
		case DIRECTION_LEFT:
		{
			row = self->row;
			col = self->col - 1;
			break;
		}
		case DIRECTION_UP:
		{
			row = self->row - 1;
			col = self->col;
			break;
		}
		case DIRECTION_DOWN:
		{
			row = self->row + 1;
			col = self->col;
			break;
		}
		case DIRECTION_UPPER_LEFT:
		{
			row = self->row - 1;
			col = self->col - 1;
			break;
		}
		case DIRECTION_LOWER_RIGHT:
		{
			row = self->row + 1;
			col = self->col + 1;
			break;
		}
		case DIRECTION_UPPER_RIGHT:
		{
			row = self->row - 1;
			col = self->col + 1;
			break;
		}
		case DIRECTION_LOWER_LEFT:
		{
			row = self->row + 1;
			col = self->col - 1;
			break;
		}
		default:
		break;
	}
	if (row >= 0) {
		gint _tmp3_;
		_tmp3_ = board_length1;
		_tmp2_ = row < _tmp3_;
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		_tmp1_ = col >= 0;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		gint _tmp4_;
		_tmp4_ = board_length2;
		_tmp0_ = col < _tmp4_;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		Cell* _tmp5_;
		Cell* _tmp6_;
		_tmp5_ = board[(row * board_length2) + col];
		_tmp6_ = _cell_ref0 (_tmp5_);
		_cell_unref0 (neighbour);
		neighbour = _tmp6_;
	}
	result = neighbour;
	return result;
}

GeeArrayList*
cell_get_neighbours (Cell* self,
                     Cell** board,
                     gint board_length1,
                     gint board_length2)
{
	GeeArrayList* neighbours = NULL;
	GeeArrayList* _tmp0_;
	Cell* right = NULL;
	Cell* left = NULL;
	Cell* up = NULL;
	Cell* down = NULL;
	Cell* _tmp1_;
	gboolean _tmp2_ = FALSE;
	Cell* _tmp3_;
	Cell* _tmp8_;
	gboolean _tmp9_ = FALSE;
	Cell* _tmp10_;
	Cell* _tmp15_;
	gboolean _tmp16_ = FALSE;
	Cell* _tmp17_;
	Cell* _tmp22_;
	gboolean _tmp23_ = FALSE;
	Cell* _tmp24_;
	GeeArrayList* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = gee_array_list_new (TYPE_CELL, (GBoxedCopyFunc) cell_ref, (GDestroyNotify) cell_unref, NULL, NULL, NULL);
	neighbours = _tmp0_;
	right = NULL;
	left = NULL;
	up = NULL;
	down = NULL;
	_tmp1_ = cell_get_neighbour (self, board, (gint) board_length1, (gint) board_length2, DIRECTION_RIGHT);
	_cell_unref0 (right);
	right = _tmp1_;
	_tmp3_ = right;
	if (_tmp3_ != NULL) {
		Cell* _tmp4_;
		Piece* _tmp5_;
		_tmp4_ = right;
		_tmp5_ = _tmp4_->piece;
		_tmp2_ = _tmp5_ == NULL;
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		GeeArrayList* _tmp6_;
		Cell* _tmp7_;
		_tmp6_ = neighbours;
		_tmp7_ = right;
		gee_abstract_collection_add ((GeeAbstractCollection*) _tmp6_, _tmp7_);
	}
	_tmp8_ = cell_get_neighbour (self, board, (gint) board_length1, (gint) board_length2, DIRECTION_LEFT);
	_cell_unref0 (left);
	left = _tmp8_;
	_tmp10_ = left;
	if (_tmp10_ != NULL) {
		Cell* _tmp11_;
		Piece* _tmp12_;
		_tmp11_ = left;
		_tmp12_ = _tmp11_->piece;
		_tmp9_ = _tmp12_ == NULL;
	} else {
		_tmp9_ = FALSE;
	}
	if (_tmp9_) {
		GeeArrayList* _tmp13_;
		Cell* _tmp14_;
		_tmp13_ = neighbours;
		_tmp14_ = left;
		gee_abstract_collection_add ((GeeAbstractCollection*) _tmp13_, _tmp14_);
	}
	_tmp15_ = cell_get_neighbour (self, board, (gint) board_length1, (gint) board_length2, DIRECTION_UP);
	_cell_unref0 (up);
	up = _tmp15_;
	_tmp17_ = up;
	if (_tmp17_ != NULL) {
		Cell* _tmp18_;
		Piece* _tmp19_;
		_tmp18_ = up;
		_tmp19_ = _tmp18_->piece;
		_tmp16_ = _tmp19_ == NULL;
	} else {
		_tmp16_ = FALSE;
	}
	if (_tmp16_) {
		GeeArrayList* _tmp20_;
		Cell* _tmp21_;
		_tmp20_ = neighbours;
		_tmp21_ = up;
		gee_abstract_collection_add ((GeeAbstractCollection*) _tmp20_, _tmp21_);
	}
	_tmp22_ = cell_get_neighbour (self, board, (gint) board_length1, (gint) board_length2, DIRECTION_DOWN);
	_cell_unref0 (down);
	down = _tmp22_;
	_tmp24_ = down;
	if (_tmp24_ != NULL) {
		Cell* _tmp25_;
		Piece* _tmp26_;
		_tmp25_ = down;
		_tmp26_ = _tmp25_->piece;
		_tmp23_ = _tmp26_ == NULL;
	} else {
		_tmp23_ = FALSE;
	}
	if (_tmp23_) {
		GeeArrayList* _tmp27_;
		Cell* _tmp28_;
		_tmp27_ = neighbours;
		_tmp28_ = down;
		gee_abstract_collection_add ((GeeAbstractCollection*) _tmp27_, _tmp28_);
	}
	result = neighbours;
	_cell_unref0 (down);
	_cell_unref0 (up);
	_cell_unref0 (left);
	_cell_unref0 (right);
	return result;
}

static void
cell_get_direction (Cell* self,
                    Cell** board,
                    gint board_length1,
                    gint board_length2,
                    Direction dir,
                    GeeArrayList** list)
{
	g_return_if_fail (self != NULL);
	if ((*list) == NULL) {
		GeeArrayList* _tmp0_;
		_tmp0_ = gee_array_list_new (TYPE_CELL, (GBoxedCopyFunc) cell_ref, (GDestroyNotify) cell_unref, NULL, NULL, NULL);
		_g_object_unref0 (*list);
		*list = _tmp0_;
	}
	{
		Cell* cell = NULL;
		Cell* _tmp1_;
		_tmp1_ = _cell_ref0 (self);
		cell = _tmp1_;
		{
			gboolean _tmp2_ = FALSE;
			_tmp2_ = TRUE;
			while (TRUE) {
				gboolean _tmp5_ = FALSE;
				gboolean _tmp6_ = FALSE;
				Cell* _tmp7_;
				Cell* _tmp13_;
				if (!_tmp2_) {
					Cell* _tmp3_;
					Cell* _tmp4_;
					_tmp3_ = cell;
					_tmp4_ = cell_get_neighbour (_tmp3_, board, (gint) board_length1, (gint) board_length2, dir);
					_cell_unref0 (cell);
					cell = _tmp4_;
				}
				_tmp2_ = FALSE;
				_tmp7_ = cell;
				if (_tmp7_ != NULL) {
					Cell* _tmp8_;
					Piece* _tmp9_;
					_tmp8_ = cell;
					_tmp9_ = _tmp8_->piece;
					_tmp6_ = _tmp9_ != NULL;
				} else {
					_tmp6_ = FALSE;
				}
				if (_tmp6_) {
					Cell* _tmp10_;
					Piece* _tmp11_;
					Piece* _tmp12_;
					_tmp10_ = cell;
					_tmp11_ = _tmp10_->piece;
					_tmp12_ = self->piece;
					_tmp5_ = piece_equal (_tmp11_, _tmp12_);
				} else {
					_tmp5_ = FALSE;
				}
				if (!_tmp5_) {
					break;
				}
				_tmp13_ = cell;
				if (!gee_abstract_collection_contains ((GeeAbstractCollection*) (*list), _tmp13_)) {
					Cell* _tmp14_;
					_tmp14_ = cell;
					gee_abstract_collection_add ((GeeAbstractCollection*) (*list), _tmp14_);
				}
			}
		}
		_cell_unref0 (cell);
	}
}

static GeeArrayList*
cell_get_horizontal (Cell* self,
                     Cell** board,
                     gint board_length1,
                     gint board_length2)
{
	GeeArrayList* list = NULL;
	GeeArrayList* result;
	g_return_val_if_fail (self != NULL, NULL);
	list = NULL;
	cell_get_direction (self, board, (gint) board_length1, (gint) board_length2, DIRECTION_LEFT, &list);
	cell_get_direction (self, board, (gint) board_length1, (gint) board_length2, DIRECTION_RIGHT, &list);
	result = list;
	return result;
}

static GeeArrayList*
cell_get_vertical (Cell* self,
                   Cell** board,
                   gint board_length1,
                   gint board_length2)
{
	GeeArrayList* list = NULL;
	GeeArrayList* result;
	g_return_val_if_fail (self != NULL, NULL);
	list = NULL;
	cell_get_direction (self, board, (gint) board_length1, (gint) board_length2, DIRECTION_UP, &list);
	cell_get_direction (self, board, (gint) board_length1, (gint) board_length2, DIRECTION_DOWN, &list);
	result = list;
	return result;
}

static GeeArrayList*
cell_get_first_diagonal (Cell* self,
                         Cell** board,
                         gint board_length1,
                         gint board_length2)
{
	GeeArrayList* list = NULL;
	GeeArrayList* result;
	g_return_val_if_fail (self != NULL, NULL);
	list = NULL;
	cell_get_direction (self, board, (gint) board_length1, (gint) board_length2, DIRECTION_UPPER_LEFT, &list);
	cell_get_direction (self, board, (gint) board_length1, (gint) board_length2, DIRECTION_LOWER_RIGHT, &list);
	result = list;
	return result;
}

static GeeArrayList*
cell_get_second_diagonal (Cell* self,
                          Cell** board,
                          gint board_length1,
                          gint board_length2)
{
	GeeArrayList* list = NULL;
	GeeArrayList* result;
	g_return_val_if_fail (self != NULL, NULL);
	list = NULL;
	cell_get_direction (self, board, (gint) board_length1, (gint) board_length2, DIRECTION_UPPER_RIGHT, &list);
	cell_get_direction (self, board, (gint) board_length1, (gint) board_length2, DIRECTION_LOWER_LEFT, &list);
	result = list;
	return result;
}

GeeHashSet*
cell_get_all_directions (Cell* self,
                         Cell** board,
                         gint board_length1,
                         gint board_length2)
{
	GeeArrayList* list = NULL;
	GeeHashSet* inactivate = NULL;
	GeeHashSet* _tmp0_;
	GeeArrayList* _tmp1_;
	GeeArrayList* _tmp2_;
	gint _tmp3_;
	gint _tmp4_;
	GeeArrayList* _tmp15_;
	GeeArrayList* _tmp16_;
	gint _tmp17_;
	gint _tmp18_;
	GeeArrayList* _tmp29_;
	GeeArrayList* _tmp30_;
	gint _tmp31_;
	gint _tmp32_;
	GeeArrayList* _tmp43_;
	GeeArrayList* _tmp44_;
	gint _tmp45_;
	gint _tmp46_;
	GeeHashSet* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = gee_hash_set_new (TYPE_CELL, (GBoxedCopyFunc) cell_ref, (GDestroyNotify) cell_unref, NULL, NULL, NULL, NULL, NULL, NULL);
	inactivate = _tmp0_;
	_tmp1_ = cell_get_horizontal (self, board, (gint) board_length1, (gint) board_length2);
	_g_object_unref0 (list);
	list = _tmp1_;
	_tmp2_ = list;
	_tmp3_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp2_);
	_tmp4_ = _tmp3_;
	if (_tmp4_ >= GAME_N_MATCH) {
		{
			GeeArrayList* _l_list = NULL;
			GeeArrayList* _tmp5_;
			gint _l_size = 0;
			GeeArrayList* _tmp6_;
			gint _tmp7_;
			gint _tmp8_;
			gint _l_index = 0;
			_tmp5_ = list;
			_l_list = _tmp5_;
			_tmp6_ = _l_list;
			_tmp7_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp6_);
			_tmp8_ = _tmp7_;
			_l_size = _tmp8_;
			_l_index = -1;
			while (TRUE) {
				gint _tmp9_;
				gint _tmp10_;
				Cell* l = NULL;
				GeeArrayList* _tmp11_;
				gpointer _tmp12_;
				GeeHashSet* _tmp13_;
				Cell* _tmp14_;
				_l_index = _l_index + 1;
				_tmp9_ = _l_index;
				_tmp10_ = _l_size;
				if (!(_tmp9_ < _tmp10_)) {
					break;
				}
				_tmp11_ = _l_list;
				_tmp12_ = gee_abstract_list_get ((GeeAbstractList*) _tmp11_, _l_index);
				l = (Cell*) _tmp12_;
				_tmp13_ = inactivate;
				_tmp14_ = l;
				gee_abstract_collection_add ((GeeAbstractCollection*) _tmp13_, _tmp14_);
				_cell_unref0 (l);
			}
		}
	}
	_tmp15_ = cell_get_vertical (self, board, (gint) board_length1, (gint) board_length2);
	_g_object_unref0 (list);
	list = _tmp15_;
	_tmp16_ = list;
	_tmp17_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp16_);
	_tmp18_ = _tmp17_;
	if (_tmp18_ >= GAME_N_MATCH) {
		{
			GeeArrayList* _l_list = NULL;
			GeeArrayList* _tmp19_;
			gint _l_size = 0;
			GeeArrayList* _tmp20_;
			gint _tmp21_;
			gint _tmp22_;
			gint _l_index = 0;
			_tmp19_ = list;
			_l_list = _tmp19_;
			_tmp20_ = _l_list;
			_tmp21_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp20_);
			_tmp22_ = _tmp21_;
			_l_size = _tmp22_;
			_l_index = -1;
			while (TRUE) {
				gint _tmp23_;
				gint _tmp24_;
				Cell* l = NULL;
				GeeArrayList* _tmp25_;
				gpointer _tmp26_;
				GeeHashSet* _tmp27_;
				Cell* _tmp28_;
				_l_index = _l_index + 1;
				_tmp23_ = _l_index;
				_tmp24_ = _l_size;
				if (!(_tmp23_ < _tmp24_)) {
					break;
				}
				_tmp25_ = _l_list;
				_tmp26_ = gee_abstract_list_get ((GeeAbstractList*) _tmp25_, _l_index);
				l = (Cell*) _tmp26_;
				_tmp27_ = inactivate;
				_tmp28_ = l;
				gee_abstract_collection_add ((GeeAbstractCollection*) _tmp27_, _tmp28_);
				_cell_unref0 (l);
			}
		}
	}
	_tmp29_ = cell_get_first_diagonal (self, board, (gint) board_length1, (gint) board_length2);
	_g_object_unref0 (list);
	list = _tmp29_;
	_tmp30_ = list;
	_tmp31_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp30_);
	_tmp32_ = _tmp31_;
	if (_tmp32_ >= GAME_N_MATCH) {
		{
			GeeArrayList* _l_list = NULL;
			GeeArrayList* _tmp33_;
			gint _l_size = 0;
			GeeArrayList* _tmp34_;
			gint _tmp35_;
			gint _tmp36_;
			gint _l_index = 0;
			_tmp33_ = list;
			_l_list = _tmp33_;
			_tmp34_ = _l_list;
			_tmp35_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp34_);
			_tmp36_ = _tmp35_;
			_l_size = _tmp36_;
			_l_index = -1;
			while (TRUE) {
				gint _tmp37_;
				gint _tmp38_;
				Cell* l = NULL;
				GeeArrayList* _tmp39_;
				gpointer _tmp40_;
				GeeHashSet* _tmp41_;
				Cell* _tmp42_;
				_l_index = _l_index + 1;
				_tmp37_ = _l_index;
				_tmp38_ = _l_size;
				if (!(_tmp37_ < _tmp38_)) {
					break;
				}
				_tmp39_ = _l_list;
				_tmp40_ = gee_abstract_list_get ((GeeAbstractList*) _tmp39_, _l_index);
				l = (Cell*) _tmp40_;
				_tmp41_ = inactivate;
				_tmp42_ = l;
				gee_abstract_collection_add ((GeeAbstractCollection*) _tmp41_, _tmp42_);
				_cell_unref0 (l);
			}
		}
	}
	_tmp43_ = cell_get_second_diagonal (self, board, (gint) board_length1, (gint) board_length2);
	_g_object_unref0 (list);
	list = _tmp43_;
	_tmp44_ = list;
	_tmp45_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp44_);
	_tmp46_ = _tmp45_;
	if (_tmp46_ >= GAME_N_MATCH) {
		{
			GeeArrayList* _l_list = NULL;
			GeeArrayList* _tmp47_;
			gint _l_size = 0;
			GeeArrayList* _tmp48_;
			gint _tmp49_;
			gint _tmp50_;
			gint _l_index = 0;
			_tmp47_ = list;
			_l_list = _tmp47_;
			_tmp48_ = _l_list;
			_tmp49_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp48_);
			_tmp50_ = _tmp49_;
			_l_size = _tmp50_;
			_l_index = -1;
			while (TRUE) {
				gint _tmp51_;
				gint _tmp52_;
				Cell* l = NULL;
				GeeArrayList* _tmp53_;
				gpointer _tmp54_;
				GeeHashSet* _tmp55_;
				Cell* _tmp56_;
				_l_index = _l_index + 1;
				_tmp51_ = _l_index;
				_tmp52_ = _l_size;
				if (!(_tmp51_ < _tmp52_)) {
					break;
				}
				_tmp53_ = _l_list;
				_tmp54_ = gee_abstract_list_get ((GeeAbstractList*) _tmp53_, _l_index);
				l = (Cell*) _tmp54_;
				_tmp55_ = inactivate;
				_tmp56_ = l;
				gee_abstract_collection_add ((GeeAbstractCollection*) _tmp55_, _tmp56_);
				_cell_unref0 (l);
			}
		}
	}
	result = inactivate;
	_g_object_unref0 (list);
	return result;
}

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

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

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

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

static gchar*
value_cell_collect_value (GValue* value,
                          guint n_collect_values,
                          GTypeCValue* collect_values,
                          guint collect_flags)
{
	if (collect_values[0].v_pointer) {
		Cell * 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 = cell_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}

static gchar*
value_cell_lcopy_value (const GValue* value,
                        guint n_collect_values,
                        GTypeCValue* collect_values,
                        guint collect_flags)
{
	Cell ** 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 = cell_ref (value->data[0].v_pointer);
	}
	return NULL;
}

GParamSpec*
param_spec_cell (const gchar* name,
                 const gchar* nick,
                 const gchar* blurb,
                 GType object_type,
                 GParamFlags flags)
{
	ParamSpecCell* spec;
	g_return_val_if_fail (g_type_is_a (object_type, TYPE_CELL), 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_cell (const GValue* value)
{
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_CELL), NULL);
	return value->data[0].v_pointer;
}

void
value_set_cell (GValue* value,
                gpointer v_object)
{
	Cell * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_CELL));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_CELL));
		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;
		cell_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		cell_unref (old);
	}
}

void
value_take_cell (GValue* value,
                 gpointer v_object)
{
	Cell * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_CELL));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_CELL));
		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) {
		cell_unref (old);
	}
}

static void
cell_class_init (CellClass * klass,
                 gpointer klass_data)
{
	cell_parent_class = g_type_class_peek_parent (klass);
	((CellClass *) klass)->finalize = cell_finalize;
}

static void
cell_instance_init (Cell * self,
                    gpointer klass)
{
	self->ref_count = 1;
}

static void
cell_finalize (Cell * obj)
{
	Cell * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_CELL, Cell);
	g_signal_handlers_destroy (self);
	_cell_unref0 (self->parent);
	_piece_unref0 (self->piece);
}

static GType
cell_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { value_cell_init, value_cell_free_value, value_cell_copy_value, value_cell_peek_pointer, "p", value_cell_collect_value, "p", value_cell_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (CellClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) cell_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Cell), 0, (GInstanceInitFunc) cell_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 cell_type_id;
	cell_type_id = g_type_register_fundamental (g_type_fundamental_next (), "Cell", &g_define_type_info, &g_define_type_fundamental_info, 0);
	return cell_type_id;
}

GType
cell_get_type (void)
{
	static volatile gsize cell_type_id__once = 0;
	if (g_once_init_enter (&cell_type_id__once)) {
		GType cell_type_id;
		cell_type_id = cell_get_type_once ();
		g_once_init_leave (&cell_type_id__once, cell_type_id);
	}
	return cell_type_id__once;
}

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

void
cell_unref (gpointer instance)
{
	Cell * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		CELL_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

static GType
direction_get_type_once (void)
{
	static const GEnumValue values[] = {{DIRECTION_RIGHT, "DIRECTION_RIGHT", "right"}, {DIRECTION_LEFT, "DIRECTION_LEFT", "left"}, {DIRECTION_UP, "DIRECTION_UP", "up"}, {DIRECTION_DOWN, "DIRECTION_DOWN", "down"}, {DIRECTION_UPPER_RIGHT, "DIRECTION_UPPER_RIGHT", "upper-right"}, {DIRECTION_LOWER_LEFT, "DIRECTION_LOWER_LEFT", "lower-left"}, {DIRECTION_UPPER_LEFT, "DIRECTION_UPPER_LEFT", "upper-left"}, {DIRECTION_LOWER_RIGHT, "DIRECTION_LOWER_RIGHT", "lower-right"}, {0, NULL, NULL}};
	GType direction_type_id;
	direction_type_id = g_enum_register_static ("Direction", values);
	return direction_type_id;
}

GType
direction_get_type (void)
{
	static volatile gsize direction_type_id__once = 0;
	if (g_once_init_enter (&direction_type_id__once)) {
		GType direction_type_id;
		direction_type_id = direction_get_type_once ();
		g_once_init_leave (&direction_type_id__once, direction_type_id);
	}
	return direction_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);
}

