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

/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-

   This file is part of GNOME Tetravex.

   Copyright (C) 2010-2013 Robert Ancell
   Copyright (C) 2019 Arnaud Bonatti

   GNOME Tetravex 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 of the License, or
   (at your option) any later version.

   GNOME Tetravex 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 GNOME Tetravex.  If not, see <https://www.gnu.org/licenses/>.
*/

#include <glib-object.h>
#include <glib.h>
#include <float.h>
#include <math.h>
#include <string.h>

#define PUZZLE_animation_duration ((guint) 250)
#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_TILE (tile_get_type ())
#define TILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_TILE, Tile))
#define TILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_TILE, TileClass))
#define IS_TILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_TILE))
#define IS_TILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_TILE))
#define TILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_TILE, TileClass))

typedef struct _Tile Tile;
typedef struct _TileClass TileClass;
typedef struct _TilePrivate TilePrivate;
enum  {
	TILE_0_PROPERTY,
	TILE_X_PROPERTY,
	TILE_Y_PROPERTY,
	TILE_NUM_PROPERTIES
};
static GParamSpec* tile_properties[TILE_NUM_PROPERTIES];

#define TYPE_PUZZLE (puzzle_get_type ())
#define PUZZLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PUZZLE, Puzzle))
#define PUZZLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_PUZZLE, PuzzleClass))
#define IS_PUZZLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PUZZLE))
#define IS_PUZZLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PUZZLE))
#define PUZZLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PUZZLE, PuzzleClass))

typedef struct _Puzzle Puzzle;
typedef struct _PuzzleClass PuzzleClass;
typedef struct _PuzzlePrivate PuzzlePrivate;

#define PUZZLE_TYPE_INVERSION (puzzle_inversion_get_type ())
#define PUZZLE_INVERSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PUZZLE_TYPE_INVERSION, PuzzleInversion))
#define PUZZLE_INVERSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PUZZLE_TYPE_INVERSION, PuzzleInversionClass))
#define PUZZLE_IS_INVERSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PUZZLE_TYPE_INVERSION))
#define PUZZLE_IS_INVERSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PUZZLE_TYPE_INVERSION))
#define PUZZLE_INVERSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PUZZLE_TYPE_INVERSION, PuzzleInversionClass))

typedef struct _PuzzleInversion PuzzleInversion;
typedef struct _PuzzleInversionClass PuzzleInversionClass;
enum  {
	PUZZLE_0_PROPERTY,
	PUZZLE_SIZE_PROPERTY,
	PUZZLE_COLORS_PROPERTY,
	PUZZLE_INITIAL_TIME_PROPERTY,
	PUZZLE_TAINTED_BY_COMMAND_LINE_PROPERTY,
	PUZZLE_ELAPSED_PROPERTY,
	PUZZLE_PAUSED_PROPERTY,
	PUZZLE_IS_SOLVED_PROPERTY,
	PUZZLE_RESTORED_PROPERTY,
	PUZZLE_GAME_IN_PROGRESS_PROPERTY,
	PUZZLE_IS_SOLVED_RIGHT_PROPERTY,
	PUZZLE_CAN_UNDO_PROPERTY,
	PUZZLE_CAN_REDO_PROPERTY,
	PUZZLE_NUM_PROPERTIES
};
static GParamSpec* puzzle_properties[PUZZLE_NUM_PROPERTIES];
#define _g_timer_destroy0(var) ((var == NULL) ? NULL : (var = (g_timer_destroy (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
typedef enum  {
	DIRECTION_NONE,
	DIRECTION_UP,
	DIRECTION_DOWN,
	DIRECTION_LEFT,
	DIRECTION_RIGHT
} Direction;

#define TYPE_DIRECTION (direction_get_type ())
#define _g_variant_type_free0(var) ((var == NULL) ? NULL : (var = (g_variant_type_free (var), NULL)))
#define _g_variant_builder_unref0(var) ((var == NULL) ? NULL : (var = (g_variant_builder_unref (var), NULL)))
#define _g_variant_unref0(var) ((var == NULL) ? NULL : (var = (g_variant_unref (var), NULL)))

#define PUZZLE_TYPE_SAVED_TILE (puzzle_saved_tile_get_type ())
typedef struct _PuzzleSavedTile PuzzleSavedTile;
#define _g_variant_iter_free0(var) ((var == NULL) ? NULL : (var = (g_variant_iter_free (var), NULL)))
#define _puzzle_saved_tile_free0(var) ((var == NULL) ? NULL : (var = (puzzle_saved_tile_free (var), NULL)))
typedef struct _PuzzleInversionPrivate PuzzleInversionPrivate;
enum  {
	PUZZLE_INVERSION_0_PROPERTY,
	PUZZLE_INVERSION_X0_PROPERTY,
	PUZZLE_INVERSION_Y0_PROPERTY,
	PUZZLE_INVERSION_X1_PROPERTY,
	PUZZLE_INVERSION_Y1_PROPERTY,
	PUZZLE_INVERSION_ID_PROPERTY,
	PUZZLE_INVERSION_NUM_PROPERTIES
};
static GParamSpec* puzzle_inversion_properties[PUZZLE_INVERSION_NUM_PROPERTIES];
enum  {
	PUZZLE_TILE_MOVED_SIGNAL,
	PUZZLE_SOLVED_SIGNAL,
	PUZZLE_SOLVED_RIGHT_SIGNAL,
	PUZZLE_SHOW_END_GAME_SIGNAL,
	PUZZLE_TICK_SIGNAL,
	PUZZLE_NUM_SIGNALS
};
static guint puzzle_signals[PUZZLE_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 _Tile {
	GObject parent_instance;
	TilePrivate * priv;
	guint8 north;
	guint8 west;
	guint8 east;
	guint8 south;
};

struct _TileClass {
	GObjectClass parent_class;
};

struct _TilePrivate {
	guint8 _x;
	guint8 _y;
};

struct _Puzzle {
	GObject parent_instance;
	PuzzlePrivate * priv;
};

struct _PuzzleClass {
	GObjectClass parent_class;
};

struct _PuzzlePrivate {
	guint8 _size;
	guint8 _colors;
	Tile** board;
	gint board_length1;
	gint board_length2;
	GTimer* clock;
	guint clock_timeout;
	gdouble _initial_time;
	gboolean _tainted_by_command_line;
	gboolean _paused;
	gboolean _is_solved;
	gboolean _restored;
	guint timeout_id;
	gboolean _game_in_progress;
	gboolean _is_solved_right;
	guint last_move_id;
	gboolean _can_undo;
	gboolean _can_redo;
	guint history_length;
	guint last_move_index;
	GList* reversed_history;
};

struct _PuzzleSavedTile {
	guint8 current_x;
	guint8 current_y;
	guint8 color_north;
	guint8 color_east;
	guint8 color_south;
	guint8 color_west;
	guint8 initial_x;
	guint8 initial_y;
};

struct _PuzzleInversion {
	GObject parent_instance;
	PuzzleInversionPrivate * priv;
};

struct _PuzzleInversionClass {
	GObjectClass parent_class;
};

struct _PuzzleInversionPrivate {
	guint8 _x0;
	guint8 _y0;
	guint8 _x1;
	guint8 _y1;
	guint _id;
};

static gint Tile_private_offset;
static gpointer tile_parent_class = NULL;
static gint Puzzle_private_offset;
static gpointer puzzle_parent_class = NULL;
static gint PuzzleInversion_private_offset;
static gpointer puzzle_inversion_parent_class = NULL;

VALA_EXTERN GType tile_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (Tile, g_object_unref)
VALA_EXTERN Tile* tile_new (guint8 x,
                guint8 y);
VALA_EXTERN Tile* tile_construct (GType object_type,
                      guint8 x,
                      guint8 y);
VALA_EXTERN guint8 tile_get_x (Tile* self);
static void tile_set_x (Tile* self,
                 guint8 value);
VALA_EXTERN guint8 tile_get_y (Tile* self);
static void tile_set_y (Tile* self,
                 guint8 value);
static void tile_finalize (GObject * obj);
static GType tile_get_type_once (void);
static void _vala_tile_get_property (GObject * object,
                              guint property_id,
                              GValue * value,
                              GParamSpec * pspec);
static void _vala_tile_set_property (GObject * object,
                              guint property_id,
                              const GValue * value,
                              GParamSpec * pspec);
VALA_EXTERN GType puzzle_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (Puzzle, g_object_unref)
static GType puzzle_inversion_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (PuzzleInversion, g_object_unref)
static void _g_object_unref0_ (gpointer var);
static inline void _g_list_free__g_object_unref0_ (GList* self);
static gboolean puzzle_check_if_solved (Puzzle* self);
VALA_EXTERN guint8 puzzle_get_size (Puzzle* self);
static void puzzle_set_is_solved (Puzzle* self,
                           gboolean value);
VALA_EXTERN Puzzle* puzzle_new (guint8 size,
                    guint8 colors);
VALA_EXTERN Puzzle* puzzle_construct (GType object_type,
                          guint8 size,
                          guint8 colors);
static inline void puzzle_init_board (guint8 size,
                        gint32 colors,
                        Tile*** board,
                        gint* board_length1,
                        gint* board_length2);
static gboolean puzzle_solved_on_right (Puzzle* self);
VALA_EXTERN Tile* puzzle_get_tile (Puzzle* self,
                       guint8 x,
                       guint8 y);
VALA_EXTERN void puzzle_get_tile_location (Puzzle* self,
                               Tile* tile,
                               guint8* x,
                               guint8* y);
static gboolean puzzle_tile_fits (Puzzle* self,
                           guint8 x0,
                           guint8 y0,
                           guint8 x1,
                           guint8 y1);
VALA_EXTERN gboolean puzzle_can_switch (Puzzle* self,
                            guint8 x0,
                            guint8 y0,
                            guint8 x1,
                            guint8 y1);
VALA_EXTERN void puzzle_switch_tiles (Puzzle* self,
                          guint8 x0,
                          guint8 y0,
                          guint8 x1,
                          guint8 y1,
                          guint delay_if_finished);
static void _puzzle_switch_tiles (Puzzle* self,
                           guint8 x0,
                           guint8 y0,
                           guint8 x1,
                           guint8 y1,
                           guint delay_if_finished,
                           gboolean undoing_or_redoing,
                           guint move_id);
static void puzzle_set_game_in_progress (Puzzle* self,
                                  gboolean value);
static inline void puzzle_add_to_history (Puzzle* self,
                            guint8 x0,
                            guint8 y0,
                            guint8 x1,
                            guint8 y1,
                            guint id);
static void puzzle_stop_clock (Puzzle* self);
static gboolean _____lambda4_ (Puzzle* self);
static gboolean ______lambda4__gsource_func (gpointer self);
static void puzzle_set_is_solved_right (Puzzle* self,
                                 gboolean value);
VALA_EXTERN gboolean puzzle_get_is_solved_right (Puzzle* self);
static inline void puzzle_switch_one_of_many_tiles (Puzzle* self,
                                      guint8 x0,
                                      guint8 y0,
                                      guint8 x1,
                                      guint8 y1);
VALA_EXTERN gboolean puzzle_move_up (Puzzle* self,
                         gboolean left_board);
static gboolean puzzle_can_move_up (Puzzle* self,
                             gboolean left_board);
VALA_EXTERN gboolean puzzle_move_down (Puzzle* self,
                           gboolean left_board);
static gboolean puzzle_can_move_down (Puzzle* self,
                               gboolean left_board);
VALA_EXTERN gboolean puzzle_move_left (Puzzle* self,
                           gboolean left_board);
static gboolean puzzle_can_move_left (Puzzle* self,
                               gboolean left_board);
VALA_EXTERN gboolean puzzle_move_right (Puzzle* self,
                            gboolean left_board);
static gboolean puzzle_can_move_right (Puzzle* self,
                                gboolean left_board);
VALA_EXTERN void puzzle_try_move (Puzzle* self,
                      guint8 x,
                      guint8 y);
VALA_EXTERN GType direction_get_type (void) G_GNUC_CONST ;
static inline Direction puzzle_can_move (Puzzle* self,
                           guint8 x,
                           guint8 y);
static inline gboolean puzzle_half_board_is_empty (Puzzle* self,
                                     gboolean left_board);
VALA_EXTERN void puzzle_solve (Puzzle* self);
VALA_EXTERN void puzzle_finish (Puzzle* self,
                    guint duration);
VALA_EXTERN gboolean puzzle_move_last_tile_if_possible (Puzzle* self);
VALA_EXTERN gboolean puzzle_only_one_remaining_tile (Puzzle* self,
                                         guint8* empty_x,
                                         guint8* empty_y);
static void puzzle_start_clock (Puzzle* self);
VALA_EXTERN gboolean puzzle_get_tainted_by_command_line (Puzzle* self);
static gboolean puzzle_timeout_cb (Puzzle* self);
static void puzzle_continue_clock (Puzzle* self);
static gboolean _puzzle_timeout_cb_gsource_func (gpointer self);
static PuzzleInversion* puzzle_inversion_new (guint8 x0,
                                       guint8 y0,
                                       guint8 x1,
                                       guint8 y1,
                                       guint id);
static PuzzleInversion* puzzle_inversion_construct (GType object_type,
                                             guint8 x0,
                                             guint8 y0,
                                             guint8 x1,
                                             guint8 y1,
                                             guint id);
static void puzzle_set_can_undo (Puzzle* self,
                          gboolean value);
static void puzzle_set_can_redo (Puzzle* self,
                          gboolean value);
VALA_EXTERN void puzzle_undo (Puzzle* self);
VALA_EXTERN gboolean puzzle_get_can_undo (Puzzle* self);
static guint puzzle_inversion_get_id (PuzzleInversion* self);
static inline void puzzle_undo_move (Puzzle* self,
                       guint8 x0,
                       guint8 y0,
                       guint8 x1,
                       guint8 y1);
static guint8 puzzle_inversion_get_x0 (PuzzleInversion* self);
static guint8 puzzle_inversion_get_y0 (PuzzleInversion* self);
static guint8 puzzle_inversion_get_x1 (PuzzleInversion* self);
static guint8 puzzle_inversion_get_y1 (PuzzleInversion* self);
VALA_EXTERN void puzzle_redo (Puzzle* self);
VALA_EXTERN gboolean puzzle_get_can_redo (Puzzle* self);
static inline void puzzle_redo_move (Puzzle* self,
                       guint8 x0,
                       guint8 y0,
                       guint8 x1,
                       guint8 y1);
VALA_EXTERN void puzzle_reload (Puzzle* self);
VALA_EXTERN GVariant* puzzle_to_variant (Puzzle* self,
                             gboolean save_time);
VALA_EXTERN guint8 puzzle_get_colors (Puzzle* self);
VALA_EXTERN gdouble puzzle_get_elapsed (Puzzle* self);
VALA_EXTERN gboolean puzzle_is_valid_saved_game (GVariant* maybe_variant,
                                     gboolean restore_finished_game);
static GType puzzle_saved_tile_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static PuzzleSavedTile* puzzle_saved_tile_dup (const PuzzleSavedTile* self);
static void puzzle_saved_tile_free (PuzzleSavedTile* self);
VALA_EXTERN Puzzle* puzzle_new_restore (GVariant* maybe_variant);
VALA_EXTERN Puzzle* puzzle_construct_restore (GType object_type,
                                  GVariant* maybe_variant);
static void puzzle_set_size (Puzzle* self,
                      guint8 value);
static void puzzle_set_colors (Puzzle* self,
                        guint8 value);
static gdouble puzzle_get_initial_time (Puzzle* self);
static void puzzle_set_initial_time (Puzzle* self,
                              gdouble value);
static void puzzle_set_tainted_by_command_line (Puzzle* self,
                                         gboolean value);
VALA_EXTERN gboolean puzzle_get_paused (Puzzle* self);
VALA_EXTERN void puzzle_set_paused (Puzzle* self,
                        gboolean value);
VALA_EXTERN gboolean puzzle_get_is_solved (Puzzle* self);
static gboolean puzzle_get_restored (Puzzle* self);
static void puzzle_set_restored (Puzzle* self,
                          gboolean value);
VALA_EXTERN gboolean puzzle_get_game_in_progress (Puzzle* self);
static void g_cclosure_user_marshal_VOID__OBJECT_UCHAR_UCHAR (GClosure * closure,
                                                       GValue * return_value,
                                                       guint n_param_values,
                                                       const GValue * param_values,
                                                       gpointer invocation_hint,
                                                       gpointer marshal_data);
static void puzzle_inversion_set_x0 (PuzzleInversion* self,
                              guint8 value);
static void puzzle_inversion_set_y0 (PuzzleInversion* self,
                              guint8 value);
static void puzzle_inversion_set_x1 (PuzzleInversion* self,
                              guint8 value);
static void puzzle_inversion_set_y1 (PuzzleInversion* self,
                              guint8 value);
static void puzzle_inversion_set_id (PuzzleInversion* self,
                              guint value);
static void puzzle_inversion_finalize (GObject * obj);
static GType puzzle_inversion_get_type_once (void);
static void _vala_puzzle_inversion_get_property (GObject * object,
                                          guint property_id,
                                          GValue * value,
                                          GParamSpec * pspec);
static void _vala_puzzle_inversion_set_property (GObject * object,
                                          guint property_id,
                                          const GValue * value,
                                          GParamSpec * pspec);
static GObject * puzzle_constructor (GType type,
                              guint n_construct_properties,
                              GObjectConstructParam * construct_properties);
static void puzzle_finalize (GObject * obj);
static GType puzzle_get_type_once (void);
static void _vala_puzzle_get_property (GObject * object,
                                guint property_id,
                                GValue * value,
                                GParamSpec * pspec);
static void _vala_puzzle_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);

static inline gpointer
tile_get_instance_private (Tile* self)
{
	return G_STRUCT_MEMBER_P (self, Tile_private_offset);
}

Tile*
tile_construct (GType object_type,
                guint8 x,
                guint8 y)
{
	Tile * self = NULL;
	self = (Tile*) g_object_new (object_type, "x", x, "y", y, NULL);
	return self;
}

Tile*
tile_new (guint8 x,
          guint8 y)
{
	return tile_construct (TYPE_TILE, x, y);
}

guint8
tile_get_x (Tile* self)
{
	guint8 result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_x;
	return result;
}

static void
tile_set_x (Tile* self,
            guint8 value)
{
	g_return_if_fail (self != NULL);
	self->priv->_x = value;
}

guint8
tile_get_y (Tile* self)
{
	guint8 result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_y;
	return result;
}

static void
tile_set_y (Tile* self,
            guint8 value)
{
	g_return_if_fail (self != NULL);
	self->priv->_y = value;
}

static void
tile_class_init (TileClass * klass,
                 gpointer klass_data)
{
	tile_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &Tile_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_tile_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_tile_set_property;
	G_OBJECT_CLASS (klass)->finalize = tile_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), TILE_X_PROPERTY, tile_properties[TILE_X_PROPERTY] = g_param_spec_uchar ("x", "x", "x", 0, G_MAXUINT8, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), TILE_Y_PROPERTY, tile_properties[TILE_Y_PROPERTY] = g_param_spec_uchar ("y", "y", "y", 0, G_MAXUINT8, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY));
}

static void
tile_instance_init (Tile * self,
                    gpointer klass)
{
	self->priv = tile_get_instance_private (self);
}

static void
tile_finalize (GObject * obj)
{
	Tile * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_TILE, Tile);
	G_OBJECT_CLASS (tile_parent_class)->finalize (obj);
}

static GType
tile_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (TileClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) tile_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Tile), 0, (GInstanceInitFunc) tile_instance_init, NULL };
	GType tile_type_id;
	tile_type_id = g_type_register_static (G_TYPE_OBJECT, "Tile", &g_define_type_info, 0);
	Tile_private_offset = g_type_add_instance_private (tile_type_id, sizeof (TilePrivate));
	return tile_type_id;
}

GType
tile_get_type (void)
{
	static volatile gsize tile_type_id__once = 0;
	if (g_once_init_enter (&tile_type_id__once)) {
		GType tile_type_id;
		tile_type_id = tile_get_type_once ();
		g_once_init_leave (&tile_type_id__once, tile_type_id);
	}
	return tile_type_id__once;
}

static void
_vala_tile_get_property (GObject * object,
                         guint property_id,
                         GValue * value,
                         GParamSpec * pspec)
{
	Tile * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_TILE, Tile);
	switch (property_id) {
		case TILE_X_PROPERTY:
		g_value_set_uchar (value, tile_get_x (self));
		break;
		case TILE_Y_PROPERTY:
		g_value_set_uchar (value, tile_get_y (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_tile_set_property (GObject * object,
                         guint property_id,
                         const GValue * value,
                         GParamSpec * pspec)
{
	Tile * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_TILE, Tile);
	switch (property_id) {
		case TILE_X_PROPERTY:
		tile_set_x (self, g_value_get_uchar (value));
		break;
		case TILE_Y_PROPERTY:
		tile_set_y (self, g_value_get_uchar (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static inline gpointer
puzzle_get_instance_private (Puzzle* self)
{
	return G_STRUCT_MEMBER_P (self, Puzzle_private_offset);
}

static void
_g_object_unref0_ (gpointer var)
{
	(var == NULL) ? NULL : (var = (g_object_unref (var), NULL));
}

static inline void
_g_list_free__g_object_unref0_ (GList* self)
{
	g_list_free_full (self, (GDestroyNotify) _g_object_unref0_);
}

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

static gboolean
puzzle_check_if_solved (Puzzle* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				guint8 _tmp2_;
				if (!_tmp0_) {
					guint8 _tmp1_;
					_tmp1_ = x;
					x = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				_tmp2_ = self->priv->_size;
				if (!(x < _tmp2_)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp3_ = FALSE;
						_tmp3_ = TRUE;
						while (TRUE) {
							guint8 _tmp5_;
							Tile* tile = NULL;
							Tile** _tmp6_;
							gint _tmp6__length1;
							gint _tmp6__length2;
							Tile* _tmp7_;
							Tile* _tmp8_;
							Tile* _tmp9_;
							if (!_tmp3_) {
								guint8 _tmp4_;
								_tmp4_ = y;
								y = _tmp4_ + 1;
							}
							_tmp3_ = FALSE;
							_tmp5_ = self->priv->_size;
							if (!(y < _tmp5_)) {
								break;
							}
							_tmp6_ = self->priv->board;
							_tmp6__length1 = self->priv->board_length1;
							_tmp6__length2 = self->priv->board_length2;
							_tmp7_ = _tmp6_[(x * _tmp6__length2) + y];
							_tmp8_ = _g_object_ref0 (_tmp7_);
							tile = _tmp8_;
							_tmp9_ = tile;
							if (_tmp9_ == NULL) {
								result = FALSE;
								_g_object_unref0 (tile);
								return result;
							}
							_g_object_unref0 (tile);
						}
					}
				}
			}
		}
	}
	puzzle_set_is_solved (self, TRUE);
	result = TRUE;
	return result;
}

Puzzle*
puzzle_construct (GType object_type,
                  guint8 size,
                  guint8 colors)
{
	Puzzle * self = NULL;
	self = (Puzzle*) g_object_new (object_type, "size", size, "colors", colors, "tainted-by-command-line", FALSE, NULL);
	return self;
}

Puzzle*
puzzle_new (guint8 size,
            guint8 colors)
{
	return puzzle_construct (TYPE_PUZZLE, size, colors);
}

static GList*
vala_g_list_remove_full (GList* self,
                         gconstpointer data,
                         GFreeFunc func)
{
	GList* l = NULL;
	GList* result;
	l = self;
	while (TRUE) {
		GList* _tmp0_;
		GList* _tmp1_;
		gconstpointer _tmp2_;
		_tmp0_ = l;
		if (!(_tmp0_ != NULL)) {
			break;
		}
		_tmp1_ = l;
		_tmp2_ = ((GList*) _tmp1_)->data;
		if (_tmp2_ != data) {
			GList* _tmp3_;
			GList* _tmp4_;
			_tmp3_ = l;
			_tmp4_ = ((GList*) _tmp3_)->next;
			l = _tmp4_;
		} else {
			GList* _tmp5_;
			gconstpointer _tmp6_;
			GList* _tmp7_;
			_tmp5_ = l;
			_tmp6_ = ((GList*) _tmp5_)->data;
			func (_tmp6_);
			_tmp7_ = l;
			self = g_list_delete_link (self, (GList*) _tmp7_);
			break;
		}
	}
	result = self;
	return result;
}

static inline void
puzzle_init_board (guint8 size,
                   gint32 colors,
                   Tile*** board,
                   gint* board_length1,
                   gint* board_length2)
{
	Tile** _vala_board = NULL;
	gint _vala_board_length1 = 0;
	gint _vala_board_length2 = 0;
	Tile** _tmp0_;
	GList* tiles = NULL;
	gint32 length = 0;
	GList* _tmp31_;
	_tmp0_ = g_new0 (Tile*, ((size * 2) * size) + 1);
	_vala_board = (_vala_array_free (_vala_board, _vala_board_length1 * _vala_board_length2, (GDestroyNotify) g_object_unref), NULL);
	_vala_board = _tmp0_;
	_vala_board_length1 = size * 2;
	_vala_board_length2 = size;
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				if (!_tmp1_) {
					guint8 _tmp2_;
					_tmp2_ = x;
					x = _tmp2_ + 1;
				}
				_tmp1_ = FALSE;
				if (!(x < size)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp3_ = FALSE;
						_tmp3_ = TRUE;
						while (TRUE) {
							Tile** _tmp5_;
							gint _tmp5__length1;
							gint _tmp5__length2;
							Tile* _tmp6_;
							if (!_tmp3_) {
								guint8 _tmp4_;
								_tmp4_ = y;
								y = _tmp4_ + 1;
							}
							_tmp3_ = FALSE;
							if (!(y < size)) {
								break;
							}
							_tmp5_ = _vala_board;
							_tmp5__length1 = _vala_board_length1;
							_tmp5__length2 = _vala_board_length2;
							_tmp6_ = tile_new (x, y);
							_g_object_unref0 (_tmp5_[(x * _tmp5__length2) + y]);
							_tmp5_[(x * _tmp5__length2) + y] = _tmp6_;
						}
					}
				}
			}
		}
	}
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp7_ = FALSE;
			_tmp7_ = TRUE;
			while (TRUE) {
				if (!_tmp7_) {
					guint8 _tmp8_;
					_tmp8_ = x;
					x = _tmp8_ + 1;
				}
				_tmp7_ = FALSE;
				if (!(x < size)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp9_ = FALSE;
						_tmp9_ = TRUE;
						while (TRUE) {
							guint8 n = 0U;
							if (!_tmp9_) {
								guint8 _tmp10_;
								_tmp10_ = y;
								y = _tmp10_ + 1;
							}
							_tmp9_ = FALSE;
							if (!(y <= size)) {
								break;
							}
							n = (guint8) g_random_int_range ((gint32) 0, colors);
							if (((gint) y) >= 1) {
								Tile** _tmp11_;
								gint _tmp11__length1;
								gint _tmp11__length2;
								Tile* _tmp12_;
								_tmp11_ = _vala_board;
								_tmp11__length1 = _vala_board_length1;
								_tmp11__length2 = _vala_board_length2;
								_tmp12_ = _tmp11_[(x * _tmp11__length2) + (y - 1)];
								G_TYPE_CHECK_INSTANCE_CAST (_tmp12_, TYPE_TILE, Tile)->south = n;
							}
							if (y < size) {
								Tile** _tmp13_;
								gint _tmp13__length1;
								gint _tmp13__length2;
								Tile* _tmp14_;
								_tmp13_ = _vala_board;
								_tmp13__length1 = _vala_board_length1;
								_tmp13__length2 = _vala_board_length2;
								_tmp14_ = _tmp13_[(x * _tmp13__length2) + y];
								G_TYPE_CHECK_INSTANCE_CAST (_tmp14_, TYPE_TILE, Tile)->north = n;
							}
						}
					}
				}
			}
		}
	}
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp15_ = FALSE;
			_tmp15_ = TRUE;
			while (TRUE) {
				if (!_tmp15_) {
					guint8 _tmp16_;
					_tmp16_ = x;
					x = _tmp16_ + 1;
				}
				_tmp15_ = FALSE;
				if (!(x <= size)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp17_ = FALSE;
						_tmp17_ = TRUE;
						while (TRUE) {
							guint8 n = 0U;
							if (!_tmp17_) {
								guint8 _tmp18_;
								_tmp18_ = y;
								y = _tmp18_ + 1;
							}
							_tmp17_ = FALSE;
							if (!(y < size)) {
								break;
							}
							n = (guint8) g_random_int_range ((gint32) 0, colors);
							if (((gint) x) >= 1) {
								Tile** _tmp19_;
								gint _tmp19__length1;
								gint _tmp19__length2;
								Tile* _tmp20_;
								_tmp19_ = _vala_board;
								_tmp19__length1 = _vala_board_length1;
								_tmp19__length2 = _vala_board_length2;
								_tmp20_ = _tmp19_[((x - 1) * _tmp19__length2) + y];
								G_TYPE_CHECK_INSTANCE_CAST (_tmp20_, TYPE_TILE, Tile)->east = n;
							}
							if (x < size) {
								Tile** _tmp21_;
								gint _tmp21__length1;
								gint _tmp21__length2;
								Tile* _tmp22_;
								_tmp21_ = _vala_board;
								_tmp21__length1 = _vala_board_length1;
								_tmp21__length2 = _vala_board_length2;
								_tmp22_ = _tmp21_[(x * _tmp21__length2) + y];
								G_TYPE_CHECK_INSTANCE_CAST (_tmp22_, TYPE_TILE, Tile)->west = n;
							}
						}
					}
				}
			}
		}
	}
	tiles = NULL;
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp23_ = FALSE;
			_tmp23_ = TRUE;
			while (TRUE) {
				if (!_tmp23_) {
					guint8 _tmp24_;
					_tmp24_ = x;
					x = _tmp24_ + 1;
				}
				_tmp23_ = FALSE;
				if (!(x < size)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp25_ = FALSE;
						_tmp25_ = TRUE;
						while (TRUE) {
							Tile** _tmp27_;
							gint _tmp27__length1;
							gint _tmp27__length2;
							Tile* _tmp28_;
							Tile* _tmp29_;
							Tile** _tmp30_;
							gint _tmp30__length1;
							gint _tmp30__length2;
							if (!_tmp25_) {
								guint8 _tmp26_;
								_tmp26_ = y;
								y = _tmp26_ + 1;
							}
							_tmp25_ = FALSE;
							if (!(y < size)) {
								break;
							}
							_tmp27_ = _vala_board;
							_tmp27__length1 = _vala_board_length1;
							_tmp27__length2 = _vala_board_length2;
							_tmp28_ = _tmp27_[(x * _tmp27__length2) + y];
							_tmp29_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp28_, TYPE_TILE, Tile));
							tiles = g_list_append (tiles, _tmp29_);
							_tmp30_ = _vala_board;
							_tmp30__length1 = _vala_board_length1;
							_tmp30__length2 = _vala_board_length2;
							_g_object_unref0 (_tmp30_[(x * _tmp30__length2) + y]);
							_tmp30_[(x * _tmp30__length2) + y] = NULL;
						}
					}
				}
			}
		}
	}
	_tmp31_ = tiles;
	length = (gint32) g_list_length (_tmp31_);
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp32_ = FALSE;
			_tmp32_ = TRUE;
			while (TRUE) {
				if (!_tmp32_) {
					guint8 _tmp33_;
					_tmp33_ = x;
					x = _tmp33_ + 1;
				}
				_tmp32_ = FALSE;
				if (!(x < size)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp34_ = FALSE;
						_tmp34_ = TRUE;
						while (TRUE) {
							gint32 n = 0;
							Tile* tile = NULL;
							GList* _tmp36_;
							gconstpointer _tmp37_;
							Tile* _tmp38_;
							Tile** _tmp39_;
							gint _tmp39__length1;
							gint _tmp39__length2;
							Tile* _tmp40_;
							Tile* _tmp41_;
							Tile* _tmp42_;
							gint32 _tmp43_;
							if (!_tmp34_) {
								guint8 _tmp35_;
								_tmp35_ = y;
								y = _tmp35_ + 1;
							}
							_tmp34_ = FALSE;
							if (!(y < size)) {
								break;
							}
							n = g_random_int_range ((gint32) 0, length);
							_tmp36_ = tiles;
							_tmp37_ = g_list_nth_data (_tmp36_, (guint) n);
							_tmp38_ = _g_object_ref0 ((Tile*) _tmp37_);
							tile = _tmp38_;
							_tmp39_ = _vala_board;
							_tmp39__length1 = _vala_board_length1;
							_tmp39__length2 = _vala_board_length2;
							_tmp40_ = tile;
							_tmp41_ = _g_object_ref0 (_tmp40_);
							_g_object_unref0 (_tmp39_[((x + size) * _tmp39__length2) + y]);
							_tmp39_[((x + size) * _tmp39__length2) + y] = _tmp41_;
							_tmp42_ = tile;
							tiles = vala_g_list_remove_full (tiles, _tmp42_, _g_object_unref0_);
							_tmp43_ = length;
							length = _tmp43_ - 1;
							_g_object_unref0 (tile);
						}
					}
				}
			}
		}
	}
	(tiles == NULL) ? NULL : (tiles = (_g_list_free__g_object_unref0_ (tiles), NULL));
	if (board) {
		*board = _vala_board;
	} else {
		_vala_board = (_vala_array_free (_vala_board, _vala_board_length1 * _vala_board_length2, (GDestroyNotify) g_object_unref), NULL);
	}
	if (board_length1) {
		*board_length1 = _vala_board_length1;
	}
	if (board_length2) {
		*board_length2 = _vala_board_length2;
	}
}

static gboolean
puzzle_solved_on_right (Puzzle* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	{
		guint8 x = 0U;
		guint8 _tmp0_;
		_tmp0_ = self->priv->_size;
		x = _tmp0_;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				guint8 _tmp3_;
				if (!_tmp1_) {
					guint8 _tmp2_;
					_tmp2_ = x;
					x = _tmp2_ + 1;
				}
				_tmp1_ = FALSE;
				_tmp3_ = self->priv->_size;
				if (!(((gint) x) < (2 * _tmp3_))) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp4_ = FALSE;
						_tmp4_ = TRUE;
						while (TRUE) {
							guint8 _tmp6_;
							Tile* tile = NULL;
							Tile** _tmp7_;
							gint _tmp7__length1;
							gint _tmp7__length2;
							Tile* _tmp8_;
							Tile* _tmp9_;
							Tile* _tmp10_;
							gboolean _tmp11_ = FALSE;
							gboolean _tmp12_ = FALSE;
							gboolean _tmp18_ = FALSE;
							gboolean _tmp19_ = FALSE;
							guint8 _tmp20_;
							gboolean _tmp26_ = FALSE;
							gboolean _tmp27_ = FALSE;
							gboolean _tmp33_ = FALSE;
							gboolean _tmp34_ = FALSE;
							guint8 _tmp35_;
							if (!_tmp4_) {
								guint8 _tmp5_;
								_tmp5_ = y;
								y = _tmp5_ + 1;
							}
							_tmp4_ = FALSE;
							_tmp6_ = self->priv->_size;
							if (!(y < _tmp6_)) {
								break;
							}
							_tmp7_ = self->priv->board;
							_tmp7__length1 = self->priv->board_length1;
							_tmp7__length2 = self->priv->board_length2;
							_tmp8_ = _tmp7_[(x * _tmp7__length2) + y];
							_tmp9_ = _g_object_ref0 (_tmp8_);
							tile = _tmp9_;
							_tmp10_ = tile;
							if (_tmp10_ == NULL) {
								result = FALSE;
								_g_object_unref0 (tile);
								return result;
							}
							if (((gint) x) > 0) {
								Tile** _tmp13_;
								gint _tmp13__length1;
								gint _tmp13__length2;
								Tile* _tmp14_;
								_tmp13_ = self->priv->board;
								_tmp13__length1 = self->priv->board_length1;
								_tmp13__length2 = self->priv->board_length2;
								_tmp14_ = _tmp13_[((x - 1) * _tmp13__length2) + y];
								_tmp12_ = _tmp14_ != NULL;
							} else {
								_tmp12_ = FALSE;
							}
							if (_tmp12_) {
								Tile** _tmp15_;
								gint _tmp15__length1;
								gint _tmp15__length2;
								Tile* _tmp16_;
								Tile* _tmp17_;
								_tmp15_ = self->priv->board;
								_tmp15__length1 = self->priv->board_length1;
								_tmp15__length2 = self->priv->board_length2;
								_tmp16_ = _tmp15_[((x - 1) * _tmp15__length2) + y];
								_tmp17_ = tile;
								_tmp11_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp16_, TYPE_TILE, Tile)->east != G_TYPE_CHECK_INSTANCE_CAST (_tmp17_, TYPE_TILE, Tile)->west;
							} else {
								_tmp11_ = FALSE;
							}
							if (_tmp11_) {
								result = FALSE;
								_g_object_unref0 (tile);
								return result;
							}
							_tmp20_ = self->priv->_size;
							if (((gint) x) < (_tmp20_ - 1)) {
								Tile** _tmp21_;
								gint _tmp21__length1;
								gint _tmp21__length2;
								Tile* _tmp22_;
								_tmp21_ = self->priv->board;
								_tmp21__length1 = self->priv->board_length1;
								_tmp21__length2 = self->priv->board_length2;
								_tmp22_ = _tmp21_[((x + 1) * _tmp21__length2) + y];
								_tmp19_ = _tmp22_ != NULL;
							} else {
								_tmp19_ = FALSE;
							}
							if (_tmp19_) {
								Tile** _tmp23_;
								gint _tmp23__length1;
								gint _tmp23__length2;
								Tile* _tmp24_;
								Tile* _tmp25_;
								_tmp23_ = self->priv->board;
								_tmp23__length1 = self->priv->board_length1;
								_tmp23__length2 = self->priv->board_length2;
								_tmp24_ = _tmp23_[((x + 1) * _tmp23__length2) + y];
								_tmp25_ = tile;
								_tmp18_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp24_, TYPE_TILE, Tile)->west != G_TYPE_CHECK_INSTANCE_CAST (_tmp25_, TYPE_TILE, Tile)->east;
							} else {
								_tmp18_ = FALSE;
							}
							if (_tmp18_) {
								result = FALSE;
								_g_object_unref0 (tile);
								return result;
							}
							if (((gint) y) > 0) {
								Tile** _tmp28_;
								gint _tmp28__length1;
								gint _tmp28__length2;
								Tile* _tmp29_;
								_tmp28_ = self->priv->board;
								_tmp28__length1 = self->priv->board_length1;
								_tmp28__length2 = self->priv->board_length2;
								_tmp29_ = _tmp28_[(x * _tmp28__length2) + (y - 1)];
								_tmp27_ = _tmp29_ != NULL;
							} else {
								_tmp27_ = FALSE;
							}
							if (_tmp27_) {
								Tile** _tmp30_;
								gint _tmp30__length1;
								gint _tmp30__length2;
								Tile* _tmp31_;
								Tile* _tmp32_;
								_tmp30_ = self->priv->board;
								_tmp30__length1 = self->priv->board_length1;
								_tmp30__length2 = self->priv->board_length2;
								_tmp31_ = _tmp30_[(x * _tmp30__length2) + (y - 1)];
								_tmp32_ = tile;
								_tmp26_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp31_, TYPE_TILE, Tile)->south != G_TYPE_CHECK_INSTANCE_CAST (_tmp32_, TYPE_TILE, Tile)->north;
							} else {
								_tmp26_ = FALSE;
							}
							if (_tmp26_) {
								result = FALSE;
								_g_object_unref0 (tile);
								return result;
							}
							_tmp35_ = self->priv->_size;
							if (((gint) y) < (_tmp35_ - 1)) {
								Tile** _tmp36_;
								gint _tmp36__length1;
								gint _tmp36__length2;
								Tile* _tmp37_;
								_tmp36_ = self->priv->board;
								_tmp36__length1 = self->priv->board_length1;
								_tmp36__length2 = self->priv->board_length2;
								_tmp37_ = _tmp36_[(x * _tmp36__length2) + (y + 1)];
								_tmp34_ = _tmp37_ != NULL;
							} else {
								_tmp34_ = FALSE;
							}
							if (_tmp34_) {
								Tile** _tmp38_;
								gint _tmp38__length1;
								gint _tmp38__length2;
								Tile* _tmp39_;
								Tile* _tmp40_;
								_tmp38_ = self->priv->board;
								_tmp38__length1 = self->priv->board_length1;
								_tmp38__length2 = self->priv->board_length2;
								_tmp39_ = _tmp38_[(x * _tmp38__length2) + (y + 1)];
								_tmp40_ = tile;
								_tmp33_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp39_, TYPE_TILE, Tile)->north != G_TYPE_CHECK_INSTANCE_CAST (_tmp40_, TYPE_TILE, Tile)->south;
							} else {
								_tmp33_ = FALSE;
							}
							if (_tmp33_) {
								result = FALSE;
								_g_object_unref0 (tile);
								return result;
							}
							_g_object_unref0 (tile);
						}
					}
				}
			}
		}
	}
	result = TRUE;
	return result;
}

Tile*
puzzle_get_tile (Puzzle* self,
                 guint8 x,
                 guint8 y)
{
	Tile** _tmp0_;
	gint _tmp0__length1;
	gint _tmp0__length2;
	Tile* _tmp1_;
	Tile* _tmp2_;
	Tile* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->board;
	_tmp0__length1 = self->priv->board_length1;
	_tmp0__length2 = self->priv->board_length2;
	_tmp1_ = _tmp0_[(x * _tmp0__length2) + y];
	_tmp2_ = _g_object_ref0 (_tmp1_);
	result = _tmp2_;
	return result;
}

void
puzzle_get_tile_location (Puzzle* self,
                          Tile* tile,
                          guint8* x,
                          guint8* y)
{
	guint8 _vala_x = 0U;
	guint8 _vala_y = 0U;
	g_return_if_fail (self != NULL);
	g_return_if_fail (tile != NULL);
	_vala_y = (guint8) 0;
	{
		gboolean _tmp0_ = FALSE;
		_vala_x = (guint8) 0;
		_tmp0_ = TRUE;
		while (TRUE) {
			guint8 _tmp2_;
			if (!_tmp0_) {
				guint8 _tmp1_;
				_tmp1_ = _vala_x;
				_vala_x = _tmp1_ + 1;
			}
			_tmp0_ = FALSE;
			_tmp2_ = self->priv->_size;
			if (!(((gint) _vala_x) < (_tmp2_ * 2))) {
				break;
			}
			{
				gboolean _tmp3_ = FALSE;
				_vala_y = (guint8) 0;
				_tmp3_ = TRUE;
				while (TRUE) {
					guint8 _tmp5_;
					Tile** _tmp6_;
					gint _tmp6__length1;
					gint _tmp6__length2;
					Tile* _tmp7_;
					if (!_tmp3_) {
						guint8 _tmp4_;
						_tmp4_ = _vala_y;
						_vala_y = _tmp4_ + 1;
					}
					_tmp3_ = FALSE;
					_tmp5_ = self->priv->_size;
					if (!(_vala_y < _tmp5_)) {
						break;
					}
					_tmp6_ = self->priv->board;
					_tmp6__length1 = self->priv->board_length1;
					_tmp6__length2 = self->priv->board_length2;
					_tmp7_ = _tmp6_[(_vala_x * _tmp6__length2) + _vala_y];
					if (_tmp7_ == tile) {
						if (x) {
							*x = _vala_x;
						}
						if (y) {
							*y = _vala_y;
						}
						return;
					}
				}
			}
		}
	}
	if (x) {
		*x = _vala_x;
	}
	if (y) {
		*y = _vala_y;
	}
}

static gboolean
puzzle_tile_fits (Puzzle* self,
                  guint8 x0,
                  guint8 y0,
                  guint8 x1,
                  guint8 y1)
{
	Tile* tile = NULL;
	Tile** _tmp0_;
	gint _tmp0__length1;
	gint _tmp0__length2;
	Tile* _tmp1_;
	Tile* _tmp2_;
	Tile* _tmp3_;
	gboolean _tmp4_ = FALSE;
	gboolean _tmp5_ = FALSE;
	gboolean _tmp6_ = FALSE;
	gboolean _tmp13_ = FALSE;
	gboolean _tmp14_ = FALSE;
	gboolean _tmp15_ = FALSE;
	guint8 _tmp16_;
	gboolean _tmp23_ = FALSE;
	gboolean _tmp24_ = FALSE;
	gboolean _tmp25_ = FALSE;
	gboolean _tmp32_ = FALSE;
	gboolean _tmp33_ = FALSE;
	gboolean _tmp34_ = FALSE;
	guint8 _tmp35_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->board;
	_tmp0__length1 = self->priv->board_length1;
	_tmp0__length2 = self->priv->board_length2;
	_tmp1_ = _tmp0_[(x0 * _tmp0__length2) + y0];
	_tmp2_ = _g_object_ref0 (_tmp1_);
	tile = _tmp2_;
	_tmp3_ = tile;
	if (_tmp3_ == NULL) {
		result = FALSE;
		_g_object_unref0 (tile);
		return result;
	}
	if (((gint) x1) > 0) {
		gboolean _tmp7_ = FALSE;
		if ((x1 - 1) == ((gint) x0)) {
			_tmp7_ = y1 == y0;
		} else {
			_tmp7_ = FALSE;
		}
		_tmp6_ = !_tmp7_;
	} else {
		_tmp6_ = FALSE;
	}
	if (_tmp6_) {
		Tile** _tmp8_;
		gint _tmp8__length1;
		gint _tmp8__length2;
		Tile* _tmp9_;
		_tmp8_ = self->priv->board;
		_tmp8__length1 = self->priv->board_length1;
		_tmp8__length2 = self->priv->board_length2;
		_tmp9_ = _tmp8_[((x1 - 1) * _tmp8__length2) + y1];
		_tmp5_ = _tmp9_ != NULL;
	} else {
		_tmp5_ = FALSE;
	}
	if (_tmp5_) {
		Tile** _tmp10_;
		gint _tmp10__length1;
		gint _tmp10__length2;
		Tile* _tmp11_;
		Tile* _tmp12_;
		_tmp10_ = self->priv->board;
		_tmp10__length1 = self->priv->board_length1;
		_tmp10__length2 = self->priv->board_length2;
		_tmp11_ = _tmp10_[((x1 - 1) * _tmp10__length2) + y1];
		_tmp12_ = tile;
		_tmp4_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp11_, TYPE_TILE, Tile)->east != G_TYPE_CHECK_INSTANCE_CAST (_tmp12_, TYPE_TILE, Tile)->west;
	} else {
		_tmp4_ = FALSE;
	}
	if (_tmp4_) {
		result = FALSE;
		_g_object_unref0 (tile);
		return result;
	}
	_tmp16_ = self->priv->_size;
	if (((gint) x1) < (_tmp16_ - 1)) {
		gboolean _tmp17_ = FALSE;
		if ((x1 + 1) == ((gint) x0)) {
			_tmp17_ = y1 == y0;
		} else {
			_tmp17_ = FALSE;
		}
		_tmp15_ = !_tmp17_;
	} else {
		_tmp15_ = FALSE;
	}
	if (_tmp15_) {
		Tile** _tmp18_;
		gint _tmp18__length1;
		gint _tmp18__length2;
		Tile* _tmp19_;
		_tmp18_ = self->priv->board;
		_tmp18__length1 = self->priv->board_length1;
		_tmp18__length2 = self->priv->board_length2;
		_tmp19_ = _tmp18_[((x1 + 1) * _tmp18__length2) + y1];
		_tmp14_ = _tmp19_ != NULL;
	} else {
		_tmp14_ = FALSE;
	}
	if (_tmp14_) {
		Tile** _tmp20_;
		gint _tmp20__length1;
		gint _tmp20__length2;
		Tile* _tmp21_;
		Tile* _tmp22_;
		_tmp20_ = self->priv->board;
		_tmp20__length1 = self->priv->board_length1;
		_tmp20__length2 = self->priv->board_length2;
		_tmp21_ = _tmp20_[((x1 + 1) * _tmp20__length2) + y1];
		_tmp22_ = tile;
		_tmp13_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp21_, TYPE_TILE, Tile)->west != G_TYPE_CHECK_INSTANCE_CAST (_tmp22_, TYPE_TILE, Tile)->east;
	} else {
		_tmp13_ = FALSE;
	}
	if (_tmp13_) {
		result = FALSE;
		_g_object_unref0 (tile);
		return result;
	}
	if (((gint) y1) > 0) {
		gboolean _tmp26_ = FALSE;
		if (x1 == x0) {
			_tmp26_ = (y1 - 1) == ((gint) y0);
		} else {
			_tmp26_ = FALSE;
		}
		_tmp25_ = !_tmp26_;
	} else {
		_tmp25_ = FALSE;
	}
	if (_tmp25_) {
		Tile** _tmp27_;
		gint _tmp27__length1;
		gint _tmp27__length2;
		Tile* _tmp28_;
		_tmp27_ = self->priv->board;
		_tmp27__length1 = self->priv->board_length1;
		_tmp27__length2 = self->priv->board_length2;
		_tmp28_ = _tmp27_[(x1 * _tmp27__length2) + (y1 - 1)];
		_tmp24_ = _tmp28_ != NULL;
	} else {
		_tmp24_ = FALSE;
	}
	if (_tmp24_) {
		Tile** _tmp29_;
		gint _tmp29__length1;
		gint _tmp29__length2;
		Tile* _tmp30_;
		Tile* _tmp31_;
		_tmp29_ = self->priv->board;
		_tmp29__length1 = self->priv->board_length1;
		_tmp29__length2 = self->priv->board_length2;
		_tmp30_ = _tmp29_[(x1 * _tmp29__length2) + (y1 - 1)];
		_tmp31_ = tile;
		_tmp23_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp30_, TYPE_TILE, Tile)->south != G_TYPE_CHECK_INSTANCE_CAST (_tmp31_, TYPE_TILE, Tile)->north;
	} else {
		_tmp23_ = FALSE;
	}
	if (_tmp23_) {
		result = FALSE;
		_g_object_unref0 (tile);
		return result;
	}
	_tmp35_ = self->priv->_size;
	if (((gint) y1) < (_tmp35_ - 1)) {
		gboolean _tmp36_ = FALSE;
		if (x1 == x0) {
			_tmp36_ = (y1 + 1) == ((gint) y0);
		} else {
			_tmp36_ = FALSE;
		}
		_tmp34_ = !_tmp36_;
	} else {
		_tmp34_ = FALSE;
	}
	if (_tmp34_) {
		Tile** _tmp37_;
		gint _tmp37__length1;
		gint _tmp37__length2;
		Tile* _tmp38_;
		_tmp37_ = self->priv->board;
		_tmp37__length1 = self->priv->board_length1;
		_tmp37__length2 = self->priv->board_length2;
		_tmp38_ = _tmp37_[(x1 * _tmp37__length2) + (y1 + 1)];
		_tmp33_ = _tmp38_ != NULL;
	} else {
		_tmp33_ = FALSE;
	}
	if (_tmp33_) {
		Tile** _tmp39_;
		gint _tmp39__length1;
		gint _tmp39__length2;
		Tile* _tmp40_;
		Tile* _tmp41_;
		_tmp39_ = self->priv->board;
		_tmp39__length1 = self->priv->board_length1;
		_tmp39__length2 = self->priv->board_length2;
		_tmp40_ = _tmp39_[(x1 * _tmp39__length2) + (y1 + 1)];
		_tmp41_ = tile;
		_tmp32_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp40_, TYPE_TILE, Tile)->north != G_TYPE_CHECK_INSTANCE_CAST (_tmp41_, TYPE_TILE, Tile)->south;
	} else {
		_tmp32_ = FALSE;
	}
	if (_tmp32_) {
		result = FALSE;
		_g_object_unref0 (tile);
		return result;
	}
	result = TRUE;
	_g_object_unref0 (tile);
	return result;
}

gboolean
puzzle_can_switch (Puzzle* self,
                   guint8 x0,
                   guint8 y0,
                   guint8 x1,
                   guint8 y1)
{
	gboolean _tmp0_ = FALSE;
	Tile* t0 = NULL;
	Tile** _tmp1_;
	gint _tmp1__length1;
	gint _tmp1__length2;
	Tile* _tmp2_;
	Tile* _tmp3_;
	Tile* t1 = NULL;
	Tile** _tmp4_;
	gint _tmp4__length1;
	gint _tmp4__length2;
	Tile* _tmp5_;
	Tile* _tmp6_;
	gboolean _tmp7_ = FALSE;
	Tile* _tmp8_;
	gboolean _tmp10_ = FALSE;
	gboolean _tmp11_ = FALSE;
	Tile* _tmp12_;
	gboolean _tmp14_ = FALSE;
	gboolean _tmp15_ = FALSE;
	Tile* _tmp16_;
	gboolean _tmp18_ = FALSE;
	gboolean _tmp19_ = FALSE;
	gboolean _tmp20_ = FALSE;
	Tile* _tmp21_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (x0 == x1) {
		_tmp0_ = y0 == y1;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		result = FALSE;
		return result;
	}
	_tmp1_ = self->priv->board;
	_tmp1__length1 = self->priv->board_length1;
	_tmp1__length2 = self->priv->board_length2;
	_tmp2_ = _tmp1_[(x0 * _tmp1__length2) + y0];
	_tmp3_ = _g_object_ref0 (_tmp2_);
	t0 = _tmp3_;
	_tmp4_ = self->priv->board;
	_tmp4__length1 = self->priv->board_length1;
	_tmp4__length2 = self->priv->board_length2;
	_tmp5_ = _tmp4_[(x1 * _tmp4__length2) + y1];
	_tmp6_ = _g_object_ref0 (_tmp5_);
	t1 = _tmp6_;
	_tmp8_ = t0;
	if (_tmp8_ == NULL) {
		Tile* _tmp9_;
		_tmp9_ = t1;
		_tmp7_ = _tmp9_ == NULL;
	} else {
		_tmp7_ = FALSE;
	}
	if (_tmp7_) {
		result = FALSE;
		_g_object_unref0 (t1);
		_g_object_unref0 (t0);
		return result;
	}
	_tmp12_ = t0;
	if (_tmp12_ != NULL) {
		guint8 _tmp13_;
		_tmp13_ = self->priv->_size;
		_tmp11_ = x1 < _tmp13_;
	} else {
		_tmp11_ = FALSE;
	}
	if (_tmp11_) {
		_tmp10_ = !puzzle_tile_fits (self, x0, y0, x1, y1);
	} else {
		_tmp10_ = FALSE;
	}
	if (_tmp10_) {
		result = FALSE;
		_g_object_unref0 (t1);
		_g_object_unref0 (t0);
		return result;
	}
	_tmp16_ = t1;
	if (_tmp16_ != NULL) {
		guint8 _tmp17_;
		_tmp17_ = self->priv->_size;
		_tmp15_ = x0 < _tmp17_;
	} else {
		_tmp15_ = FALSE;
	}
	if (_tmp15_) {
		_tmp14_ = !puzzle_tile_fits (self, x1, y1, x0, y0);
	} else {
		_tmp14_ = FALSE;
	}
	if (_tmp14_) {
		result = FALSE;
		_g_object_unref0 (t1);
		_g_object_unref0 (t0);
		return result;
	}
	_tmp21_ = t0;
	if (_tmp21_ != NULL) {
		Tile* _tmp22_;
		_tmp22_ = t1;
		_tmp20_ = _tmp22_ != NULL;
	} else {
		_tmp20_ = FALSE;
	}
	if (_tmp20_) {
		guint8 _tmp23_;
		_tmp23_ = self->priv->_size;
		_tmp19_ = x0 < _tmp23_;
	} else {
		_tmp19_ = FALSE;
	}
	if (_tmp19_) {
		guint8 _tmp24_;
		_tmp24_ = self->priv->_size;
		_tmp18_ = x1 < _tmp24_;
	} else {
		_tmp18_ = FALSE;
	}
	if (_tmp18_) {
		if (x0 == x1) {
			gboolean _tmp25_ = FALSE;
			gboolean _tmp28_ = FALSE;
			if (((gint) y0) == (y1 + 1)) {
				Tile* _tmp26_;
				Tile* _tmp27_;
				_tmp26_ = t0;
				_tmp27_ = t1;
				_tmp25_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp26_, TYPE_TILE, Tile)->south != G_TYPE_CHECK_INSTANCE_CAST (_tmp27_, TYPE_TILE, Tile)->north;
			} else {
				_tmp25_ = FALSE;
			}
			if (_tmp25_) {
				result = FALSE;
				_g_object_unref0 (t1);
				_g_object_unref0 (t0);
				return result;
			}
			if (((gint) y0) == (y1 - 1)) {
				Tile* _tmp29_;
				Tile* _tmp30_;
				_tmp29_ = t0;
				_tmp30_ = t1;
				_tmp28_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp29_, TYPE_TILE, Tile)->north != G_TYPE_CHECK_INSTANCE_CAST (_tmp30_, TYPE_TILE, Tile)->south;
			} else {
				_tmp28_ = FALSE;
			}
			if (_tmp28_) {
				result = FALSE;
				_g_object_unref0 (t1);
				_g_object_unref0 (t0);
				return result;
			}
		} else {
			if (y0 == y1) {
				gboolean _tmp31_ = FALSE;
				gboolean _tmp34_ = FALSE;
				if (((gint) x0) == (x1 + 1)) {
					Tile* _tmp32_;
					Tile* _tmp33_;
					_tmp32_ = t0;
					_tmp33_ = t1;
					_tmp31_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp32_, TYPE_TILE, Tile)->east != G_TYPE_CHECK_INSTANCE_CAST (_tmp33_, TYPE_TILE, Tile)->west;
				} else {
					_tmp31_ = FALSE;
				}
				if (_tmp31_) {
					result = FALSE;
					_g_object_unref0 (t1);
					_g_object_unref0 (t0);
					return result;
				}
				if (((gint) x0) == (x1 - 1)) {
					Tile* _tmp35_;
					Tile* _tmp36_;
					_tmp35_ = t0;
					_tmp36_ = t1;
					_tmp34_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp35_, TYPE_TILE, Tile)->west != G_TYPE_CHECK_INSTANCE_CAST (_tmp36_, TYPE_TILE, Tile)->west;
				} else {
					_tmp34_ = FALSE;
				}
				if (_tmp34_) {
					result = FALSE;
					_g_object_unref0 (t1);
					_g_object_unref0 (t0);
					return result;
				}
			}
		}
	}
	result = TRUE;
	_g_object_unref0 (t1);
	_g_object_unref0 (t0);
	return result;
}

void
puzzle_switch_tiles (Puzzle* self,
                     guint8 x0,
                     guint8 y0,
                     guint8 x1,
                     guint8 y1,
                     guint delay_if_finished)
{
	g_return_if_fail (self != NULL);
	_puzzle_switch_tiles (self, x0, y0, x1, y1, delay_if_finished, FALSE, (guint) 0);
}

static gboolean
_____lambda4_ (Puzzle* self)
{
	gboolean result;
	g_signal_emit (self, puzzle_signals[PUZZLE_SHOW_END_GAME_SIGNAL], 0);
	self->priv->timeout_id = (guint) 0;
	result = G_SOURCE_REMOVE;
	return result;
}

static gboolean
______lambda4__gsource_func (gpointer self)
{
	gboolean result;
	result = _____lambda4_ ((Puzzle*) self);
	return result;
}

static void
_puzzle_switch_tiles (Puzzle* self,
                      guint8 x0,
                      guint8 y0,
                      guint8 x1,
                      guint8 y1,
                      guint delay_if_finished,
                      gboolean undoing_or_redoing,
                      guint move_id)
{
	gboolean _tmp0_ = FALSE;
	Tile* t0 = NULL;
	Tile** _tmp1_;
	gint _tmp1__length1;
	gint _tmp1__length2;
	Tile* _tmp2_;
	Tile* _tmp3_;
	Tile* t1 = NULL;
	Tile** _tmp4_;
	gint _tmp4__length1;
	gint _tmp4__length2;
	Tile* _tmp5_;
	Tile* _tmp6_;
	gboolean _tmp7_ = FALSE;
	Tile* _tmp8_;
	Tile** _tmp10_;
	gint _tmp10__length1;
	gint _tmp10__length2;
	Tile* _tmp11_;
	Tile* _tmp12_;
	Tile** _tmp13_;
	gint _tmp13__length1;
	gint _tmp13__length2;
	Tile* _tmp14_;
	Tile* _tmp15_;
	Tile* _tmp16_;
	Tile* _tmp18_;
	g_return_if_fail (self != NULL);
	if (x0 == x1) {
		_tmp0_ = y0 == y1;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		return;
	}
	puzzle_set_game_in_progress (self, TRUE);
	_tmp1_ = self->priv->board;
	_tmp1__length1 = self->priv->board_length1;
	_tmp1__length2 = self->priv->board_length2;
	_tmp2_ = _tmp1_[(x0 * _tmp1__length2) + y0];
	_tmp3_ = _g_object_ref0 (_tmp2_);
	t0 = _tmp3_;
	_tmp4_ = self->priv->board;
	_tmp4__length1 = self->priv->board_length1;
	_tmp4__length2 = self->priv->board_length2;
	_tmp5_ = _tmp4_[(x1 * _tmp4__length2) + y1];
	_tmp6_ = _g_object_ref0 (_tmp5_);
	t1 = _tmp6_;
	_tmp8_ = t0;
	if (_tmp8_ == NULL) {
		Tile* _tmp9_;
		_tmp9_ = t1;
		_tmp7_ = _tmp9_ == NULL;
	} else {
		_tmp7_ = FALSE;
	}
	if (_tmp7_) {
		_g_object_unref0 (t1);
		_g_object_unref0 (t0);
		return;
	}
	_tmp10_ = self->priv->board;
	_tmp10__length1 = self->priv->board_length1;
	_tmp10__length2 = self->priv->board_length2;
	_tmp11_ = t1;
	_tmp12_ = _g_object_ref0 (_tmp11_);
	_g_object_unref0 (_tmp10_[(x0 * _tmp10__length2) + y0]);
	_tmp10_[(x0 * _tmp10__length2) + y0] = _tmp12_;
	_tmp13_ = self->priv->board;
	_tmp13__length1 = self->priv->board_length1;
	_tmp13__length2 = self->priv->board_length2;
	_tmp14_ = t0;
	_tmp15_ = _g_object_ref0 (_tmp14_);
	_g_object_unref0 (_tmp13_[(x1 * _tmp13__length2) + y1]);
	_tmp13_[(x1 * _tmp13__length2) + y1] = _tmp15_;
	_tmp16_ = t0;
	if (_tmp16_ != NULL) {
		Tile* _tmp17_;
		_tmp17_ = t0;
		g_signal_emit (self, puzzle_signals[PUZZLE_TILE_MOVED_SIGNAL], 0, G_TYPE_CHECK_INSTANCE_CAST (_tmp17_, TYPE_TILE, Tile), x1, y1);
	}
	_tmp18_ = t1;
	if (_tmp18_ != NULL) {
		Tile* _tmp19_;
		_tmp19_ = t1;
		g_signal_emit (self, puzzle_signals[PUZZLE_TILE_MOVED_SIGNAL], 0, G_TYPE_CHECK_INSTANCE_CAST (_tmp19_, TYPE_TILE, Tile), x0, y0);
	}
	if (!undoing_or_redoing) {
		puzzle_add_to_history (self, x0, y0, x1, y1, move_id);
	}
	if (puzzle_check_if_solved (self)) {
		puzzle_stop_clock (self);
		g_signal_emit (self, puzzle_signals[PUZZLE_SOLVED_SIGNAL], 0);
		if (delay_if_finished == ((guint) 0)) {
			g_signal_emit (self, puzzle_signals[PUZZLE_SHOW_END_GAME_SIGNAL], 0);
		} else {
			if (self->priv->timeout_id == ((guint) 0)) {
				self->priv->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT, delay_if_finished, ______lambda4__gsource_func, g_object_ref (self), g_object_unref);
			}
		}
	} else {
		if (puzzle_solved_on_right (self)) {
			puzzle_set_is_solved_right (self, TRUE);
		} else {
			gboolean _tmp20_;
			_tmp20_ = self->priv->_is_solved_right;
			if (_tmp20_) {
				puzzle_set_is_solved_right (self, FALSE);
			}
		}
	}
	_g_object_unref0 (t1);
	_g_object_unref0 (t0);
}

static inline void
puzzle_switch_one_of_many_tiles (Puzzle* self,
                                 guint8 x0,
                                 guint8 y0,
                                 guint8 x1,
                                 guint8 y1)
{
	g_return_if_fail (self != NULL);
	_puzzle_switch_tiles (self, x0, y0, x1, y1, (guint) 0, FALSE, self->priv->last_move_id);
}

gboolean
puzzle_move_up (Puzzle* self,
                gboolean left_board)
{
	gboolean _tmp0_ = FALSE;
	guint _tmp1_;
	gint _tmp2_ = 0;
	guint8 base_x = 0U;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (!puzzle_can_move_up (self, left_board)) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = self->priv->last_move_id == G_MAXUINT;
	}
	if (_tmp0_) {
		result = FALSE;
		return result;
	}
	_tmp1_ = self->priv->last_move_id;
	self->priv->last_move_id = _tmp1_ + 1;
	if (left_board) {
		_tmp2_ = 0;
	} else {
		guint8 _tmp3_;
		_tmp3_ = self->priv->_size;
		_tmp2_ = (gint) _tmp3_;
	}
	base_x = (guint8) _tmp2_;
	{
		guint8 y = 0U;
		y = (guint8) 1;
		{
			gboolean _tmp4_ = FALSE;
			_tmp4_ = TRUE;
			while (TRUE) {
				guint8 _tmp6_;
				if (!_tmp4_) {
					guint8 _tmp5_;
					_tmp5_ = y;
					y = _tmp5_ + 1;
				}
				_tmp4_ = FALSE;
				_tmp6_ = self->priv->_size;
				if (!(y < _tmp6_)) {
					break;
				}
				{
					guint8 x = 0U;
					x = (guint8) 0;
					{
						gboolean _tmp7_ = FALSE;
						_tmp7_ = TRUE;
						while (TRUE) {
							guint8 _tmp9_;
							if (!_tmp7_) {
								guint8 _tmp8_;
								_tmp8_ = x;
								x = _tmp8_ + 1;
							}
							_tmp7_ = FALSE;
							_tmp9_ = self->priv->_size;
							if (!(x < _tmp9_)) {
								break;
							}
							puzzle_switch_one_of_many_tiles (self, base_x + x, y, base_x + x, (guint8) (y - 1));
						}
					}
				}
			}
		}
	}
	result = TRUE;
	return result;
}

static gboolean
puzzle_can_move_up (Puzzle* self,
                    gboolean left_board)
{
	gint _tmp0_ = 0;
	guint8 base_x = 0U;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (left_board) {
		_tmp0_ = 0;
	} else {
		guint8 _tmp1_;
		_tmp1_ = self->priv->_size;
		_tmp0_ = (gint) _tmp1_;
	}
	base_x = (guint8) _tmp0_;
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp2_ = FALSE;
			_tmp2_ = TRUE;
			while (TRUE) {
				guint8 _tmp4_;
				Tile** _tmp5_;
				gint _tmp5__length1;
				gint _tmp5__length2;
				Tile* _tmp6_;
				if (!_tmp2_) {
					guint8 _tmp3_;
					_tmp3_ = x;
					x = _tmp3_ + 1;
				}
				_tmp2_ = FALSE;
				_tmp4_ = self->priv->_size;
				if (!(x < _tmp4_)) {
					break;
				}
				_tmp5_ = self->priv->board;
				_tmp5__length1 = self->priv->board_length1;
				_tmp5__length2 = self->priv->board_length2;
				_tmp6_ = _tmp5_[((base_x + x) * _tmp5__length2) + 0];
				if (_tmp6_ != NULL) {
					result = FALSE;
					return result;
				}
			}
		}
	}
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp7_ = FALSE;
			_tmp7_ = TRUE;
			while (TRUE) {
				guint8 _tmp9_;
				if (!_tmp7_) {
					guint8 _tmp8_;
					_tmp8_ = x;
					x = _tmp8_ + 1;
				}
				_tmp7_ = FALSE;
				_tmp9_ = self->priv->_size;
				if (!(x < _tmp9_)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 1;
					{
						gboolean _tmp10_ = FALSE;
						_tmp10_ = TRUE;
						while (TRUE) {
							guint8 _tmp12_;
							Tile** _tmp13_;
							gint _tmp13__length1;
							gint _tmp13__length2;
							Tile* _tmp14_;
							if (!_tmp10_) {
								guint8 _tmp11_;
								_tmp11_ = y;
								y = _tmp11_ + 1;
							}
							_tmp10_ = FALSE;
							_tmp12_ = self->priv->_size;
							if (!(y < _tmp12_)) {
								break;
							}
							_tmp13_ = self->priv->board;
							_tmp13__length1 = self->priv->board_length1;
							_tmp13__length2 = self->priv->board_length2;
							_tmp14_ = _tmp13_[((base_x + x) * _tmp13__length2) + y];
							if (_tmp14_ != NULL) {
								result = TRUE;
								return result;
							}
						}
					}
				}
			}
		}
	}
	result = FALSE;
	return result;
}

gboolean
puzzle_move_down (Puzzle* self,
                  gboolean left_board)
{
	gboolean _tmp0_ = FALSE;
	guint _tmp1_;
	gint _tmp2_ = 0;
	guint8 base_x = 0U;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (!puzzle_can_move_down (self, left_board)) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = self->priv->last_move_id == G_MAXUINT;
	}
	if (_tmp0_) {
		result = FALSE;
		return result;
	}
	_tmp1_ = self->priv->last_move_id;
	self->priv->last_move_id = _tmp1_ + 1;
	if (left_board) {
		_tmp2_ = 0;
	} else {
		guint8 _tmp3_;
		_tmp3_ = self->priv->_size;
		_tmp2_ = (gint) _tmp3_;
	}
	base_x = (guint8) _tmp2_;
	{
		guint8 y = 0U;
		guint8 _tmp4_;
		_tmp4_ = self->priv->_size;
		y = (guint8) (_tmp4_ - 1);
		{
			gboolean _tmp5_ = FALSE;
			_tmp5_ = TRUE;
			while (TRUE) {
				if (!_tmp5_) {
					guint8 _tmp6_;
					_tmp6_ = y;
					y = _tmp6_ - 1;
				}
				_tmp5_ = FALSE;
				if (!(((gint) y) > 0)) {
					break;
				}
				{
					guint8 x = 0U;
					x = (guint8) 0;
					{
						gboolean _tmp7_ = FALSE;
						_tmp7_ = TRUE;
						while (TRUE) {
							guint8 _tmp9_;
							if (!_tmp7_) {
								guint8 _tmp8_;
								_tmp8_ = x;
								x = _tmp8_ + 1;
							}
							_tmp7_ = FALSE;
							_tmp9_ = self->priv->_size;
							if (!(x < _tmp9_)) {
								break;
							}
							puzzle_switch_one_of_many_tiles (self, base_x + x, (guint8) (y - 1), base_x + x, y);
						}
					}
				}
			}
		}
	}
	result = TRUE;
	return result;
}

static gboolean
puzzle_can_move_down (Puzzle* self,
                      gboolean left_board)
{
	gint _tmp0_ = 0;
	guint8 base_x = 0U;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (left_board) {
		_tmp0_ = 0;
	} else {
		guint8 _tmp1_;
		_tmp1_ = self->priv->_size;
		_tmp0_ = (gint) _tmp1_;
	}
	base_x = (guint8) _tmp0_;
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp2_ = FALSE;
			_tmp2_ = TRUE;
			while (TRUE) {
				guint8 _tmp4_;
				Tile** _tmp5_;
				gint _tmp5__length1;
				gint _tmp5__length2;
				guint8 _tmp6_;
				Tile* _tmp7_;
				if (!_tmp2_) {
					guint8 _tmp3_;
					_tmp3_ = x;
					x = _tmp3_ + 1;
				}
				_tmp2_ = FALSE;
				_tmp4_ = self->priv->_size;
				if (!(x < _tmp4_)) {
					break;
				}
				_tmp5_ = self->priv->board;
				_tmp5__length1 = self->priv->board_length1;
				_tmp5__length2 = self->priv->board_length2;
				_tmp6_ = self->priv->_size;
				_tmp7_ = _tmp5_[((base_x + x) * _tmp5__length2) + (_tmp6_ - 1)];
				if (_tmp7_ != NULL) {
					result = FALSE;
					return result;
				}
			}
		}
	}
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp8_ = FALSE;
			_tmp8_ = TRUE;
			while (TRUE) {
				guint8 _tmp10_;
				if (!_tmp8_) {
					guint8 _tmp9_;
					_tmp9_ = x;
					x = _tmp9_ + 1;
				}
				_tmp8_ = FALSE;
				_tmp10_ = self->priv->_size;
				if (!(x < _tmp10_)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp11_ = FALSE;
						_tmp11_ = TRUE;
						while (TRUE) {
							guint8 _tmp13_;
							Tile** _tmp14_;
							gint _tmp14__length1;
							gint _tmp14__length2;
							Tile* _tmp15_;
							if (!_tmp11_) {
								guint8 _tmp12_;
								_tmp12_ = y;
								y = _tmp12_ + 1;
							}
							_tmp11_ = FALSE;
							_tmp13_ = self->priv->_size;
							if (!(((gint) y) < (_tmp13_ - 1))) {
								break;
							}
							_tmp14_ = self->priv->board;
							_tmp14__length1 = self->priv->board_length1;
							_tmp14__length2 = self->priv->board_length2;
							_tmp15_ = _tmp14_[((base_x + x) * _tmp14__length2) + y];
							if (_tmp15_ != NULL) {
								result = TRUE;
								return result;
							}
						}
					}
				}
			}
		}
	}
	result = FALSE;
	return result;
}

gboolean
puzzle_move_left (Puzzle* self,
                  gboolean left_board)
{
	gboolean _tmp0_ = FALSE;
	guint _tmp1_;
	gint _tmp2_ = 0;
	guint8 base_x = 0U;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (!puzzle_can_move_left (self, left_board)) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = self->priv->last_move_id == G_MAXUINT;
	}
	if (_tmp0_) {
		result = FALSE;
		return result;
	}
	_tmp1_ = self->priv->last_move_id;
	self->priv->last_move_id = _tmp1_ + 1;
	if (left_board) {
		_tmp2_ = 0;
	} else {
		guint8 _tmp3_;
		_tmp3_ = self->priv->_size;
		_tmp2_ = (gint) _tmp3_;
	}
	base_x = (guint8) _tmp2_;
	{
		guint8 x = 0U;
		x = (guint8) 1;
		{
			gboolean _tmp4_ = FALSE;
			_tmp4_ = TRUE;
			while (TRUE) {
				guint8 _tmp6_;
				if (!_tmp4_) {
					guint8 _tmp5_;
					_tmp5_ = x;
					x = _tmp5_ + 1;
				}
				_tmp4_ = FALSE;
				_tmp6_ = self->priv->_size;
				if (!(x < _tmp6_)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp7_ = FALSE;
						_tmp7_ = TRUE;
						while (TRUE) {
							guint8 _tmp9_;
							if (!_tmp7_) {
								guint8 _tmp8_;
								_tmp8_ = y;
								y = _tmp8_ + 1;
							}
							_tmp7_ = FALSE;
							_tmp9_ = self->priv->_size;
							if (!(y < _tmp9_)) {
								break;
							}
							puzzle_switch_one_of_many_tiles (self, base_x + x, y, (guint8) ((base_x + x) - 1), y);
						}
					}
				}
			}
		}
	}
	result = TRUE;
	return result;
}

static gboolean
puzzle_can_move_left (Puzzle* self,
                      gboolean left_board)
{
	gint _tmp0_ = 0;
	guint8 left_column = 0U;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (left_board) {
		_tmp0_ = 0;
	} else {
		guint8 _tmp1_;
		_tmp1_ = self->priv->_size;
		_tmp0_ = (gint) _tmp1_;
	}
	left_column = (guint8) _tmp0_;
	{
		guint8 y = 0U;
		y = (guint8) 0;
		{
			gboolean _tmp2_ = FALSE;
			_tmp2_ = TRUE;
			while (TRUE) {
				guint8 _tmp4_;
				Tile** _tmp5_;
				gint _tmp5__length1;
				gint _tmp5__length2;
				Tile* _tmp6_;
				if (!_tmp2_) {
					guint8 _tmp3_;
					_tmp3_ = y;
					y = _tmp3_ + 1;
				}
				_tmp2_ = FALSE;
				_tmp4_ = self->priv->_size;
				if (!(y < _tmp4_)) {
					break;
				}
				_tmp5_ = self->priv->board;
				_tmp5__length1 = self->priv->board_length1;
				_tmp5__length2 = self->priv->board_length2;
				_tmp6_ = _tmp5_[(left_column * _tmp5__length2) + y];
				if (_tmp6_ != NULL) {
					result = FALSE;
					return result;
				}
			}
		}
	}
	{
		guint8 x = 0U;
		x = (guint8) 1;
		{
			gboolean _tmp7_ = FALSE;
			_tmp7_ = TRUE;
			while (TRUE) {
				guint8 _tmp9_;
				if (!_tmp7_) {
					guint8 _tmp8_;
					_tmp8_ = x;
					x = _tmp8_ + 1;
				}
				_tmp7_ = FALSE;
				_tmp9_ = self->priv->_size;
				if (!(x < _tmp9_)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp10_ = FALSE;
						_tmp10_ = TRUE;
						while (TRUE) {
							guint8 _tmp12_;
							Tile** _tmp13_;
							gint _tmp13__length1;
							gint _tmp13__length2;
							Tile* _tmp14_;
							if (!_tmp10_) {
								guint8 _tmp11_;
								_tmp11_ = y;
								y = _tmp11_ + 1;
							}
							_tmp10_ = FALSE;
							_tmp12_ = self->priv->_size;
							if (!(y < _tmp12_)) {
								break;
							}
							_tmp13_ = self->priv->board;
							_tmp13__length1 = self->priv->board_length1;
							_tmp13__length2 = self->priv->board_length2;
							_tmp14_ = _tmp13_[((left_column + x) * _tmp13__length2) + y];
							if (_tmp14_ != NULL) {
								result = TRUE;
								return result;
							}
						}
					}
				}
			}
		}
	}
	result = FALSE;
	return result;
}

gboolean
puzzle_move_right (Puzzle* self,
                   gboolean left_board)
{
	gboolean _tmp0_ = FALSE;
	guint _tmp1_;
	gint _tmp2_ = 0;
	guint8 base_x = 0U;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (!puzzle_can_move_right (self, left_board)) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = self->priv->last_move_id == G_MAXUINT;
	}
	if (_tmp0_) {
		result = FALSE;
		return result;
	}
	_tmp1_ = self->priv->last_move_id;
	self->priv->last_move_id = _tmp1_ + 1;
	if (left_board) {
		_tmp2_ = 0;
	} else {
		guint8 _tmp3_;
		_tmp3_ = self->priv->_size;
		_tmp2_ = (gint) _tmp3_;
	}
	base_x = (guint8) _tmp2_;
	{
		guint8 x = 0U;
		guint8 _tmp4_;
		_tmp4_ = self->priv->_size;
		x = (guint8) (_tmp4_ - 1);
		{
			gboolean _tmp5_ = FALSE;
			_tmp5_ = TRUE;
			while (TRUE) {
				if (!_tmp5_) {
					guint8 _tmp6_;
					_tmp6_ = x;
					x = _tmp6_ - 1;
				}
				_tmp5_ = FALSE;
				if (!(((gint) x) > 0)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp7_ = FALSE;
						_tmp7_ = TRUE;
						while (TRUE) {
							guint8 _tmp9_;
							if (!_tmp7_) {
								guint8 _tmp8_;
								_tmp8_ = y;
								y = _tmp8_ + 1;
							}
							_tmp7_ = FALSE;
							_tmp9_ = self->priv->_size;
							if (!(y < _tmp9_)) {
								break;
							}
							puzzle_switch_one_of_many_tiles (self, (guint8) ((base_x + x) - 1), y, base_x + x, y);
						}
					}
				}
			}
		}
	}
	result = TRUE;
	return result;
}

static gboolean
puzzle_can_move_right (Puzzle* self,
                       gboolean left_board)
{
	gint _tmp0_ = 0;
	guint8 left_column = 0U;
	guint8 right_column = 0U;
	guint8 _tmp2_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (left_board) {
		_tmp0_ = 0;
	} else {
		guint8 _tmp1_;
		_tmp1_ = self->priv->_size;
		_tmp0_ = (gint) _tmp1_;
	}
	left_column = (guint8) _tmp0_;
	_tmp2_ = self->priv->_size;
	right_column = (guint8) ((left_column + _tmp2_) - 1);
	{
		guint8 y = 0U;
		y = (guint8) 0;
		{
			gboolean _tmp3_ = FALSE;
			_tmp3_ = TRUE;
			while (TRUE) {
				guint8 _tmp5_;
				Tile** _tmp6_;
				gint _tmp6__length1;
				gint _tmp6__length2;
				Tile* _tmp7_;
				if (!_tmp3_) {
					guint8 _tmp4_;
					_tmp4_ = y;
					y = _tmp4_ + 1;
				}
				_tmp3_ = FALSE;
				_tmp5_ = self->priv->_size;
				if (!(y < _tmp5_)) {
					break;
				}
				_tmp6_ = self->priv->board;
				_tmp6__length1 = self->priv->board_length1;
				_tmp6__length2 = self->priv->board_length2;
				_tmp7_ = _tmp6_[(right_column * _tmp6__length2) + y];
				if (_tmp7_ != NULL) {
					result = FALSE;
					return result;
				}
			}
		}
	}
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp8_ = FALSE;
			_tmp8_ = TRUE;
			while (TRUE) {
				guint8 _tmp10_;
				if (!_tmp8_) {
					guint8 _tmp9_;
					_tmp9_ = x;
					x = _tmp9_ + 1;
				}
				_tmp8_ = FALSE;
				_tmp10_ = self->priv->_size;
				if (!(((gint) x) < (_tmp10_ - 1))) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp11_ = FALSE;
						_tmp11_ = TRUE;
						while (TRUE) {
							guint8 _tmp13_;
							Tile** _tmp14_;
							gint _tmp14__length1;
							gint _tmp14__length2;
							Tile* _tmp15_;
							if (!_tmp11_) {
								guint8 _tmp12_;
								_tmp12_ = y;
								y = _tmp12_ + 1;
							}
							_tmp11_ = FALSE;
							_tmp13_ = self->priv->_size;
							if (!(y < _tmp13_)) {
								break;
							}
							_tmp14_ = self->priv->board;
							_tmp14__length1 = self->priv->board_length1;
							_tmp14__length2 = self->priv->board_length2;
							_tmp15_ = _tmp14_[((left_column + x) * _tmp14__length2) + y];
							if (_tmp15_ != NULL) {
								result = TRUE;
								return result;
							}
						}
					}
				}
			}
		}
	}
	result = FALSE;
	return result;
}

void
puzzle_try_move (Puzzle* self,
                 guint8 x,
                 guint8 y)
{
	guint8 _tmp0_;
	guint8 _tmp1_;
	gboolean left_board = FALSE;
	guint8 _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_size;
	_vala_return_if_fail (((gint) x) < (2 * _tmp0_), "x < 2 * size");
	_tmp1_ = self->priv->_size;
	_vala_return_if_fail (y < _tmp1_, "y < size");
	_tmp2_ = self->priv->_size;
	left_board = x < _tmp2_;
	switch (puzzle_can_move (self, x, y)) {
		case DIRECTION_UP:
		{
			puzzle_move_up (self, left_board);
			return;
		}
		case DIRECTION_DOWN:
		{
			puzzle_move_down (self, left_board);
			return;
		}
		case DIRECTION_LEFT:
		{
			puzzle_move_left (self, left_board);
			return;
		}
		case DIRECTION_RIGHT:
		{
			puzzle_move_right (self, left_board);
			return;
		}
		default:
		case DIRECTION_NONE:
		{
			return;
		}
	}
}

static inline Direction
puzzle_can_move (Puzzle* self,
                 guint8 x,
                 guint8 y)
{
	gboolean left_board = FALSE;
	guint8 _tmp0_;
	gint _tmp1_ = 0;
	guint8 left_column = 0U;
	gint _tmp3_ = 0;
	guint8 right_column = 0U;
	gboolean _tmp6_ = FALSE;
	gboolean _tmp7_ = FALSE;
	gboolean _tmp8_ = FALSE;
	gboolean _tmp11_ = FALSE;
	gboolean _tmp12_ = FALSE;
	gboolean _tmp13_ = FALSE;
	guint8 _tmp14_;
	gboolean _tmp17_ = FALSE;
	gboolean _tmp18_ = FALSE;
	gboolean _tmp19_ = FALSE;
	gboolean _tmp23_ = FALSE;
	gboolean _tmp24_ = FALSE;
	gboolean _tmp25_ = FALSE;
	Direction result;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = self->priv->_size;
	left_board = x < _tmp0_;
	if (puzzle_half_board_is_empty (self, left_board)) {
		result = DIRECTION_NONE;
		return result;
	}
	if (left_board) {
		_tmp1_ = 0;
	} else {
		guint8 _tmp2_;
		_tmp2_ = self->priv->_size;
		_tmp1_ = (gint) _tmp2_;
	}
	left_column = (guint8) _tmp1_;
	if (left_board) {
		guint8 _tmp4_;
		_tmp4_ = self->priv->_size;
		_tmp3_ = _tmp4_ - 1;
	} else {
		guint8 _tmp5_;
		_tmp5_ = self->priv->_size;
		_tmp3_ = (_tmp5_ * 2) - 1;
	}
	right_column = (guint8) _tmp3_;
	if (((gint) y) == 0) {
		_tmp8_ = puzzle_can_move_up (self, left_board);
	} else {
		_tmp8_ = FALSE;
	}
	if (_tmp8_) {
		gboolean _tmp9_ = FALSE;
		if (x == left_column) {
			_tmp9_ = puzzle_can_move_left (self, left_board);
		} else {
			_tmp9_ = FALSE;
		}
		_tmp7_ = !_tmp9_;
	} else {
		_tmp7_ = FALSE;
	}
	if (_tmp7_) {
		gboolean _tmp10_ = FALSE;
		if (x == right_column) {
			_tmp10_ = puzzle_can_move_right (self, left_board);
		} else {
			_tmp10_ = FALSE;
		}
		_tmp6_ = !_tmp10_;
	} else {
		_tmp6_ = FALSE;
	}
	if (_tmp6_) {
		result = DIRECTION_UP;
		return result;
	}
	_tmp14_ = self->priv->_size;
	if (((gint) y) == (_tmp14_ - 1)) {
		_tmp13_ = puzzle_can_move_down (self, left_board);
	} else {
		_tmp13_ = FALSE;
	}
	if (_tmp13_) {
		gboolean _tmp15_ = FALSE;
		if (x == left_column) {
			_tmp15_ = puzzle_can_move_left (self, left_board);
		} else {
			_tmp15_ = FALSE;
		}
		_tmp12_ = !_tmp15_;
	} else {
		_tmp12_ = FALSE;
	}
	if (_tmp12_) {
		gboolean _tmp16_ = FALSE;
		if (x == right_column) {
			_tmp16_ = puzzle_can_move_right (self, left_board);
		} else {
			_tmp16_ = FALSE;
		}
		_tmp11_ = !_tmp16_;
	} else {
		_tmp11_ = FALSE;
	}
	if (_tmp11_) {
		result = DIRECTION_DOWN;
		return result;
	}
	if (x == left_column) {
		_tmp19_ = puzzle_can_move_left (self, left_board);
	} else {
		_tmp19_ = FALSE;
	}
	if (_tmp19_) {
		gboolean _tmp20_ = FALSE;
		if (((gint) y) == 0) {
			_tmp20_ = puzzle_can_move_up (self, left_board);
		} else {
			_tmp20_ = FALSE;
		}
		_tmp18_ = !_tmp20_;
	} else {
		_tmp18_ = FALSE;
	}
	if (_tmp18_) {
		gboolean _tmp21_ = FALSE;
		guint8 _tmp22_;
		_tmp22_ = self->priv->_size;
		if (((gint) y) == (_tmp22_ - 1)) {
			_tmp21_ = puzzle_can_move_down (self, left_board);
		} else {
			_tmp21_ = FALSE;
		}
		_tmp17_ = !_tmp21_;
	} else {
		_tmp17_ = FALSE;
	}
	if (_tmp17_) {
		result = DIRECTION_LEFT;
		return result;
	}
	if (x == right_column) {
		_tmp25_ = puzzle_can_move_right (self, left_board);
	} else {
		_tmp25_ = FALSE;
	}
	if (_tmp25_) {
		gboolean _tmp26_ = FALSE;
		if (((gint) y) == 0) {
			_tmp26_ = puzzle_can_move_up (self, left_board);
		} else {
			_tmp26_ = FALSE;
		}
		_tmp24_ = !_tmp26_;
	} else {
		_tmp24_ = FALSE;
	}
	if (_tmp24_) {
		gboolean _tmp27_ = FALSE;
		guint8 _tmp28_;
		_tmp28_ = self->priv->_size;
		if (((gint) y) == (_tmp28_ - 1)) {
			_tmp27_ = puzzle_can_move_down (self, left_board);
		} else {
			_tmp27_ = FALSE;
		}
		_tmp23_ = !_tmp27_;
	} else {
		_tmp23_ = FALSE;
	}
	if (_tmp23_) {
		result = DIRECTION_RIGHT;
		return result;
	}
	result = DIRECTION_NONE;
	return result;
}

static inline gboolean
puzzle_half_board_is_empty (Puzzle* self,
                            gboolean left_board)
{
	gint _tmp0_ = 0;
	guint8 base_x = 0U;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (left_board) {
		_tmp0_ = 0;
	} else {
		guint8 _tmp1_;
		_tmp1_ = self->priv->_size;
		_tmp0_ = (gint) _tmp1_;
	}
	base_x = (guint8) _tmp0_;
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp2_ = FALSE;
			_tmp2_ = TRUE;
			while (TRUE) {
				guint8 _tmp4_;
				if (!_tmp2_) {
					guint8 _tmp3_;
					_tmp3_ = x;
					x = _tmp3_ + 1;
				}
				_tmp2_ = FALSE;
				_tmp4_ = self->priv->_size;
				if (!(x < _tmp4_)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp5_ = FALSE;
						_tmp5_ = TRUE;
						while (TRUE) {
							guint8 _tmp7_;
							Tile** _tmp8_;
							gint _tmp8__length1;
							gint _tmp8__length2;
							Tile* _tmp9_;
							if (!_tmp5_) {
								guint8 _tmp6_;
								_tmp6_ = y;
								y = _tmp6_ + 1;
							}
							_tmp5_ = FALSE;
							_tmp7_ = self->priv->_size;
							if (!(y < _tmp7_)) {
								break;
							}
							_tmp8_ = self->priv->board;
							_tmp8__length1 = self->priv->board_length1;
							_tmp8__length2 = self->priv->board_length2;
							_tmp9_ = _tmp8_[((base_x + x) * _tmp8__length2) + y];
							if (_tmp9_ != NULL) {
								result = FALSE;
								return result;
							}
						}
					}
				}
			}
		}
	}
	result = TRUE;
	return result;
}

void
puzzle_solve (Puzzle* self)
{
	GList* wrong_tiles = NULL;
	GList* _tmp21_;
	g_return_if_fail (self != NULL);
	wrong_tiles = NULL;
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				guint8 _tmp2_;
				if (!_tmp0_) {
					guint8 _tmp1_;
					_tmp1_ = x;
					x = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				_tmp2_ = self->priv->_size;
				if (!(((gint) x) < (_tmp2_ * 2))) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp3_ = FALSE;
						_tmp3_ = TRUE;
						while (TRUE) {
							guint8 _tmp5_;
							Tile* tile = NULL;
							Tile** _tmp6_;
							gint _tmp6__length1;
							gint _tmp6__length2;
							Tile* _tmp7_;
							Tile* _tmp8_;
							gboolean _tmp9_ = FALSE;
							Tile* _tmp10_;
							Tile** _tmp20_;
							gint _tmp20__length1;
							gint _tmp20__length2;
							if (!_tmp3_) {
								guint8 _tmp4_;
								_tmp4_ = y;
								y = _tmp4_ + 1;
							}
							_tmp3_ = FALSE;
							_tmp5_ = self->priv->_size;
							if (!(y < _tmp5_)) {
								break;
							}
							_tmp6_ = self->priv->board;
							_tmp6__length1 = self->priv->board_length1;
							_tmp6__length2 = self->priv->board_length2;
							_tmp7_ = _tmp6_[(x * _tmp6__length2) + y];
							_tmp8_ = _g_object_ref0 (_tmp7_);
							tile = _tmp8_;
							_tmp10_ = tile;
							if (_tmp10_ != NULL) {
								gboolean _tmp11_ = FALSE;
								Tile* _tmp12_;
								guint8 _tmp13_;
								guint8 _tmp14_;
								_tmp12_ = tile;
								_tmp13_ = tile_get_x (G_TYPE_CHECK_INSTANCE_CAST (_tmp12_, TYPE_TILE, Tile));
								_tmp14_ = _tmp13_;
								if (_tmp14_ != x) {
									_tmp11_ = TRUE;
								} else {
									Tile* _tmp15_;
									guint8 _tmp16_;
									guint8 _tmp17_;
									_tmp15_ = tile;
									_tmp16_ = tile_get_y (G_TYPE_CHECK_INSTANCE_CAST (_tmp15_, TYPE_TILE, Tile));
									_tmp17_ = _tmp16_;
									_tmp11_ = _tmp17_ != y;
								}
								_tmp9_ = _tmp11_;
							} else {
								_tmp9_ = FALSE;
							}
							if (_tmp9_) {
								Tile* _tmp18_;
								Tile* _tmp19_;
								_tmp18_ = tile;
								_tmp19_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp18_, TYPE_TILE, Tile));
								wrong_tiles = g_list_append (wrong_tiles, _tmp19_);
							}
							_tmp20_ = self->priv->board;
							_tmp20__length1 = self->priv->board_length1;
							_tmp20__length2 = self->priv->board_length2;
							_g_object_unref0 (_tmp20_[(x * _tmp20__length2) + y]);
							_tmp20_[(x * _tmp20__length2) + y] = NULL;
							_g_object_unref0 (tile);
						}
					}
				}
			}
		}
	}
	_tmp21_ = wrong_tiles;
	{
		GList* tile_collection = NULL;
		GList* tile_it = NULL;
		tile_collection = _tmp21_;
		for (tile_it = tile_collection; tile_it != NULL; tile_it = tile_it->next) {
			Tile* _tmp22_;
			Tile* tile = NULL;
			_tmp22_ = _g_object_ref0 ((Tile*) tile_it->data);
			tile = _tmp22_;
			{
				Tile** _tmp23_;
				gint _tmp23__length1;
				gint _tmp23__length2;
				Tile* _tmp24_;
				guint8 _tmp25_;
				guint8 _tmp26_;
				Tile* _tmp27_;
				guint8 _tmp28_;
				guint8 _tmp29_;
				Tile* _tmp30_;
				Tile* _tmp31_;
				Tile* _tmp32_;
				Tile* _tmp33_;
				guint8 _tmp34_;
				guint8 _tmp35_;
				Tile* _tmp36_;
				guint8 _tmp37_;
				guint8 _tmp38_;
				_tmp23_ = self->priv->board;
				_tmp23__length1 = self->priv->board_length1;
				_tmp23__length2 = self->priv->board_length2;
				_tmp24_ = tile;
				_tmp25_ = tile_get_x (_tmp24_);
				_tmp26_ = _tmp25_;
				_tmp27_ = tile;
				_tmp28_ = tile_get_y (_tmp27_);
				_tmp29_ = _tmp28_;
				_tmp30_ = tile;
				_tmp31_ = _g_object_ref0 (_tmp30_);
				_g_object_unref0 (_tmp23_[(_tmp26_ * _tmp23__length2) + _tmp29_]);
				_tmp23_[(_tmp26_ * _tmp23__length2) + _tmp29_] = _tmp31_;
				_tmp32_ = tile;
				_tmp33_ = tile;
				_tmp34_ = tile_get_x (_tmp33_);
				_tmp35_ = _tmp34_;
				_tmp36_ = tile;
				_tmp37_ = tile_get_y (_tmp36_);
				_tmp38_ = _tmp37_;
				g_signal_emit (self, puzzle_signals[PUZZLE_TILE_MOVED_SIGNAL], 0, _tmp32_, _tmp35_, _tmp38_);
				_g_object_unref0 (tile);
			}
		}
	}
	puzzle_set_is_solved (self, TRUE);
	g_signal_emit (self, puzzle_signals[PUZZLE_SOLVED_SIGNAL], 0);
	puzzle_stop_clock (self);
	(wrong_tiles == NULL) ? NULL : (wrong_tiles = (_g_list_free__g_object_unref0_ (wrong_tiles), NULL));
}

void
puzzle_finish (Puzzle* self,
               guint duration)
{
	g_return_if_fail (self != NULL);
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				guint8 _tmp2_;
				if (!_tmp0_) {
					guint8 _tmp1_;
					_tmp1_ = x;
					x = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				_tmp2_ = self->priv->_size;
				if (!(x < _tmp2_)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp3_ = FALSE;
						_tmp3_ = TRUE;
						while (TRUE) {
							guint8 _tmp5_;
							guint8 _tmp6_;
							if (!_tmp3_) {
								guint8 _tmp4_;
								_tmp4_ = y;
								y = _tmp4_ + 1;
							}
							_tmp3_ = FALSE;
							_tmp5_ = self->priv->_size;
							if (!(y < _tmp5_)) {
								break;
							}
							_tmp6_ = self->priv->_size;
							puzzle_switch_tiles (self, x + _tmp6_, y, x, y, duration);
						}
					}
				}
			}
		}
	}
}

gboolean
puzzle_move_last_tile_if_possible (Puzzle* self)
{
	guint8 empty_x = 0U;
	guint8 empty_y = 0U;
	guint8 _tmp0_ = 0U;
	guint8 _tmp1_ = 0U;
	gboolean _tmp2_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp2_ = puzzle_only_one_remaining_tile (self, &_tmp0_, &_tmp1_);
	empty_x = _tmp0_;
	empty_y = _tmp1_;
	if (!_tmp2_) {
		result = FALSE;
		return result;
	}
	{
		guint8 x = 0U;
		guint8 _tmp3_;
		_tmp3_ = self->priv->_size;
		x = _tmp3_;
		{
			gboolean _tmp4_ = FALSE;
			_tmp4_ = TRUE;
			while (TRUE) {
				guint8 _tmp6_;
				if (!_tmp4_) {
					guint8 _tmp5_;
					_tmp5_ = x;
					x = _tmp5_ + 1;
				}
				_tmp4_ = FALSE;
				_tmp6_ = self->priv->_size;
				if (!(((gint) x) < (2 * _tmp6_))) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp7_ = FALSE;
						_tmp7_ = TRUE;
						while (TRUE) {
							guint8 _tmp9_;
							Tile* _tmp10_;
							Tile* _tmp11_;
							gboolean _tmp12_;
							if (!_tmp7_) {
								guint8 _tmp8_;
								_tmp8_ = y;
								y = _tmp8_ + 1;
							}
							_tmp7_ = FALSE;
							_tmp9_ = self->priv->_size;
							if (!(y < _tmp9_)) {
								break;
							}
							_tmp10_ = puzzle_get_tile (self, x, y);
							_tmp11_ = _tmp10_;
							_tmp12_ = _tmp11_ != NULL;
							_g_object_unref0 (_tmp11_);
							if (_tmp12_) {
								if (puzzle_can_switch (self, x, y, empty_x, empty_y)) {
									puzzle_switch_tiles (self, x, y, empty_x, empty_y, (guint) 0);
									result = TRUE;
									return result;
								} else {
									result = FALSE;
									return result;
								}
							}
						}
					}
				}
			}
		}
	}
	g_assert_not_reached ();
}

gboolean
puzzle_only_one_remaining_tile (Puzzle* self,
                                guint8* empty_x,
                                guint8* empty_y)
{
	guint8 _vala_empty_x = 0U;
	guint8 _vala_empty_y = 0U;
	gboolean empty_found = FALSE;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	empty_found = FALSE;
	_vala_empty_x = G_MAXUINT8;
	_vala_empty_y = G_MAXUINT8;
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				guint8 _tmp2_;
				if (!_tmp0_) {
					guint8 _tmp1_;
					_tmp1_ = x;
					x = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				_tmp2_ = self->priv->_size;
				if (!(x < _tmp2_)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp3_ = FALSE;
						_tmp3_ = TRUE;
						while (TRUE) {
							guint8 _tmp5_;
							Tile* _tmp6_;
							Tile* _tmp7_;
							gboolean _tmp8_;
							if (!_tmp3_) {
								guint8 _tmp4_;
								_tmp4_ = y;
								y = _tmp4_ + 1;
							}
							_tmp3_ = FALSE;
							_tmp5_ = self->priv->_size;
							if (!(y < _tmp5_)) {
								break;
							}
							_tmp6_ = puzzle_get_tile (self, x, y);
							_tmp7_ = _tmp6_;
							_tmp8_ = _tmp7_ == NULL;
							_g_object_unref0 (_tmp7_);
							if (_tmp8_) {
								if (empty_found) {
									result = FALSE;
									if (empty_x) {
										*empty_x = _vala_empty_x;
									}
									if (empty_y) {
										*empty_y = _vala_empty_y;
									}
									return result;
								}
								empty_found = TRUE;
								_vala_empty_x = x;
								_vala_empty_y = y;
							}
						}
					}
				}
			}
		}
	}
	if (!empty_found) {
		result = FALSE;
		if (empty_x) {
			*empty_x = _vala_empty_x;
		}
		if (empty_y) {
			*empty_y = _vala_empty_y;
		}
		return result;
	}
	result = TRUE;
	if (empty_x) {
		*empty_x = _vala_empty_x;
	}
	if (empty_y) {
		*empty_y = _vala_empty_y;
	}
	return result;
}

static void
puzzle_start_clock (Puzzle* self)
{
	gboolean _tmp0_;
	GTimer* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_tainted_by_command_line;
	if (_tmp0_) {
		return;
	}
	_tmp1_ = self->priv->clock;
	if (_tmp1_ == NULL) {
		GTimer* _tmp2_;
		_tmp2_ = g_timer_new ();
		_g_timer_destroy0 (self->priv->clock);
		self->priv->clock = _tmp2_;
	}
	puzzle_timeout_cb (self);
}

static void
puzzle_stop_clock (Puzzle* self)
{
	gboolean _tmp0_;
	GTimer* _tmp1_;
	GTimer* _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_tainted_by_command_line;
	if (_tmp0_) {
		return;
	}
	_tmp1_ = self->priv->clock;
	if (_tmp1_ == NULL) {
		return;
	}
	if (self->priv->clock_timeout != ((guint) 0)) {
		g_source_remove (self->priv->clock_timeout);
	}
	self->priv->clock_timeout = (guint) 0;
	_tmp2_ = self->priv->clock;
	g_timer_stop ((GTimer*) _tmp2_);
	g_signal_emit (self, puzzle_signals[PUZZLE_TICK_SIGNAL], 0);
}

static void
puzzle_continue_clock (Puzzle* self)
{
	gboolean _tmp0_;
	GTimer* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_tainted_by_command_line;
	if (_tmp0_) {
		return;
	}
	_tmp1_ = self->priv->clock;
	if (_tmp1_ == NULL) {
		GTimer* _tmp2_;
		_tmp2_ = g_timer_new ();
		_g_timer_destroy0 (self->priv->clock);
		self->priv->clock = _tmp2_;
	} else {
		GTimer* _tmp3_;
		_tmp3_ = self->priv->clock;
		g_timer_continue ((GTimer*) _tmp3_);
	}
	puzzle_timeout_cb (self);
}

static gboolean
_puzzle_timeout_cb_gsource_func (gpointer self)
{
	gboolean result;
	result = puzzle_timeout_cb ((Puzzle*) self);
	return result;
}

static gboolean
puzzle_timeout_cb (Puzzle* self)
{
	GTimer* _tmp0_;
	gboolean _tmp1_;
	gdouble elapsed = 0.0;
	GTimer* _tmp2_;
	gint next = 0;
	gdouble wait = 0.0;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->clock;
	_vala_return_val_if_fail (_tmp0_ != NULL, "clock != null", FALSE);
	_tmp1_ = self->priv->_tainted_by_command_line;
	_vala_return_val_if_fail (!_tmp1_, "!tainted_by_command_line", FALSE);
	_tmp2_ = self->priv->clock;
	elapsed = g_timer_elapsed ((GTimer*) _tmp2_, NULL);
	next = (gint) (elapsed + 1.0);
	wait = ((gdouble) next) - elapsed;
	self->priv->clock_timeout = g_timeout_add_full (G_PRIORITY_DEFAULT, (guint) ((gint) (wait * 1000)), _puzzle_timeout_cb_gsource_func, g_object_ref (self), g_object_unref);
	g_signal_emit (self, puzzle_signals[PUZZLE_TICK_SIGNAL], 0);
	result = FALSE;
	return result;
}

static inline void
puzzle_add_to_history (Puzzle* self,
                       guint8 x0,
                       guint8 y0,
                       guint8 x1,
                       guint8 y1,
                       guint id)
{
	PuzzleInversion* history_entry = NULL;
	PuzzleInversion* _tmp6_;
	PuzzleInversion* _tmp7_;
	guint _tmp8_;
	g_return_if_fail (self != NULL);
	while (TRUE) {
		PuzzleInversion* inversion = NULL;
		GList* _tmp0_;
		gconstpointer _tmp1_;
		PuzzleInversion* _tmp2_;
		PuzzleInversion* _tmp3_;
		guint _tmp4_;
		guint _tmp5_;
		if (!(self->priv->last_move_index > ((guint) 0))) {
			break;
		}
		_tmp0_ = self->priv->reversed_history;
		_tmp1_ = g_list_nth_data (_tmp0_, (guint) 0);
		inversion = (PuzzleInversion*) _tmp1_;
		_tmp2_ = inversion;
		if (_tmp2_ == NULL) {
			g_assert_not_reached ();
		}
		_tmp3_ = inversion;
		self->priv->reversed_history = vala_g_list_remove_full (self->priv->reversed_history, G_TYPE_CHECK_INSTANCE_CAST (_tmp3_, PUZZLE_TYPE_INVERSION, PuzzleInversion), _g_object_unref0_);
		_tmp4_ = self->priv->last_move_index;
		self->priv->last_move_index = _tmp4_ - 1;
		_tmp5_ = self->priv->history_length;
		self->priv->history_length = _tmp5_ - 1;
	}
	_tmp6_ = puzzle_inversion_new (x0, y0, x1, y1, id);
	history_entry = _tmp6_;
	_tmp7_ = _g_object_ref0 (history_entry);
	self->priv->reversed_history = g_list_prepend (self->priv->reversed_history, _tmp7_);
	_tmp8_ = self->priv->history_length;
	self->priv->history_length = _tmp8_ + 1;
	puzzle_set_can_undo (self, TRUE);
	puzzle_set_can_redo (self, FALSE);
	_g_object_unref0 (history_entry);
}

void
puzzle_undo (Puzzle* self)
{
	gboolean _tmp0_;
	GList* inversion_item = NULL;
	GList* _tmp1_;
	GList* _tmp2_;
	GList* _tmp3_;
	PuzzleInversion* inversion = NULL;
	GList* _tmp4_;
	gconstpointer _tmp5_;
	PuzzleInversion* _tmp6_;
	guint move_id = 0U;
	PuzzleInversion* _tmp7_;
	guint _tmp8_;
	guint _tmp9_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_can_undo;
	if (!_tmp0_) {
		return;
	}
	_tmp1_ = self->priv->reversed_history;
	_tmp2_ = g_list_nth (_tmp1_, self->priv->last_move_index);
	inversion_item = _tmp2_;
	_tmp3_ = inversion_item;
	if (_tmp3_ == NULL) {
		g_assert_not_reached ();
	}
	_tmp4_ = inversion_item;
	_tmp5_ = ((GList*) _tmp4_)->data;
	inversion = (PuzzleInversion*) _tmp5_;
	_tmp6_ = inversion;
	if (_tmp6_ == NULL) {
		g_assert_not_reached ();
	}
	_tmp7_ = inversion;
	_tmp8_ = puzzle_inversion_get_id (G_TYPE_CHECK_INSTANCE_CAST (_tmp7_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
	_tmp9_ = _tmp8_;
	move_id = _tmp9_;
	if (move_id == ((guint) 0)) {
		PuzzleInversion* _tmp10_;
		guint8 _tmp11_;
		guint8 _tmp12_;
		PuzzleInversion* _tmp13_;
		guint8 _tmp14_;
		guint8 _tmp15_;
		PuzzleInversion* _tmp16_;
		guint8 _tmp17_;
		guint8 _tmp18_;
		PuzzleInversion* _tmp19_;
		guint8 _tmp20_;
		guint8 _tmp21_;
		_tmp10_ = inversion;
		_tmp11_ = puzzle_inversion_get_x0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp10_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
		_tmp12_ = _tmp11_;
		_tmp13_ = inversion;
		_tmp14_ = puzzle_inversion_get_y0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp13_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
		_tmp15_ = _tmp14_;
		_tmp16_ = inversion;
		_tmp17_ = puzzle_inversion_get_x1 (G_TYPE_CHECK_INSTANCE_CAST (_tmp16_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
		_tmp18_ = _tmp17_;
		_tmp19_ = inversion;
		_tmp20_ = puzzle_inversion_get_y1 (G_TYPE_CHECK_INSTANCE_CAST (_tmp19_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
		_tmp21_ = _tmp20_;
		puzzle_undo_move (self, _tmp12_, _tmp15_, _tmp18_, _tmp21_);
	} else {
		while (TRUE) {
			PuzzleInversion* _tmp22_;
			guint _tmp23_;
			guint _tmp24_;
			PuzzleInversion* _tmp25_;
			guint8 _tmp26_;
			guint8 _tmp27_;
			PuzzleInversion* _tmp28_;
			guint8 _tmp29_;
			guint8 _tmp30_;
			PuzzleInversion* _tmp31_;
			guint8 _tmp32_;
			guint8 _tmp33_;
			PuzzleInversion* _tmp34_;
			guint8 _tmp35_;
			guint8 _tmp36_;
			GList* _tmp37_;
			GList* _tmp38_;
			GList* _tmp39_;
			GList* _tmp40_;
			gconstpointer _tmp41_;
			_tmp22_ = inversion;
			_tmp23_ = puzzle_inversion_get_id (G_TYPE_CHECK_INSTANCE_CAST (_tmp22_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
			_tmp24_ = _tmp23_;
			if (!(move_id == _tmp24_)) {
				break;
			}
			_tmp25_ = inversion;
			_tmp26_ = puzzle_inversion_get_x0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp25_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
			_tmp27_ = _tmp26_;
			_tmp28_ = inversion;
			_tmp29_ = puzzle_inversion_get_y0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp28_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
			_tmp30_ = _tmp29_;
			_tmp31_ = inversion;
			_tmp32_ = puzzle_inversion_get_x1 (G_TYPE_CHECK_INSTANCE_CAST (_tmp31_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
			_tmp33_ = _tmp32_;
			_tmp34_ = inversion;
			_tmp35_ = puzzle_inversion_get_y1 (G_TYPE_CHECK_INSTANCE_CAST (_tmp34_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
			_tmp36_ = _tmp35_;
			puzzle_undo_move (self, _tmp27_, _tmp30_, _tmp33_, _tmp36_);
			_tmp37_ = inversion_item;
			_tmp38_ = ((GList*) _tmp37_)->next;
			inversion_item = _tmp38_;
			_tmp39_ = inversion_item;
			if (_tmp39_ == NULL) {
				break;
			}
			_tmp40_ = inversion_item;
			_tmp41_ = ((GList*) _tmp40_)->data;
			inversion = (PuzzleInversion*) _tmp41_;
		}
	}
	if (self->priv->last_move_index == self->priv->history_length) {
		puzzle_set_can_undo (self, FALSE);
	}
	puzzle_set_can_redo (self, TRUE);
}

static inline void
puzzle_undo_move (Puzzle* self,
                  guint8 x0,
                  guint8 y0,
                  guint8 x1,
                  guint8 y1)
{
	guint _tmp0_;
	g_return_if_fail (self != NULL);
	_puzzle_switch_tiles (self, x0, y0, x1, y1, PUZZLE_animation_duration, TRUE, (guint) 0);
	_tmp0_ = self->priv->last_move_index;
	self->priv->last_move_index = _tmp0_ + 1;
}

void
puzzle_redo (Puzzle* self)
{
	gboolean _tmp0_;
	GList* inversion_item = NULL;
	GList* _tmp1_;
	GList* _tmp2_;
	GList* _tmp3_;
	PuzzleInversion* inversion = NULL;
	GList* _tmp4_;
	gconstpointer _tmp5_;
	PuzzleInversion* _tmp6_;
	guint move_id = 0U;
	PuzzleInversion* _tmp7_;
	guint _tmp8_;
	guint _tmp9_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_can_redo;
	if (!_tmp0_) {
		return;
	}
	_tmp1_ = self->priv->reversed_history;
	_tmp2_ = g_list_nth (_tmp1_, self->priv->last_move_index - 1);
	inversion_item = _tmp2_;
	_tmp3_ = inversion_item;
	if (_tmp3_ == NULL) {
		g_assert_not_reached ();
	}
	_tmp4_ = inversion_item;
	_tmp5_ = ((GList*) _tmp4_)->data;
	inversion = (PuzzleInversion*) _tmp5_;
	_tmp6_ = inversion;
	if (_tmp6_ == NULL) {
		g_assert_not_reached ();
	}
	_tmp7_ = inversion;
	_tmp8_ = puzzle_inversion_get_id (G_TYPE_CHECK_INSTANCE_CAST (_tmp7_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
	_tmp9_ = _tmp8_;
	move_id = _tmp9_;
	if (move_id == ((guint) 0)) {
		PuzzleInversion* _tmp10_;
		guint8 _tmp11_;
		guint8 _tmp12_;
		PuzzleInversion* _tmp13_;
		guint8 _tmp14_;
		guint8 _tmp15_;
		PuzzleInversion* _tmp16_;
		guint8 _tmp17_;
		guint8 _tmp18_;
		PuzzleInversion* _tmp19_;
		guint8 _tmp20_;
		guint8 _tmp21_;
		_tmp10_ = inversion;
		_tmp11_ = puzzle_inversion_get_x0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp10_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
		_tmp12_ = _tmp11_;
		_tmp13_ = inversion;
		_tmp14_ = puzzle_inversion_get_y0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp13_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
		_tmp15_ = _tmp14_;
		_tmp16_ = inversion;
		_tmp17_ = puzzle_inversion_get_x1 (G_TYPE_CHECK_INSTANCE_CAST (_tmp16_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
		_tmp18_ = _tmp17_;
		_tmp19_ = inversion;
		_tmp20_ = puzzle_inversion_get_y1 (G_TYPE_CHECK_INSTANCE_CAST (_tmp19_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
		_tmp21_ = _tmp20_;
		puzzle_redo_move (self, _tmp12_, _tmp15_, _tmp18_, _tmp21_);
	} else {
		while (TRUE) {
			PuzzleInversion* _tmp22_;
			guint _tmp23_;
			guint _tmp24_;
			PuzzleInversion* _tmp25_;
			guint8 _tmp26_;
			guint8 _tmp27_;
			PuzzleInversion* _tmp28_;
			guint8 _tmp29_;
			guint8 _tmp30_;
			PuzzleInversion* _tmp31_;
			guint8 _tmp32_;
			guint8 _tmp33_;
			PuzzleInversion* _tmp34_;
			guint8 _tmp35_;
			guint8 _tmp36_;
			GList* _tmp37_;
			GList* _tmp38_;
			GList* _tmp39_;
			GList* _tmp40_;
			gconstpointer _tmp41_;
			_tmp22_ = inversion;
			_tmp23_ = puzzle_inversion_get_id (G_TYPE_CHECK_INSTANCE_CAST (_tmp22_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
			_tmp24_ = _tmp23_;
			if (!(move_id == _tmp24_)) {
				break;
			}
			_tmp25_ = inversion;
			_tmp26_ = puzzle_inversion_get_x0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp25_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
			_tmp27_ = _tmp26_;
			_tmp28_ = inversion;
			_tmp29_ = puzzle_inversion_get_y0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp28_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
			_tmp30_ = _tmp29_;
			_tmp31_ = inversion;
			_tmp32_ = puzzle_inversion_get_x1 (G_TYPE_CHECK_INSTANCE_CAST (_tmp31_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
			_tmp33_ = _tmp32_;
			_tmp34_ = inversion;
			_tmp35_ = puzzle_inversion_get_y1 (G_TYPE_CHECK_INSTANCE_CAST (_tmp34_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
			_tmp36_ = _tmp35_;
			puzzle_redo_move (self, _tmp27_, _tmp30_, _tmp33_, _tmp36_);
			_tmp37_ = inversion_item;
			_tmp38_ = ((GList*) _tmp37_)->prev;
			inversion_item = _tmp38_;
			_tmp39_ = inversion_item;
			if (_tmp39_ == NULL) {
				break;
			}
			_tmp40_ = inversion_item;
			_tmp41_ = ((GList*) _tmp40_)->data;
			inversion = (PuzzleInversion*) _tmp41_;
		}
	}
	if (self->priv->last_move_index == ((guint) 0)) {
		puzzle_set_can_redo (self, FALSE);
	}
	puzzle_set_can_undo (self, TRUE);
}

static inline void
puzzle_redo_move (Puzzle* self,
                  guint8 x0,
                  guint8 y0,
                  guint8 x1,
                  guint8 y1)
{
	guint _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->last_move_index;
	self->priv->last_move_index = _tmp0_ - 1;
	_puzzle_switch_tiles (self, x0, y0, x1, y1, PUZZLE_animation_duration, TRUE, (guint) 0);
}

void
puzzle_reload (Puzzle* self)
{
	gboolean _tmp0_;
	GList* inversion_item = NULL;
	GList* _tmp1_;
	GList* _tmp2_;
	GList* _tmp3_;
	PuzzleInversion* inversion = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_can_undo;
	if (!_tmp0_) {
		return;
	}
	_tmp1_ = self->priv->reversed_history;
	_tmp2_ = g_list_nth (_tmp1_, self->priv->last_move_index);
	inversion_item = _tmp2_;
	_tmp3_ = inversion_item;
	if (_tmp3_ == NULL) {
		g_assert_not_reached ();
	}
	{
		gboolean _tmp4_ = FALSE;
		_tmp4_ = TRUE;
		while (TRUE) {
			GList* _tmp6_;
			gconstpointer _tmp7_;
			PuzzleInversion* _tmp8_;
			PuzzleInversion* _tmp9_;
			guint8 _tmp10_;
			guint8 _tmp11_;
			PuzzleInversion* _tmp12_;
			guint8 _tmp13_;
			guint8 _tmp14_;
			PuzzleInversion* _tmp15_;
			guint8 _tmp16_;
			guint8 _tmp17_;
			PuzzleInversion* _tmp18_;
			guint8 _tmp19_;
			guint8 _tmp20_;
			GList* _tmp21_;
			GList* _tmp22_;
			if (!_tmp4_) {
				GList* _tmp5_;
				_tmp5_ = inversion_item;
				if (!(_tmp5_ != NULL)) {
					break;
				}
			}
			_tmp4_ = FALSE;
			_tmp6_ = inversion_item;
			_tmp7_ = ((GList*) _tmp6_)->data;
			inversion = (PuzzleInversion*) _tmp7_;
			_tmp8_ = inversion;
			if (_tmp8_ == NULL) {
				g_assert_not_reached ();
			}
			_tmp9_ = inversion;
			_tmp10_ = puzzle_inversion_get_x0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp9_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
			_tmp11_ = _tmp10_;
			_tmp12_ = inversion;
			_tmp13_ = puzzle_inversion_get_y0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp12_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
			_tmp14_ = _tmp13_;
			_tmp15_ = inversion;
			_tmp16_ = puzzle_inversion_get_x1 (G_TYPE_CHECK_INSTANCE_CAST (_tmp15_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
			_tmp17_ = _tmp16_;
			_tmp18_ = inversion;
			_tmp19_ = puzzle_inversion_get_y1 (G_TYPE_CHECK_INSTANCE_CAST (_tmp18_, PUZZLE_TYPE_INVERSION, PuzzleInversion));
			_tmp20_ = _tmp19_;
			puzzle_undo_move (self, _tmp11_, _tmp14_, _tmp17_, _tmp20_);
			_tmp21_ = inversion_item;
			_tmp22_ = ((GList*) _tmp21_)->next;
			inversion_item = _tmp22_;
		}
	}
	puzzle_set_can_undo (self, FALSE);
	puzzle_set_can_redo (self, TRUE);
}

GVariant*
puzzle_to_variant (Puzzle* self,
                   gboolean save_time)
{
	GVariantBuilder* builder = NULL;
	GVariantType* _tmp0_;
	GVariantType* _tmp1_;
	GVariantBuilder* _tmp2_;
	GVariantBuilder* _tmp3_;
	GVariantBuilder* _tmp4_;
	GVariantType* _tmp5_;
	GVariantType* _tmp6_;
	GVariantBuilder* _tmp7_;
	guint8 _tmp8_;
	GVariantBuilder* _tmp9_;
	guint8 _tmp10_;
	GVariantBuilder* _tmp15_;
	GVariantType* _tmp16_;
	GVariantType* _tmp17_;
	GVariantBuilder* _tmp39_;
	GVariantBuilder* _tmp40_;
	GVariantBuilder* _tmp41_;
	GVariantType* _tmp42_;
	GVariantType* _tmp43_;
	GList* entry = NULL;
	GList* _tmp44_;
	GList* _tmp45_;
	GVariantBuilder* _tmp70_;
	GVariantBuilder* _tmp71_;
	GVariantBuilder* _tmp72_;
	GVariant* _tmp73_;
	GVariant* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_variant_type_new ("m(yyda(yyyyyyyy)ua(yyyyu))");
	_tmp1_ = _tmp0_;
	_tmp2_ = g_variant_builder_new (_tmp1_);
	_tmp3_ = _tmp2_;
	_g_variant_type_free0 (_tmp1_);
	builder = _tmp3_;
	_tmp4_ = builder;
	_tmp5_ = g_variant_type_new ("(yyda(yyyyyyyy)ua(yyyyu))");
	_tmp6_ = _tmp5_;
	g_variant_builder_open (_tmp4_, _tmp6_);
	_g_variant_type_free0 (_tmp6_);
	_tmp7_ = builder;
	_tmp8_ = self->priv->_size;
	g_variant_builder_add (_tmp7_, "y", _tmp8_, NULL);
	_tmp9_ = builder;
	_tmp10_ = self->priv->_colors;
	g_variant_builder_add (_tmp9_, "y", _tmp10_, NULL);
	if (save_time) {
		GVariantBuilder* _tmp11_;
		gdouble _tmp12_;
		gdouble _tmp13_;
		_tmp11_ = builder;
		_tmp12_ = puzzle_get_elapsed (self);
		_tmp13_ = _tmp12_;
		g_variant_builder_add (_tmp11_, "d", _tmp13_, NULL);
	} else {
		GVariantBuilder* _tmp14_;
		_tmp14_ = builder;
		g_variant_builder_add (_tmp14_, "d", DBL_MAX, NULL);
	}
	_tmp15_ = builder;
	_tmp16_ = g_variant_type_new ("a(yyyyyyyy)");
	_tmp17_ = _tmp16_;
	g_variant_builder_open (_tmp15_, _tmp17_);
	_g_variant_type_free0 (_tmp17_);
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp18_ = FALSE;
			_tmp18_ = TRUE;
			while (TRUE) {
				guint8 _tmp20_;
				if (!_tmp18_) {
					guint8 _tmp19_;
					_tmp19_ = x;
					x = _tmp19_ + 1;
				}
				_tmp18_ = FALSE;
				_tmp20_ = self->priv->_size;
				if (!(((gint) x) < (_tmp20_ * 2))) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp21_ = FALSE;
						_tmp21_ = TRUE;
						while (TRUE) {
							guint8 _tmp23_;
							Tile* tile = NULL;
							Tile** _tmp24_;
							gint _tmp24__length1;
							gint _tmp24__length2;
							Tile* _tmp25_;
							Tile* _tmp26_;
							Tile* _tmp27_;
							GVariantBuilder* _tmp28_;
							Tile* _tmp29_;
							Tile* _tmp30_;
							Tile* _tmp31_;
							Tile* _tmp32_;
							Tile* _tmp33_;
							guint8 _tmp34_;
							guint8 _tmp35_;
							Tile* _tmp36_;
							guint8 _tmp37_;
							guint8 _tmp38_;
							if (!_tmp21_) {
								guint8 _tmp22_;
								_tmp22_ = y;
								y = _tmp22_ + 1;
							}
							_tmp21_ = FALSE;
							_tmp23_ = self->priv->_size;
							if (!(y < _tmp23_)) {
								break;
							}
							_tmp24_ = self->priv->board;
							_tmp24__length1 = self->priv->board_length1;
							_tmp24__length2 = self->priv->board_length2;
							_tmp25_ = _tmp24_[(x * _tmp24__length2) + y];
							_tmp26_ = _g_object_ref0 (_tmp25_);
							tile = _tmp26_;
							_tmp27_ = tile;
							if (_tmp27_ == NULL) {
								_g_object_unref0 (tile);
								continue;
							}
							_tmp28_ = builder;
							_tmp29_ = tile;
							_tmp30_ = tile;
							_tmp31_ = tile;
							_tmp32_ = tile;
							_tmp33_ = tile;
							_tmp34_ = tile_get_x (G_TYPE_CHECK_INSTANCE_CAST (_tmp33_, TYPE_TILE, Tile));
							_tmp35_ = _tmp34_;
							_tmp36_ = tile;
							_tmp37_ = tile_get_y (G_TYPE_CHECK_INSTANCE_CAST (_tmp36_, TYPE_TILE, Tile));
							_tmp38_ = _tmp37_;
							g_variant_builder_add (_tmp28_, "(yyyyyyyy)", x, y, G_TYPE_CHECK_INSTANCE_CAST (_tmp29_, TYPE_TILE, Tile)->north, G_TYPE_CHECK_INSTANCE_CAST (_tmp30_, TYPE_TILE, Tile)->east, G_TYPE_CHECK_INSTANCE_CAST (_tmp31_, TYPE_TILE, Tile)->south, G_TYPE_CHECK_INSTANCE_CAST (_tmp32_, TYPE_TILE, Tile)->west, _tmp35_, _tmp38_, NULL);
							_g_object_unref0 (tile);
						}
					}
				}
			}
		}
	}
	_tmp39_ = builder;
	g_variant_builder_close (_tmp39_);
	_tmp40_ = builder;
	g_variant_builder_add (_tmp40_, "u", self->priv->history_length - self->priv->last_move_index, NULL);
	_tmp41_ = builder;
	_tmp42_ = g_variant_type_new ("a(yyyyu)");
	_tmp43_ = _tmp42_;
	g_variant_builder_open (_tmp41_, _tmp43_);
	_g_variant_type_free0 (_tmp43_);
	_tmp44_ = self->priv->reversed_history;
	_tmp45_ = g_list_last (_tmp44_);
	entry = _tmp45_;
	while (TRUE) {
		GList* _tmp46_;
		GVariantBuilder* _tmp47_;
		GList* _tmp48_;
		gconstpointer _tmp49_;
		guint8 _tmp50_;
		guint8 _tmp51_;
		GList* _tmp52_;
		gconstpointer _tmp53_;
		guint8 _tmp54_;
		guint8 _tmp55_;
		GList* _tmp56_;
		gconstpointer _tmp57_;
		guint8 _tmp58_;
		guint8 _tmp59_;
		GList* _tmp60_;
		gconstpointer _tmp61_;
		guint8 _tmp62_;
		guint8 _tmp63_;
		GList* _tmp64_;
		gconstpointer _tmp65_;
		guint _tmp66_;
		guint _tmp67_;
		GList* _tmp68_;
		GList* _tmp69_;
		_tmp46_ = entry;
		if (!(_tmp46_ != NULL)) {
			break;
		}
		_tmp47_ = builder;
		_tmp48_ = entry;
		_tmp49_ = ((GList*) _tmp48_)->data;
		_tmp50_ = puzzle_inversion_get_x0 ((PuzzleInversion*) _tmp49_);
		_tmp51_ = _tmp50_;
		_tmp52_ = entry;
		_tmp53_ = ((GList*) _tmp52_)->data;
		_tmp54_ = puzzle_inversion_get_y0 ((PuzzleInversion*) _tmp53_);
		_tmp55_ = _tmp54_;
		_tmp56_ = entry;
		_tmp57_ = ((GList*) _tmp56_)->data;
		_tmp58_ = puzzle_inversion_get_x1 ((PuzzleInversion*) _tmp57_);
		_tmp59_ = _tmp58_;
		_tmp60_ = entry;
		_tmp61_ = ((GList*) _tmp60_)->data;
		_tmp62_ = puzzle_inversion_get_y1 ((PuzzleInversion*) _tmp61_);
		_tmp63_ = _tmp62_;
		_tmp64_ = entry;
		_tmp65_ = ((GList*) _tmp64_)->data;
		_tmp66_ = puzzle_inversion_get_id ((PuzzleInversion*) _tmp65_);
		_tmp67_ = _tmp66_;
		g_variant_builder_add (_tmp47_, "(yyyyu)", _tmp51_, _tmp55_, _tmp59_, _tmp63_, _tmp67_, NULL);
		_tmp68_ = entry;
		_tmp69_ = ((GList*) _tmp68_)->prev;
		entry = _tmp69_;
	}
	_tmp70_ = builder;
	g_variant_builder_close (_tmp70_);
	_tmp71_ = builder;
	g_variant_builder_close (_tmp71_);
	_tmp72_ = builder;
	_tmp73_ = g_variant_builder_end (_tmp72_);
	g_variant_ref_sink (_tmp73_);
	result = _tmp73_;
	_g_variant_builder_unref0 (builder);
	return result;
}

static gpointer
_puzzle_saved_tile_dup0 (gpointer self)
{
	return self ? puzzle_saved_tile_dup (self) : NULL;
}

gboolean
puzzle_is_valid_saved_game (GVariant* maybe_variant,
                            gboolean restore_finished_game)
{
	GVariant* variant = NULL;
	GVariant* _tmp0_;
	GVariant* _tmp1_;
	guint8 board_size = 0U;
	guint8 colors = 0U;
	gdouble elapsed = 0.0;
	GVariant* _tmp2_;
	guint8 _tmp3_ = 0U;
	GVariant* _tmp4_;
	guint8 _tmp5_ = 0U;
	GVariant* _tmp6_;
	gdouble _tmp7_ = 0.0;
	GVariant* array_variant = NULL;
	GVariant* _tmp8_;
	GVariant* _tmp9_;
	GVariant* _tmp10_;
	PuzzleSavedTile* saved_tiles = NULL;
	PuzzleSavedTile* _tmp11_;
	gint saved_tiles_length1;
	gint _saved_tiles_size_;
	GVariantIter* iter = NULL;
	GVariant* _tmp12_;
	GVariantIter* _tmp13_;
	gboolean _tmp38_ = FALSE;
	gboolean _tmp39_ = FALSE;
	PuzzleSavedTile* _tmp40_;
	gint _tmp40__length1;
	PuzzleSavedTile** initial_board = NULL;
	PuzzleSavedTile** _tmp49_;
	gint initial_board_length1;
	gint initial_board_length2;
	gboolean* current_board = NULL;
	gboolean* _tmp55_;
	gint current_board_length1;
	gint current_board_length2;
	gboolean result;
	g_return_val_if_fail (maybe_variant != NULL, FALSE);
	_tmp0_ = g_variant_get_maybe (maybe_variant);
	variant = _tmp0_;
	_tmp1_ = variant;
	if (_tmp1_ == NULL) {
		result = FALSE;
		_g_variant_unref0 (variant);
		return result;
	}
	_tmp2_ = variant;
	g_variant_get_child ((GVariant*) _tmp2_, (gsize) 0, "y", &_tmp3_, NULL);
	board_size = _tmp3_;
	_tmp4_ = variant;
	g_variant_get_child ((GVariant*) _tmp4_, (gsize) 1, "y", &_tmp5_, NULL);
	colors = _tmp5_;
	_tmp6_ = variant;
	g_variant_get_child ((GVariant*) _tmp6_, (gsize) 2, "d", &_tmp7_, NULL);
	elapsed = _tmp7_;
	_tmp8_ = variant;
	_tmp9_ = g_variant_get_child_value ((GVariant*) _tmp8_, (gsize) 3);
	array_variant = _tmp9_;
	_tmp10_ = array_variant;
	if (g_variant_n_children (_tmp10_) != ((gsize) (board_size * board_size))) {
		result = FALSE;
		_g_variant_unref0 (array_variant);
		_g_variant_unref0 (variant);
		return result;
	}
	_tmp11_ = g_new0 (PuzzleSavedTile, board_size * board_size);
	saved_tiles = _tmp11_;
	saved_tiles_length1 = board_size * board_size;
	_saved_tiles_size_ = saved_tiles_length1;
	_tmp12_ = array_variant;
	_tmp13_ = g_variant_iter_new (_tmp12_);
	iter = _tmp13_;
	{
		guint8 index = 0U;
		index = (guint8) 0;
		{
			gboolean _tmp14_ = FALSE;
			_tmp14_ = TRUE;
			while (TRUE) {
				GVariantIter* _tmp16_;
				GVariant* _tmp17_;
				GVariant* _tmp18_;
				PuzzleSavedTile* _tmp19_;
				gint _tmp19__length1;
				PuzzleSavedTile _tmp20_ = {0};
				GVariant* _tmp21_;
				PuzzleSavedTile* _tmp22_;
				gint _tmp22__length1;
				PuzzleSavedTile* _tmp23_;
				gint _tmp23__length1;
				PuzzleSavedTile* _tmp24_;
				gint _tmp24__length1;
				PuzzleSavedTile* _tmp25_;
				gint _tmp25__length1;
				PuzzleSavedTile* _tmp26_;
				gint _tmp26__length1;
				PuzzleSavedTile* _tmp27_;
				gint _tmp27__length1;
				PuzzleSavedTile* _tmp28_;
				gint _tmp28__length1;
				PuzzleSavedTile* _tmp29_;
				gint _tmp29__length1;
				guint8 _tmp30_ = 0U;
				guint8 _tmp31_ = 0U;
				guint8 _tmp32_ = 0U;
				guint8 _tmp33_ = 0U;
				guint8 _tmp34_ = 0U;
				guint8 _tmp35_ = 0U;
				guint8 _tmp36_ = 0U;
				guint8 _tmp37_ = 0U;
				if (!_tmp14_) {
					guint8 _tmp15_;
					_tmp15_ = index;
					index = _tmp15_ + 1;
				}
				_tmp14_ = FALSE;
				if (!(index < (board_size * board_size))) {
					break;
				}
				_tmp16_ = iter;
				_tmp17_ = g_variant_iter_next_value ((GVariantIter*) _tmp16_);
				_g_variant_unref0 (variant);
				variant = _tmp17_;
				_tmp18_ = variant;
				if (_tmp18_ == NULL) {
					g_assert_not_reached ();
				}
				_tmp19_ = saved_tiles;
				_tmp19__length1 = saved_tiles_length1;
				memset (&_tmp20_, 0, sizeof (PuzzleSavedTile));
				_tmp19_[index] = _tmp20_;
				_tmp21_ = variant;
				_tmp22_ = saved_tiles;
				_tmp22__length1 = saved_tiles_length1;
				_tmp23_ = saved_tiles;
				_tmp23__length1 = saved_tiles_length1;
				_tmp24_ = saved_tiles;
				_tmp24__length1 = saved_tiles_length1;
				_tmp25_ = saved_tiles;
				_tmp25__length1 = saved_tiles_length1;
				_tmp26_ = saved_tiles;
				_tmp26__length1 = saved_tiles_length1;
				_tmp27_ = saved_tiles;
				_tmp27__length1 = saved_tiles_length1;
				_tmp28_ = saved_tiles;
				_tmp28__length1 = saved_tiles_length1;
				_tmp29_ = saved_tiles;
				_tmp29__length1 = saved_tiles_length1;
				g_variant_get ((GVariant*) _tmp21_, "(yyyyyyyy)", &_tmp30_, &_tmp31_, &_tmp32_, &_tmp33_, &_tmp34_, &_tmp35_, &_tmp36_, &_tmp37_, NULL);
				_tmp22_[index].current_x = _tmp30_;
				_tmp23_[index].current_y = _tmp31_;
				_tmp24_[index].color_north = _tmp32_;
				_tmp25_[index].color_east = _tmp33_;
				_tmp26_[index].color_south = _tmp34_;
				_tmp27_[index].color_west = _tmp35_;
				_tmp28_[index].initial_x = _tmp36_;
				_tmp29_[index].initial_y = _tmp37_;
			}
		}
	}
	if (((gint) board_size) < 2) {
		_tmp38_ = TRUE;
	} else {
		_tmp38_ = ((gint) board_size) > 6;
	}
	if (_tmp38_) {
		result = FALSE;
		_g_variant_iter_free0 (iter);
		saved_tiles = (g_free (saved_tiles), NULL);
		_g_variant_unref0 (array_variant);
		_g_variant_unref0 (variant);
		return result;
	}
	if (((gint) colors) < 2) {
		_tmp39_ = TRUE;
	} else {
		_tmp39_ = ((gint) colors) > 10;
	}
	if (_tmp39_) {
		result = FALSE;
		_g_variant_iter_free0 (iter);
		saved_tiles = (g_free (saved_tiles), NULL);
		_g_variant_unref0 (array_variant);
		_g_variant_unref0 (variant);
		return result;
	}
	_tmp40_ = saved_tiles;
	_tmp40__length1 = saved_tiles_length1;
	{
		PuzzleSavedTile* tile_collection = NULL;
		gint tile_collection_length1 = 0;
		gint _tile_collection_size_ = 0;
		gint tile_it = 0;
		tile_collection = _tmp40_;
		tile_collection_length1 = _tmp40__length1;
		for (tile_it = 0; tile_it < tile_collection_length1; tile_it = tile_it + 1) {
			PuzzleSavedTile tile = {0};
			tile = tile_collection[tile_it];
			{
				PuzzleSavedTile _tmp41_;
				PuzzleSavedTile _tmp42_;
				PuzzleSavedTile _tmp43_;
				PuzzleSavedTile _tmp44_;
				PuzzleSavedTile _tmp45_;
				PuzzleSavedTile _tmp46_;
				PuzzleSavedTile _tmp47_;
				PuzzleSavedTile _tmp48_;
				_tmp41_ = tile;
				if (_tmp41_.initial_x >= board_size) {
					result = FALSE;
					_g_variant_iter_free0 (iter);
					saved_tiles = (g_free (saved_tiles), NULL);
					_g_variant_unref0 (array_variant);
					_g_variant_unref0 (variant);
					return result;
				}
				_tmp42_ = tile;
				if (_tmp42_.initial_y >= board_size) {
					result = FALSE;
					_g_variant_iter_free0 (iter);
					saved_tiles = (g_free (saved_tiles), NULL);
					_g_variant_unref0 (array_variant);
					_g_variant_unref0 (variant);
					return result;
				}
				_tmp43_ = tile;
				if (((gint) _tmp43_.current_x) >= (2 * board_size)) {
					result = FALSE;
					_g_variant_iter_free0 (iter);
					saved_tiles = (g_free (saved_tiles), NULL);
					_g_variant_unref0 (array_variant);
					_g_variant_unref0 (variant);
					return result;
				}
				_tmp44_ = tile;
				if (_tmp44_.current_y >= board_size) {
					result = FALSE;
					_g_variant_iter_free0 (iter);
					saved_tiles = (g_free (saved_tiles), NULL);
					_g_variant_unref0 (array_variant);
					_g_variant_unref0 (variant);
					return result;
				}
				_tmp45_ = tile;
				if (_tmp45_.color_north >= colors) {
					result = FALSE;
					_g_variant_iter_free0 (iter);
					saved_tiles = (g_free (saved_tiles), NULL);
					_g_variant_unref0 (array_variant);
					_g_variant_unref0 (variant);
					return result;
				}
				_tmp46_ = tile;
				if (_tmp46_.color_east >= colors) {
					result = FALSE;
					_g_variant_iter_free0 (iter);
					saved_tiles = (g_free (saved_tiles), NULL);
					_g_variant_unref0 (array_variant);
					_g_variant_unref0 (variant);
					return result;
				}
				_tmp47_ = tile;
				if (_tmp47_.color_south >= colors) {
					result = FALSE;
					_g_variant_iter_free0 (iter);
					saved_tiles = (g_free (saved_tiles), NULL);
					_g_variant_unref0 (array_variant);
					_g_variant_unref0 (variant);
					return result;
				}
				_tmp48_ = tile;
				if (_tmp48_.color_west >= colors) {
					result = FALSE;
					_g_variant_iter_free0 (iter);
					saved_tiles = (g_free (saved_tiles), NULL);
					_g_variant_unref0 (array_variant);
					_g_variant_unref0 (variant);
					return result;
				}
			}
		}
	}
	_tmp49_ = g_new0 (PuzzleSavedTile*, board_size * board_size);
	initial_board = _tmp49_;
	initial_board_length1 = board_size;
	initial_board_length2 = board_size;
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp50_ = FALSE;
			_tmp50_ = TRUE;
			while (TRUE) {
				if (!_tmp50_) {
					guint8 _tmp51_;
					_tmp51_ = x;
					x = _tmp51_ + 1;
				}
				_tmp50_ = FALSE;
				if (!(x < board_size)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp52_ = FALSE;
						_tmp52_ = TRUE;
						while (TRUE) {
							PuzzleSavedTile** _tmp54_;
							gint _tmp54__length1;
							gint _tmp54__length2;
							if (!_tmp52_) {
								guint8 _tmp53_;
								_tmp53_ = y;
								y = _tmp53_ + 1;
							}
							_tmp52_ = FALSE;
							if (!(y < board_size)) {
								break;
							}
							_tmp54_ = initial_board;
							_tmp54__length1 = initial_board_length1;
							_tmp54__length2 = initial_board_length2;
							_puzzle_saved_tile_free0 (_tmp54_[(x * _tmp54__length2) + y]);
							_tmp54_[(x * _tmp54__length2) + y] = NULL;
						}
					}
				}
			}
		}
	}
	_tmp55_ = g_new0 (gboolean, (board_size * 2) * board_size);
	current_board = _tmp55_;
	current_board_length1 = board_size * 2;
	current_board_length2 = board_size;
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp56_ = FALSE;
			_tmp56_ = TRUE;
			while (TRUE) {
				if (!_tmp56_) {
					guint8 _tmp57_;
					_tmp57_ = x;
					x = _tmp57_ + 1;
				}
				_tmp56_ = FALSE;
				if (!(((gint) x) < (board_size * 2))) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp58_ = FALSE;
						_tmp58_ = TRUE;
						while (TRUE) {
							gboolean* _tmp60_;
							gint _tmp60__length1;
							gint _tmp60__length2;
							if (!_tmp58_) {
								guint8 _tmp59_;
								_tmp59_ = y;
								y = _tmp59_ + 1;
							}
							_tmp58_ = FALSE;
							if (!(y < board_size)) {
								break;
							}
							_tmp60_ = current_board;
							_tmp60__length1 = current_board_length1;
							_tmp60__length2 = current_board_length2;
							_tmp60_[(x * _tmp60__length2) + y] = FALSE;
						}
					}
				}
			}
		}
	}
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp61_ = FALSE;
			_tmp61_ = TRUE;
			while (TRUE) {
				PuzzleSavedTile tile = {0};
				PuzzleSavedTile* _tmp63_;
				gint _tmp63__length1;
				PuzzleSavedTile _tmp64_;
				PuzzleSavedTile** _tmp65_;
				gint _tmp65__length1;
				gint _tmp65__length2;
				PuzzleSavedTile _tmp66_;
				PuzzleSavedTile _tmp67_;
				PuzzleSavedTile* _tmp68_;
				gboolean* _tmp69_;
				gint _tmp69__length1;
				gint _tmp69__length2;
				PuzzleSavedTile _tmp70_;
				PuzzleSavedTile _tmp71_;
				gboolean _tmp72_;
				PuzzleSavedTile** _tmp73_;
				gint _tmp73__length1;
				gint _tmp73__length2;
				PuzzleSavedTile _tmp74_;
				PuzzleSavedTile _tmp75_;
				PuzzleSavedTile _tmp76_;
				PuzzleSavedTile* _tmp77_;
				gboolean* _tmp78_;
				gint _tmp78__length1;
				gint _tmp78__length2;
				PuzzleSavedTile _tmp79_;
				PuzzleSavedTile _tmp80_;
				if (!_tmp61_) {
					guint8 _tmp62_;
					_tmp62_ = x;
					x = _tmp62_ + 1;
				}
				_tmp61_ = FALSE;
				if (!(x < (board_size * board_size))) {
					break;
				}
				_tmp63_ = saved_tiles;
				_tmp63__length1 = saved_tiles_length1;
				_tmp64_ = _tmp63_[x];
				tile = _tmp64_;
				_tmp65_ = initial_board;
				_tmp65__length1 = initial_board_length1;
				_tmp65__length2 = initial_board_length2;
				_tmp66_ = tile;
				_tmp67_ = tile;
				_tmp68_ = _tmp65_[(_tmp66_.initial_x * _tmp65__length2) + _tmp67_.initial_y];
				if (_tmp68_ != NULL) {
					result = FALSE;
					current_board = (g_free (current_board), NULL);
					initial_board = (_vala_array_free (initial_board, initial_board_length1 * initial_board_length2, (GDestroyNotify) puzzle_saved_tile_free), NULL);
					_g_variant_iter_free0 (iter);
					saved_tiles = (g_free (saved_tiles), NULL);
					_g_variant_unref0 (array_variant);
					_g_variant_unref0 (variant);
					return result;
				}
				_tmp69_ = current_board;
				_tmp69__length1 = current_board_length1;
				_tmp69__length2 = current_board_length2;
				_tmp70_ = tile;
				_tmp71_ = tile;
				_tmp72_ = _tmp69_[(_tmp70_.current_x * _tmp69__length2) + _tmp71_.current_y];
				if (_tmp72_ == TRUE) {
					result = FALSE;
					current_board = (g_free (current_board), NULL);
					initial_board = (_vala_array_free (initial_board, initial_board_length1 * initial_board_length2, (GDestroyNotify) puzzle_saved_tile_free), NULL);
					_g_variant_iter_free0 (iter);
					saved_tiles = (g_free (saved_tiles), NULL);
					_g_variant_unref0 (array_variant);
					_g_variant_unref0 (variant);
					return result;
				}
				_tmp73_ = initial_board;
				_tmp73__length1 = initial_board_length1;
				_tmp73__length2 = initial_board_length2;
				_tmp74_ = tile;
				_tmp75_ = tile;
				_tmp76_ = tile;
				_tmp77_ = _puzzle_saved_tile_dup0 (&_tmp76_);
				_puzzle_saved_tile_free0 (_tmp73_[(_tmp74_.initial_x * _tmp73__length2) + _tmp75_.initial_y]);
				_tmp73_[(_tmp74_.initial_x * _tmp73__length2) + _tmp75_.initial_y] = _tmp77_;
				_tmp78_ = current_board;
				_tmp78__length1 = current_board_length1;
				_tmp78__length2 = current_board_length2;
				_tmp79_ = tile;
				_tmp80_ = tile;
				_tmp78_[(_tmp79_.current_x * _tmp78__length2) + _tmp80_.current_y] = TRUE;
			}
		}
	}
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp81_ = FALSE;
			_tmp81_ = TRUE;
			while (TRUE) {
				if (!_tmp81_) {
					guint8 _tmp82_;
					_tmp82_ = x;
					x = _tmp82_ + 1;
				}
				_tmp81_ = FALSE;
				if (!(x < board_size)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp83_ = FALSE;
						_tmp83_ = TRUE;
						while (TRUE) {
							PuzzleSavedTile* x_y = NULL;
							PuzzleSavedTile** _tmp85_;
							gint _tmp85__length1;
							gint _tmp85__length2;
							PuzzleSavedTile* _tmp86_;
							PuzzleSavedTile* _tmp87_;
							PuzzleSavedTile* x_yplus1 = NULL;
							PuzzleSavedTile** _tmp88_;
							gint _tmp88__length1;
							gint _tmp88__length2;
							PuzzleSavedTile* _tmp89_;
							PuzzleSavedTile* _tmp90_;
							PuzzleSavedTile* y_x = NULL;
							PuzzleSavedTile** _tmp91_;
							gint _tmp91__length1;
							gint _tmp91__length2;
							PuzzleSavedTile* _tmp92_;
							PuzzleSavedTile* _tmp93_;
							PuzzleSavedTile* yplus1_x = NULL;
							PuzzleSavedTile** _tmp94_;
							gint _tmp94__length1;
							gint _tmp94__length2;
							PuzzleSavedTile* _tmp95_;
							PuzzleSavedTile* _tmp96_;
							PuzzleSavedTile* _tmp97_;
							PuzzleSavedTile* _tmp98_;
							PuzzleSavedTile* _tmp99_;
							PuzzleSavedTile* _tmp100_;
							PuzzleSavedTile* _tmp101_;
							PuzzleSavedTile* _tmp102_;
							PuzzleSavedTile* _tmp103_;
							PuzzleSavedTile* _tmp104_;
							if (!_tmp83_) {
								guint8 _tmp84_;
								_tmp84_ = y;
								y = _tmp84_ + 1;
							}
							_tmp83_ = FALSE;
							if (!(((gint) y) < (board_size - 1))) {
								break;
							}
							_tmp85_ = initial_board;
							_tmp85__length1 = initial_board_length1;
							_tmp85__length2 = initial_board_length2;
							_tmp86_ = _tmp85_[(x * _tmp85__length2) + y];
							_tmp87_ = _puzzle_saved_tile_dup0 (_tmp86_);
							x_y = _tmp87_;
							_tmp88_ = initial_board;
							_tmp88__length1 = initial_board_length1;
							_tmp88__length2 = initial_board_length2;
							_tmp89_ = _tmp88_[(x * _tmp88__length2) + (y + 1)];
							_tmp90_ = _puzzle_saved_tile_dup0 (_tmp89_);
							x_yplus1 = _tmp90_;
							_tmp91_ = initial_board;
							_tmp91__length1 = initial_board_length1;
							_tmp91__length2 = initial_board_length2;
							_tmp92_ = _tmp91_[(y * _tmp91__length2) + x];
							_tmp93_ = _puzzle_saved_tile_dup0 (_tmp92_);
							y_x = _tmp93_;
							_tmp94_ = initial_board;
							_tmp94__length1 = initial_board_length1;
							_tmp94__length2 = initial_board_length2;
							_tmp95_ = _tmp94_[((y + 1) * _tmp94__length2) + x];
							_tmp96_ = _puzzle_saved_tile_dup0 (_tmp95_);
							yplus1_x = _tmp96_;
							_tmp97_ = x_y;
							_vala_assert (_tmp97_ != NULL, "x_y != null");
							_tmp98_ = x_yplus1;
							_vala_assert (_tmp98_ != NULL, "x_yplus1 != null");
							_tmp99_ = y_x;
							_vala_assert (_tmp99_ != NULL, "y_x != null");
							_tmp100_ = yplus1_x;
							_vala_assert (_tmp100_ != NULL, "yplus1_x != null");
							_tmp101_ = x_y;
							_tmp102_ = x_yplus1;
							if (((PuzzleSavedTile) (*_tmp101_)).color_south != ((PuzzleSavedTile) (*_tmp102_)).color_north) {
								result = FALSE;
								_puzzle_saved_tile_free0 (yplus1_x);
								_puzzle_saved_tile_free0 (y_x);
								_puzzle_saved_tile_free0 (x_yplus1);
								_puzzle_saved_tile_free0 (x_y);
								current_board = (g_free (current_board), NULL);
								initial_board = (_vala_array_free (initial_board, initial_board_length1 * initial_board_length2, (GDestroyNotify) puzzle_saved_tile_free), NULL);
								_g_variant_iter_free0 (iter);
								saved_tiles = (g_free (saved_tiles), NULL);
								_g_variant_unref0 (array_variant);
								_g_variant_unref0 (variant);
								return result;
							}
							_tmp103_ = y_x;
							_tmp104_ = yplus1_x;
							if (((PuzzleSavedTile) (*_tmp103_)).color_east != ((PuzzleSavedTile) (*_tmp104_)).color_west) {
								result = FALSE;
								_puzzle_saved_tile_free0 (yplus1_x);
								_puzzle_saved_tile_free0 (y_x);
								_puzzle_saved_tile_free0 (x_yplus1);
								_puzzle_saved_tile_free0 (x_y);
								current_board = (g_free (current_board), NULL);
								initial_board = (_vala_array_free (initial_board, initial_board_length1 * initial_board_length2, (GDestroyNotify) puzzle_saved_tile_free), NULL);
								_g_variant_iter_free0 (iter);
								saved_tiles = (g_free (saved_tiles), NULL);
								_g_variant_unref0 (array_variant);
								_g_variant_unref0 (variant);
								return result;
							}
							_puzzle_saved_tile_free0 (yplus1_x);
							_puzzle_saved_tile_free0 (y_x);
							_puzzle_saved_tile_free0 (x_yplus1);
							_puzzle_saved_tile_free0 (x_y);
						}
					}
				}
			}
		}
	}
	if (restore_finished_game) {
		result = TRUE;
		current_board = (g_free (current_board), NULL);
		initial_board = (_vala_array_free (initial_board, initial_board_length1 * initial_board_length2, (GDestroyNotify) puzzle_saved_tile_free), NULL);
		_g_variant_iter_free0 (iter);
		saved_tiles = (g_free (saved_tiles), NULL);
		_g_variant_unref0 (array_variant);
		_g_variant_unref0 (variant);
		return result;
	}
	{
		guint8 x = 0U;
		x = board_size;
		{
			gboolean _tmp105_ = FALSE;
			_tmp105_ = TRUE;
			while (TRUE) {
				if (!_tmp105_) {
					guint8 _tmp106_;
					_tmp106_ = x;
					x = _tmp106_ + 1;
				}
				_tmp105_ = FALSE;
				if (!(((gint) x) < (board_size * 2))) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp107_ = FALSE;
						_tmp107_ = TRUE;
						while (TRUE) {
							gboolean* _tmp109_;
							gint _tmp109__length1;
							gint _tmp109__length2;
							gboolean _tmp110_;
							if (!_tmp107_) {
								guint8 _tmp108_;
								_tmp108_ = y;
								y = _tmp108_ + 1;
							}
							_tmp107_ = FALSE;
							if (!(y < board_size)) {
								break;
							}
							_tmp109_ = current_board;
							_tmp109__length1 = current_board_length1;
							_tmp109__length2 = current_board_length2;
							_tmp110_ = _tmp109_[(x * _tmp109__length2) + y];
							if (_tmp110_) {
								result = TRUE;
								current_board = (g_free (current_board), NULL);
								initial_board = (_vala_array_free (initial_board, initial_board_length1 * initial_board_length2, (GDestroyNotify) puzzle_saved_tile_free), NULL);
								_g_variant_iter_free0 (iter);
								saved_tiles = (g_free (saved_tiles), NULL);
								_g_variant_unref0 (array_variant);
								_g_variant_unref0 (variant);
								return result;
							}
						}
					}
				}
			}
		}
	}
	result = FALSE;
	current_board = (g_free (current_board), NULL);
	initial_board = (_vala_array_free (initial_board, initial_board_length1 * initial_board_length2, (GDestroyNotify) puzzle_saved_tile_free), NULL);
	_g_variant_iter_free0 (iter);
	saved_tiles = (g_free (saved_tiles), NULL);
	_g_variant_unref0 (array_variant);
	_g_variant_unref0 (variant);
	return result;
}

Puzzle*
puzzle_construct_restore (GType object_type,
                          GVariant* maybe_variant)
{
	Puzzle * self = NULL;
	GVariant* variant = NULL;
	GVariant* _tmp0_;
	GVariant* _tmp1_;
	guint8 _size = 0U;
	guint8 _colors = 0U;
	gdouble _elapsed = 0.0;
	GVariant* _tmp2_;
	guint8 _tmp3_ = 0U;
	GVariant* _tmp4_;
	guint8 _tmp5_ = 0U;
	GVariant* _tmp6_;
	gdouble _tmp7_ = 0.0;
	GVariant* array_variant = NULL;
	GVariant* _tmp8_;
	GVariant* _tmp9_;
	guint8 _tmp10_;
	guint8 _tmp11_;
	Tile** _tmp12_;
	GVariantIter* iter = NULL;
	GVariant* _tmp20_;
	GVariantIter* _tmp21_;
	g_return_val_if_fail (maybe_variant != NULL, NULL);
	_tmp0_ = g_variant_get_maybe (maybe_variant);
	variant = _tmp0_;
	_tmp1_ = variant;
	if (_tmp1_ == NULL) {
		g_assert_not_reached ();
	}
	_tmp2_ = variant;
	g_variant_get_child ((GVariant*) _tmp2_, (gsize) 0, "y", &_tmp3_, NULL);
	_size = _tmp3_;
	_tmp4_ = variant;
	g_variant_get_child ((GVariant*) _tmp4_, (gsize) 1, "y", &_tmp5_, NULL);
	_colors = _tmp5_;
	_tmp6_ = variant;
	g_variant_get_child ((GVariant*) _tmp6_, (gsize) 2, "d", &_tmp7_, NULL);
	_elapsed = _tmp7_;
	self = (Puzzle*) g_object_new (object_type, "size", _size, "colors", _colors, "restored", TRUE, "initial-time", _elapsed, "tainted-by-command-line", _elapsed == DBL_MAX, NULL);
	_tmp8_ = variant;
	_tmp9_ = g_variant_get_child_value ((GVariant*) _tmp8_, (gsize) 3);
	array_variant = _tmp9_;
	_tmp10_ = self->priv->_size;
	_tmp11_ = self->priv->_size;
	_tmp12_ = g_new0 (Tile*, ((_tmp10_ * 2) * _tmp11_) + 1);
	self->priv->board = (_vala_array_free (self->priv->board, self->priv->board_length1 * self->priv->board_length2, (GDestroyNotify) g_object_unref), NULL);
	self->priv->board = _tmp12_;
	self->priv->board_length1 = _tmp10_ * 2;
	self->priv->board_length2 = _tmp11_;
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp13_ = FALSE;
			_tmp13_ = TRUE;
			while (TRUE) {
				guint8 _tmp15_;
				if (!_tmp13_) {
					guint8 _tmp14_;
					_tmp14_ = x;
					x = _tmp14_ + 1;
				}
				_tmp13_ = FALSE;
				_tmp15_ = self->priv->_size;
				if (!(((gint) x) < (_tmp15_ * 2))) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp16_ = FALSE;
						_tmp16_ = TRUE;
						while (TRUE) {
							guint8 _tmp18_;
							Tile** _tmp19_;
							gint _tmp19__length1;
							gint _tmp19__length2;
							if (!_tmp16_) {
								guint8 _tmp17_;
								_tmp17_ = y;
								y = _tmp17_ + 1;
							}
							_tmp16_ = FALSE;
							_tmp18_ = self->priv->_size;
							if (!(y < _tmp18_)) {
								break;
							}
							_tmp19_ = self->priv->board;
							_tmp19__length1 = self->priv->board_length1;
							_tmp19__length2 = self->priv->board_length2;
							_g_object_unref0 (_tmp19_[(x * _tmp19__length2) + y]);
							_tmp19_[(x * _tmp19__length2) + y] = NULL;
						}
					}
				}
			}
		}
	}
	_tmp20_ = array_variant;
	_tmp21_ = g_variant_iter_new (_tmp20_);
	iter = _tmp21_;
	{
		guint8 index = 0U;
		index = (guint8) 0;
		{
			gboolean _tmp22_ = FALSE;
			_tmp22_ = TRUE;
			while (TRUE) {
				guint8 _tmp24_;
				guint8 _tmp25_;
				GVariantIter* _tmp26_;
				GVariant* _tmp27_;
				GVariant* _tmp28_;
				guint8 current_x = 0U;
				guint8 current_y = 0U;
				guint8 color_north = 0U;
				guint8 color_east = 0U;
				guint8 color_south = 0U;
				guint8 color_west = 0U;
				guint8 initial_x = 0U;
				guint8 initial_y = 0U;
				GVariant* _tmp29_;
				guint8 _tmp30_ = 0U;
				guint8 _tmp31_ = 0U;
				guint8 _tmp32_ = 0U;
				guint8 _tmp33_ = 0U;
				guint8 _tmp34_ = 0U;
				guint8 _tmp35_ = 0U;
				guint8 _tmp36_ = 0U;
				guint8 _tmp37_ = 0U;
				Tile* tile = NULL;
				Tile* _tmp38_;
				Tile* _tmp39_;
				Tile* _tmp40_;
				Tile* _tmp41_;
				Tile* _tmp42_;
				Tile** _tmp43_;
				gint _tmp43__length1;
				gint _tmp43__length2;
				Tile* _tmp44_;
				Tile* _tmp45_;
				if (!_tmp22_) {
					guint8 _tmp23_;
					_tmp23_ = index;
					index = _tmp23_ + 1;
				}
				_tmp22_ = FALSE;
				_tmp24_ = self->priv->_size;
				_tmp25_ = self->priv->_size;
				if (!(index < (_tmp24_ * _tmp25_))) {
					break;
				}
				_tmp26_ = iter;
				_tmp27_ = g_variant_iter_next_value ((GVariantIter*) _tmp26_);
				_g_variant_unref0 (variant);
				variant = _tmp27_;
				_tmp28_ = variant;
				if (_tmp28_ == NULL) {
					g_assert_not_reached ();
				}
				_tmp29_ = variant;
				g_variant_get ((GVariant*) _tmp29_, "(yyyyyyyy)", &_tmp30_, &_tmp31_, &_tmp32_, &_tmp33_, &_tmp34_, &_tmp35_, &_tmp36_, &_tmp37_, NULL);
				current_x = _tmp30_;
				current_y = _tmp31_;
				color_north = _tmp32_;
				color_east = _tmp33_;
				color_south = _tmp34_;
				color_west = _tmp35_;
				initial_x = _tmp36_;
				initial_y = _tmp37_;
				_tmp38_ = tile_new (initial_x, initial_y);
				tile = _tmp38_;
				_tmp39_ = tile;
				_tmp39_->north = color_north;
				_tmp40_ = tile;
				_tmp40_->east = color_east;
				_tmp41_ = tile;
				_tmp41_->south = color_south;
				_tmp42_ = tile;
				_tmp42_->west = color_west;
				_tmp43_ = self->priv->board;
				_tmp43__length1 = self->priv->board_length1;
				_tmp43__length2 = self->priv->board_length2;
				_tmp44_ = tile;
				_tmp45_ = _g_object_ref0 (_tmp44_);
				_g_object_unref0 (_tmp43_[(current_x * _tmp43__length2) + current_y]);
				_tmp43_[(current_x * _tmp43__length2) + current_y] = _tmp45_;
				_g_object_unref0 (tile);
			}
		}
	}
	puzzle_set_game_in_progress (self, TRUE);
	if (puzzle_solved_on_right (self)) {
		puzzle_set_is_solved_right (self, TRUE);
	}
	puzzle_check_if_solved (self);
	_g_variant_iter_free0 (iter);
	_g_variant_unref0 (array_variant);
	_g_variant_unref0 (variant);
	return self;
}

Puzzle*
puzzle_new_restore (GVariant* maybe_variant)
{
	return puzzle_construct_restore (TYPE_PUZZLE, maybe_variant);
}

guint8
puzzle_get_size (Puzzle* self)
{
	guint8 result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_size;
	return result;
}

static void
puzzle_set_size (Puzzle* self,
                 guint8 value)
{
	g_return_if_fail (self != NULL);
	self->priv->_size = value;
}

guint8
puzzle_get_colors (Puzzle* self)
{
	guint8 result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_colors;
	return result;
}

static void
puzzle_set_colors (Puzzle* self,
                   guint8 value)
{
	g_return_if_fail (self != NULL);
	self->priv->_colors = value;
}

static gdouble
puzzle_get_initial_time (Puzzle* self)
{
	gdouble result;
	g_return_val_if_fail (self != NULL, 0.0);
	result = self->priv->_initial_time;
	return result;
}

static void
puzzle_set_initial_time (Puzzle* self,
                         gdouble value)
{
	g_return_if_fail (self != NULL);
	self->priv->_initial_time = value;
}

gboolean
puzzle_get_tainted_by_command_line (Puzzle* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_tainted_by_command_line;
	return result;
}

static void
puzzle_set_tainted_by_command_line (Puzzle* self,
                                    gboolean value)
{
	g_return_if_fail (self != NULL);
	self->priv->_tainted_by_command_line = value;
}

gdouble
puzzle_get_elapsed (Puzzle* self)
{
	gdouble result;
	gboolean _tmp0_;
	GTimer* _tmp1_;
	gdouble _tmp2_;
	GTimer* _tmp3_;
	g_return_val_if_fail (self != NULL, 0.0);
	_tmp0_ = self->priv->_tainted_by_command_line;
	if (_tmp0_) {
		g_assert_not_reached ();
	}
	_tmp1_ = self->priv->clock;
	if (_tmp1_ == NULL) {
		result = 0.0;
		return result;
	}
	_tmp2_ = self->priv->_initial_time;
	_tmp3_ = self->priv->clock;
	result = _tmp2_ + g_timer_elapsed ((GTimer*) _tmp3_, NULL);
	return result;
}

gboolean
puzzle_get_paused (Puzzle* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_paused;
	return result;
}

void
puzzle_set_paused (Puzzle* self,
                   gboolean value)
{
	GTimer* _tmp0_;
	g_return_if_fail (self != NULL);
	self->priv->_paused = value;
	_tmp0_ = self->priv->clock;
	if (_tmp0_ != NULL) {
		if (value) {
			puzzle_stop_clock (self);
		} else {
			puzzle_continue_clock (self);
		}
	}
	g_object_notify_by_pspec ((GObject *) self, puzzle_properties[PUZZLE_PAUSED_PROPERTY]);
}

gboolean
puzzle_get_is_solved (Puzzle* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_is_solved;
	return result;
}

static void
puzzle_set_is_solved (Puzzle* self,
                      gboolean value)
{
	g_return_if_fail (self != NULL);
	self->priv->_is_solved = value;
}

static gboolean
puzzle_get_restored (Puzzle* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_restored;
	return result;
}

static void
puzzle_set_restored (Puzzle* self,
                     gboolean value)
{
	g_return_if_fail (self != NULL);
	self->priv->_restored = value;
}

gboolean
puzzle_get_game_in_progress (Puzzle* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_game_in_progress;
	return result;
}

static void
puzzle_set_game_in_progress (Puzzle* self,
                             gboolean value)
{
	g_return_if_fail (self != NULL);
	self->priv->_game_in_progress = value;
}

gboolean
puzzle_get_is_solved_right (Puzzle* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_is_solved_right;
	return result;
}

static void
puzzle_set_is_solved_right (Puzzle* self,
                            gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = puzzle_get_is_solved_right (self);
	if (old_value != value) {
		self->priv->_is_solved_right = value;
		g_object_notify_by_pspec ((GObject *) self, puzzle_properties[PUZZLE_IS_SOLVED_RIGHT_PROPERTY]);
	}
}

gboolean
puzzle_get_can_undo (Puzzle* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_can_undo;
	return result;
}

static void
puzzle_set_can_undo (Puzzle* self,
                     gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = puzzle_get_can_undo (self);
	if (old_value != value) {
		self->priv->_can_undo = value;
		g_object_notify_by_pspec ((GObject *) self, puzzle_properties[PUZZLE_CAN_UNDO_PROPERTY]);
	}
}

gboolean
puzzle_get_can_redo (Puzzle* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_can_redo;
	return result;
}

static void
puzzle_set_can_redo (Puzzle* self,
                     gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = puzzle_get_can_redo (self);
	if (old_value != value) {
		self->priv->_can_redo = value;
		g_object_notify_by_pspec ((GObject *) self, puzzle_properties[PUZZLE_CAN_REDO_PROPERTY]);
	}
}

static void
g_cclosure_user_marshal_VOID__OBJECT_UCHAR_UCHAR (GClosure * closure,
                                                  GValue * return_value,
                                                  guint n_param_values,
                                                  const GValue * param_values,
                                                  gpointer invocation_hint,
                                                  gpointer marshal_data)
{
	typedef void (*GMarshalFunc_VOID__OBJECT_UCHAR_UCHAR) (gpointer data1, gpointer arg_1, guint8 arg_2, guint8 arg_3, gpointer data2);
	register GMarshalFunc_VOID__OBJECT_UCHAR_UCHAR callback;
	register GCClosure * cc;
	register gpointer data1;
	register gpointer data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 4);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__OBJECT_UCHAR_UCHAR) (marshal_data ? marshal_data : cc->callback);
	callback (data1, g_value_get_object (param_values + 1), g_value_get_uchar (param_values + 2), g_value_get_uchar (param_values + 3), data2);
}

static inline gpointer
puzzle_inversion_get_instance_private (PuzzleInversion* self)
{
	return G_STRUCT_MEMBER_P (self, PuzzleInversion_private_offset);
}

static PuzzleInversion*
puzzle_inversion_construct (GType object_type,
                            guint8 x0,
                            guint8 y0,
                            guint8 x1,
                            guint8 y1,
                            guint id)
{
	PuzzleInversion * self = NULL;
	self = (PuzzleInversion*) g_object_new (object_type, "x0", x0, "y0", y0, "x1", x1, "y1", y1, "id", id, NULL);
	return self;
}

static PuzzleInversion*
puzzle_inversion_new (guint8 x0,
                      guint8 y0,
                      guint8 x1,
                      guint8 y1,
                      guint id)
{
	return puzzle_inversion_construct (PUZZLE_TYPE_INVERSION, x0, y0, x1, y1, id);
}

static guint8
puzzle_inversion_get_x0 (PuzzleInversion* self)
{
	guint8 result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_x0;
	return result;
}

static void
puzzle_inversion_set_x0 (PuzzleInversion* self,
                         guint8 value)
{
	g_return_if_fail (self != NULL);
	self->priv->_x0 = value;
}

static guint8
puzzle_inversion_get_y0 (PuzzleInversion* self)
{
	guint8 result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_y0;
	return result;
}

static void
puzzle_inversion_set_y0 (PuzzleInversion* self,
                         guint8 value)
{
	g_return_if_fail (self != NULL);
	self->priv->_y0 = value;
}

static guint8
puzzle_inversion_get_x1 (PuzzleInversion* self)
{
	guint8 result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_x1;
	return result;
}

static void
puzzle_inversion_set_x1 (PuzzleInversion* self,
                         guint8 value)
{
	g_return_if_fail (self != NULL);
	self->priv->_x1 = value;
}

static guint8
puzzle_inversion_get_y1 (PuzzleInversion* self)
{
	guint8 result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_y1;
	return result;
}

static void
puzzle_inversion_set_y1 (PuzzleInversion* self,
                         guint8 value)
{
	g_return_if_fail (self != NULL);
	self->priv->_y1 = value;
}

static guint
puzzle_inversion_get_id (PuzzleInversion* self)
{
	guint result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_id;
	return result;
}

static void
puzzle_inversion_set_id (PuzzleInversion* self,
                         guint value)
{
	g_return_if_fail (self != NULL);
	self->priv->_id = value;
}

static void
puzzle_inversion_class_init (PuzzleInversionClass * klass,
                             gpointer klass_data)
{
	puzzle_inversion_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &PuzzleInversion_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_puzzle_inversion_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_puzzle_inversion_set_property;
	G_OBJECT_CLASS (klass)->finalize = puzzle_inversion_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), PUZZLE_INVERSION_X0_PROPERTY, puzzle_inversion_properties[PUZZLE_INVERSION_X0_PROPERTY] = g_param_spec_uchar ("x0", "x0", "x0", 0, G_MAXUINT8, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), PUZZLE_INVERSION_Y0_PROPERTY, puzzle_inversion_properties[PUZZLE_INVERSION_Y0_PROPERTY] = g_param_spec_uchar ("y0", "y0", "y0", 0, G_MAXUINT8, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), PUZZLE_INVERSION_X1_PROPERTY, puzzle_inversion_properties[PUZZLE_INVERSION_X1_PROPERTY] = g_param_spec_uchar ("x1", "x1", "x1", 0, G_MAXUINT8, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), PUZZLE_INVERSION_Y1_PROPERTY, puzzle_inversion_properties[PUZZLE_INVERSION_Y1_PROPERTY] = g_param_spec_uchar ("y1", "y1", "y1", 0, G_MAXUINT8, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), PUZZLE_INVERSION_ID_PROPERTY, puzzle_inversion_properties[PUZZLE_INVERSION_ID_PROPERTY] = g_param_spec_uint ("id", "id", "id", 0, G_MAXUINT, 0U, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY));
}

static void
puzzle_inversion_instance_init (PuzzleInversion * self,
                                gpointer klass)
{
	self->priv = puzzle_inversion_get_instance_private (self);
}

static void
puzzle_inversion_finalize (GObject * obj)
{
	PuzzleInversion * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, PUZZLE_TYPE_INVERSION, PuzzleInversion);
	G_OBJECT_CLASS (puzzle_inversion_parent_class)->finalize (obj);
}

static GType
puzzle_inversion_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (PuzzleInversionClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) puzzle_inversion_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (PuzzleInversion), 0, (GInstanceInitFunc) puzzle_inversion_instance_init, NULL };
	GType puzzle_inversion_type_id;
	puzzle_inversion_type_id = g_type_register_static (G_TYPE_OBJECT, "PuzzleInversion", &g_define_type_info, 0);
	PuzzleInversion_private_offset = g_type_add_instance_private (puzzle_inversion_type_id, sizeof (PuzzleInversionPrivate));
	return puzzle_inversion_type_id;
}

static GType
puzzle_inversion_get_type (void)
{
	static volatile gsize puzzle_inversion_type_id__once = 0;
	if (g_once_init_enter (&puzzle_inversion_type_id__once)) {
		GType puzzle_inversion_type_id;
		puzzle_inversion_type_id = puzzle_inversion_get_type_once ();
		g_once_init_leave (&puzzle_inversion_type_id__once, puzzle_inversion_type_id);
	}
	return puzzle_inversion_type_id__once;
}

static void
_vala_puzzle_inversion_get_property (GObject * object,
                                     guint property_id,
                                     GValue * value,
                                     GParamSpec * pspec)
{
	PuzzleInversion * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, PUZZLE_TYPE_INVERSION, PuzzleInversion);
	switch (property_id) {
		case PUZZLE_INVERSION_X0_PROPERTY:
		g_value_set_uchar (value, puzzle_inversion_get_x0 (self));
		break;
		case PUZZLE_INVERSION_Y0_PROPERTY:
		g_value_set_uchar (value, puzzle_inversion_get_y0 (self));
		break;
		case PUZZLE_INVERSION_X1_PROPERTY:
		g_value_set_uchar (value, puzzle_inversion_get_x1 (self));
		break;
		case PUZZLE_INVERSION_Y1_PROPERTY:
		g_value_set_uchar (value, puzzle_inversion_get_y1 (self));
		break;
		case PUZZLE_INVERSION_ID_PROPERTY:
		g_value_set_uint (value, puzzle_inversion_get_id (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_puzzle_inversion_set_property (GObject * object,
                                     guint property_id,
                                     const GValue * value,
                                     GParamSpec * pspec)
{
	PuzzleInversion * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, PUZZLE_TYPE_INVERSION, PuzzleInversion);
	switch (property_id) {
		case PUZZLE_INVERSION_X0_PROPERTY:
		puzzle_inversion_set_x0 (self, g_value_get_uchar (value));
		break;
		case PUZZLE_INVERSION_Y0_PROPERTY:
		puzzle_inversion_set_y0 (self, g_value_get_uchar (value));
		break;
		case PUZZLE_INVERSION_X1_PROPERTY:
		puzzle_inversion_set_x1 (self, g_value_get_uchar (value));
		break;
		case PUZZLE_INVERSION_Y1_PROPERTY:
		puzzle_inversion_set_y1 (self, g_value_get_uchar (value));
		break;
		case PUZZLE_INVERSION_ID_PROPERTY:
		puzzle_inversion_set_id (self, g_value_get_uint (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static PuzzleSavedTile*
puzzle_saved_tile_dup (const PuzzleSavedTile* self)
{
	PuzzleSavedTile* dup;
	dup = g_new0 (PuzzleSavedTile, 1);
	memcpy (dup, self, sizeof (PuzzleSavedTile));
	return dup;
}

static void
puzzle_saved_tile_free (PuzzleSavedTile* self)
{
	g_free (self);
}

static GType
puzzle_saved_tile_get_type_once (void)
{
	GType puzzle_saved_tile_type_id;
	puzzle_saved_tile_type_id = g_boxed_type_register_static ("PuzzleSavedTile", (GBoxedCopyFunc) puzzle_saved_tile_dup, (GBoxedFreeFunc) puzzle_saved_tile_free);
	return puzzle_saved_tile_type_id;
}

static GType
puzzle_saved_tile_get_type (void)
{
	static volatile gsize puzzle_saved_tile_type_id__once = 0;
	if (g_once_init_enter (&puzzle_saved_tile_type_id__once)) {
		GType puzzle_saved_tile_type_id;
		puzzle_saved_tile_type_id = puzzle_saved_tile_get_type_once ();
		g_once_init_leave (&puzzle_saved_tile_type_id__once, puzzle_saved_tile_type_id);
	}
	return puzzle_saved_tile_type_id__once;
}

static GObject *
puzzle_constructor (GType type,
                    guint n_construct_properties,
                    GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	Puzzle * self;
	gboolean _tmp0_;
	parent_class = G_OBJECT_CLASS (puzzle_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_PUZZLE, Puzzle);
	_tmp0_ = self->priv->_restored;
	if (!_tmp0_) {
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				guint8 _tmp2_;
				guint8 _tmp3_;
				Tile** _tmp4_ = NULL;
				gint _tmp5_ = 0;
				gint _tmp6_ = 0;
				if (!_tmp1_) {
					if (!puzzle_solved_on_right (self)) {
						break;
					}
				}
				_tmp1_ = FALSE;
				_tmp2_ = self->priv->_size;
				_tmp3_ = self->priv->_colors;
				puzzle_init_board (_tmp2_, (gint32) _tmp3_, &_tmp4_, &_tmp5_, &_tmp6_);
				self->priv->board = (_vala_array_free (self->priv->board, self->priv->board_length1 * self->priv->board_length2, (GDestroyNotify) g_object_unref), NULL);
				self->priv->board = _tmp4_;
				self->priv->board_length1 = _tmp5_;
				self->priv->board_length2 = _tmp6_;
			}
		}
	}
	puzzle_start_clock (self);
	return obj;
}

static void
puzzle_class_init (PuzzleClass * klass,
                   gpointer klass_data)
{
	puzzle_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &Puzzle_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_puzzle_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_puzzle_set_property;
	G_OBJECT_CLASS (klass)->constructor = puzzle_constructor;
	G_OBJECT_CLASS (klass)->finalize = puzzle_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), PUZZLE_SIZE_PROPERTY, puzzle_properties[PUZZLE_SIZE_PROPERTY] = g_param_spec_uchar ("size", "size", "size", 0, G_MAXUINT8, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), PUZZLE_COLORS_PROPERTY, puzzle_properties[PUZZLE_COLORS_PROPERTY] = g_param_spec_uchar ("colors", "colors", "colors", 0, G_MAXUINT8, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), PUZZLE_INITIAL_TIME_PROPERTY, puzzle_properties[PUZZLE_INITIAL_TIME_PROPERTY] = g_param_spec_double ("initial-time", "initial-time", "initial-time", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), PUZZLE_TAINTED_BY_COMMAND_LINE_PROPERTY, puzzle_properties[PUZZLE_TAINTED_BY_COMMAND_LINE_PROPERTY] = g_param_spec_boolean ("tainted-by-command-line", "tainted-by-command-line", "tainted-by-command-line", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), PUZZLE_ELAPSED_PROPERTY, puzzle_properties[PUZZLE_ELAPSED_PROPERTY] = g_param_spec_double ("elapsed", "elapsed", "elapsed", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), PUZZLE_PAUSED_PROPERTY, puzzle_properties[PUZZLE_PAUSED_PROPERTY] = g_param_spec_boolean ("paused", "paused", "paused", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), PUZZLE_IS_SOLVED_PROPERTY, puzzle_properties[PUZZLE_IS_SOLVED_PROPERTY] = g_param_spec_boolean ("is-solved", "is-solved", "is-solved", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), PUZZLE_RESTORED_PROPERTY, puzzle_properties[PUZZLE_RESTORED_PROPERTY] = g_param_spec_boolean ("restored", "restored", "restored", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), PUZZLE_GAME_IN_PROGRESS_PROPERTY, puzzle_properties[PUZZLE_GAME_IN_PROGRESS_PROPERTY] = g_param_spec_boolean ("game-in-progress", "game-in-progress", "game-in-progress", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), PUZZLE_IS_SOLVED_RIGHT_PROPERTY, puzzle_properties[PUZZLE_IS_SOLVED_RIGHT_PROPERTY] = g_param_spec_boolean ("is-solved-right", "is-solved-right", "is-solved-right", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), PUZZLE_CAN_UNDO_PROPERTY, puzzle_properties[PUZZLE_CAN_UNDO_PROPERTY] = g_param_spec_boolean ("can-undo", "can-undo", "can-undo", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), PUZZLE_CAN_REDO_PROPERTY, puzzle_properties[PUZZLE_CAN_REDO_PROPERTY] = g_param_spec_boolean ("can-redo", "can-redo", "can-redo", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	puzzle_signals[PUZZLE_TILE_MOVED_SIGNAL] = g_signal_new ("tile-moved", TYPE_PUZZLE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__OBJECT_UCHAR_UCHAR, G_TYPE_NONE, 3, TYPE_TILE, G_TYPE_UCHAR, G_TYPE_UCHAR);
	puzzle_signals[PUZZLE_SOLVED_SIGNAL] = g_signal_new ("solved", TYPE_PUZZLE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	puzzle_signals[PUZZLE_SOLVED_RIGHT_SIGNAL] = g_signal_new ("solved-right", TYPE_PUZZLE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
	puzzle_signals[PUZZLE_SHOW_END_GAME_SIGNAL] = g_signal_new ("show-end-game", TYPE_PUZZLE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	puzzle_signals[PUZZLE_TICK_SIGNAL] = g_signal_new ("tick", TYPE_PUZZLE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}

static void
puzzle_instance_init (Puzzle * self,
                      gpointer klass)
{
	self->priv = puzzle_get_instance_private (self);
	self->priv->clock = NULL;
	self->priv->_initial_time = 0.0;
	self->priv->_paused = FALSE;
	self->priv->_is_solved = FALSE;
	self->priv->_restored = FALSE;
	self->priv->timeout_id = (guint) 0;
	self->priv->_game_in_progress = FALSE;
	self->priv->_is_solved_right = FALSE;
	self->priv->last_move_id = (guint) 0;
	self->priv->_can_undo = FALSE;
	self->priv->_can_redo = FALSE;
	self->priv->history_length = (guint) 0;
	self->priv->last_move_index = (guint) 0;
	self->priv->reversed_history = NULL;
}

static void
puzzle_finalize (GObject * obj)
{
	Puzzle * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_PUZZLE, Puzzle);
	self->priv->board = (_vala_array_free (self->priv->board, self->priv->board_length1 * self->priv->board_length2, (GDestroyNotify) g_object_unref), NULL);
	_g_timer_destroy0 (self->priv->clock);
	(self->priv->reversed_history == NULL) ? NULL : (self->priv->reversed_history = (_g_list_free__g_object_unref0_ (self->priv->reversed_history), NULL));
	G_OBJECT_CLASS (puzzle_parent_class)->finalize (obj);
}

static GType
puzzle_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (PuzzleClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) puzzle_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Puzzle), 0, (GInstanceInitFunc) puzzle_instance_init, NULL };
	GType puzzle_type_id;
	puzzle_type_id = g_type_register_static (G_TYPE_OBJECT, "Puzzle", &g_define_type_info, 0);
	Puzzle_private_offset = g_type_add_instance_private (puzzle_type_id, sizeof (PuzzlePrivate));
	return puzzle_type_id;
}

GType
puzzle_get_type (void)
{
	static volatile gsize puzzle_type_id__once = 0;
	if (g_once_init_enter (&puzzle_type_id__once)) {
		GType puzzle_type_id;
		puzzle_type_id = puzzle_get_type_once ();
		g_once_init_leave (&puzzle_type_id__once, puzzle_type_id);
	}
	return puzzle_type_id__once;
}

static void
_vala_puzzle_get_property (GObject * object,
                           guint property_id,
                           GValue * value,
                           GParamSpec * pspec)
{
	Puzzle * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_PUZZLE, Puzzle);
	switch (property_id) {
		case PUZZLE_SIZE_PROPERTY:
		g_value_set_uchar (value, puzzle_get_size (self));
		break;
		case PUZZLE_COLORS_PROPERTY:
		g_value_set_uchar (value, puzzle_get_colors (self));
		break;
		case PUZZLE_INITIAL_TIME_PROPERTY:
		g_value_set_double (value, puzzle_get_initial_time (self));
		break;
		case PUZZLE_TAINTED_BY_COMMAND_LINE_PROPERTY:
		g_value_set_boolean (value, puzzle_get_tainted_by_command_line (self));
		break;
		case PUZZLE_ELAPSED_PROPERTY:
		g_value_set_double (value, puzzle_get_elapsed (self));
		break;
		case PUZZLE_PAUSED_PROPERTY:
		g_value_set_boolean (value, puzzle_get_paused (self));
		break;
		case PUZZLE_IS_SOLVED_PROPERTY:
		g_value_set_boolean (value, puzzle_get_is_solved (self));
		break;
		case PUZZLE_RESTORED_PROPERTY:
		g_value_set_boolean (value, puzzle_get_restored (self));
		break;
		case PUZZLE_GAME_IN_PROGRESS_PROPERTY:
		g_value_set_boolean (value, puzzle_get_game_in_progress (self));
		break;
		case PUZZLE_IS_SOLVED_RIGHT_PROPERTY:
		g_value_set_boolean (value, puzzle_get_is_solved_right (self));
		break;
		case PUZZLE_CAN_UNDO_PROPERTY:
		g_value_set_boolean (value, puzzle_get_can_undo (self));
		break;
		case PUZZLE_CAN_REDO_PROPERTY:
		g_value_set_boolean (value, puzzle_get_can_redo (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_puzzle_set_property (GObject * object,
                           guint property_id,
                           const GValue * value,
                           GParamSpec * pspec)
{
	Puzzle * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_PUZZLE, Puzzle);
	switch (property_id) {
		case PUZZLE_SIZE_PROPERTY:
		puzzle_set_size (self, g_value_get_uchar (value));
		break;
		case PUZZLE_COLORS_PROPERTY:
		puzzle_set_colors (self, g_value_get_uchar (value));
		break;
		case PUZZLE_INITIAL_TIME_PROPERTY:
		puzzle_set_initial_time (self, g_value_get_double (value));
		break;
		case PUZZLE_TAINTED_BY_COMMAND_LINE_PROPERTY:
		puzzle_set_tainted_by_command_line (self, g_value_get_boolean (value));
		break;
		case PUZZLE_PAUSED_PROPERTY:
		puzzle_set_paused (self, g_value_get_boolean (value));
		break;
		case PUZZLE_IS_SOLVED_PROPERTY:
		puzzle_set_is_solved (self, g_value_get_boolean (value));
		break;
		case PUZZLE_RESTORED_PROPERTY:
		puzzle_set_restored (self, g_value_get_boolean (value));
		break;
		case PUZZLE_GAME_IN_PROGRESS_PROPERTY:
		puzzle_set_game_in_progress (self, g_value_get_boolean (value));
		break;
		case PUZZLE_IS_SOLVED_RIGHT_PROPERTY:
		puzzle_set_is_solved_right (self, g_value_get_boolean (value));
		break;
		case PUZZLE_CAN_UNDO_PROPERTY:
		puzzle_set_can_undo (self, g_value_get_boolean (value));
		break;
		case PUZZLE_CAN_REDO_PROPERTY:
		puzzle_set_can_redo (self, g_value_get_boolean (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static GType
direction_get_type_once (void)
{
	static const GEnumValue values[] = {{DIRECTION_NONE, "DIRECTION_NONE", "none"}, {DIRECTION_UP, "DIRECTION_UP", "up"}, {DIRECTION_DOWN, "DIRECTION_DOWN", "down"}, {DIRECTION_LEFT, "DIRECTION_LEFT", "left"}, {DIRECTION_RIGHT, "DIRECTION_RIGHT", "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);
}

