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

/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * Gnome Nibbles: Gnome Worm Game
 * Copyright (C) 2015 Iulian-Gabriel Radu <iulian.radu67@gmail.com>
 * Copyright (C) 2022-25 Ben Corby <bcorby@new-ms.com>
 *
 * This program 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 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
/*
 * Coding style.
 *
 * To help you comply with the coding style in this project use the
 * following greps. Any lines returned should be adjusted so they
 * don't match. The convoluted regular expressions are so they don't
 * match them self.
 *
 * grep -ne '[^][)(_!$ "](' *.vala
 * grep -ne '[(] ' *.vala
 * grep -ne '[ ])' *.vala
 * grep -ne ' $' *.vala
 *
 */

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

#define WORM_MAP_bits ((guint8) (sizeof (guint64) * 8))
#define ANGLE_step_multiplier_2n 38
#define ANGLE_step_multiplier 274877906944LL
#define NIBBLES_GAME_EMPTYCHAR 'a'
#define DOUBLE_BIT_ARRAY_BITS_MASK ((gulong) 0x3)
#define DOUBLE_BIT_ARRAY_size (sizeof (gulong) * 4)
#define WORM_STARTING_LIVES ((guint8) 6)
#define WORM_STARTING_LENGTH ((guint8) 5)
#define WORM_MAX_LIVES ((guint8) 12)
#define WORM_GROW_FACTOR 4
#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

typedef enum  {
	WORM_DIRECTION_NONE,
	WORM_DIRECTION_RIGHT,
	WORM_DIRECTION_EAST = WORM_DIRECTION_RIGHT,
	WORM_DIRECTION_DOWN,
	WORM_DIRECTION_SOUTH = WORM_DIRECTION_DOWN,
	WORM_DIRECTION_LEFT,
	WORM_DIRECTION_WEST = WORM_DIRECTION_LEFT,
	WORM_DIRECTION_UP,
	WORM_DIRECTION_NORTH = WORM_DIRECTION_UP
} WormDirection;

#define TYPE_WORM_DIRECTION (worm_direction_get_type ())

#define TYPE_POSITION (position_get_type ())
typedef struct _Position Position;

#define TYPE_SIGNED_POSITION (signed_position_get_type ())
typedef struct _SignedPosition SignedPosition;

#define TYPE_WORM_MAP (worm_map_get_type ())
#define WORM_MAP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_WORM_MAP, WormMap))
#define WORM_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_WORM_MAP, WormMapClass))
#define IS_WORM_MAP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_WORM_MAP))
#define IS_WORM_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_WORM_MAP))
#define WORM_MAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_WORM_MAP, WormMapClass))

typedef struct _WormMap WormMap;
typedef struct _WormMapClass WormMapClass;
typedef struct _WormMapPrivate WormMapPrivate;
enum  {
	WORM_MAP_0_PROPERTY,
	WORM_MAP_NUM_PROPERTIES
};
static GParamSpec* worm_map_properties[WORM_MAP_NUM_PROPERTIES];

#define TYPE_WORM (worm_get_type ())
#define WORM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_WORM, Worm))
#define WORM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_WORM, WormClass))
#define IS_WORM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_WORM))
#define IS_WORM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_WORM))
#define WORM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_WORM, WormClass))

typedef struct _Worm Worm;
typedef struct _WormClass WormClass;

#define TYPE_WORM_POSITIONS (worm_positions_get_type ())
#define WORM_POSITIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_WORM_POSITIONS, WormPositions))
#define WORM_POSITIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_WORM_POSITIONS, WormPositionsClass))
#define IS_WORM_POSITIONS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_WORM_POSITIONS))
#define IS_WORM_POSITIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_WORM_POSITIONS))
#define WORM_POSITIONS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_WORM_POSITIONS, WormPositionsClass))

typedef struct _WormPositions WormPositions;
typedef struct _WormPositionsClass WormPositionsClass;
typedef struct _WormPrivate WormPrivate;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

#define TYPE_INT128 (int128_get_type ())
typedef struct _int128 int128;

#define TYPE_ANGLE_ITERATOR (angle_iterator_get_type ())
#define ANGLE_ITERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ANGLE_ITERATOR, AngleIterator))
#define ANGLE_ITERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ANGLE_ITERATOR, AngleIteratorClass))
#define IS_ANGLE_ITERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ANGLE_ITERATOR))
#define IS_ANGLE_ITERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_ANGLE_ITERATOR))
#define ANGLE_ITERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_ANGLE_ITERATOR, AngleIteratorClass))

typedef struct _AngleIterator AngleIterator;
typedef struct _AngleIteratorClass AngleIteratorClass;
typedef struct _AngleIteratorPrivate AngleIteratorPrivate;

#define TYPE_ANGLE (angle_get_type ())
typedef struct _Angle Angle;
typedef struct _ParamSpecAngleIterator ParamSpecAngleIterator;
typedef enum  {
	QUARTER_Q0,
	QUARTER_Q1,
	QUARTER_Q2,
	QUARTER_Q3
} Quarter;

#define TYPE_QUARTER (quarter_get_type ())

#define TYPE_SLICE (slice_get_type ())
#define SLICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_SLICE, Slice))
#define SLICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_SLICE, SliceClass))
#define IS_SLICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_SLICE))
#define IS_SLICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_SLICE))
#define SLICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_SLICE, SliceClass))

typedef struct _Slice Slice;
typedef struct _SliceClass SliceClass;
typedef struct _SlicePrivate SlicePrivate;
enum  {
	SLICE_0_PROPERTY,
	SLICE_NUM_PROPERTIES
};
static GParamSpec* slice_properties[SLICE_NUM_PROPERTIES];

#define TYPE_BONUS (bonus_get_type ())
#define BONUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_BONUS, Bonus))
#define BONUS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_BONUS, BonusClass))
#define IS_BONUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_BONUS))
#define IS_BONUS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_BONUS))
#define BONUS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_BONUS, BonusClass))

typedef struct _Bonus Bonus;
typedef struct _BonusClass BonusClass;
#define _angle_iterator_unref0(var) ((var == NULL) ? NULL : (var = (angle_iterator_unref (var), NULL)))

#define TYPE_WORM_PROPERTIES (worm_properties_get_type ())
#define WORM_PROPERTIES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_WORM_PROPERTIES, WormProperties))
#define WORM_PROPERTIES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_WORM_PROPERTIES, WormPropertiesClass))
#define IS_WORM_PROPERTIES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_WORM_PROPERTIES))
#define IS_WORM_PROPERTIES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_WORM_PROPERTIES))
#define WORM_PROPERTIES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_WORM_PROPERTIES, WormPropertiesClass))

typedef struct _WormProperties WormProperties;
typedef struct _WormPropertiesClass WormPropertiesClass;
typedef struct _WormPropertiesPrivate WormPropertiesPrivate;
enum  {
	WORM_PROPERTIES_0_PROPERTY,
	WORM_PROPERTIES_COLOR_PROPERTY,
	WORM_PROPERTIES_UP_PROPERTY,
	WORM_PROPERTIES_DOWN_PROPERTY,
	WORM_PROPERTIES_LEFT_PROPERTY,
	WORM_PROPERTIES_RIGHT_PROPERTY,
	WORM_PROPERTIES_RAW_UP_PROPERTY,
	WORM_PROPERTIES_RAW_DOWN_PROPERTY,
	WORM_PROPERTIES_RAW_LEFT_PROPERTY,
	WORM_PROPERTIES_RAW_RIGHT_PROPERTY,
	WORM_PROPERTIES_NUM_PROPERTIES
};
static GParamSpec* worm_properties_properties[WORM_PROPERTIES_NUM_PROPERTIES];
typedef struct _WormPositionsPrivate WormPositionsPrivate;
enum  {
	WORM_POSITIONS_0_PROPERTY,
	WORM_POSITIONS_NUM_PROPERTIES
};
static GParamSpec* worm_positions_properties[WORM_POSITIONS_NUM_PROPERTIES];

#define TYPE_DOUBLE_BIT_ARRAY (double_bit_array_get_type ())
#define DOUBLE_BIT_ARRAY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_DOUBLE_BIT_ARRAY, DoubleBitArray))
#define DOUBLE_BIT_ARRAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_DOUBLE_BIT_ARRAY, DoubleBitArrayClass))
#define IS_DOUBLE_BIT_ARRAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_DOUBLE_BIT_ARRAY))
#define IS_DOUBLE_BIT_ARRAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_DOUBLE_BIT_ARRAY))
#define DOUBLE_BIT_ARRAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_DOUBLE_BIT_ARRAY, DoubleBitArrayClass))

typedef struct _DoubleBitArray DoubleBitArray;
typedef struct _DoubleBitArrayClass DoubleBitArrayClass;
typedef struct _DoubleBitArrayPrivate DoubleBitArrayPrivate;
typedef struct _ParamSpecDoubleBitArray ParamSpecDoubleBitArray;

#define WORM_TYPE_KEY_QUEUE (worm_key_queue_get_type ())
#define WORM_KEY_QUEUE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), WORM_TYPE_KEY_QUEUE, WormKeyQueue))
#define WORM_KEY_QUEUE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), WORM_TYPE_KEY_QUEUE, WormKeyQueueClass))
#define WORM_IS_KEY_QUEUE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), WORM_TYPE_KEY_QUEUE))
#define WORM_IS_KEY_QUEUE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), WORM_TYPE_KEY_QUEUE))
#define WORM_KEY_QUEUE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), WORM_TYPE_KEY_QUEUE, WormKeyQueueClass))

typedef struct _WormKeyQueue WormKeyQueue;
typedef struct _WormKeyQueueClass WormKeyQueueClass;
typedef GeeList* (*WormGetOtherWormsType) (Worm* _self_, gpointer user_data);
typedef GeeList* (*WormGetBonusesType) (gpointer user_data);
enum  {
	WORM_0_PROPERTY,
	WORM_STARTING_POSITION_PROPERTY,
	WORM_ID_PROPERTY,
	WORM_IS_MATERIALIZED_PROPERTY,
	WORM_LIVES_PROPERTY,
	WORM_CHANGE_PROPERTY,
	WORM_SCORE_PROPERTY,
	WORM_LENGTH_PROPERTY,
	WORM_HEAD_PROPERTY,
	WORM_DIRECTION_PROPERTY,
	WORM_WIDTH_PROPERTY,
	WORM_HEIGHT_PROPERTY,
	WORM_CAPACITY_PROPERTY,
	WORM_NUM_PROPERTIES
};
static GParamSpec* worm_properties[WORM_NUM_PROPERTIES];
#define _double_bit_array_unref0(var) ((var == NULL) ? NULL : (var = (double_bit_array_unref (var), NULL)))
typedef struct _Block8Data Block8Data;
typedef enum  {
	BONUS_ETYPE_REGULAR,
	BONUS_ETYPE_HALF,
	BONUS_ETYPE_DOUBLE,
	BONUS_ETYPE_LIFE,
	BONUS_ETYPE_REVERSE,
	BONUS_ETYPE_WARP
} BonuseType;

#define BONUS_TYPE_ETYPE (bonus_etype_get_type ())
typedef struct _WormKeyQueuePrivate WormKeyQueuePrivate;
enum  {
	WORM_BONUS_FOUND_SIGNAL,
	WORM_NUM_SIGNALS
};
static guint worm_signals[WORM_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 _Position {
	guint8 x;
	guint8 y;
};

struct _SignedPosition {
	gint64 x;
	gint64 y;
	gint64 x_max;
	gint64 y_max;
};

struct _WormMap {
	GObject parent_instance;
	WormMapPrivate * priv;
};

struct _WormMapClass {
	GObjectClass parent_class;
};

struct _WormMapPrivate {
	guint64* map;
	gint map_length1;
	gint map_length2;
};

struct _Worm {
	GObject parent_instance;
	WormPrivate * priv;
	gboolean is_human;
	gint rounds_to_stay_still;
	gboolean is_stopped;
	Position warp_position;
	gboolean warp_bonus;
	WormPositions* list;
};

struct _WormClass {
	GObjectClass parent_class;
};

struct _int128 {
	guint64 hi;
	guint64 lo;
	gboolean negative;
	guint64 remainder;
};

struct _AngleIterator {
	GTypeInstance parent_instance;
	volatile int ref_count;
	AngleIteratorPrivate * priv;
};

struct _AngleIteratorClass {
	GTypeClass parent_class;
	void (*finalize) (AngleIterator *self);
};

struct _Angle {
	gint64 x;
	gint64 y;
	gint64 origin_x;
	gint64 origin_y;
	gint64 x_max;
	gint64 y_max;
};

struct _AngleIteratorPrivate {
	Angle pAngle;
	guint64 index;
};

struct _ParamSpecAngleIterator {
	GParamSpec parent_instance;
};

struct _Slice {
	GObject parent_instance;
	SlicePrivate * priv;
	Angle min;
	Angle max;
};

struct _SliceClass {
	GObjectClass parent_class;
};

struct _SlicePrivate {
	gboolean min_set;
	gboolean max_set;
};

struct _WormProperties {
	GObject parent_instance;
	WormPropertiesPrivate * priv;
};

struct _WormPropertiesClass {
	GObjectClass parent_class;
};

struct _WormPropertiesPrivate {
	gint _color;
	guint _up;
	guint _down;
	guint _left;
	guint _right;
	gint _raw_up;
	gint _raw_down;
	gint _raw_left;
	gint _raw_right;
};

struct _WormPositions {
	GeeLinkedList parent_instance;
	WormPositionsPrivate * priv;
};

struct _WormPositionsClass {
	GeeLinkedListClass parent_class;
};

struct _DoubleBitArray {
	GTypeInstance parent_instance;
	volatile int ref_count;
	DoubleBitArrayPrivate * priv;
};

struct _DoubleBitArrayClass {
	GTypeClass parent_class;
	void (*finalize) (DoubleBitArray *self);
};

struct _DoubleBitArrayPrivate {
	gulong array;
};

struct _ParamSpecDoubleBitArray {
	GParamSpec parent_instance;
};

struct _WormPrivate {
	Position _starting_position;
	gint _id;
	gint rounds_to_stay_dematerialized;
	guint8 _lives;
	gint _change;
	gint _score;
	WormDirection _direction;
	WormDirection starting_direction;
	WormKeyQueue* key_queue;
	GeeArrayList* bonus_eaten;
	WormGetOtherWormsType get_other_worms;
	gpointer get_other_worms_target;
	GDestroyNotify get_other_worms_target_destroy_notify;
	WormGetBonusesType get_bonuses;
	gpointer get_bonuses_target;
	GDestroyNotify get_bonuses_target_destroy_notify;
	guint8 _width;
	guint8 _height;
	gint _capacity;
	gboolean LastUturnA;
};

struct _Block8Data {
	int _ref_count_;
	Worm* self;
	WormGetOtherWormsType cb0;
	gpointer cb0_target;
	WormGetBonusesType cb1;
	gpointer cb1_target;
};

struct _WormKeyQueue {
	DoubleBitArray parent_instance;
	WormKeyQueuePrivate * priv;
};

struct _WormKeyQueueClass {
	DoubleBitArrayClass parent_class;
};

struct _WormKeyQueuePrivate {
	gulong head;
	gulong tail;
};

static gint WormMap_private_offset;
static gpointer worm_map_parent_class = NULL;
static gint AngleIterator_private_offset;
static gpointer angle_iterator_parent_class = NULL;
static gint Slice_private_offset;
static gpointer slice_parent_class = NULL;
static gint WormProperties_private_offset;
static gpointer worm_properties_parent_class = NULL;
static gpointer worm_positions_parent_class = NULL;
static gint DoubleBitArray_private_offset;
static gpointer double_bit_array_parent_class = NULL;
static gint Worm_private_offset;
static gpointer worm_parent_class = NULL;
static guint* worm_deadend_board;
static gint worm_deadend_board_length1;
static gint worm_deadend_board_length2;
static guint* worm_deadend_board = NULL;
static gint worm_deadend_board_length1 = 0;
static gint worm_deadend_board_length2 = 0;
static guint worm_deadend_runnumber;
static guint worm_deadend_runnumber = (guint) 0;
static gint WormKeyQueue_private_offset;
static gpointer worm_key_queue_parent_class = NULL;

VALA_EXTERN GType worm_direction_get_type (void) G_GNUC_CONST ;
VALA_EXTERN WormDirection worm_direction_turn_left (WormDirection self);
VALA_EXTERN WormDirection worm_direction_turn_right (WormDirection self);
VALA_EXTERN WormDirection* worm_direction_get_space_fill_array (WormDirection self,
                                                    gint* result_length1);
VALA_EXTERN WormDirection worm_direction_reverse (WormDirection self);
VALA_EXTERN GType position_get_type (void) G_GNUC_CONST ;
VALA_EXTERN Position* position_dup (const Position* self);
VALA_EXTERN void position_free (Position* self);
VALA_EXTERN void position_move (Position *self,
                    WormDirection direction,
                    guint8 width,
                    guint8 height);
VALA_EXTERN GType signed_position_get_type (void) G_GNUC_CONST ;
VALA_EXTERN SignedPosition* signed_position_dup (const SignedPosition* self);
VALA_EXTERN void signed_position_free (SignedPosition* self);
VALA_EXTERN guint8 signed_position_wrap_x (SignedPosition *self);
VALA_EXTERN guint8 signed_position_wrap_y (SignedPosition *self);
VALA_EXTERN guint16 signed_position_wrap_xy (SignedPosition *self);
VALA_EXTERN GType worm_map_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (WormMap, g_object_unref)
VALA_EXTERN GType worm_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (Worm, g_object_unref)
VALA_EXTERN WormMap* worm_map_new (GeeList* worms,
                       guint8 map_width,
                       guint8 map_height);
VALA_EXTERN WormMap* worm_map_construct (GType object_type,
                             GeeList* worms,
                             guint8 map_width,
                             guint8 map_height);
static void worm_map_add (WormMap* self,
                   GeeList* worms);
VALA_EXTERN gboolean worm_map_contain (WormMap* self,
                           guint16 p);
VALA_EXTERN gboolean worm_map_contain_position (WormMap* self,
                                    Position* p);
VALA_EXTERN GType worm_positions_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (WormPositions, g_object_unref)
VALA_EXTERN gboolean worm_map_contains (WormMap* self,
                            WormPositions* position_list);
VALA_EXTERN gboolean worm_get_is_materialized (Worm* self);
static void worm_map_finalize (GObject * obj);
static GType worm_map_get_type_once (void);
VALA_EXTERN GType int128_get_type (void) G_GNUC_CONST ;
VALA_EXTERN int128* int128_dup (const int128* self);
VALA_EXTERN void int128_free (int128* self);
VALA_EXTERN void int128_left_shift_assign (int128 *self,
                               gint shift);
VALA_EXTERN void int128_left_shift (int128 *self,
                        gint shift,
                        int128* result);
VALA_EXTERN void int128_right_shift_assign (int128 *self,
                                gint shift);
VALA_EXTERN void int128_add_assign (int128 *self,
                        int128* a);
VALA_EXTERN gboolean int128_greater_than (int128 *self,
                              int128* a);
VALA_EXTERN gboolean int128_less_than_or_equal_to (int128 *self,
                                       int128* a);
VALA_EXTERN gboolean int128_less_than (int128 *self,
                           int128* a);
VALA_EXTERN gboolean int128_equal_to (int128 *self,
                          int128* a);
VALA_EXTERN void int128_divide_by (int128 *self,
                       gint64 x,
                       int128* result);
static void int128_minus (int128 *self,
                   int128* a);
static void int128_multiply (int128 *self,
                      guint64 _a,
                      int128* result);
static gboolean int128_is_valid_int64 (int128 *self);
VALA_EXTERN gint64 int128_get_int64 (int128 *self);
VALA_EXTERN void multiply (gint64 _a,
               gint64 _b,
               int128* result);
VALA_EXTERN void multiply_by_2n (gint64 a,
                     gint n,
                     int128* result);
VALA_EXTERN gpointer angle_iterator_ref (gpointer instance);
VALA_EXTERN void angle_iterator_unref (gpointer instance);
VALA_EXTERN GParamSpec* param_spec_angle_iterator (const gchar* name,
                                       const gchar* nick,
                                       const gchar* blurb,
                                       GType object_type,
                                       GParamFlags flags);
VALA_EXTERN void value_set_angle_iterator (GValue* value,
                               gpointer v_object);
VALA_EXTERN void value_take_angle_iterator (GValue* value,
                                gpointer v_object);
VALA_EXTERN gpointer value_get_angle_iterator (const GValue* value);
VALA_EXTERN GType angle_iterator_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (AngleIterator, angle_iterator_unref)
VALA_EXTERN GType angle_get_type (void) G_GNUC_CONST ;
VALA_EXTERN Angle* angle_dup (const Angle* self);
VALA_EXTERN void angle_free (Angle* self);
VALA_EXTERN AngleIterator* angle_iterator_new (Angle* p);
VALA_EXTERN AngleIterator* angle_iterator_construct (GType object_type,
                                         Angle* p);
VALA_EXTERN gboolean angle_iterator_next (AngleIterator* self);
VALA_EXTERN void angle_iterator_get (AngleIterator* self,
                         SignedPosition* result);
VALA_EXTERN void angle_get (Angle *self,
                guint64 i,
                SignedPosition* result);
static void angle_iterator_finalize (AngleIterator * obj);
static GType angle_iterator_get_type_once (void);
VALA_EXTERN GType quarter_get_type (void) G_GNUC_CONST ;
VALA_EXTERN void angle_assign (Angle *self,
                   Angle* o);
VALA_EXTERN gboolean angle_less_than_or_equal_to (Angle *self,
                                      Angle* o);
VALA_EXTERN gboolean angle_greater_than (Angle *self,
                             Angle* o);
static Quarter angle_get_quarter (Angle *self);
VALA_EXTERN gboolean angle_less_than (Angle *self,
                          Angle* o);
VALA_EXTERN gboolean angle_equal_to (Angle *self,
                         Angle* o);
VALA_EXTERN gboolean angle_greater_than_or_equal_to (Angle *self,
                                         Angle* o);
VALA_EXTERN void angle_set_origin (Angle *self,
                       Position* origin);
VALA_EXTERN void angle_set_wrapping (Angle *self,
                         gint x,
                         gint y);
VALA_EXTERN gboolean angle_step_along_x (Angle *self);
static gint64 angle_set_delta_x_sign (Angle *self,
                               gint64 _x);
static gint64 angle_set_delta_y_sign (Angle *self,
                               gint64 _y);
VALA_EXTERN AngleIterator* angle_iterator (Angle *self);
VALA_EXTERN GType slice_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (Slice, g_object_unref)
VALA_EXTERN Slice* slice_new (Slice* copy);
VALA_EXTERN Slice* slice_construct (GType object_type,
                        Slice* copy);
VALA_EXTERN void slice_assign (Slice* self,
                   Slice* o);
VALA_EXTERN void slice_set_direction_view (Slice* self,
                               WormDirection d,
                               gint* board,
                               gint board_length1,
                               gint board_length2);
VALA_EXTERN void slice_add_angle (Slice* self,
                      Angle* a);
VALA_EXTERN void slice_set_from_position (Slice* self,
                              Position* origin,
                              gint64 x,
                              gint64 y,
                              gint size);
VALA_EXTERN void slice_intersection_by_position (Slice* self,
                                     Position* origin,
                                     guint8 _x,
                                     guint8 _y,
                                     gint size);
VALA_EXTERN gboolean slice_is_empty (Slice* self);
VALA_EXTERN GType bonus_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (Bonus, g_object_unref)
static gboolean slice_is_bonus_at (Slice* self,
                            guint8 x,
                            guint8 y,
                            Bonus* b);
VALA_EXTERN guint8 bonus_get_x (Bonus* self);
VALA_EXTERN guint8 bonus_get_y (Bonus* self);
static gboolean slice_is_position_occupied (Slice* self,
                                     Position* p,
                                     gint* board,
                                     gint board_length1,
                                     gint board_length2,
                                     WormMap* worm_map);
VALA_EXTERN gint64 slice_is_visible (Slice* self,
                         Position* origin,
                         gint* board,
                         gint board_length1,
                         gint board_length2,
                         WormMap* worm_map,
                         Bonus* bonus);
static void slice_finalize (GObject * obj);
static GType slice_get_type_once (void);
VALA_EXTERN GType worm_properties_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (WormProperties, g_object_unref)
VALA_EXTERN WormProperties* worm_properties_new (void);
VALA_EXTERN WormProperties* worm_properties_construct (GType object_type);
VALA_EXTERN gint worm_properties_get_color (WormProperties* self);
VALA_EXTERN void worm_properties_set_color (WormProperties* self,
                                gint value);
VALA_EXTERN guint worm_properties_get_up (WormProperties* self);
VALA_EXTERN void worm_properties_set_up (WormProperties* self,
                             guint value);
VALA_EXTERN guint worm_properties_get_down (WormProperties* self);
VALA_EXTERN void worm_properties_set_down (WormProperties* self,
                               guint value);
VALA_EXTERN guint worm_properties_get_left (WormProperties* self);
VALA_EXTERN void worm_properties_set_left (WormProperties* self,
                               guint value);
VALA_EXTERN guint worm_properties_get_right (WormProperties* self);
VALA_EXTERN void worm_properties_set_right (WormProperties* self,
                                guint value);
VALA_EXTERN gint worm_properties_get_raw_up (WormProperties* self);
VALA_EXTERN void worm_properties_set_raw_up (WormProperties* self,
                                 gint value);
VALA_EXTERN gint worm_properties_get_raw_down (WormProperties* self);
VALA_EXTERN void worm_properties_set_raw_down (WormProperties* self,
                                   gint value);
VALA_EXTERN gint worm_properties_get_raw_left (WormProperties* self);
VALA_EXTERN void worm_properties_set_raw_left (WormProperties* self,
                                   gint value);
VALA_EXTERN gint worm_properties_get_raw_right (WormProperties* self);
VALA_EXTERN void worm_properties_set_raw_right (WormProperties* self,
                                    gint value);
static void worm_properties_finalize (GObject * obj);
static GType worm_properties_get_type_once (void);
static void _vala_worm_properties_get_property (GObject * object,
                                         guint property_id,
                                         GValue * value,
                                         GParamSpec * pspec);
static void _vala_worm_properties_set_property (GObject * object,
                                         guint property_id,
                                         const GValue * value,
                                         GParamSpec * pspec);
VALA_EXTERN gboolean worm_positions_append_position (WormPositions* self,
                                         Position* p);
VALA_EXTERN void worm_positions_get_head (WormPositions* self,
                              Position* result);
VALA_EXTERN void worm_positions_set_head (WormPositions* self,
                              Position* p);
VALA_EXTERN gboolean worm_positions_prepend_position (WormPositions* self,
                                          Position* p);
VALA_EXTERN void worm_positions_remove_tail (WormPositions* self,
                                 Position* result);
VALA_EXTERN WormPositions* worm_positions_new (void);
VALA_EXTERN WormPositions* worm_positions_construct (GType object_type);
static GType worm_positions_get_type_once (void);
VALA_EXTERN gpointer double_bit_array_ref (gpointer instance);
VALA_EXTERN void double_bit_array_unref (gpointer instance);
VALA_EXTERN GParamSpec* param_spec_double_bit_array (const gchar* name,
                                         const gchar* nick,
                                         const gchar* blurb,
                                         GType object_type,
                                         GParamFlags flags);
VALA_EXTERN void value_set_double_bit_array (GValue* value,
                                 gpointer v_object);
VALA_EXTERN void value_take_double_bit_array (GValue* value,
                                  gpointer v_object);
VALA_EXTERN gpointer value_get_double_bit_array (const GValue* value);
VALA_EXTERN GType double_bit_array_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DoubleBitArray, double_bit_array_unref)
VALA_EXTERN gulong double_bit_array_get_at (DoubleBitArray* self,
                                gulong index);
VALA_EXTERN void double_bit_array_set_at (DoubleBitArray* self,
                              gulong index,
                              gulong l);
VALA_EXTERN DoubleBitArray* double_bit_array_new (void);
VALA_EXTERN DoubleBitArray* double_bit_array_construct (GType object_type);
static void double_bit_array_finalize (DoubleBitArray * obj);
static GType double_bit_array_get_type_once (void);
static GType worm_key_queue_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (WormKeyQueue, double_bit_array_unref)
static WormKeyQueue* worm_key_queue_new (void);
static WormKeyQueue* worm_key_queue_construct (GType object_type);
VALA_EXTERN Worm* worm_new (gint id,
                guint8 width,
                guint8 height,
                WormGetOtherWormsType cb0,
                gpointer cb0_target,
                WormGetBonusesType cb1,
                gpointer cb1_target);
VALA_EXTERN Worm* worm_construct (GType object_type,
                      gint id,
                      guint8 width,
                      guint8 height,
                      WormGetOtherWormsType cb0,
                      gpointer cb0_target,
                      WormGetBonusesType cb1,
                      gpointer cb1_target);
static Block8Data* block8_data_ref (Block8Data* _data8_);
static void block8_data_unref (void * _userdata_);
static GeeList* __lambda4_ (Block8Data* _data8_,
                     Worm* worm);
static GeeList* ___lambda4__worm_get_other_worms_type (Worm* _self_,
                                                gpointer self);
static GeeList* __lambda5_ (Block8Data* _data8_);
static GeeList* ___lambda5__worm_get_bonuses_type (gpointer self);
VALA_EXTERN void worm_set_start (Worm* self,
                     guint8 x,
                     guint8 y,
                     WormDirection direction);
VALA_EXTERN guint8 worm_get_lives (Worm* self);
static void worm_set_starting_position (Worm* self,
                                 Position * value);
VALA_EXTERN void worm_get_starting_position (Worm* self,
                                 Position * result);
static void worm_set_direction (Worm* self,
                         WormDirection value);
VALA_EXTERN void worm_set_change (Worm* self,
                      gint value);
static void worm_key_queue_clear (WormKeyQueue* self);
VALA_EXTERN void worm_human_move (Worm* self,
                      gint* board,
                      gint board_length1,
                      gint board_length2,
                      GeeLinkedList* worms);
static gboolean worm_key_queue_is_empty (WormKeyQueue* self);
static void worm_dequeue_keypress (Worm* self,
                            gint* board,
                            gint board_length1,
                            gint board_length2,
                            GeeList* worms);
VALA_EXTERN void worm_move_part_1 (Worm* self,
                       gint* board,
                       gint board_length1,
                       gint board_length2);
VALA_EXTERN void worm_get_head (Worm* self,
                    Position * result);
VALA_EXTERN WormDirection worm_get_direction (Worm* self);
static guint8 worm_get_width (Worm* self);
static guint8 worm_get_height (Worm* self);
VALA_EXTERN void worm_move_part_2 (Worm* self,
                       gint* board,
                       gint board_length1,
                       gint board_length2,
                       Position* head_position);
static void worm_set_head (Worm* self,
                    Position * value);
VALA_EXTERN gint worm_get_change (Worm* self);
VALA_EXTERN void worm_remove_bonus_eaten_position (Worm* self,
                                       Position* p);
static void worm_materialize (Worm* self,
                       gint* board,
                       gint board_length1,
                       gint board_length2);
VALA_EXTERN void worm_add_bonus_eaten_position (Worm* self,
                                    guint8 x,
                                    guint8 y);
VALA_EXTERN gboolean worm_was_bonus_eaten_at_this_position (Worm* self,
                                                guint16 position);
VALA_EXTERN void worm_reduce_tail (Worm* self,
                       gint erase_size);
VALA_EXTERN void worm_reverse (Worm* self);
static gboolean worm_does_list_contain_position (WormPositions* position_list,
                                          guint16 position);
VALA_EXTERN gboolean worm_is_position_clear_of_materialized_worms (Worm* self,
                                                       GeeList* worms,
                                                       Position* position);
static gboolean worm_is_board_position_occupied (Position* p,
                                          gint* board,
                                          gint board_length1,
                                          gint board_length2);
VALA_EXTERN gboolean worm_can_move_to (Worm* self,
                           gint* board,
                           gint board_length1,
                           gint board_length2,
                           GeeList* worms,
                           Position* position);
VALA_EXTERN gboolean worm_can_move_to_map (Worm* self,
                               gint* board,
                               gint board_length1,
                               gint board_length2,
                               WormMap* worm_map,
                               Position* position);
VALA_EXTERN gboolean worm_can_move_direction (Worm* self,
                                  gint* board,
                                  gint board_length1,
                                  gint board_length2,
                                  GeeList* worms,
                                  WormDirection direction);
VALA_EXTERN void worm_spawn (Worm* self,
                 gint* board,
                 gint board_length1,
                 gint board_length2);
VALA_EXTERN void worm_get_position_after_direction_move (Worm* self,
                                             Position* origin,
                                             WormDirection direction,
                                             Position* result);
VALA_EXTERN void worm_dematerialize (Worm* self,
                         gint rounds,
                         gint gamedelay);
VALA_EXTERN void worm_add_life (Worm* self);
VALA_EXTERN void worm_set_lives (Worm* self,
                     guint8 value);
static inline void worm_lose_life (Worm* self);
VALA_EXTERN void worm_reset (Worm* self,
                 gint* board,
                 gint board_length1,
                 gint board_length2);
VALA_EXTERN void worm_position_move (Worm* self,
                         Position* result);
static WormDirection worm_uturn (Worm* self,
                          gint* board,
                          gint board_length1,
                          gint board_length2,
                          GeeList* worms,
                          WormDirection direction);
static gint worm_get_raw_key (Worm* self,
                       guint keyval);
VALA_EXTERN gboolean worm_handle_keypress (Worm* self,
                               guint keycode,
                               GeeHashMap* worm_props);
static void worm_queue_keypress (Worm* self,
                          WormDirection dir);
static void worm_key_queue_append (WormKeyQueue* self,
                            WormDirection _direction);
static WormDirection worm_key_queue_remove (WormKeyQueue* self);
static void worm_key_queue_prepend (WormKeyQueue* self,
                             WormDirection _direction);
static gint worm_ai_deadend (gint* board,
                      gint board_length1,
                      gint board_length2,
                      WormMap* worm_map,
                      Position* position,
                      gint length);
static void _vala_array_add9 (Position* * array,
                       gint* length,
                       gint* size,
                       const Position* value);
VALA_EXTERN gint worm_ai_deadend_after (gint* board,
                            gint board_length1,
                            gint board_length2,
                            GeeLinkedList* worms,
                            WormMap* worm_map,
                            Position* old_position,
                            WormDirection direction,
                            gint length);
static inline gboolean worm_ai_too_close (Worm* self,
                            GeeLinkedList* worms,
                            WormDirection direction);
VALA_EXTERN GType bonus_etype_get_type (void) G_GNUC_CONST ;
VALA_EXTERN gboolean worm_ai_is_bonus_more_attractive (Worm* self,
                                           BonuseType b0,
                                           gint64 d0,
                                           BonuseType b1,
                                           gint64 d1);
VALA_EXTERN gboolean worm_ai_can_see_bonus (Worm* self,
                                gint* board,
                                gint board_length1,
                                gint board_length2,
                                Position* origin,
                                Bonus* bonus,
                                WormDirection direction);
VALA_EXTERN gint64 worm_ai_count_distance_to_a_bonus_in_direction (Worm* self,
                                                       gint* board,
                                                       gint board_length1,
                                                       gint board_length2,
                                                       WormMap* worm_map,
                                                       Position* origin,
                                                       WormDirection direction,
                                                       BonuseType* bonus_type);
VALA_EXTERN BonuseType bonus_get_etype (Bonus* self);
VALA_EXTERN void worm_ai_move (Worm* self,
                   gint* board,
                   gint board_length1,
                   gint board_length2,
                   GeeLinkedList* worms);
static gint worm_get_capacity (Worm* self);
VALA_EXTERN gint worm_get_length (Worm* self);
static gboolean _position_equal (const Position * s1,
                          const Position * s2);
VALA_EXTERN gint worm_get_id (Worm* self);
static void worm_set_id (Worm* self,
                  gint value);
VALA_EXTERN gint worm_get_score (Worm* self);
VALA_EXTERN void worm_set_score (Worm* self,
                     gint value);
static void worm_set_width (Worm* self,
                     guint8 value);
static void worm_set_height (Worm* self,
                      guint8 value);
static void worm_set_capacity (Worm* self,
                        gint value);
static WormDirection worm_key_queue_convert_to_direction (WormKeyQueue* self,
                                                   gulong l);
static gulong worm_key_queue_convert_from_direction (WormKeyQueue* self,
                                              WormDirection dir);
static gulong worm_key_queue_peek_tail (WormKeyQueue* self);
static gulong worm_key_queue_peek_head (WormKeyQueue* self);
static gboolean worm_key_queue_is_full (WormKeyQueue* self);
static void worm_key_queue_join_queue (WormKeyQueue* self,
                                gulong d);
static void worm_key_queue_finalize (DoubleBitArray * obj);
static GType worm_key_queue_get_type_once (void);
static GObject * worm_constructor (GType type,
                            guint n_construct_properties,
                            GObjectConstructParam * construct_properties);
static void worm_finalize (GObject * obj);
static GType worm_get_type_once (void);
static void _vala_worm_get_property (GObject * object,
                              guint property_id,
                              GValue * value,
                              GParamSpec * pspec);
static void _vala_worm_set_property (GObject * object,
                              guint property_id,
                              const GValue * value,
                              GParamSpec * pspec);

WormDirection
worm_direction_turn_left (WormDirection self)
{
	WormDirection result;
	switch (self) {
		case WORM_DIRECTION_EAST:
		{
			result = WORM_DIRECTION_NORTH;
			return result;
		}
		case WORM_DIRECTION_NORTH:
		{
			result = WORM_DIRECTION_WEST;
			return result;
		}
		case WORM_DIRECTION_WEST:
		{
			result = WORM_DIRECTION_SOUTH;
			return result;
		}
		case WORM_DIRECTION_SOUTH:
		{
			result = WORM_DIRECTION_EAST;
			return result;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
}

WormDirection
worm_direction_turn_right (WormDirection self)
{
	WormDirection result;
	switch (self) {
		case WORM_DIRECTION_EAST:
		{
			result = WORM_DIRECTION_SOUTH;
			return result;
		}
		case WORM_DIRECTION_SOUTH:
		{
			result = WORM_DIRECTION_WEST;
			return result;
		}
		case WORM_DIRECTION_WEST:
		{
			result = WORM_DIRECTION_NORTH;
			return result;
		}
		case WORM_DIRECTION_NORTH:
		{
			result = WORM_DIRECTION_EAST;
			return result;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
}

WormDirection*
worm_direction_get_space_fill_array (WormDirection self,
                                     gint* result_length1)
{
	WormDirection* result;
	switch (self) {
		case WORM_DIRECTION_WEST:
		{
			WormDirection* _tmp0_;
			WormDirection* _tmp1_;
			gint _tmp1__length1;
			_tmp0_ = g_new0 (WormDirection, 3);
			_tmp0_[0] = WORM_DIRECTION_SOUTH;
			_tmp0_[1] = WORM_DIRECTION_WEST;
			_tmp0_[2] = WORM_DIRECTION_NORTH;
			_tmp1_ = _tmp0_;
			_tmp1__length1 = 3;
			if (result_length1) {
				*result_length1 = _tmp1__length1;
			}
			result = _tmp1_;
			return result;
		}
		case WORM_DIRECTION_NORTH:
		{
			WormDirection* _tmp2_;
			WormDirection* _tmp3_;
			gint _tmp3__length1;
			_tmp2_ = g_new0 (WormDirection, 3);
			_tmp2_[0] = WORM_DIRECTION_EAST;
			_tmp2_[1] = WORM_DIRECTION_WEST;
			_tmp2_[2] = WORM_DIRECTION_NORTH;
			_tmp3_ = _tmp2_;
			_tmp3__length1 = 3;
			if (result_length1) {
				*result_length1 = _tmp3__length1;
			}
			result = _tmp3_;
			return result;
		}
		case WORM_DIRECTION_EAST:
		{
			WormDirection* _tmp4_;
			WormDirection* _tmp5_;
			gint _tmp5__length1;
			_tmp4_ = g_new0 (WormDirection, 3);
			_tmp4_[0] = WORM_DIRECTION_EAST;
			_tmp4_[1] = WORM_DIRECTION_SOUTH;
			_tmp4_[2] = WORM_DIRECTION_NORTH;
			_tmp5_ = _tmp4_;
			_tmp5__length1 = 3;
			if (result_length1) {
				*result_length1 = _tmp5__length1;
			}
			result = _tmp5_;
			return result;
		}
		case WORM_DIRECTION_SOUTH:
		{
			WormDirection* _tmp6_;
			WormDirection* _tmp7_;
			gint _tmp7__length1;
			_tmp6_ = g_new0 (WormDirection, 3);
			_tmp6_[0] = WORM_DIRECTION_EAST;
			_tmp6_[1] = WORM_DIRECTION_SOUTH;
			_tmp6_[2] = WORM_DIRECTION_WEST;
			_tmp7_ = _tmp6_;
			_tmp7__length1 = 3;
			if (result_length1) {
				*result_length1 = _tmp7__length1;
			}
			result = _tmp7_;
			return result;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
}

WormDirection
worm_direction_reverse (WormDirection self)
{
	WormDirection result;
	switch (self) {
		case WORM_DIRECTION_EAST:
		{
			result = WORM_DIRECTION_WEST;
			return result;
		}
		case WORM_DIRECTION_SOUTH:
		{
			result = WORM_DIRECTION_NORTH;
			return result;
		}
		case WORM_DIRECTION_WEST:
		{
			result = WORM_DIRECTION_EAST;
			return result;
		}
		case WORM_DIRECTION_NORTH:
		{
			result = WORM_DIRECTION_SOUTH;
			return result;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
}

 G_GNUC_NO_INLINE static GType
worm_direction_get_type_once (void)
{
	static const GEnumValue values[] = {{WORM_DIRECTION_NONE, "WORM_DIRECTION_NONE", "none"}, {WORM_DIRECTION_RIGHT, "WORM_DIRECTION_RIGHT", "right"}, {WORM_DIRECTION_EAST, "WORM_DIRECTION_EAST", "east"}, {WORM_DIRECTION_DOWN, "WORM_DIRECTION_DOWN", "down"}, {WORM_DIRECTION_SOUTH, "WORM_DIRECTION_SOUTH", "south"}, {WORM_DIRECTION_LEFT, "WORM_DIRECTION_LEFT", "left"}, {WORM_DIRECTION_WEST, "WORM_DIRECTION_WEST", "west"}, {WORM_DIRECTION_UP, "WORM_DIRECTION_UP", "up"}, {WORM_DIRECTION_NORTH, "WORM_DIRECTION_NORTH", "north"}, {0, NULL, NULL}};
	GType worm_direction_type_id;
	worm_direction_type_id = g_enum_register_static ("WormDirection", values);
	return worm_direction_type_id;
}

GType
worm_direction_get_type (void)
{
	static GType worm_direction_type_id__once = 0;
	if (g_once_init_enter_pointer (&worm_direction_type_id__once)) {
		GType worm_direction_type_id;
		worm_direction_type_id = worm_direction_get_type_once ();
		g_once_init_leave_pointer (&worm_direction_type_id__once, worm_direction_type_id);
	}
	return worm_direction_type_id__once;
}

void
position_move (Position *self,
               WormDirection direction,
               guint8 width,
               guint8 height)
{
	switch (direction) {
		case WORM_DIRECTION_NORTH:
		{
			if (((gint) (*self).y) == 0) {
				(*self).y = (guint8) (height - 1);
			} else {
				guint8 _tmp0_;
				_tmp0_ = (*self).y;
				(*self).y = _tmp0_ - 1;
			}
			break;
		}
		case WORM_DIRECTION_SOUTH:
		{
			if (((gint) (*self).y) >= (height - 1)) {
				(*self).y = (guint8) 0;
			} else {
				guint8 _tmp1_;
				_tmp1_ = (*self).y;
				(*self).y = _tmp1_ + 1;
			}
			break;
		}
		case WORM_DIRECTION_WEST:
		{
			if (((gint) (*self).x) == 0) {
				(*self).x = (guint8) (width - 1);
			} else {
				guint8 _tmp2_;
				_tmp2_ = (*self).x;
				(*self).x = _tmp2_ - 1;
			}
			break;
		}
		case WORM_DIRECTION_EAST:
		{
			if (((gint) (*self).x) >= (width - 1)) {
				(*self).x = (guint8) 0;
			} else {
				guint8 _tmp3_;
				_tmp3_ = (*self).x;
				(*self).x = _tmp3_ + 1;
			}
			break;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
}

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

void
position_free (Position* self)
{
	g_free (self);
}

 G_GNUC_NO_INLINE static GType
position_get_type_once (void)
{
	GType position_type_id;
	position_type_id = g_boxed_type_register_static ("Position", (GBoxedCopyFunc) position_dup, (GBoxedFreeFunc) position_free);
	return position_type_id;
}

GType
position_get_type (void)
{
	static GType position_type_id__once = 0;
	if (g_once_init_enter_pointer (&position_type_id__once)) {
		GType position_type_id;
		position_type_id = position_get_type_once ();
		g_once_init_leave_pointer (&position_type_id__once, position_type_id);
	}
	return position_type_id__once;
}

guint8
signed_position_wrap_x (SignedPosition *self)
{
	guint8 result;
	_vala_assert ((*self).x_max > ((gint64) 0), "x_max > 0");
	if ((*self).x > (*self).x_max) {
		result = (guint8) ((*self).x % (*self).x_max);
		return result;
	} else {
		if ((*self).x < ((gint64) 0)) {
			result = (guint8) ((*self).x + (((llabs ((*self).x) / (*self).x_max) + 1) * (*self).x_max));
			return result;
		} else {
			result = (guint8) (*self).x;
			return result;
		}
	}
}

guint8
signed_position_wrap_y (SignedPosition *self)
{
	guint8 result;
	_vala_assert ((*self).y_max > ((gint64) 0), "y_max > 0");
	if ((*self).y > (*self).y_max) {
		result = (guint8) ((*self).y % (*self).y_max);
		return result;
	} else {
		if ((*self).y < ((gint64) 0)) {
			result = (guint8) ((*self).y + (((llabs ((*self).y) / (*self).y_max) + 1) * (*self).y_max));
			return result;
		} else {
			result = (guint8) (*self).y;
			return result;
		}
	}
}

guint16
signed_position_wrap_xy (SignedPosition *self)
{
	guint16 result;
	result = (guint16) ((((guint16) signed_position_wrap_x (&(*self))) << 8) | signed_position_wrap_y (&(*self)));
	return result;
}

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

void
signed_position_free (SignedPosition* self)
{
	g_free (self);
}

 G_GNUC_NO_INLINE static GType
signed_position_get_type_once (void)
{
	GType signed_position_type_id;
	signed_position_type_id = g_boxed_type_register_static ("SignedPosition", (GBoxedCopyFunc) signed_position_dup, (GBoxedFreeFunc) signed_position_free);
	return signed_position_type_id;
}

GType
signed_position_get_type (void)
{
	static GType signed_position_type_id__once = 0;
	if (g_once_init_enter_pointer (&signed_position_type_id__once)) {
		GType signed_position_type_id;
		signed_position_type_id = signed_position_get_type_once ();
		g_once_init_leave_pointer (&signed_position_type_id__once, signed_position_type_id);
	}
	return signed_position_type_id__once;
}

static inline gpointer
worm_map_get_instance_private (WormMap* self)
{
	return G_STRUCT_MEMBER_P (self, WormMap_private_offset);
}

WormMap*
worm_map_construct (GType object_type,
                    GeeList* worms,
                    guint8 map_width,
                    guint8 map_height)
{
	WormMap * self = NULL;
	guint64* _tmp0_;
	g_return_val_if_fail (worms != NULL, NULL);
	self = (WormMap*) g_object_new (object_type, NULL);
	_tmp0_ = g_new0 (guint64, (((map_width - 1) / WORM_MAP_bits) + 1) * map_height);
	self->priv->map = (g_free (self->priv->map), NULL);
	self->priv->map = _tmp0_;
	self->priv->map_length1 = ((map_width - 1) / WORM_MAP_bits) + 1;
	self->priv->map_length2 = map_height;
	worm_map_add (self, worms);
	return self;
}

WormMap*
worm_map_new (GeeList* worms,
              guint8 map_width,
              guint8 map_height)
{
	return worm_map_construct (TYPE_WORM_MAP, worms, map_width, map_height);
}

gboolean
worm_map_contain (WormMap* self,
                  guint16 p)
{
	guint8 quotient = 0U;
	guint8 remainder = 0U;
	guint64* _tmp0_;
	gint _tmp0__length1;
	gint _tmp0__length2;
	guint64 _tmp1_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	quotient = (guint8) ((p >> 8) / WORM_MAP_bits);
	remainder = (guint8) ((p >> 8) % WORM_MAP_bits);
	_tmp0_ = self->priv->map;
	_tmp0__length1 = self->priv->map_length1;
	_tmp0__length2 = self->priv->map_length2;
	_tmp1_ = _tmp0_[(quotient * _tmp0__length2) + ((guint8) p)];
	result = ((_tmp1_ >> remainder) & 1) > ((guint64) 0);
	return result;
}

gboolean
worm_map_contain_position (WormMap* self,
                           Position* p)
{
	Position _tmp0_;
	Position _tmp1_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (p != NULL, FALSE);
	_tmp0_ = *p;
	_tmp1_ = *p;
	result = worm_map_contain (self, (guint16) ((((guint16) _tmp0_.x) << 8) | _tmp1_.y));
	return result;
}

gboolean
worm_map_contains (WormMap* self,
                   WormPositions* position_list)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (position_list != NULL, FALSE);
	{
		WormPositions* _p_list = NULL;
		gint _p_size = 0;
		WormPositions* _tmp0_;
		gint _tmp1_;
		gint _tmp2_;
		gint _p_index = 0;
		_p_list = position_list;
		_tmp0_ = _p_list;
		_tmp1_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp0_);
		_tmp2_ = _tmp1_;
		_p_size = _tmp2_;
		_p_index = -1;
		while (TRUE) {
			gint _tmp3_;
			gint _tmp4_;
			guint16 p = 0U;
			WormPositions* _tmp5_;
			gpointer _tmp6_;
			_p_index = _p_index + 1;
			_tmp3_ = _p_index;
			_tmp4_ = _p_size;
			if (!(_tmp3_ < _tmp4_)) {
				break;
			}
			_tmp5_ = _p_list;
			_tmp6_ = gee_abstract_list_get ((GeeAbstractList*) _tmp5_, _p_index);
			p = (guint16) ((guintptr) _tmp6_);
			if (worm_map_contain (self, p)) {
				result = TRUE;
				return result;
			}
		}
	}
	result = FALSE;
	return result;
}

static void
worm_map_add (WormMap* self,
              GeeList* worms)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (worms != NULL);
	{
		GeeList* _worm_list = NULL;
		gint _worm_size = 0;
		GeeList* _tmp0_;
		gint _tmp1_;
		gint _tmp2_;
		gint _worm_index = 0;
		_worm_list = worms;
		_tmp0_ = _worm_list;
		_tmp1_ = gee_collection_get_size ((GeeCollection*) _tmp0_);
		_tmp2_ = _tmp1_;
		_worm_size = _tmp2_;
		_worm_index = -1;
		while (TRUE) {
			gint _tmp3_;
			gint _tmp4_;
			Worm* worm = NULL;
			GeeList* _tmp5_;
			gpointer _tmp6_;
			gboolean _tmp7_ = FALSE;
			Worm* _tmp8_;
			gboolean _tmp9_;
			gboolean _tmp10_;
			_worm_index = _worm_index + 1;
			_tmp3_ = _worm_index;
			_tmp4_ = _worm_size;
			if (!(_tmp3_ < _tmp4_)) {
				break;
			}
			_tmp5_ = _worm_list;
			_tmp6_ = gee_list_get (_tmp5_, _worm_index);
			worm = (Worm*) _tmp6_;
			_tmp8_ = worm;
			_tmp9_ = worm_get_is_materialized (_tmp8_);
			_tmp10_ = _tmp9_;
			if (_tmp10_) {
				Worm* _tmp11_;
				_tmp11_ = worm;
				_tmp7_ = !_tmp11_->is_stopped;
			} else {
				_tmp7_ = FALSE;
			}
			if (_tmp7_) {
				{
					WormPositions* _p_list = NULL;
					Worm* _tmp12_;
					WormPositions* _tmp13_;
					gint _p_size = 0;
					WormPositions* _tmp14_;
					gint _tmp15_;
					gint _tmp16_;
					gint _p_index = 0;
					_tmp12_ = worm;
					_tmp13_ = _tmp12_->list;
					_p_list = _tmp13_;
					_tmp14_ = _p_list;
					_tmp15_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp14_);
					_tmp16_ = _tmp15_;
					_p_size = _tmp16_;
					_p_index = -1;
					while (TRUE) {
						gint _tmp17_;
						gint _tmp18_;
						guint16 p = 0U;
						WormPositions* _tmp19_;
						gpointer _tmp20_;
						guint8 x = 0U;
						guint8 y = 0U;
						guint64* _tmp21_;
						gint _tmp21__length1;
						gint _tmp21__length2;
						_p_index = _p_index + 1;
						_tmp17_ = _p_index;
						_tmp18_ = _p_size;
						if (!(_tmp17_ < _tmp18_)) {
							break;
						}
						_tmp19_ = _p_list;
						_tmp20_ = gee_abstract_list_get ((GeeAbstractList*) _tmp19_, _p_index);
						p = (guint16) ((guintptr) _tmp20_);
						x = (guint8) (p >> 8);
						y = (guint8) p;
						_tmp21_ = self->priv->map;
						_tmp21__length1 = self->priv->map_length1;
						_tmp21__length2 = self->priv->map_length2;
						_tmp21_[((x / WORM_MAP_bits) * _tmp21__length2) + y] |= ((guint64) 1) << (x % WORM_MAP_bits);
					}
				}
			}
			_g_object_unref0 (worm);
		}
	}
}

static void
worm_map_class_init (WormMapClass * klass,
                     gpointer klass_data)
{
	worm_map_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &WormMap_private_offset);
	G_OBJECT_CLASS (klass)->finalize = worm_map_finalize;
}

static void
worm_map_instance_init (WormMap * self,
                        gpointer klass)
{
	self->priv = worm_map_get_instance_private (self);
}

static void
worm_map_finalize (GObject * obj)
{
	WormMap * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_WORM_MAP, WormMap);
	self->priv->map = (g_free (self->priv->map), NULL);
	G_OBJECT_CLASS (worm_map_parent_class)->finalize (obj);
}

 G_GNUC_NO_INLINE static GType
worm_map_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (WormMapClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) worm_map_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (WormMap), 0, (GInstanceInitFunc) worm_map_instance_init, NULL };
	GType worm_map_type_id;
	worm_map_type_id = g_type_register_static (G_TYPE_OBJECT, "WormMap", &g_define_type_info, G_TYPE_FLAG_NONE);
	WormMap_private_offset = g_type_add_instance_private (worm_map_type_id, sizeof (WormMapPrivate));
	return worm_map_type_id;
}

GType
worm_map_get_type (void)
{
	static GType worm_map_type_id__once = 0;
	if (g_once_init_enter_pointer (&worm_map_type_id__once)) {
		GType worm_map_type_id;
		worm_map_type_id = worm_map_get_type_once ();
		g_once_init_leave_pointer (&worm_map_type_id__once, worm_map_type_id);
	}
	return worm_map_type_id__once;
}

void
int128_left_shift_assign (int128 *self,
                          gint shift)
{
	if (shift >= 64) {
		(*self).hi = (*self).lo;
		(*self).lo = (guint64) 0;
		shift = shift - 64;
	}
	if (shift > 0) {
		(*self).hi = (*self).hi << shift;
		(*self).hi = (*self).hi | ((*self).lo >> (64 - shift));
		(*self).lo = (*self).lo << shift;
	}
}

void
int128_left_shift (int128 *self,
                   gint shift,
                   int128* result)
{
	int128 r = {0};
	int128 _tmp0_ = {0};
	_tmp0_.hi = (*self).hi;
	_tmp0_.lo = (*self).lo;
	_tmp0_.negative = (*self).negative;
	r = _tmp0_;
	int128_left_shift_assign (&r, shift);
	*result = r;
	return;
}

void
int128_right_shift_assign (int128 *self,
                           gint shift)
{
	if (shift >= 64) {
		(*self).lo = (*self).hi;
		(*self).hi = (guint64) 0;
		shift = shift - 64;
	}
	if (shift > 0) {
		(*self).lo = (*self).lo >> shift;
		(*self).lo = (*self).lo | ((*self).hi << (64 - shift));
		(*self).hi = (*self).hi >> shift;
	}
}

void
int128_add_assign (int128 *self,
                   int128* a)
{
	int128 _tmp0_;
	guint64 o = 0ULL;
	int128 _tmp1_;
	g_return_if_fail (a != NULL);
	_tmp0_ = *a;
	(*self).hi = (*self).hi + _tmp0_.hi;
	o = (*self).lo;
	_tmp1_ = *a;
	(*self).lo = (*self).lo + _tmp1_.lo;
	if ((*self).lo < o) {
		(*self).hi = (*self).hi + 1;
	}
}

gboolean
int128_greater_than (int128 *self,
                     int128* a)
{
	gboolean _tmp0_ = FALSE;
	gboolean result;
	g_return_val_if_fail (a != NULL, FALSE);
	if (!(*self).negative) {
		int128 _tmp1_;
		_tmp1_ = *a;
		_tmp0_ = !_tmp1_.negative;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		gboolean _tmp2_ = FALSE;
		int128 _tmp3_;
		_tmp3_ = *a;
		if ((*self).hi > _tmp3_.hi) {
			_tmp2_ = TRUE;
		} else {
			gboolean _tmp4_ = FALSE;
			int128 _tmp5_;
			_tmp5_ = *a;
			if ((*self).hi == _tmp5_.hi) {
				int128 _tmp6_;
				_tmp6_ = *a;
				_tmp4_ = (*self).lo > _tmp6_.lo;
			} else {
				_tmp4_ = FALSE;
			}
			_tmp2_ = _tmp4_;
		}
		result = _tmp2_;
		return result;
	} else {
		gboolean _tmp7_ = FALSE;
		if (!(*self).negative) {
			int128 _tmp8_;
			_tmp8_ = *a;
			_tmp7_ = _tmp8_.negative;
		} else {
			_tmp7_ = FALSE;
		}
		if (_tmp7_) {
			result = TRUE;
			return result;
		} else {
			gboolean _tmp9_ = FALSE;
			if ((*self).negative) {
				int128 _tmp10_;
				_tmp10_ = *a;
				_tmp9_ = !_tmp10_.negative;
			} else {
				_tmp9_ = FALSE;
			}
			if (_tmp9_) {
				result = FALSE;
				return result;
			} else {
				gboolean _tmp11_ = FALSE;
				int128 _tmp12_;
				_tmp12_ = *a;
				if ((*self).hi < _tmp12_.hi) {
					_tmp11_ = TRUE;
				} else {
					gboolean _tmp13_ = FALSE;
					int128 _tmp14_;
					_tmp14_ = *a;
					if ((*self).hi == _tmp14_.hi) {
						int128 _tmp15_;
						_tmp15_ = *a;
						_tmp13_ = (*self).lo < _tmp15_.lo;
					} else {
						_tmp13_ = FALSE;
					}
					_tmp11_ = _tmp13_;
				}
				result = _tmp11_;
				return result;
			}
		}
	}
}

gboolean
int128_less_than_or_equal_to (int128 *self,
                              int128* a)
{
	int128 _tmp0_;
	gboolean result;
	g_return_val_if_fail (a != NULL, FALSE);
	_tmp0_ = *a;
	result = !int128_greater_than (&(*self), &_tmp0_);
	return result;
}

gboolean
int128_less_than (int128 *self,
                  int128* a)
{
	gboolean _tmp0_ = FALSE;
	gboolean result;
	g_return_val_if_fail (a != NULL, FALSE);
	if (!(*self).negative) {
		int128 _tmp1_;
		_tmp1_ = *a;
		_tmp0_ = !_tmp1_.negative;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		gboolean _tmp2_ = FALSE;
		int128 _tmp3_;
		_tmp3_ = *a;
		if ((*self).hi < _tmp3_.hi) {
			_tmp2_ = TRUE;
		} else {
			gboolean _tmp4_ = FALSE;
			int128 _tmp5_;
			_tmp5_ = *a;
			if ((*self).hi == _tmp5_.hi) {
				int128 _tmp6_;
				_tmp6_ = *a;
				_tmp4_ = (*self).lo < _tmp6_.lo;
			} else {
				_tmp4_ = FALSE;
			}
			_tmp2_ = _tmp4_;
		}
		result = _tmp2_;
		return result;
	} else {
		gboolean _tmp7_ = FALSE;
		if (!(*self).negative) {
			int128 _tmp8_;
			_tmp8_ = *a;
			_tmp7_ = _tmp8_.negative;
		} else {
			_tmp7_ = FALSE;
		}
		if (_tmp7_) {
			result = FALSE;
			return result;
		} else {
			gboolean _tmp9_ = FALSE;
			if ((*self).negative) {
				int128 _tmp10_;
				_tmp10_ = *a;
				_tmp9_ = !_tmp10_.negative;
			} else {
				_tmp9_ = FALSE;
			}
			if (_tmp9_) {
				result = TRUE;
				return result;
			} else {
				gboolean _tmp11_ = FALSE;
				int128 _tmp12_;
				_tmp12_ = *a;
				if ((*self).hi > _tmp12_.hi) {
					_tmp11_ = TRUE;
				} else {
					gboolean _tmp13_ = FALSE;
					int128 _tmp14_;
					_tmp14_ = *a;
					if ((*self).hi == _tmp14_.hi) {
						int128 _tmp15_;
						_tmp15_ = *a;
						_tmp13_ = (*self).lo > _tmp15_.lo;
					} else {
						_tmp13_ = FALSE;
					}
					_tmp11_ = _tmp13_;
				}
				result = _tmp11_;
				return result;
			}
		}
	}
}

gboolean
int128_equal_to (int128 *self,
                 int128* a)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	int128 _tmp2_;
	gboolean result;
	g_return_val_if_fail (a != NULL, FALSE);
	_tmp2_ = *a;
	if ((*self).negative == _tmp2_.negative) {
		int128 _tmp3_;
		_tmp3_ = *a;
		_tmp1_ = (*self).hi == _tmp3_.hi;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		int128 _tmp4_;
		_tmp4_ = *a;
		_tmp0_ = (*self).lo == _tmp4_.lo;
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

void
int128_divide_by (int128 *self,
                  gint64 x,
                  int128* result)
{
	guint64 div = 0ULL;
	int128 s = {0};
	int128 _tmp0_ = {0};
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	int128 d = {0};
	int128 _tmp4_ = {0};
	gboolean _tmp5_ = FALSE;
	int128 _tmp6_;
	int128 _tmp24_;
	div = (guint64) llabs (x);
	_tmp0_.hi = (*self).hi;
	_tmp0_.lo = (*self).lo;
	s = _tmp0_;
	if ((*self).negative) {
		_tmp2_ = x >= ((gint64) 0);
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		_tmp1_ = TRUE;
	} else {
		gboolean _tmp3_ = FALSE;
		if (!(*self).negative) {
			_tmp3_ = x < ((gint64) 0);
		} else {
			_tmp3_ = FALSE;
		}
		_tmp1_ = _tmp3_;
	}
	_tmp4_.hi = (guint64) 0;
	_tmp4_.lo = (guint64) 0;
	_tmp4_.negative = _tmp1_;
	d = _tmp4_;
	_tmp6_ = s;
	if (_tmp6_.hi == ((guint64) 0)) {
		int128 _tmp7_;
		_tmp7_ = s;
		_tmp5_ = _tmp7_.lo == ((guint64) 0);
	} else {
		_tmp5_ = FALSE;
	}
	if (_tmp5_) {
		int128 _tmp8_ = {0};
		_tmp8_.hi = (guint64) 0;
		_tmp8_.lo = (guint64) 0;
		_tmp8_.negative = FALSE;
		d = _tmp8_;
		*result = d;
		return;
	} else {
		if (div == ((guint64) 0)) {
			d.hi = (guint64) 0xffffffffffffffffLL;
			d.lo = (guint64) 0xffffffffffffffffLL;
			*result = d;
			return;
		}
	}
	{
		gboolean _tmp9_ = FALSE;
		_tmp9_ = TRUE;
		while (TRUE) {
			gboolean _tmp10_ = FALSE;
			int128 _tmp11_;
			if (!_tmp9_) {
				int128_right_shift_assign (&s, 1);
				div >>= (guint64) 1;
			}
			_tmp9_ = FALSE;
			_tmp11_ = s;
			if ((_tmp11_.lo & 1) == ((guint64) 0)) {
				_tmp10_ = (div & 1) == ((guint64) 0);
			} else {
				_tmp10_ = FALSE;
			}
			if (!_tmp10_) {
				break;
			}
		}
	}
	if (div == ((guint64) 1)) {
		int128 _tmp12_;
		_tmp12_ = d;
		s.negative = _tmp12_.negative;
		*result = s;
		return;
	}
	{
		gboolean _tmp13_ = FALSE;
		_tmp13_ = TRUE;
		while (TRUE) {
			int128 _tmp14_;
			gint shift = 0;
			int128 a = {0};
			int128 _tmp15_;
			int128 _tmp16_;
			int128 _tmp17_ = {0};
			int128 _tmp18_;
			int128 _tmp22_ = {0};
			int128 _tmp23_;
			if (!_tmp13_) {
			}
			_tmp13_ = FALSE;
			_tmp14_ = s;
			if (!(_tmp14_.hi > ((guint64) 0))) {
				break;
			}
			shift = 0;
			_tmp15_ = s;
			_tmp16_ = s;
			_tmp17_.hi = _tmp15_.hi;
			_tmp17_.lo = _tmp16_.lo;
			a = _tmp17_;
			_tmp18_ = a;
			if (_tmp18_.hi < div) {
				{
					gboolean _tmp19_ = FALSE;
					_tmp19_ = TRUE;
					while (TRUE) {
						int128 _tmp21_;
						if (!_tmp19_) {
							gint _tmp20_;
							int128_right_shift_assign (&a, 1);
							shift = shift + 1;
							_tmp20_ = shift;
						}
						_tmp19_ = FALSE;
						_tmp21_ = a;
						if (!(_tmp21_.hi > ((guint64) 0))) {
							break;
						}
					}
				}
			}
			a.hi = a.hi / div;
			a.lo = a.lo / div;
			int128_left_shift_assign (&a, shift);
			int128_multiply (&a, div, &_tmp22_);
			int128_minus (&s, &_tmp22_);
			_tmp23_ = a;
			int128_add_assign (&d, &_tmp23_);
		}
	}
	_tmp24_ = s;
	if (_tmp24_.lo >= div) {
		int128 a = {0};
		int128 _tmp25_;
		int128 _tmp26_ = {0};
		int128 _tmp27_;
		int128 _tmp28_;
		_tmp25_ = s;
		_tmp26_.hi = (guint64) 0;
		_tmp26_.lo = _tmp25_.lo / div;
		a = _tmp26_;
		_tmp27_ = a;
		int128_add_assign (&d, &_tmp27_);
		_tmp28_ = s;
		d.remainder = _tmp28_.lo % div;
	} else {
		int128 _tmp29_;
		_tmp29_ = s;
		d.remainder = _tmp29_.lo;
	}
	*result = d;
	return;
}

static gboolean
int128_is_valid_int64 (int128 *self)
{
	gboolean _tmp0_ = FALSE;
	gboolean result;
	if ((*self).hi == ((guint64) 0)) {
		gboolean _tmp1_ = FALSE;
		gboolean _tmp2_ = FALSE;
		if (!(*self).negative) {
			_tmp2_ = ((*self).lo & 0x8000000000000000LL) == ((guint64) 0);
		} else {
			_tmp2_ = FALSE;
		}
		if (_tmp2_) {
			_tmp1_ = TRUE;
		} else {
			gboolean _tmp3_ = FALSE;
			if ((*self).negative) {
				_tmp3_ = (*self).lo <= ((guint64) 0x8000000000000000LL);
			} else {
				_tmp3_ = FALSE;
			}
			_tmp1_ = _tmp3_;
		}
		_tmp0_ = _tmp1_;
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

gint64
int128_get_int64 (int128 *self)
{
	gint64 _tmp0_ = 0LL;
	gint64 result;
	_vala_assert (int128_is_valid_int64 (&(*self)), "is_valid_int64 ()");
	if ((*self).negative) {
		_tmp0_ = (gint64) (-(*self).lo);
	} else {
		_tmp0_ = (gint64) (*self).lo;
	}
	result = _tmp0_;
	return result;
}

static void
int128_multiply (int128 *self,
                 guint64 _a,
                 int128* result)
{
	int128 a = {0};
	int128 _tmp0_ = {0};
	int128 r = {0};
	int128 _tmp1_ = {0};
	_tmp0_.hi = (guint64) 0;
	_tmp0_.lo = _a;
	_tmp0_.negative = FALSE;
	a = _tmp0_;
	_tmp1_.hi = (guint64) 0;
	_tmp1_.lo = (guint64) 0;
	_tmp1_.negative = FALSE;
	r = _tmp1_;
	{
		gint shift = 0;
		shift = 0;
		{
			gboolean _tmp2_ = FALSE;
			_tmp2_ = TRUE;
			while (TRUE) {
				gboolean _tmp4_ = FALSE;
				int128 _tmp5_;
				int128 _tmp7_;
				if (!_tmp2_) {
					gint _tmp3_;
					int128_right_shift_assign (&a, 1);
					_tmp3_ = shift;
					shift = _tmp3_ + 1;
				}
				_tmp2_ = FALSE;
				_tmp5_ = a;
				if (_tmp5_.hi > ((guint64) 0)) {
					_tmp4_ = TRUE;
				} else {
					int128 _tmp6_;
					_tmp6_ = a;
					_tmp4_ = _tmp6_.lo > ((guint64) 0);
				}
				if (!_tmp4_) {
					break;
				}
				_tmp7_ = a;
				if ((_tmp7_.lo & 1) > ((guint64) 0)) {
					int128 _tmp8_ = {0};
					int128_left_shift (&(*self), shift, &_tmp8_);
					int128_add_assign (&r, &_tmp8_);
				}
			}
		}
	}
	*result = r;
	return;
}

static void
int128_minus (int128 *self,
              int128* a)
{
	int128 _tmp0_;
	int128 _tmp1_;
	int128 _tmp3_;
	g_return_if_fail (a != NULL);
	_tmp0_ = *a;
	(*self).hi = (*self).hi - _tmp0_.hi;
	_tmp1_ = *a;
	if ((*self).lo < _tmp1_.lo) {
		guint64 _tmp2_;
		(*self).hi = (*self).hi - 1;
		_tmp2_ = (*self).hi;
	}
	_tmp3_ = *a;
	(*self).lo = (*self).lo - _tmp3_.lo;
}

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

void
int128_free (int128* self)
{
	g_free (self);
}

 G_GNUC_NO_INLINE static GType
int128_get_type_once (void)
{
	GType int128_type_id;
	int128_type_id = g_boxed_type_register_static ("int128", (GBoxedCopyFunc) int128_dup, (GBoxedFreeFunc) int128_free);
	return int128_type_id;
}

GType
int128_get_type (void)
{
	static GType int128_type_id__once = 0;
	if (g_once_init_enter_pointer (&int128_type_id__once)) {
		GType int128_type_id;
		int128_type_id = int128_get_type_once ();
		g_once_init_leave_pointer (&int128_type_id__once, int128_type_id);
	}
	return int128_type_id__once;
}

void
multiply (gint64 _a,
          gint64 _b,
          int128* result)
{
	gint64 _tmp0_ = 0LL;
	int128 a = {0};
	int128 _tmp1_ = {0};
	gint64 _tmp2_ = 0LL;
	int128 b = {0};
	int128 _tmp3_ = {0};
	gboolean _tmp4_ = FALSE;
	gboolean _tmp5_ = FALSE;
	int128 r = {0};
	int128 _tmp7_ = {0};
	if (llabs (_a) < llabs (_b)) {
		_tmp0_ = llabs (_b);
	} else {
		_tmp0_ = llabs (_a);
	}
	_tmp1_.hi = (guint64) 0;
	_tmp1_.lo = (guint64) _tmp0_;
	a = _tmp1_;
	if (llabs (_a) >= llabs (_b)) {
		_tmp2_ = llabs (_b);
	} else {
		_tmp2_ = llabs (_a);
	}
	_tmp3_.hi = (guint64) 0;
	_tmp3_.lo = (guint64) _tmp2_;
	b = _tmp3_;
	if (_a < ((gint64) 0)) {
		_tmp5_ = _b >= ((gint64) 0);
	} else {
		_tmp5_ = FALSE;
	}
	if (_tmp5_) {
		_tmp4_ = TRUE;
	} else {
		gboolean _tmp6_ = FALSE;
		if (_a >= ((gint64) 0)) {
			_tmp6_ = _b < ((gint64) 0);
		} else {
			_tmp6_ = FALSE;
		}
		_tmp4_ = _tmp6_;
	}
	_tmp7_.hi = (guint64) 0;
	_tmp7_.lo = (guint64) 0;
	_tmp7_.negative = _tmp4_;
	r = _tmp7_;
	{
		gint shift = 0;
		shift = 0;
		{
			gboolean _tmp8_ = FALSE;
			_tmp8_ = TRUE;
			while (TRUE) {
				gboolean _tmp10_ = FALSE;
				int128 _tmp11_;
				int128 _tmp13_;
				if (!_tmp8_) {
					gint _tmp9_;
					int128_right_shift_assign (&b, 1);
					_tmp9_ = shift;
					shift = _tmp9_ + 1;
				}
				_tmp8_ = FALSE;
				_tmp11_ = b;
				if (_tmp11_.hi > ((guint64) 0)) {
					_tmp10_ = TRUE;
				} else {
					int128 _tmp12_;
					_tmp12_ = b;
					_tmp10_ = _tmp12_.lo > ((guint64) 0);
				}
				if (!_tmp10_) {
					break;
				}
				_tmp13_ = b;
				if ((_tmp13_.lo & 1) > ((guint64) 0)) {
					int128 _tmp14_ = {0};
					int128_left_shift (&a, shift, &_tmp14_);
					int128_add_assign (&r, &_tmp14_);
				}
			}
		}
	}
	*result = r;
	return;
}

void
multiply_by_2n (gint64 a,
                gint n,
                int128* result)
{
	int128 r = {0};
	int128 _tmp0_ = {0};
	_tmp0_.hi = (guint64) 0;
	_tmp0_.lo = (guint64) llabs (a);
	_tmp0_.negative = a < ((gint64) 0);
	r = _tmp0_;
	int128_left_shift_assign (&r, n);
	*result = r;
	return;
}

static inline gpointer
angle_iterator_get_instance_private (AngleIterator* self)
{
	return G_STRUCT_MEMBER_P (self, AngleIterator_private_offset);
}

AngleIterator*
angle_iterator_construct (GType object_type,
                          Angle* p)
{
	AngleIterator* self = NULL;
	Angle _tmp0_;
	g_return_val_if_fail (p != NULL, NULL);
	self = (AngleIterator*) g_type_create_instance (object_type);
	_tmp0_ = *p;
	self->priv->pAngle = _tmp0_;
	self->priv->index = (guint64) 0;
	return self;
}

AngleIterator*
angle_iterator_new (Angle* p)
{
	return angle_iterator_construct (TYPE_ANGLE_ITERATOR, p);
}

gboolean
angle_iterator_next (AngleIterator* self)
{
	guint64 _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	self->priv->index = self->priv->index + 1;
	_tmp0_ = self->priv->index;
	result = TRUE;
	return result;
}

void
angle_iterator_get (AngleIterator* self,
                    SignedPosition* result)
{
	SignedPosition _tmp0_ = {0};
	g_return_if_fail (self != NULL);
	angle_get (&self->priv->pAngle, self->priv->index, &_tmp0_);
	*result = _tmp0_;
	return;
}

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

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

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

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

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

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

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

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

void
value_set_angle_iterator (GValue* value,
                          gpointer v_object)
{
	AngleIterator * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_ANGLE_ITERATOR));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_ANGLE_ITERATOR));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		angle_iterator_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		angle_iterator_unref (old);
	}
}

void
value_take_angle_iterator (GValue* value,
                           gpointer v_object)
{
	AngleIterator * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_ANGLE_ITERATOR));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_ANGLE_ITERATOR));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		angle_iterator_unref (old);
	}
}

static void
angle_iterator_class_init (AngleIteratorClass * klass,
                           gpointer klass_data)
{
	angle_iterator_parent_class = g_type_class_peek_parent (klass);
	((AngleIteratorClass *) klass)->finalize = angle_iterator_finalize;
	g_type_class_adjust_private_offset (klass, &AngleIterator_private_offset);
}

static void
angle_iterator_instance_init (AngleIterator * self,
                              gpointer klass)
{
	self->priv = angle_iterator_get_instance_private (self);
	self->ref_count = 1;
}

static void
angle_iterator_finalize (AngleIterator * obj)
{
	AngleIterator * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_ANGLE_ITERATOR, AngleIterator);
	g_signal_handlers_destroy (self);
}

 G_GNUC_NO_INLINE static GType
angle_iterator_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { value_angle_iterator_init, value_angle_iterator_free_value, value_angle_iterator_copy_value, value_angle_iterator_peek_pointer, "p", value_angle_iterator_collect_value, "p", value_angle_iterator_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (AngleIteratorClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) angle_iterator_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (AngleIterator), 0, (GInstanceInitFunc) angle_iterator_instance_init, &g_define_type_value_table };
	static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
	GType angle_iterator_type_id;
	angle_iterator_type_id = g_type_register_fundamental (g_type_fundamental_next (), "AngleIterator", &g_define_type_info, &g_define_type_fundamental_info, G_TYPE_FLAG_NONE);
	AngleIterator_private_offset = g_type_add_instance_private (angle_iterator_type_id, sizeof (AngleIteratorPrivate));
	return angle_iterator_type_id;
}

GType
angle_iterator_get_type (void)
{
	static GType angle_iterator_type_id__once = 0;
	if (g_once_init_enter_pointer (&angle_iterator_type_id__once)) {
		GType angle_iterator_type_id;
		angle_iterator_type_id = angle_iterator_get_type_once ();
		g_once_init_leave_pointer (&angle_iterator_type_id__once, angle_iterator_type_id);
	}
	return angle_iterator_type_id__once;
}

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

void
angle_iterator_unref (gpointer instance)
{
	AngleIterator * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		ANGLE_ITERATOR_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

 G_GNUC_NO_INLINE static GType
quarter_get_type_once (void)
{
	static const GEnumValue values[] = {{QUARTER_Q0, "QUARTER_Q0", "q0"}, {QUARTER_Q1, "QUARTER_Q1", "q1"}, {QUARTER_Q2, "QUARTER_Q2", "q2"}, {QUARTER_Q3, "QUARTER_Q3", "q3"}, {0, NULL, NULL}};
	GType quarter_type_id;
	quarter_type_id = g_enum_register_static ("Quarter", values);
	return quarter_type_id;
}

GType
quarter_get_type (void)
{
	static GType quarter_type_id__once = 0;
	if (g_once_init_enter_pointer (&quarter_type_id__once)) {
		GType quarter_type_id;
		quarter_type_id = quarter_get_type_once ();
		g_once_init_leave_pointer (&quarter_type_id__once, quarter_type_id);
	}
	return quarter_type_id__once;
}

void
angle_assign (Angle *self,
              Angle* o)
{
	Angle _tmp0_;
	Angle _tmp1_;
	Angle _tmp2_;
	Angle _tmp3_;
	Angle _tmp4_;
	Angle _tmp5_;
	g_return_if_fail (o != NULL);
	_tmp0_ = *o;
	(*self).x = _tmp0_.x;
	_tmp1_ = *o;
	(*self).y = _tmp1_.y;
	_tmp2_ = *o;
	(*self).origin_x = _tmp2_.origin_x;
	_tmp3_ = *o;
	(*self).origin_y = _tmp3_.origin_y;
	_tmp4_ = *o;
	(*self).x_max = _tmp4_.x_max;
	_tmp5_ = *o;
	(*self).y_max = _tmp5_.y_max;
}

gboolean
angle_less_than_or_equal_to (Angle *self,
                             Angle* o)
{
	Angle _tmp0_;
	gboolean result;
	g_return_val_if_fail (o != NULL, FALSE);
	_tmp0_ = *o;
	result = !angle_greater_than (&(*self), &_tmp0_);
	return result;
}

gboolean
angle_greater_than (Angle *self,
                    Angle* o)
{
	Quarter q = 0;
	gboolean result;
	g_return_val_if_fail (o != NULL, FALSE);
	q = angle_get_quarter (o);
	switch (angle_get_quarter (&(*self))) {
		case QUARTER_Q0:
		{
			if (q == QUARTER_Q3) {
				result = TRUE;
				return result;
			} else {
				if (q == QUARTER_Q1) {
					result = FALSE;
					return result;
				} else {
					Angle _tmp0_;
					int128 _tmp1_ = {0};
					Angle _tmp2_;
					int128 _tmp3_ = {0};
					_tmp0_ = *o;
					multiply ((*self).x, _tmp0_.y, &_tmp1_);
					_tmp2_ = *o;
					multiply (_tmp2_.x, (*self).y, &_tmp3_);
					result = int128_less_than (&_tmp1_, &_tmp3_);
					return result;
				}
			}
		}
		case QUARTER_Q1:
		{
			if (q == QUARTER_Q0) {
				result = TRUE;
				return result;
			} else {
				if (q == QUARTER_Q2) {
					result = FALSE;
					return result;
				} else {
					Angle _tmp4_;
					int128 _tmp5_ = {0};
					Angle _tmp6_;
					int128 _tmp7_ = {0};
					_tmp4_ = *o;
					multiply ((*self).x, _tmp4_.y, &_tmp5_);
					_tmp6_ = *o;
					multiply (_tmp6_.x, (*self).y, &_tmp7_);
					result = int128_less_than (&_tmp5_, &_tmp7_);
					return result;
				}
			}
		}
		case QUARTER_Q2:
		{
			if (q == QUARTER_Q1) {
				result = TRUE;
				return result;
			} else {
				if (q == QUARTER_Q3) {
					result = FALSE;
					return result;
				} else {
					Angle _tmp8_;
					int128 _tmp9_ = {0};
					Angle _tmp10_;
					int128 _tmp11_ = {0};
					_tmp8_ = *o;
					multiply ((*self).x, _tmp8_.y, &_tmp9_);
					_tmp10_ = *o;
					multiply (_tmp10_.x, (*self).y, &_tmp11_);
					result = int128_less_than (&_tmp9_, &_tmp11_);
					return result;
				}
			}
		}
		case QUARTER_Q3:
		{
			if (q == QUARTER_Q2) {
				result = TRUE;
				return result;
			} else {
				if (q == QUARTER_Q0) {
					result = FALSE;
					return result;
				} else {
					Angle _tmp12_;
					int128 _tmp13_ = {0};
					Angle _tmp14_;
					int128 _tmp15_ = {0};
					_tmp12_ = *o;
					multiply ((*self).x, _tmp12_.y, &_tmp13_);
					_tmp14_ = *o;
					multiply (_tmp14_.x, (*self).y, &_tmp15_);
					result = int128_less_than (&_tmp13_, &_tmp15_);
					return result;
				}
			}
		}
		default:
		{
			result = FALSE;
			return result;
		}
	}
}

gboolean
angle_less_than (Angle *self,
                 Angle* o)
{
	gboolean _tmp0_ = FALSE;
	Angle _tmp1_;
	gboolean result;
	g_return_val_if_fail (o != NULL, FALSE);
	_tmp1_ = *o;
	if (!angle_equal_to (&(*self), &_tmp1_)) {
		Angle _tmp2_;
		_tmp2_ = *o;
		_tmp0_ = angle_less_than_or_equal_to (&(*self), &_tmp2_);
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

gboolean
angle_greater_than_or_equal_to (Angle *self,
                                Angle* o)
{
	Quarter q = 0;
	gboolean result;
	g_return_val_if_fail (o != NULL, FALSE);
	q = angle_get_quarter (o);
	switch (angle_get_quarter (&(*self))) {
		case QUARTER_Q0:
		{
			if (q == QUARTER_Q3) {
				result = TRUE;
				return result;
			} else {
				if (q == QUARTER_Q1) {
					result = FALSE;
					return result;
				} else {
					if (q == QUARTER_Q2) {
						Angle _tmp0_;
						int128 _tmp1_ = {0};
						Angle _tmp2_;
						int128 _tmp3_ = {0};
						_tmp0_ = *o;
						multiply ((*self).x, _tmp0_.y, &_tmp1_);
						_tmp2_ = *o;
						multiply (_tmp2_.x, (*self).y, &_tmp3_);
						result = int128_less_than (&_tmp1_, &_tmp3_);
						return result;
					} else {
						Angle _tmp4_;
						int128 _tmp5_ = {0};
						Angle _tmp6_;
						int128 _tmp7_ = {0};
						_tmp4_ = *o;
						multiply ((*self).x, _tmp4_.y, &_tmp5_);
						_tmp6_ = *o;
						multiply (_tmp6_.x, (*self).y, &_tmp7_);
						result = int128_less_than_or_equal_to (&_tmp5_, &_tmp7_);
						return result;
					}
				}
			}
		}
		case QUARTER_Q1:
		{
			if (q == QUARTER_Q0) {
				result = TRUE;
				return result;
			} else {
				if (q == QUARTER_Q2) {
					result = FALSE;
					return result;
				} else {
					if (q == QUARTER_Q3) {
						Angle _tmp8_;
						int128 _tmp9_ = {0};
						Angle _tmp10_;
						int128 _tmp11_ = {0};
						_tmp8_ = *o;
						multiply ((*self).x, _tmp8_.y, &_tmp9_);
						_tmp10_ = *o;
						multiply (_tmp10_.x, (*self).y, &_tmp11_);
						result = int128_less_than (&_tmp9_, &_tmp11_);
						return result;
					} else {
						Angle _tmp12_;
						int128 _tmp13_ = {0};
						Angle _tmp14_;
						int128 _tmp15_ = {0};
						_tmp12_ = *o;
						multiply ((*self).x, _tmp12_.y, &_tmp13_);
						_tmp14_ = *o;
						multiply (_tmp14_.x, (*self).y, &_tmp15_);
						result = int128_less_than_or_equal_to (&_tmp13_, &_tmp15_);
						return result;
					}
				}
			}
		}
		case QUARTER_Q2:
		{
			if (q == QUARTER_Q1) {
				result = TRUE;
				return result;
			} else {
				if (q == QUARTER_Q3) {
					result = FALSE;
					return result;
				} else {
					if (q == QUARTER_Q0) {
						Angle _tmp16_;
						int128 _tmp17_ = {0};
						Angle _tmp18_;
						int128 _tmp19_ = {0};
						_tmp16_ = *o;
						multiply ((*self).x, _tmp16_.y, &_tmp17_);
						_tmp18_ = *o;
						multiply (_tmp18_.x, (*self).y, &_tmp19_);
						result = int128_less_than (&_tmp17_, &_tmp19_);
						return result;
					} else {
						Angle _tmp20_;
						int128 _tmp21_ = {0};
						Angle _tmp22_;
						int128 _tmp23_ = {0};
						_tmp20_ = *o;
						multiply ((*self).x, _tmp20_.y, &_tmp21_);
						_tmp22_ = *o;
						multiply (_tmp22_.x, (*self).y, &_tmp23_);
						result = int128_less_than_or_equal_to (&_tmp21_, &_tmp23_);
						return result;
					}
				}
			}
		}
		case QUARTER_Q3:
		{
			if (q == QUARTER_Q2) {
				result = TRUE;
				return result;
			} else {
				if (q == QUARTER_Q0) {
					result = FALSE;
					return result;
				} else {
					if (q == QUARTER_Q1) {
						Angle _tmp24_;
						int128 _tmp25_ = {0};
						Angle _tmp26_;
						int128 _tmp27_ = {0};
						_tmp24_ = *o;
						multiply ((*self).x, _tmp24_.y, &_tmp25_);
						_tmp26_ = *o;
						multiply (_tmp26_.x, (*self).y, &_tmp27_);
						result = int128_less_than (&_tmp25_, &_tmp27_);
						return result;
					} else {
						Angle _tmp28_;
						int128 _tmp29_ = {0};
						Angle _tmp30_;
						int128 _tmp31_ = {0};
						_tmp28_ = *o;
						multiply ((*self).x, _tmp28_.y, &_tmp29_);
						_tmp30_ = *o;
						multiply (_tmp30_.x, (*self).y, &_tmp31_);
						result = int128_less_than_or_equal_to (&_tmp29_, &_tmp31_);
						return result;
					}
				}
			}
		}
		default:
		{
			result = FALSE;
			return result;
		}
	}
}

gboolean
angle_equal_to (Angle *self,
                Angle* o)
{
	gboolean _tmp0_ = FALSE;
	gboolean result;
	g_return_val_if_fail (o != NULL, FALSE);
	if (angle_get_quarter (&(*self)) == angle_get_quarter (o)) {
		Angle _tmp1_;
		int128 _tmp2_ = {0};
		Angle _tmp3_;
		int128 _tmp4_ = {0};
		_tmp1_ = *o;
		multiply ((*self).x, _tmp1_.y, &_tmp2_);
		_tmp3_ = *o;
		multiply (_tmp3_.x, (*self).y, &_tmp4_);
		_tmp0_ = int128_equal_to (&_tmp2_, &_tmp4_);
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

void
angle_set_origin (Angle *self,
                  Position* origin)
{
	Position _tmp0_;
	Position _tmp1_;
	g_return_if_fail (origin != NULL);
	_tmp0_ = *origin;
	(*self).origin_x = ((_tmp0_.x * 2) + 1) * (ANGLE_step_multiplier / 2);
	_tmp1_ = *origin;
	(*self).origin_y = ((_tmp1_.y * 2) + 1) * (ANGLE_step_multiplier / 2);
}

void
angle_set_wrapping (Angle *self,
                    gint x,
                    gint y)
{
	(*self).x_max = (gint64) x;
	(*self).y_max = (gint64) y;
}

gboolean
angle_step_along_x (Angle *self)
{
	gboolean result;
	result = llabs ((*self).x) > llabs ((*self).y);
	return result;
}

void
angle_get (Angle *self,
           guint64 i,
           SignedPosition* result)
{
	gint64 _tmp0_ = 0LL;
	gint64 delta_x = 0LL;
	gint64 _tmp3_ = 0LL;
	gint64 delta_y = 0LL;
	gint64 x_i = 0LL;
	gint64 y_i = 0LL;
	SignedPosition _tmp6_ = {0};
	if (angle_step_along_x (&(*self))) {
		_tmp0_ = angle_set_delta_x_sign (&(*self), ANGLE_step_multiplier);
	} else {
		int128 _tmp1_ = {0};
		int128 _tmp2_ = {0};
		multiply_by_2n ((*self).x, ANGLE_step_multiplier_2n, &_tmp1_);
		int128_divide_by (&_tmp1_, (*self).y, &_tmp2_);
		_tmp0_ = angle_set_delta_x_sign (&(*self), int128_get_int64 (&_tmp2_));
	}
	delta_x = _tmp0_;
	if (angle_step_along_x (&(*self))) {
		int128 _tmp4_ = {0};
		int128 _tmp5_ = {0};
		multiply_by_2n ((*self).y, ANGLE_step_multiplier_2n, &_tmp4_);
		int128_divide_by (&_tmp4_, (*self).x, &_tmp5_);
		_tmp3_ = angle_set_delta_y_sign (&(*self), int128_get_int64 (&_tmp5_));
	} else {
		_tmp3_ = angle_set_delta_y_sign (&(*self), ANGLE_step_multiplier);
	}
	delta_y = _tmp3_;
	x_i = (*self).origin_x + (delta_x * ((gint64) i));
	y_i = (*self).origin_y + (delta_y * ((gint64) i));
	_tmp6_.x = x_i >> ANGLE_step_multiplier_2n;
	_tmp6_.y = y_i >> ANGLE_step_multiplier_2n;
	_tmp6_.x_max = (*self).x_max;
	_tmp6_.y_max = (*self).y_max;
	*result = _tmp6_;
	return;
}

AngleIterator*
angle_iterator (Angle *self)
{
	AngleIterator* _tmp0_;
	AngleIterator* result;
	_tmp0_ = angle_iterator_new (&(*self));
	result = _tmp0_;
	return result;
}

static Quarter
angle_get_quarter (Angle *self)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp2_ = FALSE;
	Quarter result;
	if ((*self).x >= ((gint64) 0)) {
		_tmp0_ = (*self).y < ((gint64) 0);
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		result = QUARTER_Q0;
		return result;
	} else {
		gboolean _tmp1_ = FALSE;
		if ((*self).x > ((gint64) 0)) {
			_tmp1_ = (*self).y >= ((gint64) 0);
		} else {
			_tmp1_ = FALSE;
		}
		if (_tmp1_) {
			result = QUARTER_Q1;
			return result;
		}
	}
	if ((*self).x <= ((gint64) 0)) {
		_tmp2_ = (*self).y > ((gint64) 0);
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		result = QUARTER_Q2;
		return result;
	} else {
		result = QUARTER_Q3;
		return result;
	}
}

static gint64
angle_set_delta_x_sign (Angle *self,
                        gint64 _x)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gint64 result;
	if ((*self).x >= ((gint64) 0)) {
		_tmp1_ = _x < ((gint64) 0);
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		gboolean _tmp2_ = FALSE;
		if ((*self).x < ((gint64) 0)) {
			_tmp2_ = _x >= ((gint64) 0);
		} else {
			_tmp2_ = FALSE;
		}
		_tmp0_ = _tmp2_;
	}
	if (_tmp0_) {
		result = -_x;
		return result;
	} else {
		result = _x;
		return result;
	}
}

static gint64
angle_set_delta_y_sign (Angle *self,
                        gint64 _y)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gint64 result;
	if ((*self).y >= ((gint64) 0)) {
		_tmp1_ = _y < ((gint64) 0);
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		gboolean _tmp2_ = FALSE;
		if ((*self).y < ((gint64) 0)) {
			_tmp2_ = _y >= ((gint64) 0);
		} else {
			_tmp2_ = FALSE;
		}
		_tmp0_ = _tmp2_;
	}
	if (_tmp0_) {
		result = -_y;
		return result;
	} else {
		result = _y;
		return result;
	}
}

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

void
angle_free (Angle* self)
{
	g_free (self);
}

 G_GNUC_NO_INLINE static GType
angle_get_type_once (void)
{
	GType angle_type_id;
	angle_type_id = g_boxed_type_register_static ("Angle", (GBoxedCopyFunc) angle_dup, (GBoxedFreeFunc) angle_free);
	return angle_type_id;
}

GType
angle_get_type (void)
{
	static GType angle_type_id__once = 0;
	if (g_once_init_enter_pointer (&angle_type_id__once)) {
		GType angle_type_id;
		angle_type_id = angle_get_type_once ();
		g_once_init_leave_pointer (&angle_type_id__once, angle_type_id);
	}
	return angle_type_id__once;
}

static inline gpointer
slice_get_instance_private (Slice* self)
{
	return G_STRUCT_MEMBER_P (self, Slice_private_offset);
}

Slice*
slice_construct (GType object_type,
                 Slice* copy)
{
	Slice * self = NULL;
	self = (Slice*) g_object_new (object_type, NULL);
	if (copy == NULL) {
		self->priv->min_set = FALSE;
		self->priv->max_set = FALSE;
	} else {
		slice_assign (self, copy);
	}
	return self;
}

Slice*
slice_new (Slice* copy)
{
	return slice_construct (TYPE_SLICE, copy);
}

void
slice_assign (Slice* self,
              Slice* o)
{
	Angle _tmp0_;
	Angle _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (o != NULL);
	_tmp0_ = o->min;
	angle_assign (&self->min, &_tmp0_);
	_tmp1_ = o->max;
	angle_assign (&self->max, &_tmp1_);
	self->priv->min_set = o->priv->min_set;
	self->priv->max_set = o->priv->max_set;
}

void
slice_set_direction_view (Slice* self,
                          WormDirection d,
                          gint* board,
                          gint board_length1,
                          gint board_length2)
{
	static const gint64 x = (gint64) 369665159;
	static const gint64 y = -14116942878LL;
	gint _tmp8_;
	gint _tmp9_;
	gint _tmp10_;
	gint _tmp11_;
	g_return_if_fail (self != NULL);
	switch (d) {
		case WORM_DIRECTION_EAST:
		{
			Angle _tmp0_ = {0};
			Angle _tmp1_ = {0};
			_tmp0_.x = -y;
			_tmp0_.y = -x;
			self->min = _tmp0_;
			_tmp1_.x = -y;
			_tmp1_.y = +x;
			self->max = _tmp1_;
			break;
		}
		case WORM_DIRECTION_SOUTH:
		{
			Angle _tmp2_ = {0};
			Angle _tmp3_ = {0};
			_tmp2_.x = +x;
			_tmp2_.y = -y;
			self->min = _tmp2_;
			_tmp3_.x = -x;
			_tmp3_.y = -y;
			self->max = _tmp3_;
			break;
		}
		case WORM_DIRECTION_WEST:
		{
			Angle _tmp4_ = {0};
			Angle _tmp5_ = {0};
			_tmp4_.x = +y;
			_tmp4_.y = +x;
			self->min = _tmp4_;
			_tmp5_.x = +y;
			_tmp5_.y = -x;
			self->max = _tmp5_;
			break;
		}
		case WORM_DIRECTION_NORTH:
		{
			Angle _tmp6_ = {0};
			Angle _tmp7_ = {0};
			_tmp6_.x = -x;
			_tmp6_.y = +y;
			self->min = _tmp6_;
			_tmp7_.x = +x;
			_tmp7_.y = +y;
			self->max = _tmp7_;
			break;
		}
		default:
		{
			break;
		}
	}
	self->priv->min_set = TRUE;
	self->priv->max_set = TRUE;
	_tmp8_ = board_length1;
	_tmp9_ = board_length2;
	angle_set_wrapping (&self->min, _tmp8_, _tmp9_);
	_tmp10_ = board_length1;
	_tmp11_ = board_length2;
	angle_set_wrapping (&self->max, _tmp10_, _tmp11_);
}

void
slice_add_angle (Slice* self,
                 Angle* a)
{
	gboolean _tmp0_ = FALSE;
	g_return_if_fail (self != NULL);
	g_return_if_fail (a != NULL);
	if (!self->priv->min_set) {
		_tmp0_ = !self->priv->max_set;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		Angle _tmp1_;
		_tmp1_ = *a;
		angle_assign (&self->min, &_tmp1_);
		self->priv->min_set = TRUE;
	} else {
		if (!self->priv->min_set) {
			Angle _tmp2_;
			_tmp2_ = self->max;
			if (angle_greater_than (a, &_tmp2_)) {
				Angle _tmp3_;
				Angle _tmp4_;
				_tmp3_ = self->max;
				angle_assign (&self->min, &_tmp3_);
				_tmp4_ = *a;
				angle_assign (&self->max, &_tmp4_);
			} else {
				Angle _tmp5_;
				_tmp5_ = *a;
				angle_assign (&self->min, &_tmp5_);
			}
			self->priv->min_set = TRUE;
		} else {
			if (!self->priv->max_set) {
				Angle _tmp6_;
				_tmp6_ = self->min;
				if (angle_greater_than (a, &_tmp6_)) {
					Angle _tmp7_;
					_tmp7_ = *a;
					angle_assign (&self->max, &_tmp7_);
				} else {
					Angle _tmp8_;
					Angle _tmp9_;
					_tmp8_ = self->min;
					angle_assign (&self->max, &_tmp8_);
					_tmp9_ = *a;
					angle_assign (&self->min, &_tmp9_);
				}
				self->priv->max_set = TRUE;
			} else {
				Angle _tmp10_;
				_tmp10_ = self->min;
				if (angle_less_than (a, &_tmp10_)) {
					Angle _tmp11_;
					_tmp11_ = *a;
					angle_assign (&self->min, &_tmp11_);
				} else {
					Angle _tmp12_;
					_tmp12_ = self->max;
					if (angle_greater_than (a, &_tmp12_)) {
						Angle _tmp13_;
						_tmp13_ = *a;
						angle_assign (&self->max, &_tmp13_);
					}
				}
			}
		}
	}
}

void
slice_set_from_position (Slice* self,
                         Position* origin,
                         gint64 x,
                         gint64 y,
                         gint size)
{
	Position _tmp0_;
	Position _tmp1_;
	Angle _tmp2_ = {0};
	Position _tmp3_;
	Position _tmp4_;
	Angle _tmp5_ = {0};
	Position _tmp6_;
	Position _tmp7_;
	Angle _tmp8_ = {0};
	Position _tmp9_;
	Position _tmp10_;
	Angle _tmp11_ = {0};
	g_return_if_fail (self != NULL);
	g_return_if_fail (origin != NULL);
	self->priv->min_set = FALSE;
	self->priv->max_set = FALSE;
	_tmp0_ = *origin;
	_tmp1_ = *origin;
	_tmp2_.x = (x * 2) - ((_tmp0_.x * 2) + 1);
	_tmp2_.y = (y * 2) - ((_tmp1_.y * 2) + 1);
	slice_add_angle (self, &_tmp2_);
	_tmp3_ = *origin;
	_tmp4_ = *origin;
	_tmp5_.x = ((x + (1 * size)) * 2) - ((_tmp3_.x * 2) + 1);
	_tmp5_.y = (y * 2) - ((_tmp4_.y * 2) + 1);
	slice_add_angle (self, &_tmp5_);
	_tmp6_ = *origin;
	_tmp7_ = *origin;
	_tmp8_.x = (x * 2) - ((_tmp6_.x * 2) + 1);
	_tmp8_.y = ((y + (1 * size)) * 2) - ((_tmp7_.y * 2) + 1);
	slice_add_angle (self, &_tmp8_);
	_tmp9_ = *origin;
	_tmp10_ = *origin;
	_tmp11_.x = ((x + (1 * size)) * 2) - ((_tmp9_.x * 2) + 1);
	_tmp11_.y = ((y + (1 * size)) * 2) - ((_tmp10_.y * 2) + 1);
	slice_add_angle (self, &_tmp11_);
}

void
slice_intersection_by_position (Slice* self,
                                Position* origin,
                                guint8 _x,
                                guint8 _y,
                                gint size)
{
	gint64 x = 0LL;
	gint64 y = 0LL;
	gboolean _tmp0_ = FALSE;
	Angle _tmp1_;
	Angle old_min = {0};
	Angle _tmp20_ = {0};
	Angle _tmp21_;
	Angle old_max = {0};
	Angle _tmp22_ = {0};
	Angle _tmp23_;
	Position _tmp24_;
	Angle _tmp25_;
	Angle _tmp27_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (origin != NULL);
	x = (gint64) _x;
	y = (gint64) _y;
	_tmp1_ = self->min;
	if (_tmp1_.x >= ((gint64) 0)) {
		Angle _tmp2_;
		_tmp2_ = self->max;
		_tmp0_ = _tmp2_.x >= ((gint64) 0);
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		Position _tmp3_;
		_tmp3_ = *origin;
		if (!((x + (size - 1)) > ((gint64) _tmp3_.x))) {
			Angle _tmp4_;
			_tmp4_ = self->min;
			x += _tmp4_.x_max;
		}
	} else {
		gboolean _tmp5_ = FALSE;
		Angle _tmp6_;
		_tmp6_ = self->min;
		if (_tmp6_.x < ((gint64) 0)) {
			Angle _tmp7_;
			_tmp7_ = self->max;
			_tmp5_ = _tmp7_.x < ((gint64) 0);
		} else {
			_tmp5_ = FALSE;
		}
		if (_tmp5_) {
			Position _tmp8_;
			_tmp8_ = *origin;
			if (!(x < ((gint64) _tmp8_.x))) {
				Angle _tmp9_;
				_tmp9_ = self->min;
				x -= _tmp9_.x_max;
			}
		} else {
			gboolean _tmp10_ = FALSE;
			Angle _tmp11_;
			_tmp11_ = self->min;
			if (_tmp11_.y >= ((gint64) 0)) {
				Angle _tmp12_;
				_tmp12_ = self->max;
				_tmp10_ = _tmp12_.y >= ((gint64) 0);
			} else {
				_tmp10_ = FALSE;
			}
			if (_tmp10_) {
				Position _tmp13_;
				_tmp13_ = *origin;
				if (!((y + (size - 1)) > ((gint64) _tmp13_.y))) {
					Angle _tmp14_;
					_tmp14_ = self->min;
					y += _tmp14_.y_max;
				}
			} else {
				gboolean _tmp15_ = FALSE;
				Angle _tmp16_;
				_tmp16_ = self->min;
				if (_tmp16_.y < ((gint64) 0)) {
					Angle _tmp17_;
					_tmp17_ = self->max;
					_tmp15_ = _tmp17_.y < ((gint64) 0);
				} else {
					_tmp15_ = FALSE;
				}
				if (_tmp15_) {
					Position _tmp18_;
					_tmp18_ = *origin;
					if (!(y < ((gint64) _tmp18_.y))) {
						Angle _tmp19_;
						_tmp19_ = self->min;
						y -= _tmp19_.y_max;
					}
				}
			}
		}
	}
	old_min = _tmp20_;
	_tmp21_ = self->min;
	angle_assign (&old_min, &_tmp21_);
	old_max = _tmp22_;
	_tmp23_ = self->max;
	angle_assign (&old_max, &_tmp23_);
	_tmp24_ = *origin;
	slice_set_from_position (self, &_tmp24_, x, y, size);
	_tmp25_ = self->min;
	if (angle_greater_than (&old_min, &_tmp25_)) {
		Angle _tmp26_;
		_tmp26_ = old_min;
		angle_assign (&self->min, &_tmp26_);
	}
	_tmp27_ = self->max;
	if (angle_less_than (&old_max, &_tmp27_)) {
		Angle _tmp28_;
		_tmp28_ = old_max;
		angle_assign (&self->max, &_tmp28_);
	}
}

gboolean
slice_is_empty (Slice* self)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (!self->priv->min_set) {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = !self->priv->max_set;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		Angle _tmp2_;
		_tmp2_ = self->max;
		_tmp0_ = angle_greater_than_or_equal_to (&self->min, &_tmp2_);
	}
	result = _tmp0_;
	return result;
}

static gboolean
slice_is_bonus_at (Slice* self,
                   guint8 x,
                   guint8 y,
                   Bonus* b)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_ = FALSE;
	guint8 _tmp4_;
	guint8 _tmp5_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (b != NULL, FALSE);
	_tmp4_ = bonus_get_x (b);
	_tmp5_ = _tmp4_;
	if (_tmp5_ == x) {
		guint8 _tmp6_;
		guint8 _tmp7_;
		_tmp6_ = bonus_get_y (b);
		_tmp7_ = _tmp6_;
		_tmp3_ = _tmp7_ == y;
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		_tmp2_ = TRUE;
	} else {
		gboolean _tmp8_ = FALSE;
		guint8 _tmp9_;
		guint8 _tmp10_;
		_tmp9_ = bonus_get_x (b);
		_tmp10_ = _tmp9_;
		if ((_tmp10_ + 1) == ((gint) x)) {
			guint8 _tmp11_;
			guint8 _tmp12_;
			_tmp11_ = bonus_get_y (b);
			_tmp12_ = _tmp11_;
			_tmp8_ = _tmp12_ == y;
		} else {
			_tmp8_ = FALSE;
		}
		_tmp2_ = _tmp8_;
	}
	if (_tmp2_) {
		_tmp1_ = TRUE;
	} else {
		gboolean _tmp13_ = FALSE;
		guint8 _tmp14_;
		guint8 _tmp15_;
		_tmp14_ = bonus_get_x (b);
		_tmp15_ = _tmp14_;
		if (_tmp15_ == x) {
			guint8 _tmp16_;
			guint8 _tmp17_;
			_tmp16_ = bonus_get_y (b);
			_tmp17_ = _tmp16_;
			_tmp13_ = (_tmp17_ + 1) == ((gint) y);
		} else {
			_tmp13_ = FALSE;
		}
		_tmp1_ = _tmp13_;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		gboolean _tmp18_ = FALSE;
		guint8 _tmp19_;
		guint8 _tmp20_;
		_tmp19_ = bonus_get_x (b);
		_tmp20_ = _tmp19_;
		if ((_tmp20_ + 1) == ((gint) x)) {
			guint8 _tmp21_;
			guint8 _tmp22_;
			_tmp21_ = bonus_get_y (b);
			_tmp22_ = _tmp21_;
			_tmp18_ = (_tmp22_ + 1) == ((gint) y);
		} else {
			_tmp18_ = FALSE;
		}
		_tmp0_ = _tmp18_;
	}
	result = _tmp0_;
	return result;
}

static gboolean
slice_is_position_occupied (Slice* self,
                            Position* p,
                            gint* board,
                            gint board_length1,
                            gint board_length2,
                            WormMap* worm_map)
{
	gboolean _tmp0_ = FALSE;
	Position _tmp1_;
	Position _tmp2_;
	gint _tmp3_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (p != NULL, FALSE);
	g_return_val_if_fail (worm_map != NULL, FALSE);
	_tmp1_ = *p;
	_tmp2_ = *p;
	_tmp3_ = board[(_tmp1_.x * board_length2) + _tmp2_.y];
	if (_tmp3_ > ((gint) NIBBLES_GAME_EMPTYCHAR)) {
		_tmp0_ = TRUE;
	} else {
		Position _tmp4_;
		_tmp4_ = *p;
		_tmp0_ = worm_map_contain_position (worm_map, &_tmp4_);
	}
	result = _tmp0_;
	return result;
}

gint64
slice_is_visible (Slice* self,
                  Position* origin,
                  gint* board,
                  gint board_length1,
                  gint board_length2,
                  WormMap* worm_map,
                  Bonus* bonus)
{
	GeeArrayList* checked_positions = NULL;
	GeeArrayList* _tmp0_;
	gint64 result;
	g_return_val_if_fail (self != NULL, -1LL);
	g_return_val_if_fail (origin != NULL, -1LL);
	g_return_val_if_fail (worm_map != NULL, -1LL);
	g_return_val_if_fail (bonus != NULL, -1LL);
	_tmp0_ = gee_array_list_new (G_TYPE_UINT, NULL, NULL, NULL, NULL, NULL);
	checked_positions = _tmp0_;
	{
		gboolean _tmp1_ = FALSE;
		_tmp1_ = TRUE;
		while (TRUE) {
			gint64 distance = 0LL;
			Position _tmp2_;
			gint _tmp3_;
			gint _tmp4_;
			if (!_tmp1_) {
			}
			_tmp1_ = FALSE;
			if (!(!slice_is_empty (self))) {
				break;
			}
			distance = (gint64) 0;
			_tmp2_ = *origin;
			angle_set_origin (&self->min, &_tmp2_);
			_tmp3_ = board_length1;
			_tmp4_ = board_length2;
			angle_set_wrapping (&self->min, _tmp3_, _tmp4_);
			{
				AngleIterator* _p_it = NULL;
				AngleIterator* _tmp5_;
				_tmp5_ = angle_iterator (&self->min);
				_p_it = _tmp5_;
				while (TRUE) {
					AngleIterator* _tmp6_;
					SignedPosition p = {0};
					AngleIterator* _tmp7_;
					SignedPosition _tmp8_ = {0};
					gint64 _tmp9_;
					GeeArrayList* _tmp10_;
					_tmp6_ = _p_it;
					if (!angle_iterator_next (_tmp6_)) {
						break;
					}
					_tmp7_ = _p_it;
					angle_iterator_get (_tmp7_, &_tmp8_);
					p = _tmp8_;
					_tmp9_ = distance;
					distance = _tmp9_ + 1;
					_tmp10_ = checked_positions;
					if (!gee_abstract_collection_contains ((GeeAbstractCollection*) _tmp10_, (gpointer) ((guintptr) signed_position_wrap_xy (&p)))) {
						if (slice_is_bonus_at (self, signed_position_wrap_x (&p), signed_position_wrap_y (&p), bonus)) {
							gint64 _tmp11_ = 0LL;
							if (angle_step_along_x (&self->min)) {
								Position _tmp12_;
								SignedPosition _tmp13_;
								_tmp12_ = *origin;
								_tmp13_ = p;
								_tmp11_ = distance + llabs (_tmp12_.y - _tmp13_.y);
							} else {
								Position _tmp14_;
								SignedPosition _tmp15_;
								_tmp14_ = *origin;
								_tmp15_ = p;
								_tmp11_ = distance + llabs (_tmp14_.x - _tmp15_.x);
							}
							result = _tmp11_;
							_angle_iterator_unref0 (_p_it);
							_g_object_unref0 (checked_positions);
							return result;
						} else {
							gboolean _tmp16_ = FALSE;
							gint _tmp17_ = 0;
							if (angle_step_along_x (&self->min)) {
								gint _tmp18_;
								_tmp18_ = board_length1;
								_tmp17_ = _tmp18_;
							} else {
								gint _tmp19_;
								_tmp19_ = board_length2;
								_tmp17_ = _tmp19_;
							}
							if (distance > ((gint64) (_tmp17_ * 2))) {
								_tmp16_ = TRUE;
							} else {
								Position _tmp20_ = {0};
								_tmp20_.x = signed_position_wrap_x (&p);
								_tmp20_.y = signed_position_wrap_y (&p);
								_tmp16_ = slice_is_position_occupied (self, &_tmp20_, board, (gint) board_length1, (gint) board_length2, worm_map);
							}
							if (_tmp16_) {
								GeeArrayList* _tmp21_;
								Slice* s = NULL;
								Slice* _tmp22_;
								Slice* _tmp23_;
								Position _tmp24_;
								SignedPosition _tmp25_;
								SignedPosition _tmp26_;
								Slice* _tmp27_;
								Angle _tmp28_;
								_tmp21_ = checked_positions;
								gee_abstract_collection_add ((GeeAbstractCollection*) _tmp21_, (gpointer) ((guintptr) signed_position_wrap_xy (&p)));
								_tmp22_ = slice_new (NULL);
								s = _tmp22_;
								_tmp23_ = s;
								_tmp24_ = *origin;
								_tmp25_ = p;
								_tmp26_ = p;
								slice_set_from_position (_tmp23_, &_tmp24_, _tmp25_.x, _tmp26_.y, 1);
								_tmp27_ = s;
								_tmp28_ = _tmp27_->max;
								angle_assign (&self->min, &_tmp28_);
								_g_object_unref0 (s);
								break;
							}
						}
					}
				}
				_angle_iterator_unref0 (_p_it);
			}
		}
	}
	result = G_MAXINT64;
	_g_object_unref0 (checked_positions);
	return result;
}

static void
slice_class_init (SliceClass * klass,
                  gpointer klass_data)
{
	slice_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &Slice_private_offset);
	G_OBJECT_CLASS (klass)->finalize = slice_finalize;
}

static void
slice_instance_init (Slice * self,
                     gpointer klass)
{
	self->priv = slice_get_instance_private (self);
}

static void
slice_finalize (GObject * obj)
{
	Slice * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_SLICE, Slice);
	G_OBJECT_CLASS (slice_parent_class)->finalize (obj);
}

 G_GNUC_NO_INLINE static GType
slice_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (SliceClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) slice_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Slice), 0, (GInstanceInitFunc) slice_instance_init, NULL };
	GType slice_type_id;
	slice_type_id = g_type_register_static (G_TYPE_OBJECT, "Slice", &g_define_type_info, G_TYPE_FLAG_NONE);
	Slice_private_offset = g_type_add_instance_private (slice_type_id, sizeof (SlicePrivate));
	return slice_type_id;
}

GType
slice_get_type (void)
{
	static GType slice_type_id__once = 0;
	if (g_once_init_enter_pointer (&slice_type_id__once)) {
		GType slice_type_id;
		slice_type_id = slice_get_type_once ();
		g_once_init_leave_pointer (&slice_type_id__once, slice_type_id);
	}
	return slice_type_id__once;
}

static inline gpointer
worm_properties_get_instance_private (WormProperties* self)
{
	return G_STRUCT_MEMBER_P (self, WormProperties_private_offset);
}

WormProperties*
worm_properties_construct (GType object_type)
{
	WormProperties * self = NULL;
	self = (WormProperties*) g_object_new (object_type, NULL);
	return self;
}

WormProperties*
worm_properties_new (void)
{
	return worm_properties_construct (TYPE_WORM_PROPERTIES);
}

gint
worm_properties_get_color (WormProperties* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_color;
	return result;
}

void
worm_properties_set_color (WormProperties* self,
                           gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = worm_properties_get_color (self);
	if (old_value != value) {
		self->priv->_color = value;
		g_object_notify_by_pspec ((GObject *) self, worm_properties_properties[WORM_PROPERTIES_COLOR_PROPERTY]);
	}
}

guint
worm_properties_get_up (WormProperties* self)
{
	guint result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_up;
	return result;
}

void
worm_properties_set_up (WormProperties* self,
                        guint value)
{
	guint old_value;
	g_return_if_fail (self != NULL);
	old_value = worm_properties_get_up (self);
	if (old_value != value) {
		self->priv->_up = value;
		g_object_notify_by_pspec ((GObject *) self, worm_properties_properties[WORM_PROPERTIES_UP_PROPERTY]);
	}
}

guint
worm_properties_get_down (WormProperties* self)
{
	guint result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_down;
	return result;
}

void
worm_properties_set_down (WormProperties* self,
                          guint value)
{
	guint old_value;
	g_return_if_fail (self != NULL);
	old_value = worm_properties_get_down (self);
	if (old_value != value) {
		self->priv->_down = value;
		g_object_notify_by_pspec ((GObject *) self, worm_properties_properties[WORM_PROPERTIES_DOWN_PROPERTY]);
	}
}

guint
worm_properties_get_left (WormProperties* self)
{
	guint result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_left;
	return result;
}

void
worm_properties_set_left (WormProperties* self,
                          guint value)
{
	guint old_value;
	g_return_if_fail (self != NULL);
	old_value = worm_properties_get_left (self);
	if (old_value != value) {
		self->priv->_left = value;
		g_object_notify_by_pspec ((GObject *) self, worm_properties_properties[WORM_PROPERTIES_LEFT_PROPERTY]);
	}
}

guint
worm_properties_get_right (WormProperties* self)
{
	guint result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_right;
	return result;
}

void
worm_properties_set_right (WormProperties* self,
                           guint value)
{
	guint old_value;
	g_return_if_fail (self != NULL);
	old_value = worm_properties_get_right (self);
	if (old_value != value) {
		self->priv->_right = value;
		g_object_notify_by_pspec ((GObject *) self, worm_properties_properties[WORM_PROPERTIES_RIGHT_PROPERTY]);
	}
}

gint
worm_properties_get_raw_up (WormProperties* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_raw_up;
	return result;
}

void
worm_properties_set_raw_up (WormProperties* self,
                            gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = worm_properties_get_raw_up (self);
	if (old_value != value) {
		self->priv->_raw_up = value;
		g_object_notify_by_pspec ((GObject *) self, worm_properties_properties[WORM_PROPERTIES_RAW_UP_PROPERTY]);
	}
}

gint
worm_properties_get_raw_down (WormProperties* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_raw_down;
	return result;
}

void
worm_properties_set_raw_down (WormProperties* self,
                              gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = worm_properties_get_raw_down (self);
	if (old_value != value) {
		self->priv->_raw_down = value;
		g_object_notify_by_pspec ((GObject *) self, worm_properties_properties[WORM_PROPERTIES_RAW_DOWN_PROPERTY]);
	}
}

gint
worm_properties_get_raw_left (WormProperties* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_raw_left;
	return result;
}

void
worm_properties_set_raw_left (WormProperties* self,
                              gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = worm_properties_get_raw_left (self);
	if (old_value != value) {
		self->priv->_raw_left = value;
		g_object_notify_by_pspec ((GObject *) self, worm_properties_properties[WORM_PROPERTIES_RAW_LEFT_PROPERTY]);
	}
}

gint
worm_properties_get_raw_right (WormProperties* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_raw_right;
	return result;
}

void
worm_properties_set_raw_right (WormProperties* self,
                               gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = worm_properties_get_raw_right (self);
	if (old_value != value) {
		self->priv->_raw_right = value;
		g_object_notify_by_pspec ((GObject *) self, worm_properties_properties[WORM_PROPERTIES_RAW_RIGHT_PROPERTY]);
	}
}

static void
worm_properties_class_init (WormPropertiesClass * klass,
                            gpointer klass_data)
{
	worm_properties_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &WormProperties_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_worm_properties_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_worm_properties_set_property;
	G_OBJECT_CLASS (klass)->finalize = worm_properties_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_PROPERTIES_COLOR_PROPERTY, worm_properties_properties[WORM_PROPERTIES_COLOR_PROPERTY] = g_param_spec_int ("color", "color", "color", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_PROPERTIES_UP_PROPERTY, worm_properties_properties[WORM_PROPERTIES_UP_PROPERTY] = g_param_spec_uint ("up", "up", "up", 0, G_MAXUINT, 0U, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_PROPERTIES_DOWN_PROPERTY, worm_properties_properties[WORM_PROPERTIES_DOWN_PROPERTY] = g_param_spec_uint ("down", "down", "down", 0, G_MAXUINT, 0U, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_PROPERTIES_LEFT_PROPERTY, worm_properties_properties[WORM_PROPERTIES_LEFT_PROPERTY] = g_param_spec_uint ("left", "left", "left", 0, G_MAXUINT, 0U, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_PROPERTIES_RIGHT_PROPERTY, worm_properties_properties[WORM_PROPERTIES_RIGHT_PROPERTY] = g_param_spec_uint ("right", "right", "right", 0, G_MAXUINT, 0U, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_PROPERTIES_RAW_UP_PROPERTY, worm_properties_properties[WORM_PROPERTIES_RAW_UP_PROPERTY] = g_param_spec_int ("raw-up", "raw-up", "raw-up", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_PROPERTIES_RAW_DOWN_PROPERTY, worm_properties_properties[WORM_PROPERTIES_RAW_DOWN_PROPERTY] = g_param_spec_int ("raw-down", "raw-down", "raw-down", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_PROPERTIES_RAW_LEFT_PROPERTY, worm_properties_properties[WORM_PROPERTIES_RAW_LEFT_PROPERTY] = g_param_spec_int ("raw-left", "raw-left", "raw-left", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_PROPERTIES_RAW_RIGHT_PROPERTY, worm_properties_properties[WORM_PROPERTIES_RAW_RIGHT_PROPERTY] = g_param_spec_int ("raw-right", "raw-right", "raw-right", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
}

static void
worm_properties_instance_init (WormProperties * self,
                               gpointer klass)
{
	self->priv = worm_properties_get_instance_private (self);
}

static void
worm_properties_finalize (GObject * obj)
{
	WormProperties * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_WORM_PROPERTIES, WormProperties);
	G_OBJECT_CLASS (worm_properties_parent_class)->finalize (obj);
}

 G_GNUC_NO_INLINE static GType
worm_properties_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (WormPropertiesClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) worm_properties_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (WormProperties), 0, (GInstanceInitFunc) worm_properties_instance_init, NULL };
	GType worm_properties_type_id;
	worm_properties_type_id = g_type_register_static (G_TYPE_OBJECT, "WormProperties", &g_define_type_info, G_TYPE_FLAG_NONE);
	WormProperties_private_offset = g_type_add_instance_private (worm_properties_type_id, sizeof (WormPropertiesPrivate));
	return worm_properties_type_id;
}

GType
worm_properties_get_type (void)
{
	static GType worm_properties_type_id__once = 0;
	if (g_once_init_enter_pointer (&worm_properties_type_id__once)) {
		GType worm_properties_type_id;
		worm_properties_type_id = worm_properties_get_type_once ();
		g_once_init_leave_pointer (&worm_properties_type_id__once, worm_properties_type_id);
	}
	return worm_properties_type_id__once;
}

static void
_vala_worm_properties_get_property (GObject * object,
                                    guint property_id,
                                    GValue * value,
                                    GParamSpec * pspec)
{
	WormProperties * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_WORM_PROPERTIES, WormProperties);
	switch (property_id) {
		case WORM_PROPERTIES_COLOR_PROPERTY:
		g_value_set_int (value, worm_properties_get_color (self));
		break;
		case WORM_PROPERTIES_UP_PROPERTY:
		g_value_set_uint (value, worm_properties_get_up (self));
		break;
		case WORM_PROPERTIES_DOWN_PROPERTY:
		g_value_set_uint (value, worm_properties_get_down (self));
		break;
		case WORM_PROPERTIES_LEFT_PROPERTY:
		g_value_set_uint (value, worm_properties_get_left (self));
		break;
		case WORM_PROPERTIES_RIGHT_PROPERTY:
		g_value_set_uint (value, worm_properties_get_right (self));
		break;
		case WORM_PROPERTIES_RAW_UP_PROPERTY:
		g_value_set_int (value, worm_properties_get_raw_up (self));
		break;
		case WORM_PROPERTIES_RAW_DOWN_PROPERTY:
		g_value_set_int (value, worm_properties_get_raw_down (self));
		break;
		case WORM_PROPERTIES_RAW_LEFT_PROPERTY:
		g_value_set_int (value, worm_properties_get_raw_left (self));
		break;
		case WORM_PROPERTIES_RAW_RIGHT_PROPERTY:
		g_value_set_int (value, worm_properties_get_raw_right (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_worm_properties_set_property (GObject * object,
                                    guint property_id,
                                    const GValue * value,
                                    GParamSpec * pspec)
{
	WormProperties * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_WORM_PROPERTIES, WormProperties);
	switch (property_id) {
		case WORM_PROPERTIES_COLOR_PROPERTY:
		worm_properties_set_color (self, g_value_get_int (value));
		break;
		case WORM_PROPERTIES_UP_PROPERTY:
		worm_properties_set_up (self, g_value_get_uint (value));
		break;
		case WORM_PROPERTIES_DOWN_PROPERTY:
		worm_properties_set_down (self, g_value_get_uint (value));
		break;
		case WORM_PROPERTIES_LEFT_PROPERTY:
		worm_properties_set_left (self, g_value_get_uint (value));
		break;
		case WORM_PROPERTIES_RIGHT_PROPERTY:
		worm_properties_set_right (self, g_value_get_uint (value));
		break;
		case WORM_PROPERTIES_RAW_UP_PROPERTY:
		worm_properties_set_raw_up (self, g_value_get_int (value));
		break;
		case WORM_PROPERTIES_RAW_DOWN_PROPERTY:
		worm_properties_set_raw_down (self, g_value_get_int (value));
		break;
		case WORM_PROPERTIES_RAW_LEFT_PROPERTY:
		worm_properties_set_raw_left (self, g_value_get_int (value));
		break;
		case WORM_PROPERTIES_RAW_RIGHT_PROPERTY:
		worm_properties_set_raw_right (self, g_value_get_int (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

gboolean
worm_positions_append_position (WormPositions* self,
                                Position* p)
{
	Position _tmp0_;
	Position _tmp1_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (p != NULL, FALSE);
	_tmp0_ = *p;
	_tmp1_ = *p;
	result = gee_abstract_collection_add ((GeeAbstractCollection*) self, (gpointer) ((guintptr) ((((guint16) _tmp0_.x) << 8) | _tmp1_.y)));
	return result;
}

void
worm_positions_get_head (WormPositions* self,
                         Position* result)
{
	guint16 head = 0U;
	gpointer _tmp0_;
	Position _tmp1_ = {0};
	g_return_if_fail (self != NULL);
	_tmp0_ = gee_linked_list_first ((GeeLinkedList*) self);
	head = (guint16) ((guintptr) _tmp0_);
	_tmp1_.x = (guint8) (head >> 8);
	_tmp1_.y = (guint8) head;
	*result = _tmp1_;
	return;
}

void
worm_positions_set_head (WormPositions* self,
                         Position* p)
{
	Position _tmp0_;
	Position _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (p != NULL);
	_tmp0_ = *p;
	_tmp1_ = *p;
	gee_abstract_list_set ((GeeAbstractList*) self, 0, (gpointer) ((guintptr) ((((guint16) _tmp0_.x) << 8) | _tmp1_.y)));
}

gboolean
worm_positions_prepend_position (WormPositions* self,
                                 Position* p)
{
	gint _tmp0_;
	gint _tmp1_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (p != NULL, FALSE);
	_tmp0_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) self);
	_tmp1_ = _tmp0_;
	if (_tmp1_ > 0) {
		Position _tmp2_;
		Position _tmp3_;
		_tmp2_ = *p;
		_tmp3_ = *p;
		result = gee_deque_offer_head ((GeeDeque*) self, (gpointer) ((guintptr) ((((guint16) _tmp2_.x) << 8) | _tmp3_.y)));
		return result;
	} else {
		Position _tmp4_;
		_tmp4_ = *p;
		result = worm_positions_append_position (self, &_tmp4_);
		return result;
	}
}

void
worm_positions_remove_tail (WormPositions* self,
                            Position* result)
{
	guint16 tail = 0U;
	gpointer _tmp0_;
	Position _tmp1_ = {0};
	g_return_if_fail (self != NULL);
	_tmp0_ = gee_deque_poll_tail ((GeeDeque*) self);
	tail = (guint16) ((guintptr) _tmp0_);
	_tmp1_.x = (guint8) (tail >> 8);
	_tmp1_.y = (guint8) tail;
	*result = _tmp1_;
	return;
}

WormPositions*
worm_positions_construct (GType object_type)
{
	WormPositions * self = NULL;
	self = (WormPositions*) gee_linked_list_construct (object_type, G_TYPE_UINT, NULL, NULL, NULL, NULL, NULL);
	return self;
}

WormPositions*
worm_positions_new (void)
{
	return worm_positions_construct (TYPE_WORM_POSITIONS);
}

static void
worm_positions_class_init (WormPositionsClass * klass,
                           gpointer klass_data)
{
	worm_positions_parent_class = g_type_class_peek_parent (klass);
}

static void
worm_positions_instance_init (WormPositions * self,
                              gpointer klass)
{
}

 G_GNUC_NO_INLINE static GType
worm_positions_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (WormPositionsClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) worm_positions_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (WormPositions), 0, (GInstanceInitFunc) worm_positions_instance_init, NULL };
	GType worm_positions_type_id;
	worm_positions_type_id = g_type_register_static (GEE_TYPE_LINKED_LIST, "WormPositions", &g_define_type_info, G_TYPE_FLAG_NONE);
	return worm_positions_type_id;
}

GType
worm_positions_get_type (void)
{
	static GType worm_positions_type_id__once = 0;
	if (g_once_init_enter_pointer (&worm_positions_type_id__once)) {
		GType worm_positions_type_id;
		worm_positions_type_id = worm_positions_get_type_once ();
		g_once_init_leave_pointer (&worm_positions_type_id__once, worm_positions_type_id);
	}
	return worm_positions_type_id__once;
}

static inline gpointer
double_bit_array_get_instance_private (DoubleBitArray* self)
{
	return G_STRUCT_MEMBER_P (self, DoubleBitArray_private_offset);
}

gulong
double_bit_array_get_at (DoubleBitArray* self,
                         gulong index)
{
	gulong result;
	g_return_val_if_fail (self != NULL, 0UL);
	_vala_return_val_if_fail (index < DOUBLE_BIT_ARRAY_size, "index < size", 0UL);
	result = (self->priv->array >> (2 * index)) & DOUBLE_BIT_ARRAY_BITS_MASK;
	return result;
}

void
double_bit_array_set_at (DoubleBitArray* self,
                         gulong index,
                         gulong l)
{
	g_return_if_fail (self != NULL);
	_vala_return_if_fail (index < DOUBLE_BIT_ARRAY_size, "index < size");
	self->priv->array = self->priv->array & (~(DOUBLE_BIT_ARRAY_BITS_MASK << (2 * index)));
	self->priv->array = self->priv->array | ((l & DOUBLE_BIT_ARRAY_BITS_MASK) << (2 * index));
}

DoubleBitArray*
double_bit_array_construct (GType object_type)
{
	DoubleBitArray* self = NULL;
	self = (DoubleBitArray*) g_type_create_instance (object_type);
	return self;
}

DoubleBitArray*
double_bit_array_new (void)
{
	return double_bit_array_construct (TYPE_DOUBLE_BIT_ARRAY);
}

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

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

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

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

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

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

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

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

void
value_set_double_bit_array (GValue* value,
                            gpointer v_object)
{
	DoubleBitArray * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_DOUBLE_BIT_ARRAY));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_DOUBLE_BIT_ARRAY));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		double_bit_array_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		double_bit_array_unref (old);
	}
}

void
value_take_double_bit_array (GValue* value,
                             gpointer v_object)
{
	DoubleBitArray * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_DOUBLE_BIT_ARRAY));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_DOUBLE_BIT_ARRAY));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		double_bit_array_unref (old);
	}
}

static void
double_bit_array_class_init (DoubleBitArrayClass * klass,
                             gpointer klass_data)
{
	double_bit_array_parent_class = g_type_class_peek_parent (klass);
	((DoubleBitArrayClass *) klass)->finalize = double_bit_array_finalize;
	g_type_class_adjust_private_offset (klass, &DoubleBitArray_private_offset);
}

static void
double_bit_array_instance_init (DoubleBitArray * self,
                                gpointer klass)
{
	self->priv = double_bit_array_get_instance_private (self);
	self->ref_count = 1;
}

static void
double_bit_array_finalize (DoubleBitArray * obj)
{
	DoubleBitArray * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_DOUBLE_BIT_ARRAY, DoubleBitArray);
	g_signal_handlers_destroy (self);
}

 G_GNUC_NO_INLINE static GType
double_bit_array_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { value_double_bit_array_init, value_double_bit_array_free_value, value_double_bit_array_copy_value, value_double_bit_array_peek_pointer, "p", value_double_bit_array_collect_value, "p", value_double_bit_array_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (DoubleBitArrayClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) double_bit_array_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DoubleBitArray), 0, (GInstanceInitFunc) double_bit_array_instance_init, &g_define_type_value_table };
	static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
	GType double_bit_array_type_id;
	double_bit_array_type_id = g_type_register_fundamental (g_type_fundamental_next (), "DoubleBitArray", &g_define_type_info, &g_define_type_fundamental_info, G_TYPE_FLAG_NONE);
	DoubleBitArray_private_offset = g_type_add_instance_private (double_bit_array_type_id, sizeof (DoubleBitArrayPrivate));
	return double_bit_array_type_id;
}

GType
double_bit_array_get_type (void)
{
	static GType double_bit_array_type_id__once = 0;
	if (g_once_init_enter_pointer (&double_bit_array_type_id__once)) {
		GType double_bit_array_type_id;
		double_bit_array_type_id = double_bit_array_get_type_once ();
		g_once_init_leave_pointer (&double_bit_array_type_id__once, double_bit_array_type_id);
	}
	return double_bit_array_type_id__once;
}

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

void
double_bit_array_unref (gpointer instance)
{
	DoubleBitArray * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		DOUBLE_BIT_ARRAY_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

static inline gpointer
worm_get_instance_private (Worm* self)
{
	return G_STRUCT_MEMBER_P (self, Worm_private_offset);
}

static Block8Data*
block8_data_ref (Block8Data* _data8_)
{
	g_atomic_int_inc (&_data8_->_ref_count_);
	return _data8_;
}

static void
block8_data_unref (void * _userdata_)
{
	Block8Data* _data8_;
	_data8_ = (Block8Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data8_->_ref_count_)) {
		Worm* self;
		self = _data8_->self;
		_g_object_unref0 (self);
		g_slice_free (Block8Data, _data8_);
	}
}

static GeeList*
__lambda4_ (Block8Data* _data8_,
            Worm* worm)
{
	Worm* self;
	GeeList* _tmp0_;
	GeeList* result;
	self = _data8_->self;
	g_return_val_if_fail (worm != NULL, NULL);
	_tmp0_ = _data8_->cb0 (worm, _data8_->cb0_target);
	result = _tmp0_;
	return result;
}

static GeeList*
___lambda4__worm_get_other_worms_type (Worm* _self_,
                                       gpointer self)
{
	GeeList* result;
	result = __lambda4_ (self, _self_);
	return result;
}

static GeeList*
__lambda5_ (Block8Data* _data8_)
{
	Worm* self;
	GeeList* _tmp0_;
	GeeList* result;
	self = _data8_->self;
	_tmp0_ = _data8_->cb1 (_data8_->cb1_target);
	result = _tmp0_;
	return result;
}

static GeeList*
___lambda5__worm_get_bonuses_type (gpointer self)
{
	GeeList* result;
	result = __lambda5_ (self);
	return result;
}

Worm*
worm_construct (GType object_type,
                gint id,
                guint8 width,
                guint8 height,
                WormGetOtherWormsType cb0,
                gpointer cb0_target,
                WormGetBonusesType cb1,
                gpointer cb1_target)
{
	Worm * self = NULL;
	Block8Data* _data8_;
	gint capacity = 0;
	_data8_ = g_slice_new0 (Block8Data);
	_data8_->_ref_count_ = 1;
	_data8_->cb0 = cb0;
	_data8_->cb0_target = cb0_target;
	_data8_->cb1 = cb1;
	_data8_->cb1_target = cb1_target;
	capacity = (gint) (width * height);
	self = (Worm*) g_object_new (object_type, "id", id, "width", width, "height", height, "capacity", capacity, NULL);
	_data8_->self = g_object_ref (self);
	(self->priv->get_other_worms_target_destroy_notify == NULL) ? NULL : (self->priv->get_other_worms_target_destroy_notify (self->priv->get_other_worms_target), NULL);
	self->priv->get_other_worms = NULL;
	self->priv->get_other_worms_target = NULL;
	self->priv->get_other_worms_target_destroy_notify = NULL;
	self->priv->get_other_worms = ___lambda4__worm_get_other_worms_type;
	self->priv->get_other_worms_target = block8_data_ref (_data8_);
	self->priv->get_other_worms_target_destroy_notify = block8_data_unref;
	(self->priv->get_bonuses_target_destroy_notify == NULL) ? NULL : (self->priv->get_bonuses_target_destroy_notify (self->priv->get_bonuses_target), NULL);
	self->priv->get_bonuses = NULL;
	self->priv->get_bonuses_target = NULL;
	self->priv->get_bonuses_target_destroy_notify = NULL;
	self->priv->get_bonuses = ___lambda5__worm_get_bonuses_type;
	self->priv->get_bonuses_target = block8_data_ref (_data8_);
	self->priv->get_bonuses_target_destroy_notify = block8_data_unref;
	block8_data_unref (_data8_);
	_data8_ = NULL;
	return self;
}

Worm*
worm_new (gint id,
          guint8 width,
          guint8 height,
          WormGetOtherWormsType cb0,
          gpointer cb0_target,
          WormGetBonusesType cb1,
          gpointer cb1_target)
{
	return worm_construct (TYPE_WORM, id, width, height, cb0, cb0_target, cb1, cb1_target);
}

void
worm_set_start (Worm* self,
                guint8 x,
                guint8 y,
                WormDirection direction)
{
	WormPositions* _tmp0_;
	guint8 _tmp1_;
	WormKeyQueue* _tmp6_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->list;
	gee_abstract_collection_clear ((GeeAbstractCollection*) _tmp0_);
	_tmp1_ = self->priv->_lives;
	if (((gint) _tmp1_) > 0) {
		GeeArrayList* _tmp2_;
		Position _tmp3_ = {0};
		WormPositions* _tmp4_;
		Position _tmp5_;
		_tmp2_ = self->priv->bonus_eaten;
		gee_abstract_collection_clear ((GeeAbstractCollection*) _tmp2_);
		_tmp3_.x = x;
		_tmp3_.y = y;
		worm_set_starting_position (self, &_tmp3_);
		_tmp4_ = self->list;
		_tmp5_ = self->priv->_starting_position;
		worm_positions_append_position (_tmp4_, &_tmp5_);
		self->priv->starting_direction = direction;
		worm_set_direction (self, direction);
	}
	worm_set_change (self, 0);
	_tmp6_ = self->priv->key_queue;
	worm_key_queue_clear (_tmp6_);
}

void
worm_human_move (Worm* self,
                 gint* board,
                 gint board_length1,
                 gint board_length2,
                 GeeLinkedList* worms)
{
	WormKeyQueue* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (worms != NULL);
	_tmp0_ = self->priv->key_queue;
	if (!worm_key_queue_is_empty (_tmp0_)) {
		worm_dequeue_keypress (self, board, (gint) board_length1, (gint) board_length2, (GeeList*) worms);
	}
}

void
worm_move_part_1 (Worm* self,
                  gint* board,
                  gint board_length1,
                  gint board_length2)
{
	Position position = {0};
	Position _tmp0_ = {0};
	Position _tmp1_;
	WormDirection _tmp2_;
	guint8 _tmp3_;
	guint8 _tmp4_;
	WormPositions* _tmp5_;
	Position _tmp6_;
	g_return_if_fail (self != NULL);
	worm_get_head (self, &_tmp0_);
	_tmp1_ = _tmp0_;
	position = _tmp1_;
	_tmp2_ = self->priv->_direction;
	_tmp3_ = self->priv->_width;
	_tmp4_ = self->priv->_height;
	position_move (&position, _tmp2_, _tmp3_, _tmp4_);
	_tmp5_ = self->list;
	_tmp6_ = position;
	worm_positions_prepend_position (_tmp5_, &_tmp6_);
}

void
worm_move_part_2 (Worm* self,
                  gint* board,
                  gint board_length1,
                  gint board_length2,
                  Position* head_position)
{
	gint _tmp1_;
	g_return_if_fail (self != NULL);
	if (head_position != NULL) {
		Position _tmp0_ = {0};
		memset (&_tmp0_, 0, sizeof (Position));
		_tmp0_.x = (*head_position).x;
		_tmp0_.y = (*head_position).y;
		worm_set_head (self, &_tmp0_);
	}
	_tmp1_ = self->priv->_change;
	if (_tmp1_ > 0) {
		gint _tmp2_;
		_tmp2_ = self->priv->_change;
		worm_set_change (self, _tmp2_ - 1);
	} else {
		WormPositions* _tmp3_;
		gint _tmp4_;
		gint _tmp5_;
		WormPositions* _tmp6_;
		Position _tmp7_ = {0};
		_tmp3_ = self->list;
		_tmp4_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp3_);
		_tmp5_ = _tmp4_;
		_vala_assert (_tmp5_ > 0, "list.size > 0");
		_tmp6_ = self->list;
		worm_positions_remove_tail (_tmp6_, &_tmp7_);
		worm_remove_bonus_eaten_position (self, &_tmp7_);
	}
	g_signal_emit (self, worm_signals[WORM_BONUS_FOUND_SIGNAL], 0);
	if (self->priv->rounds_to_stay_dematerialized > 1) {
		self->priv->rounds_to_stay_dematerialized = self->priv->rounds_to_stay_dematerialized - 1;
	}
	if (self->priv->rounds_to_stay_dematerialized == 1) {
		worm_materialize (self, board, (gint) board_length1, (gint) board_length2);
	}
}

void
worm_remove_bonus_eaten_position (Worm* self,
                                  Position* p)
{
	GeeArrayList* _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (p != NULL);
	_tmp0_ = self->priv->bonus_eaten;
	_tmp1_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp0_);
	_tmp2_ = _tmp1_;
	if (_tmp2_ > 0) {
		guint16 a = 0U;
		Position _tmp3_;
		Position _tmp4_;
		GeeArrayList* _tmp5_;
		_tmp3_ = *p;
		_tmp4_ = *p;
		a = (guint16) ((((guint16) _tmp3_.x) << 8) | _tmp4_.y);
		_tmp5_ = self->priv->bonus_eaten;
		if (gee_abstract_collection_contains ((GeeAbstractCollection*) _tmp5_, (gpointer) ((guintptr) a))) {
			GeeArrayList* _tmp6_;
			_tmp6_ = self->priv->bonus_eaten;
			gee_abstract_collection_remove ((GeeAbstractCollection*) _tmp6_, (gpointer) ((guintptr) a));
		}
	}
}

void
worm_add_bonus_eaten_position (Worm* self,
                               guint8 x,
                               guint8 y)
{
	GeeArrayList* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->bonus_eaten;
	gee_abstract_collection_add ((GeeAbstractCollection*) _tmp0_, (gpointer) ((guintptr) ((((guint16) x) << 8) | y)));
}

gboolean
worm_was_bonus_eaten_at_this_position (Worm* self,
                                       guint16 position)
{
	GeeArrayList* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->bonus_eaten;
	result = gee_abstract_collection_contains ((GeeAbstractCollection*) _tmp0_, (gpointer) ((guintptr) position));
	return result;
}

void
worm_reduce_tail (Worm* self,
                  gint erase_size)
{
	g_return_if_fail (self != NULL);
	if (erase_size > 0) {
		{
			gint i = 0;
			i = 0;
			{
				gboolean _tmp0_ = FALSE;
				_tmp0_ = TRUE;
				while (TRUE) {
					WormPositions* _tmp2_;
					gint _tmp3_;
					gint _tmp4_;
					WormPositions* _tmp5_;
					Position _tmp6_ = {0};
					if (!_tmp0_) {
						gint _tmp1_;
						_tmp1_ = i;
						i = _tmp1_ + 1;
					}
					_tmp0_ = FALSE;
					if (!(i < erase_size)) {
						break;
					}
					_tmp2_ = self->list;
					_tmp3_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp2_);
					_tmp4_ = _tmp3_;
					_vala_assert (_tmp4_ > 0, "list.size > 0");
					_tmp5_ = self->list;
					worm_positions_remove_tail (_tmp5_, &_tmp6_);
					worm_remove_bonus_eaten_position (self, &_tmp6_);
				}
			}
		}
	}
}

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

void
worm_reverse (Worm* self)
{
	gboolean _tmp0_ = FALSE;
	g_return_if_fail (self != NULL);
	if (!self->is_stopped) {
		WormPositions* _tmp1_;
		gboolean _tmp2_;
		gboolean _tmp3_;
		_tmp1_ = self->list;
		_tmp2_ = gee_collection_get_is_empty ((GeeCollection*) _tmp1_);
		_tmp3_ = _tmp2_;
		_tmp0_ = !_tmp3_;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		WormPositions* reversed_list = NULL;
		WormPositions* _tmp4_;
		WormPositions* _tmp18_;
		WormPositions* _tmp19_;
		WormPositions* _tmp20_;
		gpointer _tmp21_;
		WormPositions* _tmp22_;
		gpointer _tmp23_;
		_tmp4_ = worm_positions_new ();
		reversed_list = _tmp4_;
		{
			WormPositions* _pos_list = NULL;
			WormPositions* _tmp5_;
			gint _pos_size = 0;
			WormPositions* _tmp6_;
			gint _tmp7_;
			gint _tmp8_;
			gint _pos_index = 0;
			_tmp5_ = self->list;
			_pos_list = _tmp5_;
			_tmp6_ = _pos_list;
			_tmp7_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp6_);
			_tmp8_ = _tmp7_;
			_pos_size = _tmp8_;
			_pos_index = -1;
			while (TRUE) {
				gint _tmp9_;
				gint _tmp10_;
				guint16 pos = 0U;
				WormPositions* _tmp11_;
				gpointer _tmp12_;
				WormPositions* _tmp13_;
				gint _tmp14_;
				gint _tmp15_;
				_pos_index = _pos_index + 1;
				_tmp9_ = _pos_index;
				_tmp10_ = _pos_size;
				if (!(_tmp9_ < _tmp10_)) {
					break;
				}
				_tmp11_ = _pos_list;
				_tmp12_ = gee_abstract_list_get ((GeeAbstractList*) _tmp11_, _pos_index);
				pos = (guint16) ((guintptr) _tmp12_);
				_tmp13_ = reversed_list;
				_tmp14_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp13_);
				_tmp15_ = _tmp14_;
				if (_tmp15_ > 0) {
					WormPositions* _tmp16_;
					_tmp16_ = reversed_list;
					gee_deque_offer_head ((GeeDeque*) _tmp16_, (gpointer) ((guintptr) pos));
				} else {
					WormPositions* _tmp17_;
					_tmp17_ = reversed_list;
					gee_abstract_collection_add ((GeeAbstractCollection*) _tmp17_, (gpointer) ((guintptr) pos));
				}
			}
		}
		_tmp18_ = reversed_list;
		_tmp19_ = _g_object_ref0 (_tmp18_);
		_g_object_unref0 (self->list);
		self->list = _tmp19_;
		_tmp20_ = self->list;
		_tmp21_ = gee_abstract_list_get ((GeeAbstractList*) _tmp20_, 0);
		_tmp22_ = self->list;
		_tmp23_ = gee_abstract_list_get ((GeeAbstractList*) _tmp22_, 1);
		if (((guint8) ((guint16) ((guintptr) _tmp21_))) == ((guint8) ((guint16) ((guintptr) _tmp23_)))) {
			WormDirection _tmp24_ = 0;
			WormPositions* _tmp25_;
			gpointer _tmp26_;
			WormPositions* _tmp27_;
			gpointer _tmp28_;
			_tmp25_ = self->list;
			_tmp26_ = gee_abstract_list_get ((GeeAbstractList*) _tmp25_, 0);
			_tmp27_ = self->list;
			_tmp28_ = gee_abstract_list_get ((GeeAbstractList*) _tmp27_, 1);
			if ((((guint16) ((guintptr) _tmp26_)) >> 8) > (((guint16) ((guintptr) _tmp28_)) >> 8)) {
				_tmp24_ = WORM_DIRECTION_RIGHT;
			} else {
				_tmp24_ = WORM_DIRECTION_LEFT;
			}
			worm_set_direction (self, _tmp24_);
		} else {
			WormDirection _tmp29_ = 0;
			WormPositions* _tmp30_;
			gpointer _tmp31_;
			WormPositions* _tmp32_;
			gpointer _tmp33_;
			_tmp30_ = self->list;
			_tmp31_ = gee_abstract_list_get ((GeeAbstractList*) _tmp30_, 0);
			_tmp32_ = self->list;
			_tmp33_ = gee_abstract_list_get ((GeeAbstractList*) _tmp32_, 1);
			if (((guint8) ((guint16) ((guintptr) _tmp31_))) > ((guint8) ((guint16) ((guintptr) _tmp33_)))) {
				_tmp29_ = WORM_DIRECTION_DOWN;
			} else {
				_tmp29_ = WORM_DIRECTION_UP;
			}
			worm_set_direction (self, _tmp29_);
		}
		_g_object_unref0 (reversed_list);
	}
}

static gboolean
worm_does_list_contain_position (WormPositions* position_list,
                                 guint16 position)
{
	gboolean result;
	g_return_val_if_fail (position_list != NULL, FALSE);
	if (position_list != NULL) {
		{
			WormPositions* _p_list = NULL;
			gint _p_size = 0;
			WormPositions* _tmp0_;
			gint _tmp1_;
			gint _tmp2_;
			gint _p_index = 0;
			_p_list = position_list;
			_tmp0_ = _p_list;
			_tmp1_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp0_);
			_tmp2_ = _tmp1_;
			_p_size = _tmp2_;
			_p_index = -1;
			while (TRUE) {
				gint _tmp3_;
				gint _tmp4_;
				guint16 p = 0U;
				WormPositions* _tmp5_;
				gpointer _tmp6_;
				_p_index = _p_index + 1;
				_tmp3_ = _p_index;
				_tmp4_ = _p_size;
				if (!(_tmp3_ < _tmp4_)) {
					break;
				}
				_tmp5_ = _p_list;
				_tmp6_ = gee_abstract_list_get ((GeeAbstractList*) _tmp5_, _p_index);
				p = (guint16) ((guintptr) _tmp6_);
				if (p == position) {
					result = TRUE;
					return result;
				}
			}
		}
	}
	result = FALSE;
	return result;
}

gboolean
worm_is_position_clear_of_materialized_worms (Worm* self,
                                              GeeList* worms,
                                              Position* position)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (worms != NULL, FALSE);
	g_return_val_if_fail (position != NULL, FALSE);
	{
		GeeList* _worm_list = NULL;
		gint _worm_size = 0;
		GeeList* _tmp0_;
		gint _tmp1_;
		gint _tmp2_;
		gint _worm_index = 0;
		_worm_list = worms;
		_tmp0_ = _worm_list;
		_tmp1_ = gee_collection_get_size ((GeeCollection*) _tmp0_);
		_tmp2_ = _tmp1_;
		_worm_size = _tmp2_;
		_worm_index = -1;
		while (TRUE) {
			gint _tmp3_;
			gint _tmp4_;
			Worm* worm = NULL;
			GeeList* _tmp5_;
			gpointer _tmp6_;
			gboolean _tmp7_ = FALSE;
			Worm* _tmp8_;
			gboolean _tmp9_;
			gboolean _tmp10_;
			_worm_index = _worm_index + 1;
			_tmp3_ = _worm_index;
			_tmp4_ = _worm_size;
			if (!(_tmp3_ < _tmp4_)) {
				break;
			}
			_tmp5_ = _worm_list;
			_tmp6_ = gee_list_get (_tmp5_, _worm_index);
			worm = (Worm*) _tmp6_;
			_tmp8_ = worm;
			_tmp9_ = worm_get_is_materialized (_tmp8_);
			_tmp10_ = _tmp9_;
			if (_tmp10_) {
				Worm* _tmp11_;
				WormPositions* _tmp12_;
				Position _tmp13_;
				Position _tmp14_;
				_tmp11_ = worm;
				_tmp12_ = _tmp11_->list;
				_tmp13_ = *position;
				_tmp14_ = *position;
				_tmp7_ = worm_does_list_contain_position (_tmp12_, (guint16) ((((guint16) _tmp13_.x) << 8) | _tmp14_.y));
			} else {
				_tmp7_ = FALSE;
			}
			if (_tmp7_) {
				result = FALSE;
				_g_object_unref0 (worm);
				return result;
			}
			_g_object_unref0 (worm);
		}
	}
	result = TRUE;
	return result;
}

static gboolean
worm_is_board_position_occupied (Position* p,
                                 gint* board,
                                 gint board_length1,
                                 gint board_length2)
{
	Position _tmp0_;
	Position _tmp1_;
	gint _tmp2_;
	gboolean result;
	g_return_val_if_fail (p != NULL, FALSE);
	_tmp0_ = *p;
	_tmp1_ = *p;
	_tmp2_ = board[(_tmp0_.x * board_length2) + _tmp1_.y];
	result = _tmp2_ > ((gint) NIBBLES_GAME_EMPTYCHAR);
	return result;
}

gboolean
worm_can_move_to (Worm* self,
                  gint* board,
                  gint board_length1,
                  gint board_length2,
                  GeeList* worms,
                  Position* position)
{
	Position _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (worms != NULL, FALSE);
	g_return_val_if_fail (position != NULL, FALSE);
	_tmp0_ = *position;
	if (worm_is_board_position_occupied (&_tmp0_, board, (gint) board_length1, (gint) board_length2)) {
		result = FALSE;
		return result;
	} else {
		Position _tmp1_;
		_tmp1_ = *position;
		if (!worm_is_position_clear_of_materialized_worms (self, worms, &_tmp1_)) {
			gboolean _tmp2_;
			gboolean _tmp3_;
			_tmp2_ = worm_get_is_materialized (self);
			_tmp3_ = _tmp2_;
			result = !_tmp3_;
			return result;
		} else {
			result = TRUE;
			return result;
		}
	}
}

gboolean
worm_can_move_to_map (Worm* self,
                      gint* board,
                      gint board_length1,
                      gint board_length2,
                      WormMap* worm_map,
                      Position* position)
{
	Position _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (worm_map != NULL, FALSE);
	g_return_val_if_fail (position != NULL, FALSE);
	_tmp0_ = *position;
	if (worm_is_board_position_occupied (&_tmp0_, board, (gint) board_length1, (gint) board_length2)) {
		result = FALSE;
		return result;
	} else {
		Position _tmp1_;
		_tmp1_ = *position;
		if (worm_map_contain_position (worm_map, &_tmp1_)) {
			gboolean _tmp2_;
			gboolean _tmp3_;
			_tmp2_ = worm_get_is_materialized (self);
			_tmp3_ = _tmp2_;
			result = !_tmp3_;
			return result;
		} else {
			result = TRUE;
			return result;
		}
	}
}

gboolean
worm_can_move_direction (Worm* self,
                         gint* board,
                         gint board_length1,
                         gint board_length2,
                         GeeList* worms,
                         WormDirection direction)
{
	Position position = {0};
	WormPositions* _tmp0_;
	Position _tmp1_ = {0};
	guint8 _tmp2_;
	guint8 _tmp3_;
	Position _tmp4_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (worms != NULL, FALSE);
	_tmp0_ = self->list;
	worm_positions_get_head (_tmp0_, &_tmp1_);
	position = _tmp1_;
	_tmp2_ = self->priv->_width;
	_tmp3_ = self->priv->_height;
	position_move (&position, direction, _tmp2_, _tmp3_);
	_tmp4_ = position;
	result = worm_can_move_to (self, board, (gint) board_length1, (gint) board_length2, worms, &_tmp4_);
	return result;
}

void
worm_spawn (Worm* self,
            gint* board,
            gint board_length1,
            gint board_length2)
{
	WormPositions* _tmp0_;
	gboolean _tmp1_;
	gboolean _tmp2_;
	g_return_if_fail (self != NULL);
	_vala_return_if_fail (((gint) WORM_STARTING_LENGTH) > 0, "STARTING_LENGTH > 0");
	_tmp0_ = self->list;
	_tmp1_ = gee_collection_get_is_empty ((GeeCollection*) _tmp0_);
	_tmp2_ = _tmp1_;
	if (!_tmp2_) {
		worm_set_change (self, WORM_STARTING_LENGTH - 1);
		self->priv->rounds_to_stay_dematerialized = (gint) WORM_STARTING_LENGTH;
		{
			guint8 i = 0U;
			i = (guint8) 0;
			{
				gboolean _tmp3_ = FALSE;
				_tmp3_ = TRUE;
				while (TRUE) {
					if (!_tmp3_) {
						guint8 _tmp4_;
						_tmp4_ = i;
						i = _tmp4_ + 1;
					}
					_tmp3_ = FALSE;
					if (!(i < WORM_STARTING_LENGTH)) {
						break;
					}
					worm_move_part_1 (self, board, (gint) board_length1, (gint) board_length2);
					worm_move_part_2 (self, board, (gint) board_length1, (gint) board_length2, NULL);
				}
			}
		}
	}
}

static void
worm_materialize (Worm* self,
                  gint* board,
                  gint board_length1,
                  gint board_length2)
{
	WormMap* worm_map = NULL;
	WormGetOtherWormsType _tmp0_;
	gpointer _tmp0__target;
	GeeList* _tmp1_;
	GeeList* _tmp2_;
	guint8 _tmp3_;
	guint8 _tmp4_;
	WormMap* _tmp5_;
	WormMap* _tmp6_;
	WormMap* _tmp7_;
	WormPositions* _tmp8_;
	Position position = {0};
	Position _tmp9_ = {0};
	Position _tmp10_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->get_other_worms;
	_tmp0__target = self->priv->get_other_worms_target;
	_tmp1_ = _tmp0_ (self, _tmp0__target);
	_tmp2_ = _tmp1_;
	_tmp3_ = self->priv->_width;
	_tmp4_ = self->priv->_height;
	_tmp5_ = worm_map_new (_tmp2_, _tmp3_, _tmp4_);
	_tmp6_ = _tmp5_;
	_g_object_unref0 (_tmp2_);
	worm_map = _tmp6_;
	_tmp7_ = worm_map;
	_tmp8_ = self->list;
	if (worm_map_contains (_tmp7_, _tmp8_)) {
		self->priv->rounds_to_stay_dematerialized = self->priv->rounds_to_stay_dematerialized + 1;
		_g_object_unref0 (worm_map);
		return;
	}
	worm_get_head (self, &_tmp9_);
	_tmp10_ = _tmp9_;
	position = _tmp10_;
	{
		gint i = 0;
		i = 12;
		{
			gboolean _tmp11_ = FALSE;
			_tmp11_ = TRUE;
			while (TRUE) {
				Position _tmp13_;
				WormDirection _tmp14_;
				Position _tmp15_ = {0};
				Position _tmp16_;
				WormMap* _tmp17_;
				Position _tmp18_;
				if (!_tmp11_) {
					gint _tmp12_;
					_tmp12_ = i;
					i = _tmp12_ - 1;
				}
				_tmp11_ = FALSE;
				if (!(i > 0)) {
					break;
				}
				_tmp13_ = position;
				_tmp14_ = self->priv->_direction;
				worm_get_position_after_direction_move (self, &_tmp13_, _tmp14_, &_tmp15_);
				position = _tmp15_;
				_tmp16_ = position;
				if (worm_is_board_position_occupied (&_tmp16_, board, (gint) board_length1, (gint) board_length2)) {
					self->priv->rounds_to_stay_dematerialized = 0;
					_g_object_unref0 (worm_map);
					return;
				}
				_tmp17_ = worm_map;
				_tmp18_ = position;
				if (worm_map_contain_position (_tmp17_, &_tmp18_)) {
					self->priv->rounds_to_stay_dematerialized = self->priv->rounds_to_stay_dematerialized + 1;
					_g_object_unref0 (worm_map);
					return;
				}
			}
		}
	}
	self->priv->rounds_to_stay_dematerialized = 0;
	_g_object_unref0 (worm_map);
}

void
worm_dematerialize (Worm* self,
                    gint rounds,
                    gint gamedelay)
{
	gint _tmp0_ = 0;
	g_return_if_fail (self != NULL);
	if (rounds > 1) {
		_tmp0_ = rounds;
	} else {
		_tmp0_ = 1;
	}
	self->priv->rounds_to_stay_dematerialized = _tmp0_;
	self->rounds_to_stay_still = 2;
}

void
worm_add_life (Worm* self)
{
	guint8 _tmp0_;
	guint8 _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_lives;
	if (_tmp0_ > WORM_MAX_LIVES) {
		return;
	}
	_tmp1_ = self->priv->_lives;
	worm_set_lives (self, _tmp1_ + 1);
}

static inline void
worm_lose_life (Worm* self)
{
	guint8 _tmp0_;
	guint8 _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_lives;
	if (((gint) _tmp0_) == 0) {
		return;
	}
	_tmp1_ = self->priv->_lives;
	worm_set_lives (self, _tmp1_ - 1);
}

void
worm_reset (Worm* self,
            gint* board,
            gint board_length1,
            gint board_length2)
{
	WormKeyQueue* _tmp0_;
	WormPositions* _tmp1_;
	GeeArrayList* _tmp2_;
	guint8 _tmp3_;
	g_return_if_fail (self != NULL);
	self->is_stopped = TRUE;
	self->priv->rounds_to_stay_dematerialized = 0;
	_tmp0_ = self->priv->key_queue;
	worm_key_queue_clear (_tmp0_);
	worm_lose_life (self);
	_tmp1_ = self->list;
	gee_abstract_collection_clear ((GeeAbstractCollection*) _tmp1_);
	_tmp2_ = self->priv->bonus_eaten;
	gee_abstract_collection_clear ((GeeAbstractCollection*) _tmp2_);
	_tmp3_ = self->priv->_lives;
	if (((gint) _tmp3_) > 0) {
		WormPositions* _tmp4_;
		Position _tmp5_;
		_tmp4_ = self->list;
		_tmp5_ = self->priv->_starting_position;
		worm_positions_append_position (_tmp4_, &_tmp5_);
		worm_set_direction (self, self->priv->starting_direction);
		worm_spawn (self, board, (gint) board_length1, (gint) board_length2);
		worm_dematerialize (self, 3, 35);
	}
}

void
worm_position_move (Worm* self,
                    Position* result)
{
	Position position = {0};
	Position _tmp0_ = {0};
	Position _tmp1_;
	Position _tmp2_ = {0};
	Position _tmp3_;
	Position _tmp4_ = {0};
	WormDirection _tmp5_;
	guint8 _tmp6_;
	guint8 _tmp7_;
	g_return_if_fail (self != NULL);
	worm_get_head (self, &_tmp0_);
	_tmp1_ = _tmp0_;
	worm_get_head (self, &_tmp2_);
	_tmp3_ = _tmp2_;
	_tmp4_.x = _tmp1_.x;
	_tmp4_.y = _tmp3_.y;
	position = _tmp4_;
	_tmp5_ = self->priv->_direction;
	_tmp6_ = self->priv->_width;
	_tmp7_ = self->priv->_height;
	position_move (&position, _tmp5_, _tmp6_, _tmp7_);
	*result = position;
	return;
}

void
worm_get_position_after_direction_move (Worm* self,
                                        Position* origin,
                                        WormDirection direction,
                                        Position* result)
{
	Position position = {0};
	Position _tmp0_;
	Position _tmp1_;
	Position _tmp2_ = {0};
	guint8 _tmp3_;
	guint8 _tmp4_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (origin != NULL);
	_tmp0_ = *origin;
	_tmp1_ = *origin;
	_tmp2_.x = _tmp0_.x;
	_tmp2_.y = _tmp1_.y;
	position = _tmp2_;
	_tmp3_ = self->priv->_width;
	_tmp4_ = self->priv->_height;
	position_move (&position, direction, _tmp3_, _tmp4_);
	*result = position;
	return;
}

static WormDirection
worm_uturn (Worm* self,
            gint* board,
            gint board_length1,
            gint board_length2,
            GeeList* worms,
            WormDirection direction)
{
	Position tmp = {0};
	WormDirection dirA = 0;
	WormDirection dirB = 0;
	gint length_posA = 0;
	gint length_posB = 0;
	gboolean _tmp0_ = FALSE;
	WormDirection result;
	g_return_val_if_fail (self != NULL, 0);
	g_return_val_if_fail (worms != NULL, 0);
	length_posA = 0;
	length_posB = 0;
	if (direction == WORM_DIRECTION_DOWN) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = direction == WORM_DIRECTION_UP;
	}
	if (_tmp0_) {
		WormPositions* _tmp1_;
		gpointer _tmp2_;
		WormPositions* _tmp3_;
		gpointer _tmp4_;
		Position _tmp5_ = {0};
		guint8 _tmp6_;
		guint8 _tmp7_;
		WormPositions* _tmp15_;
		gpointer _tmp16_;
		WormPositions* _tmp17_;
		gpointer _tmp18_;
		Position _tmp19_ = {0};
		guint8 _tmp20_;
		guint8 _tmp21_;
		_tmp1_ = self->list;
		_tmp2_ = gee_abstract_list_get ((GeeAbstractList*) _tmp1_, 0);
		_tmp3_ = self->list;
		_tmp4_ = gee_abstract_list_get ((GeeAbstractList*) _tmp3_, 0);
		_tmp5_.x = (guint8) (((guint16) ((guintptr) _tmp2_)) >> 8);
		_tmp5_.y = (guint8) ((guint16) ((guintptr) _tmp4_));
		tmp = _tmp5_;
		dirA = WORM_DIRECTION_LEFT;
		_tmp6_ = self->priv->_width;
		_tmp7_ = self->priv->_height;
		position_move (&tmp, dirA, _tmp6_, _tmp7_);
		{
			gboolean _tmp8_ = FALSE;
			length_posA = 0;
			_tmp8_ = TRUE;
			while (TRUE) {
				gboolean _tmp12_ = FALSE;
				guint8 _tmp13_;
				if (!_tmp8_) {
					gint _tmp9_;
					guint8 _tmp10_;
					guint8 _tmp11_;
					_tmp9_ = length_posA;
					length_posA = _tmp9_ + 1;
					_tmp10_ = self->priv->_width;
					_tmp11_ = self->priv->_height;
					position_move (&tmp, direction, _tmp10_, _tmp11_);
				}
				_tmp8_ = FALSE;
				_tmp13_ = self->priv->_height;
				if (length_posA < ((gint) _tmp13_)) {
					Position _tmp14_;
					_tmp14_ = tmp;
					_tmp12_ = worm_can_move_to (self, board, (gint) board_length1, (gint) board_length2, worms, &_tmp14_);
				} else {
					_tmp12_ = FALSE;
				}
				if (!_tmp12_) {
					break;
				}
			}
		}
		_tmp15_ = self->list;
		_tmp16_ = gee_abstract_list_get ((GeeAbstractList*) _tmp15_, 0);
		_tmp17_ = self->list;
		_tmp18_ = gee_abstract_list_get ((GeeAbstractList*) _tmp17_, 0);
		_tmp19_.x = (guint8) (((guint16) ((guintptr) _tmp16_)) >> 8);
		_tmp19_.y = (guint8) ((guint16) ((guintptr) _tmp18_));
		tmp = _tmp19_;
		dirB = WORM_DIRECTION_RIGHT;
		_tmp20_ = self->priv->_width;
		_tmp21_ = self->priv->_height;
		position_move (&tmp, dirB, _tmp20_, _tmp21_);
		{
			gboolean _tmp22_ = FALSE;
			length_posB = 0;
			_tmp22_ = TRUE;
			while (TRUE) {
				gboolean _tmp26_ = FALSE;
				guint8 _tmp27_;
				if (!_tmp22_) {
					gint _tmp23_;
					guint8 _tmp24_;
					guint8 _tmp25_;
					_tmp23_ = length_posB;
					length_posB = _tmp23_ + 1;
					_tmp24_ = self->priv->_width;
					_tmp25_ = self->priv->_height;
					position_move (&tmp, direction, _tmp24_, _tmp25_);
				}
				_tmp22_ = FALSE;
				_tmp27_ = self->priv->_height;
				if (length_posB < ((gint) _tmp27_)) {
					Position _tmp28_;
					_tmp28_ = tmp;
					_tmp26_ = worm_can_move_to (self, board, (gint) board_length1, (gint) board_length2, worms, &_tmp28_);
				} else {
					_tmp26_ = FALSE;
				}
				if (!_tmp26_) {
					break;
				}
			}
		}
	} else {
		WormPositions* _tmp29_;
		gpointer _tmp30_;
		WormPositions* _tmp31_;
		gpointer _tmp32_;
		Position _tmp33_ = {0};
		guint8 _tmp34_;
		guint8 _tmp35_;
		WormPositions* _tmp43_;
		gpointer _tmp44_;
		WormPositions* _tmp45_;
		gpointer _tmp46_;
		Position _tmp47_ = {0};
		guint8 _tmp48_;
		guint8 _tmp49_;
		_tmp29_ = self->list;
		_tmp30_ = gee_abstract_list_get ((GeeAbstractList*) _tmp29_, 0);
		_tmp31_ = self->list;
		_tmp32_ = gee_abstract_list_get ((GeeAbstractList*) _tmp31_, 0);
		_tmp33_.x = (guint8) (((guint16) ((guintptr) _tmp30_)) >> 8);
		_tmp33_.y = (guint8) ((guint16) ((guintptr) _tmp32_));
		tmp = _tmp33_;
		dirA = WORM_DIRECTION_UP;
		_tmp34_ = self->priv->_width;
		_tmp35_ = self->priv->_height;
		position_move (&tmp, dirA, _tmp34_, _tmp35_);
		{
			gboolean _tmp36_ = FALSE;
			length_posA = 0;
			_tmp36_ = TRUE;
			while (TRUE) {
				gboolean _tmp40_ = FALSE;
				guint8 _tmp41_;
				if (!_tmp36_) {
					gint _tmp37_;
					guint8 _tmp38_;
					guint8 _tmp39_;
					_tmp37_ = length_posA;
					length_posA = _tmp37_ + 1;
					_tmp38_ = self->priv->_width;
					_tmp39_ = self->priv->_height;
					position_move (&tmp, direction, _tmp38_, _tmp39_);
				}
				_tmp36_ = FALSE;
				_tmp41_ = self->priv->_width;
				if (length_posA < ((gint) _tmp41_)) {
					Position _tmp42_;
					_tmp42_ = tmp;
					_tmp40_ = worm_can_move_to (self, board, (gint) board_length1, (gint) board_length2, worms, &_tmp42_);
				} else {
					_tmp40_ = FALSE;
				}
				if (!_tmp40_) {
					break;
				}
			}
		}
		_tmp43_ = self->list;
		_tmp44_ = gee_abstract_list_get ((GeeAbstractList*) _tmp43_, 0);
		_tmp45_ = self->list;
		_tmp46_ = gee_abstract_list_get ((GeeAbstractList*) _tmp45_, 0);
		_tmp47_.x = (guint8) (((guint16) ((guintptr) _tmp44_)) >> 8);
		_tmp47_.y = (guint8) ((guint16) ((guintptr) _tmp46_));
		tmp = _tmp47_;
		dirB = WORM_DIRECTION_DOWN;
		_tmp48_ = self->priv->_width;
		_tmp49_ = self->priv->_height;
		position_move (&tmp, dirB, _tmp48_, _tmp49_);
		{
			gboolean _tmp50_ = FALSE;
			length_posB = 0;
			_tmp50_ = TRUE;
			while (TRUE) {
				gboolean _tmp54_ = FALSE;
				guint8 _tmp55_;
				if (!_tmp50_) {
					gint _tmp51_;
					guint8 _tmp52_;
					guint8 _tmp53_;
					_tmp51_ = length_posB;
					length_posB = _tmp51_ + 1;
					_tmp52_ = self->priv->_width;
					_tmp53_ = self->priv->_height;
					position_move (&tmp, direction, _tmp52_, _tmp53_);
				}
				_tmp50_ = FALSE;
				_tmp55_ = self->priv->_width;
				if (length_posB < ((gint) _tmp55_)) {
					Position _tmp56_;
					_tmp56_ = tmp;
					_tmp54_ = worm_can_move_to (self, board, (gint) board_length1, (gint) board_length2, worms, &_tmp56_);
				} else {
					_tmp54_ = FALSE;
				}
				if (!_tmp54_) {
					break;
				}
			}
		}
	}
	if (length_posA > length_posB) {
		self->priv->LastUturnA = TRUE;
		result = dirA;
		return result;
	} else {
		if (length_posA < length_posB) {
			self->priv->LastUturnA = FALSE;
			result = dirB;
			return result;
		} else {
			if (length_posA > 0) {
				if (self->priv->LastUturnA) {
					result = dirA;
					return result;
				} else {
					result = dirB;
					return result;
				}
			} else {
				result = worm_direction_reverse (direction);
				return result;
			}
		}
	}
}

static gint
worm_get_raw_key (Worm* self,
                  guint keyval)
{
	GdkKeymapKey* keys = NULL;
	gint keys_length1 = 0;
	gint _keys_size_ = 0;
	GdkDisplay* _tmp0_;
	GdkKeymapKey* _tmp1_ = NULL;
	gint _tmp2_ = 0;
	gboolean _tmp3_;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	_tmp0_ = gdk_display_get_default ();
	_tmp3_ = gdk_display_map_keyval (_tmp0_, keyval, &_tmp1_, &_tmp2_);
	keys = (g_free (keys), NULL);
	keys = _tmp1_;
	keys_length1 = _tmp2_;
	_keys_size_ = keys_length1;
	if (_tmp3_) {
		GdkKeymapKey* _tmp4_;
		gint _tmp4__length1;
		_tmp4_ = keys;
		_tmp4__length1 = keys_length1;
		if (_tmp4__length1 > 0) {
			GdkKeymapKey* _tmp5_;
			gint _tmp5__length1;
			GdkKeymapKey _tmp6_;
			_tmp5_ = keys;
			_tmp5__length1 = keys_length1;
			_tmp6_ = _tmp5_[0];
			result = (gint) _tmp6_.keycode;
			keys = (g_free (keys), NULL);
			return result;
		}
	}
	result = -1;
	keys = (g_free (keys), NULL);
	return result;
}

gboolean
worm_handle_keypress (Worm* self,
                      guint keycode,
                      GeeHashMap* worm_props)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	guint8 _tmp2_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (worm_props != NULL, FALSE);
	_tmp2_ = self->priv->_lives;
	if (((gint) _tmp2_) == 0) {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = self->is_stopped;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		WormPositions* _tmp3_;
		gboolean _tmp4_;
		gboolean _tmp5_;
		_tmp3_ = self->list;
		_tmp4_ = gee_collection_get_is_empty ((GeeCollection*) _tmp3_);
		_tmp5_ = _tmp4_;
		_tmp0_ = _tmp5_;
	}
	if (_tmp0_) {
		result = FALSE;
		return result;
	} else {
		WormProperties* properties = NULL;
		gpointer _tmp6_;
		WormProperties* _tmp7_;
		gint _tmp8_;
		gint _tmp9_;
		WormProperties* _tmp14_;
		gint _tmp15_;
		gint _tmp16_;
		WormProperties* _tmp17_;
		gint _tmp18_;
		gint _tmp19_;
		WormProperties* _tmp24_;
		gint _tmp25_;
		gint _tmp26_;
		WormProperties* _tmp27_;
		gint _tmp28_;
		gint _tmp29_;
		WormProperties* _tmp34_;
		gint _tmp35_;
		gint _tmp36_;
		WormProperties* _tmp37_;
		gint _tmp38_;
		gint _tmp39_;
		WormProperties* _tmp44_;
		gint _tmp45_;
		gint _tmp46_;
		_tmp6_ = gee_abstract_map_get ((GeeAbstractMap*) worm_props, self);
		properties = (WormProperties*) _tmp6_;
		_tmp7_ = properties;
		_tmp8_ = worm_properties_get_raw_up (_tmp7_);
		_tmp9_ = _tmp8_;
		if (_tmp9_ < 0) {
			WormProperties* _tmp10_;
			WormProperties* _tmp11_;
			guint _tmp12_;
			guint _tmp13_;
			_tmp10_ = properties;
			_tmp11_ = properties;
			_tmp12_ = worm_properties_get_up (_tmp11_);
			_tmp13_ = _tmp12_;
			worm_properties_set_raw_up (_tmp10_, worm_get_raw_key (self, _tmp13_));
		}
		_tmp14_ = properties;
		_tmp15_ = worm_properties_get_raw_up (_tmp14_);
		_tmp16_ = _tmp15_;
		if (keycode == ((guint) _tmp16_)) {
			worm_queue_keypress (self, WORM_DIRECTION_UP);
			result = TRUE;
			_g_object_unref0 (properties);
			return result;
		}
		_tmp17_ = properties;
		_tmp18_ = worm_properties_get_raw_down (_tmp17_);
		_tmp19_ = _tmp18_;
		if (_tmp19_ < 0) {
			WormProperties* _tmp20_;
			WormProperties* _tmp21_;
			guint _tmp22_;
			guint _tmp23_;
			_tmp20_ = properties;
			_tmp21_ = properties;
			_tmp22_ = worm_properties_get_down (_tmp21_);
			_tmp23_ = _tmp22_;
			worm_properties_set_raw_down (_tmp20_, worm_get_raw_key (self, _tmp23_));
		}
		_tmp24_ = properties;
		_tmp25_ = worm_properties_get_raw_down (_tmp24_);
		_tmp26_ = _tmp25_;
		if (keycode == ((guint) _tmp26_)) {
			worm_queue_keypress (self, WORM_DIRECTION_DOWN);
			result = TRUE;
			_g_object_unref0 (properties);
			return result;
		}
		_tmp27_ = properties;
		_tmp28_ = worm_properties_get_raw_left (_tmp27_);
		_tmp29_ = _tmp28_;
		if (_tmp29_ < 0) {
			WormProperties* _tmp30_;
			WormProperties* _tmp31_;
			guint _tmp32_;
			guint _tmp33_;
			_tmp30_ = properties;
			_tmp31_ = properties;
			_tmp32_ = worm_properties_get_left (_tmp31_);
			_tmp33_ = _tmp32_;
			worm_properties_set_raw_left (_tmp30_, worm_get_raw_key (self, _tmp33_));
		}
		_tmp34_ = properties;
		_tmp35_ = worm_properties_get_raw_left (_tmp34_);
		_tmp36_ = _tmp35_;
		if (keycode == ((guint) _tmp36_)) {
			worm_queue_keypress (self, WORM_DIRECTION_LEFT);
			result = TRUE;
			_g_object_unref0 (properties);
			return result;
		}
		_tmp37_ = properties;
		_tmp38_ = worm_properties_get_raw_right (_tmp37_);
		_tmp39_ = _tmp38_;
		if (_tmp39_ < 0) {
			WormProperties* _tmp40_;
			WormProperties* _tmp41_;
			guint _tmp42_;
			guint _tmp43_;
			_tmp40_ = properties;
			_tmp41_ = properties;
			_tmp42_ = worm_properties_get_right (_tmp41_);
			_tmp43_ = _tmp42_;
			worm_properties_set_raw_right (_tmp40_, worm_get_raw_key (self, _tmp43_));
		}
		_tmp44_ = properties;
		_tmp45_ = worm_properties_get_raw_right (_tmp44_);
		_tmp46_ = _tmp45_;
		if (keycode == ((guint) _tmp46_)) {
			worm_queue_keypress (self, WORM_DIRECTION_RIGHT);
			result = TRUE;
			_g_object_unref0 (properties);
			return result;
		}
		result = FALSE;
		_g_object_unref0 (properties);
		return result;
	}
}

static void
worm_queue_keypress (Worm* self,
                     WormDirection dir)
{
	WormKeyQueue* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->key_queue;
	worm_key_queue_append (_tmp0_, dir);
}

static void
worm_dequeue_keypress (Worm* self,
                       gint* board,
                       gint board_length1,
                       gint board_length2,
                       GeeList* worms)
{
	WormKeyQueue* _tmp0_;
	WormKeyQueue* _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (worms != NULL);
	_tmp0_ = self->priv->key_queue;
	_vala_return_if_fail (!worm_key_queue_is_empty (_tmp0_), "!key_queue.is_empty ()");
	_tmp1_ = self->priv->key_queue;
	switch (worm_key_queue_remove (_tmp1_)) {
		case WORM_DIRECTION_UP:
		{
			WormDirection _tmp2_;
			_tmp2_ = self->priv->_direction;
			if (_tmp2_ == WORM_DIRECTION_DOWN) {
				gboolean _tmp3_ = FALSE;
				WormDirection _tmp4_;
				worm_set_direction (self, worm_uturn (self, board, (gint) board_length1, (gint) board_length2, worms, WORM_DIRECTION_UP));
				_tmp4_ = self->priv->_direction;
				if (_tmp4_ != WORM_DIRECTION_UP) {
					WormDirection _tmp5_;
					_tmp5_ = self->priv->_direction;
					_tmp3_ = _tmp5_ != WORM_DIRECTION_DOWN;
				} else {
					_tmp3_ = FALSE;
				}
				if (_tmp3_) {
					WormKeyQueue* _tmp6_;
					_tmp6_ = self->priv->key_queue;
					worm_key_queue_prepend (_tmp6_, WORM_DIRECTION_UP);
				}
			} else {
				if (worm_can_move_direction (self, board, (gint) board_length1, (gint) board_length2, worms, WORM_DIRECTION_UP)) {
					worm_set_direction (self, WORM_DIRECTION_UP);
				}
			}
			break;
		}
		case WORM_DIRECTION_DOWN:
		{
			WormDirection _tmp7_;
			_tmp7_ = self->priv->_direction;
			if (_tmp7_ == WORM_DIRECTION_UP) {
				gboolean _tmp8_ = FALSE;
				WormDirection _tmp9_;
				worm_set_direction (self, worm_uturn (self, board, (gint) board_length1, (gint) board_length2, worms, WORM_DIRECTION_DOWN));
				_tmp9_ = self->priv->_direction;
				if (_tmp9_ != WORM_DIRECTION_DOWN) {
					WormDirection _tmp10_;
					_tmp10_ = self->priv->_direction;
					_tmp8_ = _tmp10_ != WORM_DIRECTION_UP;
				} else {
					_tmp8_ = FALSE;
				}
				if (_tmp8_) {
					WormKeyQueue* _tmp11_;
					_tmp11_ = self->priv->key_queue;
					worm_key_queue_prepend (_tmp11_, WORM_DIRECTION_DOWN);
				}
			} else {
				if (worm_can_move_direction (self, board, (gint) board_length1, (gint) board_length2, worms, WORM_DIRECTION_DOWN)) {
					worm_set_direction (self, WORM_DIRECTION_DOWN);
				}
			}
			break;
		}
		case WORM_DIRECTION_LEFT:
		{
			WormDirection _tmp12_;
			_tmp12_ = self->priv->_direction;
			if (_tmp12_ == WORM_DIRECTION_RIGHT) {
				gboolean _tmp13_ = FALSE;
				WormDirection _tmp14_;
				worm_set_direction (self, worm_uturn (self, board, (gint) board_length1, (gint) board_length2, worms, WORM_DIRECTION_LEFT));
				_tmp14_ = self->priv->_direction;
				if (_tmp14_ != WORM_DIRECTION_LEFT) {
					WormDirection _tmp15_;
					_tmp15_ = self->priv->_direction;
					_tmp13_ = _tmp15_ != WORM_DIRECTION_RIGHT;
				} else {
					_tmp13_ = FALSE;
				}
				if (_tmp13_) {
					WormKeyQueue* _tmp16_;
					_tmp16_ = self->priv->key_queue;
					worm_key_queue_prepend (_tmp16_, WORM_DIRECTION_LEFT);
				}
			} else {
				if (worm_can_move_direction (self, board, (gint) board_length1, (gint) board_length2, worms, WORM_DIRECTION_LEFT)) {
					worm_set_direction (self, WORM_DIRECTION_LEFT);
				}
			}
			break;
		}
		case WORM_DIRECTION_RIGHT:
		{
			WormDirection _tmp17_;
			_tmp17_ = self->priv->_direction;
			if (_tmp17_ == WORM_DIRECTION_LEFT) {
				gboolean _tmp18_ = FALSE;
				WormDirection _tmp19_;
				worm_set_direction (self, worm_uturn (self, board, (gint) board_length1, (gint) board_length2, worms, WORM_DIRECTION_RIGHT));
				_tmp19_ = self->priv->_direction;
				if (_tmp19_ != WORM_DIRECTION_RIGHT) {
					WormDirection _tmp20_;
					_tmp20_ = self->priv->_direction;
					_tmp18_ = _tmp20_ != WORM_DIRECTION_LEFT;
				} else {
					_tmp18_ = FALSE;
				}
				if (_tmp18_) {
					WormKeyQueue* _tmp21_;
					_tmp21_ = self->priv->key_queue;
					worm_key_queue_prepend (_tmp21_, WORM_DIRECTION_RIGHT);
				}
			} else {
				if (worm_can_move_direction (self, board, (gint) board_length1, (gint) board_length2, worms, WORM_DIRECTION_RIGHT)) {
					worm_set_direction (self, WORM_DIRECTION_RIGHT);
				}
			}
			break;
		}
		default:
		{
			break;
		}
	}
}

static void
_vala_array_add9 (Position* * array,
                  gint* length,
                  gint* size,
                  const Position* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (Position, *array, *size);
	}
	(*array)[(*length)++] = *value;
}

static gint
worm_ai_deadend (gint* board,
                 gint board_length1,
                 gint board_length2,
                 WormMap* worm_map,
                 Position* position,
                 gint length)
{
	Position* p = NULL;
	Position _tmp0_;
	Position* _tmp1_;
	gint p_length1;
	gint _p_size_;
	gint _tmp27_ = 0;
	Position* _tmp28_;
	gint _tmp28__length1;
	gint result;
	g_return_val_if_fail (worm_map != NULL, -1);
	g_return_val_if_fail (position != NULL, -1);
	_tmp0_ = *position;
	_tmp1_ = g_new0 (Position, 1);
	_tmp1_[0] = _tmp0_;
	p = _tmp1_;
	p_length1 = 1;
	_p_size_ = p_length1;
	{
		guint i = 0U;
		i = (guint) 0;
		{
			gboolean _tmp2_ = FALSE;
			_tmp2_ = TRUE;
			while (TRUE) {
				gboolean _tmp4_ = FALSE;
				Position* _tmp5_;
				gint _tmp5__length1;
				if (!_tmp2_) {
					guint _tmp3_;
					_tmp3_ = i;
					i = _tmp3_ + 1;
				}
				_tmp2_ = FALSE;
				_tmp5_ = p;
				_tmp5__length1 = p_length1;
				if (((guint) _tmp5__length1) > i) {
					Position* _tmp6_;
					gint _tmp6__length1;
					_tmp6_ = p;
					_tmp6__length1 = p_length1;
					_tmp4_ = (_tmp6__length1 - 1) < length;
				} else {
					_tmp4_ = FALSE;
				}
				if (!_tmp4_) {
					break;
				}
				{
					guint dir = 0U;
					dir = (guint) 4;
					{
						gboolean _tmp7_ = FALSE;
						_tmp7_ = TRUE;
						while (TRUE) {
							gboolean _tmp9_ = FALSE;
							Position new_position = {0};
							Position* _tmp11_;
							gint _tmp11__length1;
							Position _tmp12_;
							gint _tmp13_;
							gint _tmp14_;
							gboolean _tmp15_ = FALSE;
							gboolean _tmp16_ = FALSE;
							guint* _tmp17_;
							gint _tmp17__length1;
							gint _tmp17__length2;
							Position _tmp18_;
							Position _tmp19_;
							guint _tmp20_;
							if (!_tmp7_) {
								guint _tmp8_;
								_tmp8_ = dir;
								dir = _tmp8_ - 1;
							}
							_tmp7_ = FALSE;
							if (dir > ((guint) 0)) {
								Position* _tmp10_;
								gint _tmp10__length1;
								_tmp10_ = p;
								_tmp10__length1 = p_length1;
								_tmp9_ = (_tmp10__length1 - 1) < length;
							} else {
								_tmp9_ = FALSE;
							}
							if (!_tmp9_) {
								break;
							}
							_tmp11_ = p;
							_tmp11__length1 = p_length1;
							_tmp12_ = _tmp11_[i];
							new_position = _tmp12_;
							_tmp13_ = board_length1;
							_tmp14_ = board_length2;
							position_move (&new_position, (WormDirection) dir, (guint8) _tmp13_, (guint8) _tmp14_);
							_tmp17_ = worm_deadend_board;
							_tmp17__length1 = worm_deadend_board_length1;
							_tmp17__length2 = worm_deadend_board_length2;
							_tmp18_ = new_position;
							_tmp19_ = new_position;
							_tmp20_ = _tmp17_[(_tmp18_.x * _tmp17__length2) + _tmp19_.y];
							if (_tmp20_ != worm_deadend_runnumber) {
								Position _tmp21_;
								_tmp21_ = new_position;
								_tmp16_ = !worm_is_board_position_occupied (&_tmp21_, board, (gint) board_length1, (gint) board_length2);
							} else {
								_tmp16_ = FALSE;
							}
							if (_tmp16_) {
								Position _tmp22_;
								_tmp22_ = new_position;
								_tmp15_ = !worm_map_contain_position (worm_map, &_tmp22_);
							} else {
								_tmp15_ = FALSE;
							}
							if (_tmp15_) {
								guint* _tmp23_;
								gint _tmp23__length1;
								gint _tmp23__length2;
								Position _tmp24_;
								Position _tmp25_;
								Position _tmp26_;
								_tmp23_ = worm_deadend_board;
								_tmp23__length1 = worm_deadend_board_length1;
								_tmp23__length2 = worm_deadend_board_length2;
								_tmp24_ = new_position;
								_tmp25_ = new_position;
								_tmp23_[(_tmp24_.x * _tmp23__length2) + _tmp25_.y] = worm_deadend_runnumber;
								_tmp26_ = new_position;
								_vala_array_add9 (&p, &p_length1, &_p_size_, &_tmp26_);
							}
						}
					}
				}
			}
		}
	}
	_tmp28_ = p;
	_tmp28__length1 = p_length1;
	if ((_tmp28__length1 - 1) > length) {
		_tmp27_ = 0;
	} else {
		Position* _tmp29_;
		gint _tmp29__length1;
		_tmp29_ = p;
		_tmp29__length1 = p_length1;
		_tmp27_ = length - (_tmp29__length1 - 1);
	}
	result = _tmp27_;
	p = (g_free (p), NULL);
	return result;
}

gint
worm_ai_deadend_after (gint* board,
                       gint board_length1,
                       gint board_length2,
                       GeeLinkedList* worms,
                       WormMap* worm_map,
                       Position* old_position,
                       WormDirection direction,
                       gint length)
{
	guint8 width = 0U;
	gint _tmp0_;
	guint8 height = 0U;
	gint _tmp1_;
	guint _tmp2_;
	Position new_position = {0};
	Position _tmp47_;
	guint* _tmp48_;
	gint _tmp48__length1;
	gint _tmp48__length2;
	Position _tmp49_;
	Position _tmp50_;
	guint* _tmp51_;
	gint _tmp51__length1;
	gint _tmp51__length2;
	Position _tmp52_;
	Position _tmp53_;
	gint cl = 0;
	Position _tmp54_;
	gint result;
	g_return_val_if_fail (worms != NULL, -1);
	g_return_val_if_fail (worm_map != NULL, -1);
	g_return_val_if_fail (old_position != NULL, -1);
	_tmp0_ = board_length1;
	width = (guint8) _tmp0_;
	_tmp1_ = board_length2;
	height = (guint8) _tmp1_;
	worm_deadend_runnumber = worm_deadend_runnumber + 1;
	_tmp2_ = worm_deadend_runnumber;
	if (_tmp2_ == ((guint) 0)) {
		guint _tmp12_;
		{
			gint x = 0;
			x = 0;
			{
				gboolean _tmp3_ = FALSE;
				_tmp3_ = TRUE;
				while (TRUE) {
					guint* _tmp5_;
					gint _tmp5__length1;
					gint _tmp5__length2;
					gint _tmp6_;
					if (!_tmp3_) {
						gint _tmp4_;
						_tmp4_ = x;
						x = _tmp4_ + 1;
					}
					_tmp3_ = FALSE;
					_tmp5_ = worm_deadend_board;
					_tmp5__length1 = worm_deadend_board_length1;
					_tmp5__length2 = worm_deadend_board_length2;
					_tmp6_ = _tmp5__length1;
					if (!(x < _tmp6_)) {
						break;
					}
					{
						gint y = 0;
						y = 0;
						{
							gboolean _tmp7_ = FALSE;
							_tmp7_ = TRUE;
							while (TRUE) {
								guint* _tmp9_;
								gint _tmp9__length1;
								gint _tmp9__length2;
								gint _tmp10_;
								guint* _tmp11_;
								gint _tmp11__length1;
								gint _tmp11__length2;
								if (!_tmp7_) {
									gint _tmp8_;
									_tmp8_ = y;
									y = _tmp8_ + 1;
								}
								_tmp7_ = FALSE;
								_tmp9_ = worm_deadend_board;
								_tmp9__length1 = worm_deadend_board_length1;
								_tmp9__length2 = worm_deadend_board_length2;
								_tmp10_ = _tmp9__length2;
								if (!(y < _tmp10_)) {
									break;
								}
								_tmp11_ = worm_deadend_board;
								_tmp11__length1 = worm_deadend_board_length1;
								_tmp11__length2 = worm_deadend_board_length2;
								_tmp11_[(x * _tmp11__length2) + y] = worm_deadend_runnumber;
							}
						}
					}
				}
			}
		}
		_tmp12_ = worm_deadend_runnumber;
		worm_deadend_runnumber = _tmp12_ + 1;
	}
	{
		gint i = 0;
		gint _tmp13_;
		gint _tmp14_;
		_tmp13_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) worms);
		_tmp14_ = _tmp13_;
		i = _tmp14_ - 1;
		{
			gboolean _tmp15_ = FALSE;
			_tmp15_ = TRUE;
			while (TRUE) {
				gboolean _tmp17_ = FALSE;
				gpointer _tmp18_;
				Worm* _tmp19_;
				gboolean _tmp20_;
				if (!_tmp15_) {
					gint _tmp16_;
					_tmp16_ = i;
					i = _tmp16_ - 1;
				}
				_tmp15_ = FALSE;
				if (!(i >= 0)) {
					break;
				}
				_tmp18_ = gee_abstract_list_get ((GeeAbstractList*) worms, i);
				_tmp19_ = (Worm*) _tmp18_;
				_tmp20_ = !_tmp19_->is_stopped;
				_g_object_unref0 (_tmp19_);
				if (_tmp20_) {
					gpointer _tmp21_;
					Worm* _tmp22_;
					WormPositions* _tmp23_;
					gboolean _tmp24_;
					gboolean _tmp25_;
					_tmp21_ = gee_abstract_list_get ((GeeAbstractList*) worms, i);
					_tmp22_ = (Worm*) _tmp21_;
					_tmp23_ = _tmp22_->list;
					_tmp24_ = gee_collection_get_is_empty ((GeeCollection*) _tmp23_);
					_tmp25_ = _tmp24_;
					_tmp17_ = !_tmp25_;
					_g_object_unref0 (_tmp22_);
				} else {
					_tmp17_ = FALSE;
				}
				if (_tmp17_) {
					guint8 target_x = 0U;
					gpointer _tmp26_;
					Worm* _tmp27_;
					Position _tmp28_ = {0};
					Position _tmp29_;
					guint8 _tmp30_;
					guint8 target_y = 0U;
					gpointer _tmp31_;
					Worm* _tmp32_;
					Position _tmp33_ = {0};
					Position _tmp34_;
					guint8 _tmp35_;
					gboolean _tmp36_ = FALSE;
					Position _tmp37_;
					_tmp26_ = gee_abstract_list_get ((GeeAbstractList*) worms, i);
					_tmp27_ = (Worm*) _tmp26_;
					worm_get_head (_tmp27_, &_tmp28_);
					_tmp29_ = _tmp28_;
					_tmp30_ = _tmp29_.x;
					_g_object_unref0 (_tmp27_);
					target_x = _tmp30_;
					_tmp31_ = gee_abstract_list_get ((GeeAbstractList*) worms, i);
					_tmp32_ = (Worm*) _tmp31_;
					worm_get_head (_tmp32_, &_tmp33_);
					_tmp34_ = _tmp33_;
					_tmp35_ = _tmp34_.y;
					_g_object_unref0 (_tmp32_);
					target_y = _tmp35_;
					_tmp37_ = *old_position;
					if (target_x == _tmp37_.x) {
						Position _tmp38_;
						_tmp38_ = *old_position;
						_tmp36_ = target_y == _tmp38_.y;
					} else {
						_tmp36_ = FALSE;
					}
					if (_tmp36_) {
						continue;
					}
					if (((gint) target_x) > 0) {
						guint* _tmp39_;
						gint _tmp39__length1;
						gint _tmp39__length2;
						_tmp39_ = worm_deadend_board;
						_tmp39__length1 = worm_deadend_board_length1;
						_tmp39__length2 = worm_deadend_board_length2;
						_tmp39_[((target_x - 1) * _tmp39__length2) + target_y] = worm_deadend_runnumber;
					} else {
						guint* _tmp40_;
						gint _tmp40__length1;
						gint _tmp40__length2;
						_tmp40_ = worm_deadend_board;
						_tmp40__length1 = worm_deadend_board_length1;
						_tmp40__length2 = worm_deadend_board_length2;
						_tmp40_[((width - 1) * _tmp40__length2) + target_y] = worm_deadend_runnumber;
					}
					if (((gint) target_y) > 0) {
						guint* _tmp41_;
						gint _tmp41__length1;
						gint _tmp41__length2;
						_tmp41_ = worm_deadend_board;
						_tmp41__length1 = worm_deadend_board_length1;
						_tmp41__length2 = worm_deadend_board_length2;
						_tmp41_[(target_x * _tmp41__length2) + (target_y - 1)] = worm_deadend_runnumber;
					} else {
						guint* _tmp42_;
						gint _tmp42__length1;
						gint _tmp42__length2;
						_tmp42_ = worm_deadend_board;
						_tmp42__length1 = worm_deadend_board_length1;
						_tmp42__length2 = worm_deadend_board_length2;
						_tmp42_[(target_x * _tmp42__length2) + (height - 1)] = worm_deadend_runnumber;
					}
					if (((gint) target_x) < (width - 1)) {
						guint* _tmp43_;
						gint _tmp43__length1;
						gint _tmp43__length2;
						_tmp43_ = worm_deadend_board;
						_tmp43__length1 = worm_deadend_board_length1;
						_tmp43__length2 = worm_deadend_board_length2;
						_tmp43_[((target_x + 1) * _tmp43__length2) + target_y] = worm_deadend_runnumber;
					} else {
						guint* _tmp44_;
						gint _tmp44__length1;
						gint _tmp44__length2;
						_tmp44_ = worm_deadend_board;
						_tmp44__length1 = worm_deadend_board_length1;
						_tmp44__length2 = worm_deadend_board_length2;
						_tmp44_[(0 * _tmp44__length2) + target_y] = worm_deadend_runnumber;
					}
					if (((gint) target_y) < (height - 1)) {
						guint* _tmp45_;
						gint _tmp45__length1;
						gint _tmp45__length2;
						_tmp45_ = worm_deadend_board;
						_tmp45__length1 = worm_deadend_board_length1;
						_tmp45__length2 = worm_deadend_board_length2;
						_tmp45_[(target_x * _tmp45__length2) + (target_y + 1)] = worm_deadend_runnumber;
					} else {
						guint* _tmp46_;
						gint _tmp46__length1;
						gint _tmp46__length2;
						_tmp46_ = worm_deadend_board;
						_tmp46__length1 = worm_deadend_board_length1;
						_tmp46__length2 = worm_deadend_board_length2;
						_tmp46_[(target_x * _tmp46__length2) + 0] = worm_deadend_runnumber;
					}
				}
			}
		}
	}
	_tmp47_ = *old_position;
	new_position = _tmp47_;
	position_move (&new_position, direction, width, height);
	_tmp48_ = worm_deadend_board;
	_tmp48__length1 = worm_deadend_board_length1;
	_tmp48__length2 = worm_deadend_board_length2;
	_tmp49_ = *old_position;
	_tmp50_ = *old_position;
	_tmp48_[(_tmp49_.x * _tmp48__length2) + _tmp50_.y] = worm_deadend_runnumber;
	_tmp51_ = worm_deadend_board;
	_tmp51__length1 = worm_deadend_board_length1;
	_tmp51__length2 = worm_deadend_board_length2;
	_tmp52_ = new_position;
	_tmp53_ = new_position;
	_tmp51_[(_tmp52_.x * _tmp51__length2) + _tmp53_.y] = worm_deadend_runnumber;
	cl = (length * length) / 16;
	if (cl < ((gint) width)) {
		cl = (gint) width;
	}
	_tmp54_ = new_position;
	result = worm_ai_deadend (board, (gint) board_length1, (gint) board_length2, worm_map, &_tmp54_, cl);
	return result;
}

static inline gboolean
worm_ai_too_close (Worm* self,
                   GeeLinkedList* worms,
                   WormDirection direction)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (worms != NULL, FALSE);
	{
		GeeLinkedList* _worm_list = NULL;
		gint _worm_size = 0;
		GeeLinkedList* _tmp0_;
		gint _tmp1_;
		gint _tmp2_;
		gint _worm_index = 0;
		_worm_list = worms;
		_tmp0_ = _worm_list;
		_tmp1_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp0_);
		_tmp2_ = _tmp1_;
		_worm_size = _tmp2_;
		_worm_index = -1;
		while (TRUE) {
			gint _tmp3_;
			gint _tmp4_;
			Worm* worm = NULL;
			GeeLinkedList* _tmp5_;
			gpointer _tmp6_;
			gboolean _tmp7_ = FALSE;
			gboolean _tmp8_ = FALSE;
			Worm* _tmp9_;
			gint16 dx = 0;
			Position _tmp15_ = {0};
			Position _tmp16_;
			Worm* _tmp17_;
			Position _tmp18_ = {0};
			Position _tmp19_;
			gint16 dy = 0;
			Position _tmp20_ = {0};
			Position _tmp21_;
			Worm* _tmp22_;
			Position _tmp23_ = {0};
			Position _tmp24_;
			_worm_index = _worm_index + 1;
			_tmp3_ = _worm_index;
			_tmp4_ = _worm_size;
			if (!(_tmp3_ < _tmp4_)) {
				break;
			}
			_tmp5_ = _worm_list;
			_tmp6_ = gee_abstract_list_get ((GeeAbstractList*) _tmp5_, _worm_index);
			worm = (Worm*) _tmp6_;
			_tmp9_ = worm;
			if (_tmp9_ == self) {
				_tmp8_ = TRUE;
			} else {
				Worm* _tmp10_;
				_tmp10_ = worm;
				_tmp8_ = _tmp10_->is_stopped;
			}
			if (_tmp8_) {
				_tmp7_ = TRUE;
			} else {
				Worm* _tmp11_;
				WormPositions* _tmp12_;
				gboolean _tmp13_;
				gboolean _tmp14_;
				_tmp11_ = worm;
				_tmp12_ = _tmp11_->list;
				_tmp13_ = gee_collection_get_is_empty ((GeeCollection*) _tmp12_);
				_tmp14_ = _tmp13_;
				_tmp7_ = _tmp14_;
			}
			if (_tmp7_) {
				_g_object_unref0 (worm);
				continue;
			}
			worm_get_head (self, &_tmp15_);
			_tmp16_ = _tmp15_;
			_tmp17_ = worm;
			worm_get_head (_tmp17_, &_tmp18_);
			_tmp19_ = _tmp18_;
			dx = ((gint16) _tmp16_.x) - ((gint16) _tmp19_.x);
			worm_get_head (self, &_tmp20_);
			_tmp21_ = _tmp20_;
			_tmp22_ = worm;
			worm_get_head (_tmp22_, &_tmp23_);
			_tmp24_ = _tmp23_;
			dy = ((gint16) _tmp21_.y) - ((gint16) _tmp24_.y);
			switch (direction) {
				case WORM_DIRECTION_UP:
				{
					gboolean _tmp25_ = FALSE;
					gboolean _tmp26_ = FALSE;
					gboolean _tmp27_ = FALSE;
					if (((gint) dy) > 0) {
						_tmp27_ = ((gint) dy) <= 3;
					} else {
						_tmp27_ = FALSE;
					}
					if (_tmp27_) {
						_tmp26_ = ((gint) dx) >= -1;
					} else {
						_tmp26_ = FALSE;
					}
					if (_tmp26_) {
						_tmp25_ = ((gint) dx) <= 1;
					} else {
						_tmp25_ = FALSE;
					}
					if (_tmp25_) {
						result = TRUE;
						_g_object_unref0 (worm);
						return result;
					}
					break;
				}
				case WORM_DIRECTION_DOWN:
				{
					gboolean _tmp28_ = FALSE;
					gboolean _tmp29_ = FALSE;
					gboolean _tmp30_ = FALSE;
					if (((gint) dy) < 0) {
						_tmp30_ = ((gint) dy) >= -3;
					} else {
						_tmp30_ = FALSE;
					}
					if (_tmp30_) {
						_tmp29_ = ((gint) dx) >= -1;
					} else {
						_tmp29_ = FALSE;
					}
					if (_tmp29_) {
						_tmp28_ = ((gint) dx) <= 1;
					} else {
						_tmp28_ = FALSE;
					}
					if (_tmp28_) {
						result = TRUE;
						_g_object_unref0 (worm);
						return result;
					}
					break;
				}
				case WORM_DIRECTION_LEFT:
				{
					gboolean _tmp31_ = FALSE;
					gboolean _tmp32_ = FALSE;
					gboolean _tmp33_ = FALSE;
					if (((gint) dx) > 0) {
						_tmp33_ = ((gint) dx) <= 3;
					} else {
						_tmp33_ = FALSE;
					}
					if (_tmp33_) {
						_tmp32_ = ((gint) dy) >= -1;
					} else {
						_tmp32_ = FALSE;
					}
					if (_tmp32_) {
						_tmp31_ = ((gint) dy) <= 1;
					} else {
						_tmp31_ = FALSE;
					}
					if (_tmp31_) {
						result = TRUE;
						_g_object_unref0 (worm);
						return result;
					}
					break;
				}
				case WORM_DIRECTION_RIGHT:
				{
					gboolean _tmp34_ = FALSE;
					gboolean _tmp35_ = FALSE;
					gboolean _tmp36_ = FALSE;
					if (((gint) dx) < 0) {
						_tmp36_ = ((gint) dx) >= -3;
					} else {
						_tmp36_ = FALSE;
					}
					if (_tmp36_) {
						_tmp35_ = ((gint) dy) >= -1;
					} else {
						_tmp35_ = FALSE;
					}
					if (_tmp35_) {
						_tmp34_ = ((gint) dy) <= 1;
					} else {
						_tmp34_ = FALSE;
					}
					if (_tmp34_) {
						result = TRUE;
						_g_object_unref0 (worm);
						return result;
					}
					break;
				}
				default:
				{
					g_assert_not_reached ();
				}
			}
			_g_object_unref0 (worm);
		}
	}
	result = FALSE;
	return result;
}

gboolean
worm_ai_is_bonus_more_attractive (Worm* self,
                                  BonuseType b0,
                                  gint64 d0,
                                  BonuseType b1,
                                  gint64 d1)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_ = FALSE;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (b0 == BONUS_ETYPE_LIFE) {
		_tmp3_ = b1 == BONUS_ETYPE_LIFE;
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		_tmp2_ = TRUE;
	} else {
		gboolean _tmp4_ = FALSE;
		if (b0 != BONUS_ETYPE_LIFE) {
			_tmp4_ = b1 != BONUS_ETYPE_LIFE;
		} else {
			_tmp4_ = FALSE;
		}
		_tmp2_ = _tmp4_;
	}
	if (_tmp2_) {
		_tmp1_ = d0 < d1;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		gboolean _tmp5_ = FALSE;
		if (b0 == BONUS_ETYPE_LIFE) {
			_tmp5_ = b1 != BONUS_ETYPE_LIFE;
		} else {
			_tmp5_ = FALSE;
		}
		_tmp0_ = _tmp5_;
	}
	result = _tmp0_;
	return result;
}

gboolean
worm_ai_can_see_bonus (Worm* self,
                       gint* board,
                       gint board_length1,
                       gint board_length2,
                       Position* origin,
                       Bonus* bonus,
                       WormDirection direction)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_ = FALSE;
	Position _tmp4_;
	guint8 _tmp5_;
	guint8 _tmp6_;
	Slice* slice = NULL;
	Slice* _tmp31_;
	Slice* _tmp32_;
	Slice* _tmp33_;
	Position _tmp34_;
	guint8 _tmp35_;
	guint8 _tmp36_;
	guint8 _tmp37_;
	guint8 _tmp38_;
	Slice* _tmp39_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (origin != NULL, FALSE);
	g_return_val_if_fail (bonus != NULL, FALSE);
	_tmp4_ = *origin;
	_tmp5_ = bonus_get_x (bonus);
	_tmp6_ = _tmp5_;
	if (_tmp4_.x == _tmp6_) {
		Position _tmp7_;
		guint8 _tmp8_;
		guint8 _tmp9_;
		_tmp7_ = *origin;
		_tmp8_ = bonus_get_y (bonus);
		_tmp9_ = _tmp8_;
		_tmp3_ = _tmp7_.y == _tmp9_;
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		_tmp2_ = TRUE;
	} else {
		gboolean _tmp10_ = FALSE;
		Position _tmp11_;
		guint8 _tmp12_;
		guint8 _tmp13_;
		_tmp11_ = *origin;
		_tmp12_ = bonus_get_x (bonus);
		_tmp13_ = _tmp12_;
		if (((gint) _tmp11_.x) == (_tmp13_ + 1)) {
			Position _tmp14_;
			guint8 _tmp15_;
			guint8 _tmp16_;
			_tmp14_ = *origin;
			_tmp15_ = bonus_get_y (bonus);
			_tmp16_ = _tmp15_;
			_tmp10_ = _tmp14_.y == _tmp16_;
		} else {
			_tmp10_ = FALSE;
		}
		_tmp2_ = _tmp10_;
	}
	if (_tmp2_) {
		_tmp1_ = TRUE;
	} else {
		gboolean _tmp17_ = FALSE;
		Position _tmp18_;
		guint8 _tmp19_;
		guint8 _tmp20_;
		_tmp18_ = *origin;
		_tmp19_ = bonus_get_x (bonus);
		_tmp20_ = _tmp19_;
		if (_tmp18_.x == _tmp20_) {
			Position _tmp21_;
			guint8 _tmp22_;
			guint8 _tmp23_;
			_tmp21_ = *origin;
			_tmp22_ = bonus_get_y (bonus);
			_tmp23_ = _tmp22_;
			_tmp17_ = ((gint) _tmp21_.y) == (_tmp23_ + 1);
		} else {
			_tmp17_ = FALSE;
		}
		_tmp1_ = _tmp17_;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		gboolean _tmp24_ = FALSE;
		Position _tmp25_;
		guint8 _tmp26_;
		guint8 _tmp27_;
		_tmp25_ = *origin;
		_tmp26_ = bonus_get_x (bonus);
		_tmp27_ = _tmp26_;
		if (((gint) _tmp25_.x) == (_tmp27_ + 1)) {
			Position _tmp28_;
			guint8 _tmp29_;
			guint8 _tmp30_;
			_tmp28_ = *origin;
			_tmp29_ = bonus_get_y (bonus);
			_tmp30_ = _tmp29_;
			_tmp24_ = ((gint) _tmp28_.y) == (_tmp30_ + 1);
		} else {
			_tmp24_ = FALSE;
		}
		_tmp0_ = _tmp24_;
	}
	if (_tmp0_) {
		result = TRUE;
		return result;
	}
	_tmp31_ = slice_new (NULL);
	slice = _tmp31_;
	_tmp32_ = slice;
	slice_set_direction_view (_tmp32_, direction, board, (gint) board_length1, (gint) board_length2);
	_tmp33_ = slice;
	_tmp34_ = *origin;
	_tmp35_ = bonus_get_x (bonus);
	_tmp36_ = _tmp35_;
	_tmp37_ = bonus_get_y (bonus);
	_tmp38_ = _tmp37_;
	slice_intersection_by_position (_tmp33_, &_tmp34_, _tmp36_, _tmp38_, 2);
	_tmp39_ = slice;
	result = !slice_is_empty (_tmp39_);
	_g_object_unref0 (slice);
	return result;
}

gint64
worm_ai_count_distance_to_a_bonus_in_direction (Worm* self,
                                                gint* board,
                                                gint board_length1,
                                                gint board_length2,
                                                WormMap* worm_map,
                                                Position* origin,
                                                WormDirection direction,
                                                BonuseType* bonus_type)
{
	BonuseType _vala_bonus_type = 0;
	gint64 bonus_distance = 0LL;
	Slice* slice = NULL;
	Slice* _tmp0_;
	gint64 result;
	g_return_val_if_fail (self != NULL, -1LL);
	g_return_val_if_fail (worm_map != NULL, -1LL);
	g_return_val_if_fail (origin != NULL, -1LL);
	bonus_distance = G_MAXINT64;
	_vala_bonus_type = (BonuseType) -1;
	_tmp0_ = slice_new (NULL);
	slice = _tmp0_;
	{
		GeeList* _b_list = NULL;
		WormGetBonusesType _tmp1_;
		gpointer _tmp1__target;
		GeeList* _tmp2_;
		gint _b_size = 0;
		GeeList* _tmp3_;
		gint _tmp4_;
		gint _tmp5_;
		gint _b_index = 0;
		_tmp1_ = self->priv->get_bonuses;
		_tmp1__target = self->priv->get_bonuses_target;
		_tmp2_ = _tmp1_ (_tmp1__target);
		_b_list = _tmp2_;
		_tmp3_ = _b_list;
		_tmp4_ = gee_collection_get_size ((GeeCollection*) _tmp3_);
		_tmp5_ = _tmp4_;
		_b_size = _tmp5_;
		_b_index = -1;
		while (TRUE) {
			gint _tmp6_;
			gint _tmp7_;
			Bonus* b = NULL;
			GeeList* _tmp8_;
			gpointer _tmp9_;
			gboolean _tmp10_ = FALSE;
			gboolean _tmp11_ = FALSE;
			_b_index = _b_index + 1;
			_tmp6_ = _b_index;
			_tmp7_ = _b_size;
			if (!(_tmp6_ < _tmp7_)) {
				break;
			}
			_tmp8_ = _b_list;
			_tmp9_ = gee_list_get (_tmp8_, _b_index);
			b = (Bonus*) _tmp9_;
			if (_vala_bonus_type == BONUS_ETYPE_LIFE) {
				Bonus* _tmp12_;
				BonuseType _tmp13_;
				BonuseType _tmp14_;
				_tmp12_ = b;
				_tmp13_ = bonus_get_etype (_tmp12_);
				_tmp14_ = _tmp13_;
				_tmp11_ = _tmp14_ == BONUS_ETYPE_LIFE;
			} else {
				_tmp11_ = FALSE;
			}
			if (_tmp11_) {
				_tmp10_ = TRUE;
			} else {
				gboolean _tmp15_ = FALSE;
				if (_vala_bonus_type != BONUS_ETYPE_LIFE) {
					gboolean _tmp16_ = FALSE;
					gboolean _tmp17_ = FALSE;
					gboolean _tmp18_ = FALSE;
					Bonus* _tmp19_;
					BonuseType _tmp20_;
					BonuseType _tmp21_;
					_tmp19_ = b;
					_tmp20_ = bonus_get_etype (_tmp19_);
					_tmp21_ = _tmp20_;
					if (_tmp21_ == BONUS_ETYPE_REGULAR) {
						_tmp18_ = TRUE;
					} else {
						Bonus* _tmp22_;
						BonuseType _tmp23_;
						BonuseType _tmp24_;
						_tmp22_ = b;
						_tmp23_ = bonus_get_etype (_tmp22_);
						_tmp24_ = _tmp23_;
						_tmp18_ = _tmp24_ == BONUS_ETYPE_DOUBLE;
					}
					if (_tmp18_) {
						_tmp17_ = TRUE;
					} else {
						Bonus* _tmp25_;
						BonuseType _tmp26_;
						BonuseType _tmp27_;
						_tmp25_ = b;
						_tmp26_ = bonus_get_etype (_tmp25_);
						_tmp27_ = _tmp26_;
						_tmp17_ = _tmp27_ == BONUS_ETYPE_LIFE;
					}
					if (_tmp17_) {
						_tmp16_ = TRUE;
					} else {
						Bonus* _tmp28_;
						BonuseType _tmp29_;
						BonuseType _tmp30_;
						_tmp28_ = b;
						_tmp29_ = bonus_get_etype (_tmp28_);
						_tmp30_ = _tmp29_;
						_tmp16_ = _tmp30_ == BONUS_ETYPE_REVERSE;
					}
					_tmp15_ = _tmp16_;
				} else {
					_tmp15_ = FALSE;
				}
				_tmp10_ = _tmp15_;
			}
			if (_tmp10_) {
				Slice* _tmp31_;
				Slice* _tmp32_;
				Position _tmp33_;
				Bonus* _tmp34_;
				guint8 _tmp35_;
				guint8 _tmp36_;
				Bonus* _tmp37_;
				guint8 _tmp38_;
				guint8 _tmp39_;
				Slice* _tmp40_;
				_tmp31_ = slice;
				slice_set_direction_view (_tmp31_, direction, board, (gint) board_length1, (gint) board_length2);
				_tmp32_ = slice;
				_tmp33_ = *origin;
				_tmp34_ = b;
				_tmp35_ = bonus_get_x (_tmp34_);
				_tmp36_ = _tmp35_;
				_tmp37_ = b;
				_tmp38_ = bonus_get_y (_tmp37_);
				_tmp39_ = _tmp38_;
				slice_intersection_by_position (_tmp32_, &_tmp33_, _tmp36_, _tmp39_, 2);
				_tmp40_ = slice;
				if (!slice_is_empty (_tmp40_)) {
					gint64 distance = 0LL;
					Slice* _tmp41_;
					Position _tmp42_;
					Bonus* _tmp43_;
					gboolean _tmp44_ = FALSE;
					_tmp41_ = slice;
					_tmp42_ = *origin;
					_tmp43_ = b;
					distance = slice_is_visible (_tmp41_, &_tmp42_, board, (gint) board_length1, (gint) board_length2, worm_map, _tmp43_);
					if (distance < bonus_distance) {
						Position _tmp45_;
						Position _tmp46_ = {0};
						Bonus* _tmp47_;
						_tmp45_ = *origin;
						worm_get_position_after_direction_move (self, &_tmp45_, direction, &_tmp46_);
						_tmp47_ = b;
						_tmp44_ = worm_ai_can_see_bonus (self, board, (gint) board_length1, (gint) board_length2, &_tmp46_, _tmp47_, direction);
					} else {
						_tmp44_ = FALSE;
					}
					if (_tmp44_) {
						Bonus* _tmp48_;
						BonuseType _tmp49_;
						BonuseType _tmp50_;
						bonus_distance = distance;
						_tmp48_ = b;
						_tmp49_ = bonus_get_etype (_tmp48_);
						_tmp50_ = _tmp49_;
						_vala_bonus_type = _tmp50_;
					}
				}
			}
			_g_object_unref0 (b);
		}
		_g_object_unref0 (_b_list);
	}
	result = bonus_distance;
	_g_object_unref0 (slice);
	if (bonus_type) {
		*bonus_type = _vala_bonus_type;
	}
	return result;
}

void
worm_ai_move (Worm* self,
              gint* board,
              gint board_length1,
              gint board_length2,
              GeeLinkedList* worms)
{
	WormMap* worm_map = NULL;
	guint8 _tmp0_;
	guint8 _tmp1_;
	WormMap* _tmp2_;
	BonuseType bonus_type = 0;
	gint64 shortest_distance = 0LL;
	WormDirection shortest_dir = 0;
	WormDirection _tmp3_;
	BonuseType shortest_bonus_type = 0;
	WormDirection dir[3] = {0};
	WormDirection _tmp4_;
	WormDirection _tmp5_;
	WormDirection _tmp6_;
	WormDirection _tmp7_[3] = {0};
	WormDirection bonus_dir = 0;
	WormDirection best_dir = 0;
	gint64 best_yet = 0LL;
	WormDirection _tmp38_;
	gint _tmp39_ = 0;
	WormDirection* _tmp40_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (worms != NULL);
	_tmp0_ = self->priv->_width;
	_tmp1_ = self->priv->_height;
	_tmp2_ = worm_map_new ((GeeList*) worms, _tmp0_, _tmp1_);
	worm_map = _tmp2_;
	shortest_distance = G_MAXINT64;
	_tmp3_ = self->priv->_direction;
	shortest_dir = _tmp3_;
	shortest_bonus_type = (BonuseType) -1;
	_tmp4_ = self->priv->_direction;
	_tmp5_ = self->priv->_direction;
	_tmp6_ = self->priv->_direction;
	_tmp7_[0] = _tmp4_;
	_tmp7_[1] = worm_direction_turn_left (_tmp5_);
	_tmp7_[2] = worm_direction_turn_right (_tmp6_);
	memcpy (dir, _tmp7_, 3 * sizeof (WormDirection));
	{
		WormDirection* direction_collection = NULL;
		gint direction_collection_length1 = 0;
		gint _direction_collection_size_ = 0;
		gint direction_it = 0;
		direction_collection = dir;
		direction_collection_length1 = 3;
		for (direction_it = 0; direction_it < direction_collection_length1; direction_it = direction_it + 1) {
			WormDirection direction = 0;
			direction = direction_collection[direction_it];
			{
				gint64 d = 0LL;
				WormMap* _tmp8_;
				Position _tmp9_ = {0};
				Position _tmp10_;
				BonuseType _tmp11_ = 0;
				gint64 _tmp12_;
				gboolean _tmp13_ = FALSE;
				_tmp8_ = worm_map;
				worm_get_head (self, &_tmp9_);
				_tmp10_ = _tmp9_;
				_tmp12_ = worm_ai_count_distance_to_a_bonus_in_direction (self, board, (gint) board_length1, (gint) board_length2, _tmp8_, &_tmp10_, direction, &_tmp11_);
				bonus_type = _tmp11_;
				d = _tmp12_;
				if (worm_ai_is_bonus_more_attractive (self, bonus_type, d, shortest_bonus_type, shortest_distance)) {
					_tmp13_ = worm_can_move_direction (self, board, (gint) board_length1, (gint) board_length2, (GeeList*) worms, direction);
				} else {
					_tmp13_ = FALSE;
				}
				if (_tmp13_) {
					shortest_distance = d;
					shortest_dir = direction;
					shortest_bonus_type = bonus_type;
				}
			}
		}
	}
	if (shortest_distance >= G_MAXINT64) {
		WormDirection start_direction[4] = {0};
		WormDirection _tmp14_;
		WormDirection _tmp15_;
		WormDirection _tmp16_;
		WormDirection _tmp17_;
		WormDirection _tmp18_[4] = {0};
		WormDirection look_direction[4] = {0};
		WormDirection _tmp19_;
		WormDirection _tmp20_;
		WormDirection _tmp21_;
		WormDirection _tmp22_;
		WormDirection _tmp23_[4] = {0};
		gint64 d = 0LL;
		_tmp14_ = self->priv->_direction;
		_tmp15_ = self->priv->_direction;
		_tmp16_ = self->priv->_direction;
		_tmp17_ = self->priv->_direction;
		_tmp18_[0] = _tmp14_;
		_tmp18_[1] = _tmp15_;
		_tmp18_[2] = worm_direction_turn_right (_tmp16_);
		_tmp18_[3] = worm_direction_turn_left (_tmp17_);
		memcpy (start_direction, _tmp18_, 4 * sizeof (WormDirection));
		_tmp19_ = self->priv->_direction;
		_tmp20_ = self->priv->_direction;
		_tmp21_ = self->priv->_direction;
		_tmp22_ = self->priv->_direction;
		_tmp23_[0] = worm_direction_turn_left (_tmp19_);
		_tmp23_[1] = worm_direction_turn_right (_tmp20_);
		_tmp23_[2] = _tmp21_;
		_tmp23_[3] = _tmp22_;
		memcpy (look_direction, _tmp23_, 4 * sizeof (WormDirection));
		{
			gint i = 0;
			i = 0;
			{
				gboolean _tmp24_ = FALSE;
				_tmp24_ = TRUE;
				while (TRUE) {
					WormMap* _tmp26_;
					Position _tmp27_ = {0};
					Position _tmp28_;
					WormDirection _tmp29_;
					Position _tmp30_ = {0};
					WormDirection _tmp31_;
					BonuseType _tmp32_ = 0;
					gint64 _tmp33_;
					if (!_tmp24_) {
						gint _tmp25_;
						_tmp25_ = i;
						i = _tmp25_ + 1;
					}
					_tmp24_ = FALSE;
					if (!(i < 4)) {
						break;
					}
					_tmp26_ = worm_map;
					worm_get_head (self, &_tmp27_);
					_tmp28_ = _tmp27_;
					_tmp29_ = start_direction[i];
					worm_get_position_after_direction_move (self, &_tmp28_, _tmp29_, &_tmp30_);
					_tmp31_ = look_direction[i];
					_tmp33_ = worm_ai_count_distance_to_a_bonus_in_direction (self, board, (gint) board_length1, (gint) board_length2, _tmp26_, &_tmp30_, _tmp31_, &_tmp32_);
					bonus_type = _tmp32_;
					d = _tmp33_;
					if (worm_ai_is_bonus_more_attractive (self, bonus_type, d, shortest_bonus_type, shortest_distance)) {
						WormDirection _tmp34_;
						shortest_distance = d + 1;
						_tmp34_ = start_direction[i];
						shortest_dir = _tmp34_;
						shortest_bonus_type = bonus_type;
					}
				}
			}
		}
	}
	bonus_type = shortest_bonus_type;
	if (shortest_distance >= G_MAXINT64) {
		if (g_random_int_range ((gint32) 0, (gint32) 30) == ((gint32) 1)) {
			WormDirection _tmp35_ = 0;
			if (g_random_boolean ()) {
				WormDirection _tmp36_;
				_tmp36_ = self->priv->_direction;
				_tmp35_ = worm_direction_turn_right (_tmp36_);
			} else {
				WormDirection _tmp37_;
				_tmp37_ = self->priv->_direction;
				_tmp35_ = worm_direction_turn_left (_tmp37_);
			}
			shortest_dir = _tmp35_;
		}
	}
	bonus_dir = shortest_dir;
	best_dir = WORM_DIRECTION_NONE;
	best_yet = G_MAXINT64;
	_tmp38_ = dir[0];
	_tmp40_ = worm_direction_get_space_fill_array (_tmp38_, &_tmp39_);
	{
		WormDirection* direction_collection = NULL;
		gint direction_collection_length1 = 0;
		gint _direction_collection_size_ = 0;
		gint direction_it = 0;
		direction_collection = _tmp40_;
		direction_collection_length1 = _tmp39_;
		for (direction_it = 0; direction_it < direction_collection_length1; direction_it = direction_it + 1) {
			WormDirection direction = 0;
			direction = direction_collection[direction_it];
			{
				gint this_len = 0;
				gboolean _tmp41_ = FALSE;
				gboolean _tmp53_ = FALSE;
				this_len = 0;
				if (direction == bonus_dir) {
					_tmp41_ = bonus_type == BONUS_ETYPE_LIFE;
				} else {
					_tmp41_ = FALSE;
				}
				if (!_tmp41_) {
					WormMap* _tmp42_;
					Position _tmp43_ = {0};
					Position _tmp44_;
					Position _tmp45_ = {0};
					WormMap* _tmp47_;
					Position _tmp48_ = {0};
					Position _tmp49_;
					gint _tmp50_;
					gint _tmp51_;
					gint _tmp52_;
					_tmp42_ = worm_map;
					worm_get_head (self, &_tmp43_);
					_tmp44_ = _tmp43_;
					worm_get_position_after_direction_move (self, &_tmp44_, direction, &_tmp45_);
					if (!worm_can_move_to_map (self, board, (gint) board_length1, (gint) board_length2, _tmp42_, &_tmp45_)) {
						gint _tmp46_;
						_tmp46_ = self->priv->_capacity;
						this_len += _tmp46_;
					}
					if (worm_ai_too_close (self, worms, direction)) {
						this_len += 4;
					}
					_tmp47_ = worm_map;
					worm_get_head (self, &_tmp48_);
					_tmp49_ = _tmp48_;
					_tmp50_ = worm_get_length (self);
					_tmp51_ = _tmp50_;
					_tmp52_ = self->priv->_change;
					this_len += worm_ai_deadend_after (board, (gint) board_length1, (gint) board_length2, worms, _tmp47_, &_tmp49_, direction, _tmp51_ + _tmp52_);
				}
				if (direction == bonus_dir) {
					_tmp53_ = this_len <= 0;
				} else {
					_tmp53_ = FALSE;
				}
				if (_tmp53_) {
					this_len -= 100;
				}
				if (this_len <= 0) {
					this_len -= (gint) g_random_int_range ((gint32) 0, (gint32) 100);
				}
				if (((gint64) this_len) < best_yet) {
					best_yet = (gint64) this_len;
					best_dir = direction;
				}
			}
		}
		direction_collection = (g_free (direction_collection), NULL);
	}
	worm_set_direction (self, best_dir);
	_g_object_unref0 (worm_map);
}

void
worm_get_starting_position (Worm* self,
                            Position * result)
{
	Position _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_starting_position;
	*result = _tmp0_;
	return;
}

static gboolean
_position_equal (const Position * s1,
                 const Position * s2)
{
	if (s1 == s2) {
		return TRUE;
	}
	if (s1 == NULL) {
		return FALSE;
	}
	if (s2 == NULL) {
		return FALSE;
	}
	if (s1->x != s2->x) {
		return FALSE;
	}
	if (s1->y != s2->y) {
		return FALSE;
	}
	return TRUE;
}

static void
worm_set_starting_position (Worm* self,
                            Position * value)
{
	Position old_value;
	g_return_if_fail (self != NULL);
	worm_get_starting_position (self, &old_value);
	if (_position_equal (value, &old_value) != TRUE) {
		Position _tmp0_;
		_tmp0_ = *value;
		self->priv->_starting_position = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, worm_properties[WORM_STARTING_POSITION_PROPERTY]);
	}
}

gint
worm_get_id (Worm* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_id;
	return result;
}

static void
worm_set_id (Worm* self,
             gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = worm_get_id (self);
	if (old_value != value) {
		self->priv->_id = value;
		g_object_notify_by_pspec ((GObject *) self, worm_properties[WORM_ID_PROPERTY]);
	}
}

gboolean
worm_get_is_materialized (Worm* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->rounds_to_stay_dematerialized <= 0;
	return result;
}

guint8
worm_get_lives (Worm* self)
{
	guint8 result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_lives;
	return result;
}

void
worm_set_lives (Worm* self,
                guint8 value)
{
	guint8 old_value;
	g_return_if_fail (self != NULL);
	old_value = worm_get_lives (self);
	if (old_value != value) {
		self->priv->_lives = value;
		g_object_notify_by_pspec ((GObject *) self, worm_properties[WORM_LIVES_PROPERTY]);
	}
}

gint
worm_get_change (Worm* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_change;
	return result;
}

void
worm_set_change (Worm* self,
                 gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = worm_get_change (self);
	if (old_value != value) {
		self->priv->_change = value;
		g_object_notify_by_pspec ((GObject *) self, worm_properties[WORM_CHANGE_PROPERTY]);
	}
}

gint
worm_get_score (Worm* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_score;
	return result;
}

void
worm_set_score (Worm* self,
                gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = worm_get_score (self);
	if (old_value != value) {
		self->priv->_score = value;
		g_object_notify_by_pspec ((GObject *) self, worm_properties[WORM_SCORE_PROPERTY]);
	}
}

gint
worm_get_length (Worm* self)
{
	gint result;
	WormPositions* _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	g_return_val_if_fail (self != NULL, -1);
	_tmp0_ = self->list;
	_tmp1_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp0_);
	_tmp2_ = _tmp1_;
	result = _tmp2_;
	return result;
}

void
worm_get_head (Worm* self,
               Position * result)
{
	Position head = {0};
	WormPositions* _tmp0_;
	Position _tmp1_ = {0};
	Position _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->list;
	worm_positions_get_head (_tmp0_, &_tmp1_);
	head = _tmp1_;
	_tmp2_ = head;
	*result = _tmp2_;
	return;
}

static void
worm_set_head (Worm* self,
               Position * value)
{
	WormPositions* _tmp0_;
	Position _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->list;
	_tmp1_ = *value;
	worm_positions_set_head (_tmp0_, &_tmp1_);
	g_object_notify_by_pspec ((GObject *) self, worm_properties[WORM_HEAD_PROPERTY]);
}

WormDirection
worm_get_direction (Worm* self)
{
	WormDirection result;
	g_return_val_if_fail (self != NULL, 0);
	result = self->priv->_direction;
	return result;
}

static void
worm_set_direction (Worm* self,
                    WormDirection value)
{
	WormDirection old_value;
	g_return_if_fail (self != NULL);
	old_value = worm_get_direction (self);
	if (old_value != value) {
		self->priv->_direction = value;
		g_object_notify_by_pspec ((GObject *) self, worm_properties[WORM_DIRECTION_PROPERTY]);
	}
}

static guint8
worm_get_width (Worm* self)
{
	guint8 result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_width;
	return result;
}

static void
worm_set_width (Worm* self,
                guint8 value)
{
	guint8 old_value;
	g_return_if_fail (self != NULL);
	old_value = worm_get_width (self);
	if (old_value != value) {
		self->priv->_width = value;
		g_object_notify_by_pspec ((GObject *) self, worm_properties[WORM_WIDTH_PROPERTY]);
	}
}

static guint8
worm_get_height (Worm* self)
{
	guint8 result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_height;
	return result;
}

static void
worm_set_height (Worm* self,
                 guint8 value)
{
	guint8 old_value;
	g_return_if_fail (self != NULL);
	old_value = worm_get_height (self);
	if (old_value != value) {
		self->priv->_height = value;
		g_object_notify_by_pspec ((GObject *) self, worm_properties[WORM_HEIGHT_PROPERTY]);
	}
}

static gint
worm_get_capacity (Worm* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_capacity;
	return result;
}

static void
worm_set_capacity (Worm* self,
                   gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = worm_get_capacity (self);
	if (old_value != value) {
		self->priv->_capacity = value;
		g_object_notify_by_pspec ((GObject *) self, worm_properties[WORM_CAPACITY_PROPERTY]);
	}
}

static inline gpointer
worm_key_queue_get_instance_private (WormKeyQueue* self)
{
	return G_STRUCT_MEMBER_P (self, WormKeyQueue_private_offset);
}

static WormDirection
worm_key_queue_convert_to_direction (WormKeyQueue* self,
                                     gulong l)
{
	WormDirection result;
	g_return_val_if_fail (self != NULL, 0);
	result = l + 1;
	return result;
}

static gulong
worm_key_queue_convert_from_direction (WormKeyQueue* self,
                                       WormDirection dir)
{
	gulong result;
	g_return_val_if_fail (self != NULL, 0UL);
	result = (gulong) (dir - 1);
	return result;
}

static gulong
worm_key_queue_peek_tail (WormKeyQueue* self)
{
	gulong _tmp0_ = 0UL;
	gulong result;
	g_return_val_if_fail (self != NULL, 0UL);
	_vala_return_val_if_fail (!worm_key_queue_is_empty (self), "!is_empty ()", 0UL);
	if (self->priv->tail > ((gulong) 0)) {
		_tmp0_ = self->priv->tail;
	} else {
		_tmp0_ = DOUBLE_BIT_ARRAY_size;
	}
	result = double_bit_array_get_at ((DoubleBitArray*) self, _tmp0_ - 1);
	return result;
}

static gulong
worm_key_queue_peek_head (WormKeyQueue* self)
{
	gulong result;
	g_return_val_if_fail (self != NULL, 0UL);
	_vala_return_val_if_fail (!worm_key_queue_is_empty (self), "!is_empty ()", 0UL);
	result = double_bit_array_get_at ((DoubleBitArray*) self, self->priv->head);
	return result;
}

static gboolean
worm_key_queue_is_full (WormKeyQueue* self)
{
	gulong _tmp0_ = 0UL;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (self->priv->head > ((gulong) 0)) {
		_tmp0_ = self->priv->head;
	} else {
		_tmp0_ = DOUBLE_BIT_ARRAY_size;
	}
	result = self->priv->tail == (_tmp0_ - 1);
	return result;
}

static void
worm_key_queue_join_queue (WormKeyQueue* self,
                           gulong d)
{
	gulong _tmp0_;
	gulong _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->tail;
	self->priv->tail = _tmp0_ + 1;
	_tmp1_ = d;
	double_bit_array_set_at ((DoubleBitArray*) self, _tmp0_, _tmp1_);
	if (self->priv->tail >= DOUBLE_BIT_ARRAY_size) {
		self->priv->tail = (gulong) 0;
	}
}

static void
worm_key_queue_append (WormKeyQueue* self,
                       WormDirection _direction)
{
	gulong d = 0UL;
	gboolean _tmp0_ = FALSE;
	g_return_if_fail (self != NULL);
	_vala_return_if_fail (_direction != WORM_DIRECTION_NONE, "_direction != NONE");
	d = worm_key_queue_convert_from_direction (self, _direction);
	if (worm_key_queue_is_empty (self)) {
		_tmp0_ = TRUE;
	} else {
		gboolean _tmp1_ = FALSE;
		if (worm_key_queue_peek_tail (self) != d) {
			_tmp1_ = !worm_key_queue_is_full (self);
		} else {
			_tmp1_ = FALSE;
		}
		_tmp0_ = _tmp1_;
	}
	if (_tmp0_) {
		worm_key_queue_join_queue (self, d);
	}
}

static void
worm_key_queue_prepend (WormKeyQueue* self,
                        WormDirection _direction)
{
	gulong d = 0UL;
	g_return_if_fail (self != NULL);
	_vala_return_if_fail (_direction != WORM_DIRECTION_NONE, "_direction != NONE");
	d = worm_key_queue_convert_from_direction (self, _direction);
	if (worm_key_queue_is_empty (self)) {
		worm_key_queue_join_queue (self, d);
	} else {
		gboolean _tmp0_ = FALSE;
		if (worm_key_queue_peek_head (self) != d) {
			_tmp0_ = !worm_key_queue_is_full (self);
		} else {
			_tmp0_ = FALSE;
		}
		if (_tmp0_) {
			if (self->priv->head > ((gulong) 0)) {
				gulong _tmp1_;
				_tmp1_ = self->priv->head;
				self->priv->head = _tmp1_ - 1;
			} else {
				self->priv->head = DOUBLE_BIT_ARRAY_size - 1;
			}
			double_bit_array_set_at ((DoubleBitArray*) self, self->priv->head, d);
		}
	}
}

static void
worm_key_queue_clear (WormKeyQueue* self)
{
	g_return_if_fail (self != NULL);
	self->priv->head = self->priv->tail;
}

static gboolean
worm_key_queue_is_empty (WormKeyQueue* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->head == self->priv->tail;
	return result;
}

static WormDirection
worm_key_queue_remove (WormKeyQueue* self)
{
	WormDirection r = 0;
	WormDirection result;
	g_return_val_if_fail (self != NULL, 0);
	r = worm_key_queue_convert_to_direction (self, worm_key_queue_peek_head (self));
	if (self->priv->head < (DOUBLE_BIT_ARRAY_size - 1)) {
		gulong _tmp0_;
		_tmp0_ = self->priv->head;
		self->priv->head = _tmp0_ + 1;
	} else {
		self->priv->head = (gulong) 0;
	}
	result = r;
	return result;
}

static WormKeyQueue*
worm_key_queue_construct (GType object_type)
{
	WormKeyQueue* self = NULL;
	self = (WormKeyQueue*) double_bit_array_construct (object_type);
	return self;
}

static WormKeyQueue*
worm_key_queue_new (void)
{
	return worm_key_queue_construct (WORM_TYPE_KEY_QUEUE);
}

static void
worm_key_queue_class_init (WormKeyQueueClass * klass,
                           gpointer klass_data)
{
	worm_key_queue_parent_class = g_type_class_peek_parent (klass);
	((DoubleBitArrayClass *) klass)->finalize = worm_key_queue_finalize;
	g_type_class_adjust_private_offset (klass, &WormKeyQueue_private_offset);
}

static void
worm_key_queue_instance_init (WormKeyQueue * self,
                              gpointer klass)
{
	self->priv = worm_key_queue_get_instance_private (self);
	self->priv->head = (gulong) 0;
	self->priv->tail = (gulong) 0;
}

static void
worm_key_queue_finalize (DoubleBitArray * obj)
{
	WormKeyQueue * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, WORM_TYPE_KEY_QUEUE, WormKeyQueue);
	DOUBLE_BIT_ARRAY_CLASS (worm_key_queue_parent_class)->finalize (obj);
}

 G_GNUC_NO_INLINE static GType
worm_key_queue_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (WormKeyQueueClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) worm_key_queue_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (WormKeyQueue), 0, (GInstanceInitFunc) worm_key_queue_instance_init, NULL };
	GType worm_key_queue_type_id;
	worm_key_queue_type_id = g_type_register_static (TYPE_DOUBLE_BIT_ARRAY, "WormKeyQueue", &g_define_type_info, G_TYPE_FLAG_NONE);
	WormKeyQueue_private_offset = g_type_add_instance_private (worm_key_queue_type_id, sizeof (WormKeyQueuePrivate));
	return worm_key_queue_type_id;
}

static GType
worm_key_queue_get_type (void)
{
	static GType worm_key_queue_type_id__once = 0;
	if (g_once_init_enter_pointer (&worm_key_queue_type_id__once)) {
		GType worm_key_queue_type_id;
		worm_key_queue_type_id = worm_key_queue_get_type_once ();
		g_once_init_leave_pointer (&worm_key_queue_type_id__once, worm_key_queue_type_id);
	}
	return worm_key_queue_type_id__once;
}

static GObject *
worm_constructor (GType type,
                  guint n_construct_properties,
                  GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	Worm * self;
	guint8 _tmp0_;
	guint8 _tmp1_;
	guint* _tmp2_;
	parent_class = G_OBJECT_CLASS (worm_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_WORM, Worm);
	_tmp0_ = self->priv->_width;
	_tmp1_ = self->priv->_height;
	_tmp2_ = g_new0 (guint, _tmp0_ * _tmp1_);
	worm_deadend_board = (g_free (worm_deadend_board), NULL);
	worm_deadend_board = _tmp2_;
	worm_deadend_board_length1 = _tmp0_;
	worm_deadend_board_length2 = _tmp1_;
	return obj;
}

static void
worm_class_init (WormClass * klass,
                 gpointer klass_data)
{
	worm_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &Worm_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_worm_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_worm_set_property;
	G_OBJECT_CLASS (klass)->constructor = worm_constructor;
	G_OBJECT_CLASS (klass)->finalize = worm_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_STARTING_POSITION_PROPERTY, worm_properties[WORM_STARTING_POSITION_PROPERTY] = g_param_spec_boxed ("starting-position", "starting-position", "starting-position", TYPE_POSITION, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_ID_PROPERTY, worm_properties[WORM_ID_PROPERTY] = g_param_spec_int ("id", "id", "id", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_IS_MATERIALIZED_PROPERTY, worm_properties[WORM_IS_MATERIALIZED_PROPERTY] = g_param_spec_boolean ("is-materialized", "is-materialized", "is-materialized", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_LIVES_PROPERTY, worm_properties[WORM_LIVES_PROPERTY] = g_param_spec_uchar ("lives", "lives", "lives", 0, G_MAXUINT8, WORM_STARTING_LIVES, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_CHANGE_PROPERTY, worm_properties[WORM_CHANGE_PROPERTY] = g_param_spec_int ("change", "change", "change", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_SCORE_PROPERTY, worm_properties[WORM_SCORE_PROPERTY] = g_param_spec_int ("score", "score", "score", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_LENGTH_PROPERTY, worm_properties[WORM_LENGTH_PROPERTY] = g_param_spec_int ("length", "length", "length", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_HEAD_PROPERTY, worm_properties[WORM_HEAD_PROPERTY] = g_param_spec_boxed ("head", "head", "head", TYPE_POSITION, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_DIRECTION_PROPERTY, worm_properties[WORM_DIRECTION_PROPERTY] = g_param_spec_enum ("direction", "direction", "direction", TYPE_WORM_DIRECTION, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_WIDTH_PROPERTY, worm_properties[WORM_WIDTH_PROPERTY] = g_param_spec_uchar ("width", "width", "width", 0, G_MAXUINT8, 0, G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_HEIGHT_PROPERTY, worm_properties[WORM_HEIGHT_PROPERTY] = g_param_spec_uchar ("height", "height", "height", 0, G_MAXUINT8, 0, G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), WORM_CAPACITY_PROPERTY, worm_properties[WORM_CAPACITY_PROPERTY] = g_param_spec_int ("capacity", "capacity", "capacity", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	worm_signals[WORM_BONUS_FOUND_SIGNAL] = g_signal_new ("bonus-found", TYPE_WORM, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}

static void
worm_instance_init (Worm * self,
                    gpointer klass)
{
	WormKeyQueue* _tmp0_;
	WormPositions* _tmp1_;
	GeeArrayList* _tmp2_;
	self->priv = worm_get_instance_private (self);
	self->is_stopped = FALSE;
	self->priv->_lives = WORM_STARTING_LIVES;
	self->priv->_change = 0;
	self->priv->_score = 0;
	_tmp0_ = worm_key_queue_new ();
	self->priv->key_queue = _tmp0_;
	_tmp1_ = worm_positions_new ();
	self->list = _tmp1_;
	_tmp2_ = gee_array_list_new (G_TYPE_UINT, NULL, NULL, NULL, NULL, NULL);
	self->priv->bonus_eaten = _tmp2_;
	self->priv->LastUturnA = FALSE;
}

static void
worm_finalize (GObject * obj)
{
	Worm * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_WORM, Worm);
	_double_bit_array_unref0 (self->priv->key_queue);
	_g_object_unref0 (self->list);
	_g_object_unref0 (self->priv->bonus_eaten);
	(self->priv->get_other_worms_target_destroy_notify == NULL) ? NULL : (self->priv->get_other_worms_target_destroy_notify (self->priv->get_other_worms_target), NULL);
	self->priv->get_other_worms = NULL;
	self->priv->get_other_worms_target = NULL;
	self->priv->get_other_worms_target_destroy_notify = NULL;
	(self->priv->get_bonuses_target_destroy_notify == NULL) ? NULL : (self->priv->get_bonuses_target_destroy_notify (self->priv->get_bonuses_target), NULL);
	self->priv->get_bonuses = NULL;
	self->priv->get_bonuses_target = NULL;
	self->priv->get_bonuses_target_destroy_notify = NULL;
	G_OBJECT_CLASS (worm_parent_class)->finalize (obj);
}

 G_GNUC_NO_INLINE static GType
worm_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (WormClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) worm_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Worm), 0, (GInstanceInitFunc) worm_instance_init, NULL };
	GType worm_type_id;
	worm_type_id = g_type_register_static (G_TYPE_OBJECT, "Worm", &g_define_type_info, G_TYPE_FLAG_NONE);
	Worm_private_offset = g_type_add_instance_private (worm_type_id, sizeof (WormPrivate));
	return worm_type_id;
}

GType
worm_get_type (void)
{
	static GType worm_type_id__once = 0;
	if (g_once_init_enter_pointer (&worm_type_id__once)) {
		GType worm_type_id;
		worm_type_id = worm_get_type_once ();
		g_once_init_leave_pointer (&worm_type_id__once, worm_type_id);
	}
	return worm_type_id__once;
}

static void
_vala_worm_get_property (GObject * object,
                         guint property_id,
                         GValue * value,
                         GParamSpec * pspec)
{
	Worm * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_WORM, Worm);
	switch (property_id) {
		case WORM_STARTING_POSITION_PROPERTY:
		{
			Position boxed;
			worm_get_starting_position (self, &boxed);
			g_value_set_boxed (value, &boxed);
		}
		break;
		case WORM_ID_PROPERTY:
		g_value_set_int (value, worm_get_id (self));
		break;
		case WORM_IS_MATERIALIZED_PROPERTY:
		g_value_set_boolean (value, worm_get_is_materialized (self));
		break;
		case WORM_LIVES_PROPERTY:
		g_value_set_uchar (value, worm_get_lives (self));
		break;
		case WORM_CHANGE_PROPERTY:
		g_value_set_int (value, worm_get_change (self));
		break;
		case WORM_SCORE_PROPERTY:
		g_value_set_int (value, worm_get_score (self));
		break;
		case WORM_LENGTH_PROPERTY:
		g_value_set_int (value, worm_get_length (self));
		break;
		case WORM_HEAD_PROPERTY:
		{
			Position boxed;
			worm_get_head (self, &boxed);
			g_value_set_boxed (value, &boxed);
		}
		break;
		case WORM_DIRECTION_PROPERTY:
		g_value_set_enum (value, worm_get_direction (self));
		break;
		case WORM_WIDTH_PROPERTY:
		g_value_set_uchar (value, worm_get_width (self));
		break;
		case WORM_HEIGHT_PROPERTY:
		g_value_set_uchar (value, worm_get_height (self));
		break;
		case WORM_CAPACITY_PROPERTY:
		g_value_set_int (value, worm_get_capacity (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_worm_set_property (GObject * object,
                         guint property_id,
                         const GValue * value,
                         GParamSpec * pspec)
{
	Worm * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_WORM, Worm);
	switch (property_id) {
		case WORM_STARTING_POSITION_PROPERTY:
		worm_set_starting_position (self, g_value_get_boxed (value));
		break;
		case WORM_ID_PROPERTY:
		worm_set_id (self, g_value_get_int (value));
		break;
		case WORM_LIVES_PROPERTY:
		worm_set_lives (self, g_value_get_uchar (value));
		break;
		case WORM_CHANGE_PROPERTY:
		worm_set_change (self, g_value_get_int (value));
		break;
		case WORM_SCORE_PROPERTY:
		worm_set_score (self, g_value_get_int (value));
		break;
		case WORM_HEAD_PROPERTY:
		worm_set_head (self, g_value_get_boxed (value));
		break;
		case WORM_DIRECTION_PROPERTY:
		worm_set_direction (self, g_value_get_enum (value));
		break;
		case WORM_WIDTH_PROPERTY:
		worm_set_width (self, g_value_get_uchar (value));
		break;
		case WORM_HEIGHT_PROPERTY:
		worm_set_height (self, g_value_get_uchar (value));
		break;
		case WORM_CAPACITY_PROPERTY:
		worm_set_capacity (self, g_value_get_int (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

