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

/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
   This file is part of GNOME Reversi, also known as Iagno.

   Copyright 2010-2013 Robert Ancell
   Copyright 2013-2014 Michael Catanzaro
   Copyright 2014-2019 Arnaud Bonatti

   GNOME Reversi 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.

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

#include <glib-object.h>
#include <glib.h>
#include <string.h>
#include <stdlib.h>

#define COMPUTER_REVERSI_POSITIVE_INFINITY ((gint16) 32000)
#define COMPUTER_REVERSI_NEGATIVE_INFINITY ((gint16) -32000)
#define COMPUTER_REVERSE_HARD_border_penalty ((gint16) 86)
#define COMPUTER_REVERSE_HARD_corner_penalty ((gint16) 86)
#define COMPUTER_REVERSI_HARD_border_penalty ((gint16) 206)
#define COMPUTER_REVERSI_HARD_corner_penalty ((gint16) 206)
#define COMPUTER_REVERSI_LESS_THAN_NEGATIVE_INFINITY ((gint16) -32001)
#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif
#if !defined(VALA_EXTERN)
#if defined(_MSC_VER)
#define VALA_EXTERN __declspec(dllexport) extern
#elif __GNUC__ >= 4
#define VALA_EXTERN __attribute__((visibility("default"))) extern
#else
#define VALA_EXTERN extern
#endif
#endif

#define TYPE_POSSIBLE_MOVE (possible_move_get_type ())
typedef struct _PossibleMove PossibleMove;

#define TYPE_COMPUTER_PLAYER (computer_player_get_type ())
#define COMPUTER_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_COMPUTER_PLAYER, ComputerPlayer))
#define COMPUTER_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_COMPUTER_PLAYER, ComputerPlayerClass))
#define IS_COMPUTER_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_COMPUTER_PLAYER))
#define IS_COMPUTER_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_COMPUTER_PLAYER))
#define COMPUTER_PLAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_COMPUTER_PLAYER, ComputerPlayerClass))

typedef struct _ComputerPlayer ComputerPlayer;
typedef struct _ComputerPlayerClass ComputerPlayerClass;
typedef struct _ComputerPlayerPrivate ComputerPlayerPrivate;

#define TYPE_COMPUTER_REVERSI (computer_reversi_get_type ())
#define COMPUTER_REVERSI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_COMPUTER_REVERSI, ComputerReversi))
#define COMPUTER_REVERSI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_COMPUTER_REVERSI, ComputerReversiClass))
#define IS_COMPUTER_REVERSI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_COMPUTER_REVERSI))
#define IS_COMPUTER_REVERSI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_COMPUTER_REVERSI))
#define COMPUTER_REVERSI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_COMPUTER_REVERSI, ComputerReversiClass))

typedef struct _ComputerReversi ComputerReversi;
typedef struct _ComputerReversiClass ComputerReversiClass;
typedef struct _ComputerReversiPrivate ComputerReversiPrivate;

#define TYPE_GAME_STATE_STRUCT (game_state_struct_get_type ())
typedef struct _GameStateStruct GameStateStruct;
typedef enum  {
	PLAYER_NONE,
	PLAYER_DARK,
	PLAYER_LIGHT
} Player;

#define TYPE_PLAYER (player_get_type ())

#define TYPE_COMPUTER_REVERSE_EASY (computer_reverse_easy_get_type ())
#define COMPUTER_REVERSE_EASY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_COMPUTER_REVERSE_EASY, ComputerReverseEasy))
#define COMPUTER_REVERSE_EASY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_COMPUTER_REVERSE_EASY, ComputerReverseEasyClass))
#define IS_COMPUTER_REVERSE_EASY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_COMPUTER_REVERSE_EASY))
#define IS_COMPUTER_REVERSE_EASY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_COMPUTER_REVERSE_EASY))
#define COMPUTER_REVERSE_EASY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_COMPUTER_REVERSE_EASY, ComputerReverseEasyClass))

typedef struct _ComputerReverseEasy ComputerReverseEasy;
typedef struct _ComputerReverseEasyClass ComputerReverseEasyClass;
typedef struct _ComputerReverseEasyPrivate ComputerReverseEasyPrivate;
enum  {
	COMPUTER_REVERSE_EASY_0_PROPERTY,
	COMPUTER_REVERSE_EASY_NUM_PROPERTIES
};
static GParamSpec* computer_reverse_easy_properties[COMPUTER_REVERSE_EASY_NUM_PROPERTIES];

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

typedef struct _Game Game;
typedef struct _GameClass GameClass;

#define TYPE_COMPUTER_REVERSE_HARD (computer_reverse_hard_get_type ())
#define COMPUTER_REVERSE_HARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_COMPUTER_REVERSE_HARD, ComputerReverseHard))
#define COMPUTER_REVERSE_HARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_COMPUTER_REVERSE_HARD, ComputerReverseHardClass))
#define IS_COMPUTER_REVERSE_HARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_COMPUTER_REVERSE_HARD))
#define IS_COMPUTER_REVERSE_HARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_COMPUTER_REVERSE_HARD))
#define COMPUTER_REVERSE_HARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_COMPUTER_REVERSE_HARD, ComputerReverseHardClass))

typedef struct _ComputerReverseHard ComputerReverseHard;
typedef struct _ComputerReverseHardClass ComputerReverseHardClass;
typedef struct _ComputerReverseHardPrivate ComputerReverseHardPrivate;
enum  {
	COMPUTER_REVERSE_HARD_0_PROPERTY,
	COMPUTER_REVERSE_HARD_EVEN_DEPTH_PROPERTY,
	COMPUTER_REVERSE_HARD_FIXED_HEURISTIC_PROPERTY,
	COMPUTER_REVERSE_HARD_NUM_PROPERTIES
};
static GParamSpec* computer_reverse_hard_properties[COMPUTER_REVERSE_HARD_NUM_PROPERTIES];
typedef enum  {
	MAIN_LINE_TOP,
	MAIN_LINE_LEFT,
	MAIN_LINE_RIGHT,
	MAIN_LINE_BOTTOM,
	MAIN_LINE_TOPLEFT,
	MAIN_LINE_TOPRIGHT
} MainLine;

#define TYPE_MAIN_LINE (main_line_get_type ())

#define TYPE_COMPUTER_REVERSI_EASY (computer_reversi_easy_get_type ())
#define COMPUTER_REVERSI_EASY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_COMPUTER_REVERSI_EASY, ComputerReversiEasy))
#define COMPUTER_REVERSI_EASY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_COMPUTER_REVERSI_EASY, ComputerReversiEasyClass))
#define IS_COMPUTER_REVERSI_EASY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_COMPUTER_REVERSI_EASY))
#define IS_COMPUTER_REVERSI_EASY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_COMPUTER_REVERSI_EASY))
#define COMPUTER_REVERSI_EASY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_COMPUTER_REVERSI_EASY, ComputerReversiEasyClass))

typedef struct _ComputerReversiEasy ComputerReversiEasy;
typedef struct _ComputerReversiEasyClass ComputerReversiEasyClass;
typedef struct _ComputerReversiEasyPrivate ComputerReversiEasyPrivate;
enum  {
	COMPUTER_REVERSI_EASY_0_PROPERTY,
	COMPUTER_REVERSI_EASY_NUM_PROPERTIES
};
static GParamSpec* computer_reversi_easy_properties[COMPUTER_REVERSI_EASY_NUM_PROPERTIES];

#define TYPE_COMPUTER_REVERSI_HARD (computer_reversi_hard_get_type ())
#define COMPUTER_REVERSI_HARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_COMPUTER_REVERSI_HARD, ComputerReversiHard))
#define COMPUTER_REVERSI_HARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_COMPUTER_REVERSI_HARD, ComputerReversiHardClass))
#define IS_COMPUTER_REVERSI_HARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_COMPUTER_REVERSI_HARD))
#define IS_COMPUTER_REVERSI_HARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_COMPUTER_REVERSI_HARD))
#define COMPUTER_REVERSI_HARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_COMPUTER_REVERSI_HARD, ComputerReversiHardClass))

typedef struct _ComputerReversiHard ComputerReversiHard;
typedef struct _ComputerReversiHardClass ComputerReversiHardClass;
typedef struct _ComputerReversiHardPrivate ComputerReversiHardPrivate;
enum  {
	COMPUTER_REVERSI_HARD_0_PROPERTY,
	COMPUTER_REVERSI_HARD_EVEN_DEPTH_PROPERTY,
	COMPUTER_REVERSI_HARD_FIXED_HEURISTIC_PROPERTY,
	COMPUTER_REVERSI_HARD_NUM_PROPERTIES
};
static GParamSpec* computer_reversi_hard_properties[COMPUTER_REVERSI_HARD_NUM_PROPERTIES];
enum  {
	COMPUTER_REVERSI_0_PROPERTY,
	COMPUTER_REVERSI_GAME_PROPERTY,
	COMPUTER_REVERSI_INITIAL_DEPTH_PROPERTY,
	COMPUTER_REVERSI_SIZE_PROPERTY,
	COMPUTER_REVERSI_MOVE_RANDOMLY_PROPERTY,
	COMPUTER_REVERSI_NUM_PROPERTIES
};
static GParamSpec* computer_reversi_properties[COMPUTER_REVERSI_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))

#define TYPE_GAME_STATE_OBJECT (game_state_object_get_type ())
#define GAME_STATE_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_GAME_STATE_OBJECT, GameStateObject))
#define GAME_STATE_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_GAME_STATE_OBJECT, GameStateObjectClass))
#define IS_GAME_STATE_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_GAME_STATE_OBJECT))
#define IS_GAME_STATE_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_GAME_STATE_OBJECT))
#define GAME_STATE_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_GAME_STATE_OBJECT, GameStateObjectClass))

typedef struct _GameStateObject GameStateObject;
typedef struct _GameStateObjectClass GameStateObjectClass;
#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 _PossibleMove {
	guint8 x;
	guint8 y;
	guint8 n_tiles;
	guint8 n_tiles_n;
	guint8 n_tiles_ne;
	guint8 n_tiles_e;
	guint8 n_tiles_se;
	guint8 n_tiles_s;
	guint8 n_tiles_so;
	guint8 n_tiles_o;
	guint8 n_tiles_no;
};

struct _ComputerPlayer {
	GObject parent_instance;
	ComputerPlayerPrivate * priv;
};

struct _ComputerPlayerClass {
	GObjectClass parent_class;
	void (*run_search) (ComputerPlayer* self, PossibleMove* chosen_move);
	void (*complete_move) (ComputerPlayer* self, PossibleMove* chosen_move);
};

struct _GameStateStruct {
	Player current_color;
	Player opponent_color;
	guint8 size;
	guint8 n_current_tiles;
	guint8 n_opponent_tiles;
	guint8 n_tiles;
	gboolean current_player_can_move;
	gboolean is_complete;
	Player* tiles;
	gint tiles_length1;
	gint tiles_length2;
	guint8* neighbor_tiles;
	gint neighbor_tiles_length1;
	gint neighbor_tiles_length2;
	guint8 x_saved;
	guint8 y_saved;
	guint8* empty_neighbors;
	gint empty_neighbors_length1;
	gint empty_neighbors_length2;
};

struct _ComputerReversi {
	ComputerPlayer parent_instance;
	ComputerReversiPrivate * priv;
	guint8* neighbor_tiles;
	gint neighbor_tiles_length1;
	gint neighbor_tiles_length2;
};

struct _ComputerReversiClass {
	ComputerPlayerClass parent_class;
	gint16 (*calculate_heuristic) (ComputerReversi* self, GameStateStruct* g);
	gint16 (*end_of_game) (ComputerReversi* self, GameStateStruct* g);
	void (*sort_moves) (ComputerReversi* self, GSList** moves);
};

struct _ComputerReverseEasy {
	ComputerReversi parent_instance;
	ComputerReverseEasyPrivate * priv;
};

struct _ComputerReverseEasyClass {
	ComputerReversiClass parent_class;
};

struct _ComputerReverseHard {
	ComputerReversi parent_instance;
	ComputerReverseHardPrivate * priv;
};

struct _ComputerReverseHardClass {
	ComputerReversiClass parent_class;
};

struct _ComputerReverseHardPrivate {
	gboolean _even_depth;
	gboolean _fixed_heuristic;
	gint16* heuristic;
	gint heuristic_length1;
	gint heuristic_length2;
};

struct _ComputerReversiEasy {
	ComputerReversi parent_instance;
	ComputerReversiEasyPrivate * priv;
};

struct _ComputerReversiEasyClass {
	ComputerReversiClass parent_class;
};

struct _ComputerReversiHard {
	ComputerReversi parent_instance;
	ComputerReversiHardPrivate * priv;
};

struct _ComputerReversiHardClass {
	ComputerReversiClass parent_class;
};

struct _ComputerReversiHardPrivate {
	gboolean _even_depth;
	gboolean _fixed_heuristic;
	gint16* heuristic;
	gint heuristic_length1;
	gint heuristic_length2;
};

struct _ComputerReversiPrivate {
	Game* _game;
	guint8 _initial_depth;
	guint8 _size;
	guint8 _move_randomly;
};

static gpointer computer_reverse_easy_parent_class = NULL;
static gint ComputerReverseHard_private_offset;
static gpointer computer_reverse_hard_parent_class = NULL;
static gpointer computer_reversi_easy_parent_class = NULL;
static gint ComputerReversiHard_private_offset;
static gpointer computer_reversi_hard_parent_class = NULL;
static gint ComputerReversi_private_offset;
static gpointer computer_reversi_parent_class = NULL;

VALA_EXTERN GType possible_move_get_type (void) G_GNUC_CONST ;
VALA_EXTERN PossibleMove* possible_move_dup (const PossibleMove* self);
VALA_EXTERN void possible_move_free (PossibleMove* self);
VALA_EXTERN void possible_move_init (PossibleMove *self,
                         guint8 x,
                         guint8 y);
VALA_EXTERN GType computer_player_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ComputerPlayer, g_object_unref)
VALA_EXTERN GType computer_reversi_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ComputerReversi, g_object_unref)
VALA_EXTERN GType game_state_struct_get_type (void) G_GNUC_CONST ;
VALA_EXTERN GType player_get_type (void) G_GNUC_CONST ;
VALA_EXTERN GameStateStruct* game_state_struct_dup (const GameStateStruct* self);
VALA_EXTERN void game_state_struct_free (GameStateStruct* self);
VALA_EXTERN void game_state_struct_copy (const GameStateStruct* self,
                             GameStateStruct* dest);
VALA_EXTERN void game_state_struct_destroy (GameStateStruct* self);
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (GameStateStruct, game_state_struct_destroy)
VALA_EXTERN GType computer_reverse_easy_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ComputerReverseEasy, g_object_unref)
VALA_EXTERN void computer_reversi_sort_moves (ComputerReversi* self,
                                  GSList** moves);
VALA_EXTERN gint16 computer_reversi_end_of_game (ComputerReversi* self,
                                     GameStateStruct* g);
VALA_EXTERN gint16 computer_reversi_calculate_heuristic (ComputerReversi* self,
                                             GameStateStruct* g);
VALA_EXTERN GType game_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (Game, g_object_unref)
VALA_EXTERN ComputerReverseEasy* computer_reverse_easy_new (Game* game);
VALA_EXTERN ComputerReverseEasy* computer_reverse_easy_construct (GType object_type,
                                                      Game* game);
static void computer_reverse_easy_real_sort_moves (ComputerReversi* base,
                                            GSList** moves);
static inline gint computer_reverse_easy_compare_move (PossibleMove* a,
                                         PossibleMove* b);
static gint _computer_reverse_easy_compare_move_gcompare_func (gconstpointer a,
                                                        gconstpointer b);
static gint16 computer_reverse_easy_real_end_of_game (ComputerReversi* base,
                                               GameStateStruct* g);
static gint16 computer_reverse_easy_real_calculate_heuristic (ComputerReversi* base,
                                                       GameStateStruct* g);
static GType computer_reverse_easy_get_type_once (void);
VALA_EXTERN GType computer_reverse_hard_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ComputerReverseHard, g_object_unref)
VALA_EXTERN ComputerReverseHard* computer_reverse_hard_new (Game* game,
                                                guint8 initial_depth,
                                                gboolean fixed_heuristic);
VALA_EXTERN ComputerReverseHard* computer_reverse_hard_construct (GType object_type,
                                                      Game* game,
                                                      guint8 initial_depth,
                                                      gboolean fixed_heuristic);
static void computer_reverse_hard_real_sort_moves (ComputerReversi* base,
                                            GSList** moves);
static inline gint computer_reverse_hard_compare_move (ComputerReverseHard* self,
                                         PossibleMove* a,
                                         PossibleMove* b);
static gint _computer_reverse_hard_compare_move_gcompare_data_func (gconstpointer a,
                                                             gconstpointer b,
                                                             gpointer self);
static inline gint computer_reverse_hard_calculate_move_heuristic (ComputerReverseHard* self,
                                                     PossibleMove* move);
static inline void computer_reverse_hard_calculate_dir_heuristic (ComputerReverseHard* self,
                                                    gint* comparator,
                                                    guint8 x,
                                                    guint8 y,
                                                    gint8 x_step,
                                                    gint8 y_step,
                                                    guint8 count);
static gint16 computer_reverse_hard_real_end_of_game (ComputerReversi* base,
                                               GameStateStruct* g);
static gint16 computer_reverse_hard_real_calculate_heuristic (ComputerReversi* base,
                                                       GameStateStruct* g);
static inline gint16 computer_reverse_hard_eval_heuristic (GameStateStruct* g,
                                             gint16** heuristic,
                                             gint* heuristic_length1,
                                             gint* heuristic_length2,
                                             gboolean even_depth);
static gboolean computer_reverse_hard_get_even_depth (ComputerReverseHard* self);
VALA_EXTERN guint8 game_state_struct_get_empty_neighbors (GameStateStruct *self,
                                              guint8 x,
                                              guint8 y);
VALA_EXTERN gboolean game_state_struct_is_empty_tile (GameStateStruct *self,
                                          guint8 x,
                                          guint8 y);
VALA_EXTERN gboolean game_state_struct_is_current_color (GameStateStruct *self,
                                             guint8 x,
                                             guint8 y);
VALA_EXTERN GType main_line_get_type (void) G_GNUC_CONST ;
static void computer_reverse_hard_mainline_penalty (GameStateStruct* g,
                                             gint16 penalty,
                                             gint16* count,
                                             MainLine mainline_id);
VALA_EXTERN Player* game_state_struct_get_mainline (GameStateStruct *self,
                                        MainLine mainline_id,
                                        gint* result_length1);
static void computer_reverse_hard_init_heuristic (guint8 size,
                                           gboolean fixed_heuristic,
                                           gint16** heuristic,
                                           gint* heuristic_length1,
                                           gint* heuristic_length2);
static gint16* _vala_array_dup1 (gint16* self,
                          gssize length);
static void computer_reverse_hard_create_heuristic (guint8 size,
                                             gint16** heuristic,
                                             gint* heuristic_length1,
                                             gint* heuristic_length2);
static void computer_reverse_hard_set_even_depth (ComputerReverseHard* self,
                                           gboolean value);
static gboolean computer_reverse_hard_get_fixed_heuristic (ComputerReverseHard* self);
static void computer_reverse_hard_set_fixed_heuristic (ComputerReverseHard* self,
                                                gboolean value);
static GObject * computer_reverse_hard_constructor (GType type,
                                             guint n_construct_properties,
                                             GObjectConstructParam * construct_properties);
VALA_EXTERN guint8 computer_reversi_get_size (ComputerReversi* self);
static void computer_reverse_hard_finalize (GObject * obj);
static GType computer_reverse_hard_get_type_once (void);
static void _vala_computer_reverse_hard_get_property (GObject * object,
                                               guint property_id,
                                               GValue * value,
                                               GParamSpec * pspec);
static void _vala_computer_reverse_hard_set_property (GObject * object,
                                               guint property_id,
                                               const GValue * value,
                                               GParamSpec * pspec);
VALA_EXTERN GType computer_reversi_easy_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ComputerReversiEasy, g_object_unref)
VALA_EXTERN ComputerReversiEasy* computer_reversi_easy_new (Game* game);
VALA_EXTERN ComputerReversiEasy* computer_reversi_easy_construct (GType object_type,
                                                      Game* game);
static void computer_reversi_easy_real_sort_moves (ComputerReversi* base,
                                            GSList** moves);
static inline gint computer_reversi_easy_compare_move (PossibleMove* a,
                                         PossibleMove* b);
static gint _computer_reversi_easy_compare_move_gcompare_func (gconstpointer a,
                                                        gconstpointer b);
static gint16 computer_reversi_easy_real_end_of_game (ComputerReversi* base,
                                               GameStateStruct* g);
static gint16 computer_reversi_easy_real_calculate_heuristic (ComputerReversi* base,
                                                       GameStateStruct* g);
static GType computer_reversi_easy_get_type_once (void);
VALA_EXTERN GType computer_reversi_hard_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ComputerReversiHard, g_object_unref)
VALA_EXTERN ComputerReversiHard* computer_reversi_hard_new (Game* game,
                                                guint8 initial_depth,
                                                gboolean fixed_heuristic);
VALA_EXTERN ComputerReversiHard* computer_reversi_hard_construct (GType object_type,
                                                      Game* game,
                                                      guint8 initial_depth,
                                                      gboolean fixed_heuristic);
static void computer_reversi_hard_real_sort_moves (ComputerReversi* base,
                                            GSList** moves);
static inline gint computer_reversi_hard_compare_move (ComputerReversiHard* self,
                                         PossibleMove* a,
                                         PossibleMove* b);
static gint _computer_reversi_hard_compare_move_gcompare_data_func (gconstpointer a,
                                                             gconstpointer b,
                                                             gpointer self);
static inline gint computer_reversi_hard_calculate_move_heuristic (ComputerReversiHard* self,
                                                     PossibleMove* move);
static inline void computer_reversi_hard_calculate_dir_heuristic (ComputerReversiHard* self,
                                                    gint* comparator,
                                                    guint8 x,
                                                    guint8 y,
                                                    gint8 x_step,
                                                    gint8 y_step,
                                                    guint8 count);
static gint16 computer_reversi_hard_real_end_of_game (ComputerReversi* base,
                                               GameStateStruct* g);
static gint16 computer_reversi_hard_real_calculate_heuristic (ComputerReversi* base,
                                                       GameStateStruct* g);
static inline gint16 computer_reversi_hard_eval_heuristic (GameStateStruct* g,
                                             gint16** heuristic,
                                             gint* heuristic_length1,
                                             gint* heuristic_length2,
                                             gboolean even_depth);
static gboolean computer_reversi_hard_get_even_depth (ComputerReversiHard* self);
static void computer_reversi_hard_mainline_penalty (GameStateStruct* g,
                                             gint16 penalty,
                                             gint16* count,
                                             MainLine mainline_id);
static inline void computer_reversi_hard_init_heuristic (guint8 size,
                                           gboolean fixed_heuristic,
                                           gint16** heuristic,
                                           gint* heuristic_length1,
                                           gint* heuristic_length2);
static gint16* _vala_array_dup2 (gint16* self,
                          gssize length);
static void computer_reversi_hard_create_heuristic (guint8 size,
                                             gint16** heuristic,
                                             gint* heuristic_length1,
                                             gint* heuristic_length2);
static void computer_reversi_hard_set_even_depth (ComputerReversiHard* self,
                                           gboolean value);
static gboolean computer_reversi_hard_get_fixed_heuristic (ComputerReversiHard* self);
static void computer_reversi_hard_set_fixed_heuristic (ComputerReversiHard* self,
                                                gboolean value);
static GObject * computer_reversi_hard_constructor (GType type,
                                             guint n_construct_properties,
                                             GObjectConstructParam * construct_properties);
static void computer_reversi_hard_finalize (GObject * obj);
static GType computer_reversi_hard_get_type_once (void);
static void _vala_computer_reversi_hard_get_property (GObject * object,
                                               guint property_id,
                                               GValue * value,
                                               GParamSpec * pspec);
static void _vala_computer_reversi_hard_set_property (GObject * object,
                                               guint property_id,
                                               const GValue * value,
                                               GParamSpec * pspec);
VALA_EXTERN void computer_player_complete_move (ComputerPlayer* self,
                                    PossibleMove* chosen_move);
VALA_EXTERN void computer_player_run_search (ComputerPlayer* self,
                                 PossibleMove* chosen_move);
static void computer_reversi_real_complete_move (ComputerPlayer* base,
                                          PossibleMove* chosen_move);
static Game* computer_reversi_get_game (ComputerReversi* self);
VALA_EXTERN gboolean game_place_tile (Game* self,
                          guint8 x,
                          guint8 y);
VALA_EXTERN gchar* game_to_string (Game* self);
static void computer_reversi_random_select (GameStateStruct* g,
                                     PossibleMove* random_move);
VALA_EXTERN GType game_state_object_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GameStateObject, g_object_unref)
VALA_EXTERN GameStateObject* game_get_current_state (Game* self);
VALA_EXTERN void game_state_object_get_game_state_struct (GameStateObject* self,
                                              GameStateStruct * result);
VALA_EXTERN void game_state_struct_get_possible_moves (GameStateStruct *self,
                                           GSList** moves);
static void _possible_move_free0_ (gpointer var);
static inline void _g_slist_free__possible_move_free0_ (GSList* self);
static void computer_reversi_real_run_search (ComputerPlayer* base,
                                       PossibleMove* best_move);
VALA_EXTERN guint8 computer_reversi_get_move_randomly (ComputerReversi* self);
VALA_EXTERN gboolean game_get_reverse (Game* self);
VALA_EXTERN void game_get_possible_moves (Game* self,
                              GSList** moves);
VALA_EXTERN void game_state_struct_init_copy_and_move (GameStateStruct *self,
                                           GameStateStruct* game,
                                           PossibleMove* move);
static gint16 computer_reversi_search (ComputerReversi* self,
                                GameStateStruct* g,
                                guint8 depth,
                                gint16 a,
                                gint16 b);
static guint8 computer_reversi_get_initial_depth (ComputerReversi* self);
VALA_EXTERN gboolean computer_player_get_move_pending (ComputerPlayer* self);
VALA_EXTERN void game_state_struct_init_copy_and_pass (GameStateStruct *self,
                                           GameStateStruct* game);
static gint16 computer_reversi_real_calculate_heuristic (ComputerReversi* self,
                                                  GameStateStruct* g);
static gint16 computer_reversi_real_end_of_game (ComputerReversi* self,
                                          GameStateStruct* g);
static void computer_reversi_real_sort_moves (ComputerReversi* self,
                                       GSList** moves);
VALA_EXTERN ComputerReversi* computer_reversi_construct (GType object_type);
VALA_EXTERN ComputerPlayer* computer_player_construct (GType object_type);
static void computer_reversi_set_game (ComputerReversi* self,
                                Game* value);
static void computer_reversi_set_initial_depth (ComputerReversi* self,
                                         guint8 value);
static void computer_reversi_set_size (ComputerReversi* self,
                                guint8 value);
static void computer_reversi_set_move_randomly (ComputerReversi* self,
                                         guint8 value);
static GObject * computer_reversi_constructor (GType type,
                                        guint n_construct_properties,
                                        GObjectConstructParam * construct_properties);
VALA_EXTERN guint8 game_get_size (Game* self);
VALA_EXTERN guint8 game_get_initial_number_of_tiles (Game* self);
VALA_EXTERN guint8* game_copy_neighbor_tiles (Game* self,
                                  gint* result_length1,
                                  gint* result_length2);
static void computer_reversi_finalize (GObject * obj);
static GType computer_reversi_get_type_once (void);
static void _vala_computer_reversi_get_property (GObject * object,
                                          guint property_id,
                                          GValue * value,
                                          GParamSpec * pspec);
static void _vala_computer_reversi_set_property (GObject * object,
                                          guint property_id,
                                          const GValue * value,
                                          GParamSpec * pspec);

const gint16 heuristic_8[8][8] = {{(gint16) 410, (gint16) 23, (gint16) 13, (gint16) 8, (gint16) 8, (gint16) 13, (gint16) 23, (gint16) 410}, {(gint16) 23, (gint16) -75, (gint16) -22, (gint16) -51, (gint16) -51, (gint16) -22, (gint16) -75, (gint16) 23}, {(gint16) 13, (gint16) -22, (gint16) 41, (gint16) 3, (gint16) 3, (gint16) 41, (gint16) -22, (gint16) 13}, {(gint16) 8, (gint16) -51, (gint16) 3, (gint16) -87, (gint16) -87, (gint16) 3, (gint16) -51, (gint16) 8}, {(gint16) 8, (gint16) -51, (gint16) 3, (gint16) -87, (gint16) -87, (gint16) 3, (gint16) -51, (gint16) 8}, {(gint16) 13, (gint16) -22, (gint16) 41, (gint16) 3, (gint16) 3, (gint16) 41, (gint16) -22, (gint16) 13}, {(gint16) 23, (gint16) -75, (gint16) -22, (gint16) -51, (gint16) -51, (gint16) -22, (gint16) -75, (gint16) 23}, {(gint16) 410, (gint16) 23, (gint16) 13, (gint16) 8, (gint16) 8, (gint16) 13, (gint16) 23, (gint16) 410}};

void
possible_move_init (PossibleMove *self,
                    guint8 x,
                    guint8 y)
{
	memset (self, 0, sizeof (PossibleMove));
	(*self).x = x;
	(*self).y = y;
}

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

void
possible_move_free (PossibleMove* self)
{
	g_free (self);
}

 G_GNUC_NO_INLINE static GType
possible_move_get_type_once (void)
{
	GType possible_move_type_id;
	possible_move_type_id = g_boxed_type_register_static ("PossibleMove", (GBoxedCopyFunc) possible_move_dup, (GBoxedFreeFunc) possible_move_free);
	return possible_move_type_id;
}

GType
possible_move_get_type (void)
{
	static gsize possible_move_type_id__once = 0;
	if (g_once_init_enter (&possible_move_type_id__once)) {
		GType possible_move_type_id;
		possible_move_type_id = possible_move_get_type_once ();
		g_once_init_leave (&possible_move_type_id__once, possible_move_type_id);
	}
	return possible_move_type_id__once;
}

ComputerReverseEasy*
computer_reverse_easy_construct (GType object_type,
                                 Game* game)
{
	ComputerReverseEasy * self = NULL;
	g_return_val_if_fail (game != NULL, NULL);
	self = (ComputerReverseEasy*) g_object_new (object_type, "game", game, "initial-depth", 2, NULL);
	return self;
}

ComputerReverseEasy*
computer_reverse_easy_new (Game* game)
{
	return computer_reverse_easy_construct (TYPE_COMPUTER_REVERSE_EASY, game);
}

static gint
_computer_reverse_easy_compare_move_gcompare_func (gconstpointer a,
                                                   gconstpointer b)
{
	gint result;
	result = computer_reverse_easy_compare_move ((PossibleMove*) a, (PossibleMove*) b);
	return result;
}

static void
computer_reverse_easy_real_sort_moves (ComputerReversi* base,
                                       GSList** moves)
{
	ComputerReverseEasy * self;
	self = (ComputerReverseEasy*) base;
	*moves = g_slist_sort (*moves, _computer_reverse_easy_compare_move_gcompare_func);
}

static inline gint
computer_reverse_easy_compare_move (PossibleMove* a,
                                    PossibleMove* b)
{
	gint _tmp0_ = 0;
	gint result;
	if (((PossibleMove) (*a)).n_tiles <= ((PossibleMove) (*b)).n_tiles) {
		_tmp0_ = -1;
	} else {
		_tmp0_ = 1;
	}
	result = _tmp0_;
	return result;
}

static gint16
computer_reverse_easy_real_end_of_game (ComputerReversi* base,
                                        GameStateStruct* g)
{
	ComputerReverseEasy * self;
	gint16 _tmp0_ = 0;
	GameStateStruct _tmp1_;
	GameStateStruct _tmp2_;
	gint16 result;
	self = (ComputerReverseEasy*) base;
	g_return_val_if_fail (g != NULL, -1);
	_tmp1_ = *g;
	_tmp2_ = *g;
	if (_tmp1_.n_current_tiles < _tmp2_.n_opponent_tiles) {
		GameStateStruct _tmp3_;
		_tmp3_ = *g;
		_tmp0_ = COMPUTER_REVERSI_POSITIVE_INFINITY - ((gint16) _tmp3_.n_current_tiles);
	} else {
		GameStateStruct _tmp4_;
		_tmp4_ = *g;
		_tmp0_ = COMPUTER_REVERSI_NEGATIVE_INFINITY + ((gint16) _tmp4_.n_opponent_tiles);
	}
	result = _tmp0_;
	return result;
}

static gint16
computer_reverse_easy_real_calculate_heuristic (ComputerReversi* base,
                                                GameStateStruct* g)
{
	ComputerReverseEasy * self;
	GameStateStruct _tmp0_;
	GameStateStruct _tmp1_;
	gint16 result;
	self = (ComputerReverseEasy*) base;
	g_return_val_if_fail (g != NULL, -1);
	_tmp0_ = *g;
	_tmp1_ = *g;
	result = ((gint16) _tmp0_.n_current_tiles) - ((gint16) _tmp1_.n_opponent_tiles);
	return result;
}

static void
computer_reverse_easy_class_init (ComputerReverseEasyClass * klass,
                                  gpointer klass_data)
{
	computer_reverse_easy_parent_class = g_type_class_peek_parent (klass);
	((ComputerReversiClass *) klass)->sort_moves = (void (*) (ComputerReversi*, GSList**)) computer_reverse_easy_real_sort_moves;
	((ComputerReversiClass *) klass)->end_of_game = (gint16 (*) (ComputerReversi*, GameStateStruct*)) computer_reverse_easy_real_end_of_game;
	((ComputerReversiClass *) klass)->calculate_heuristic = (gint16 (*) (ComputerReversi*, GameStateStruct*)) computer_reverse_easy_real_calculate_heuristic;
}

static void
computer_reverse_easy_instance_init (ComputerReverseEasy * self,
                                     gpointer klass)
{
}

 G_GNUC_NO_INLINE static GType
computer_reverse_easy_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ComputerReverseEasyClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) computer_reverse_easy_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ComputerReverseEasy), 0, (GInstanceInitFunc) computer_reverse_easy_instance_init, NULL };
	GType computer_reverse_easy_type_id;
	computer_reverse_easy_type_id = g_type_register_static (TYPE_COMPUTER_REVERSI, "ComputerReverseEasy", &g_define_type_info, G_TYPE_FLAG_NONE);
	return computer_reverse_easy_type_id;
}

GType
computer_reverse_easy_get_type (void)
{
	static gsize computer_reverse_easy_type_id__once = 0;
	if (g_once_init_enter (&computer_reverse_easy_type_id__once)) {
		GType computer_reverse_easy_type_id;
		computer_reverse_easy_type_id = computer_reverse_easy_get_type_once ();
		g_once_init_leave (&computer_reverse_easy_type_id__once, computer_reverse_easy_type_id);
	}
	return computer_reverse_easy_type_id__once;
}

static inline gpointer
computer_reverse_hard_get_instance_private (ComputerReverseHard* self)
{
	return G_STRUCT_MEMBER_P (self, ComputerReverseHard_private_offset);
}

ComputerReverseHard*
computer_reverse_hard_construct (GType object_type,
                                 Game* game,
                                 guint8 initial_depth,
                                 gboolean fixed_heuristic)
{
	ComputerReverseHard * self = NULL;
	g_return_val_if_fail (game != NULL, NULL);
	self = (ComputerReverseHard*) g_object_new (object_type, "game", game, "even-depth", (initial_depth % 2) == 0, "initial-depth", initial_depth, "fixed-heuristic", fixed_heuristic, NULL);
	return self;
}

ComputerReverseHard*
computer_reverse_hard_new (Game* game,
                           guint8 initial_depth,
                           gboolean fixed_heuristic)
{
	return computer_reverse_hard_construct (TYPE_COMPUTER_REVERSE_HARD, game, initial_depth, fixed_heuristic);
}

static gint
_computer_reverse_hard_compare_move_gcompare_data_func (gconstpointer a,
                                                        gconstpointer b,
                                                        gpointer self)
{
	gint result;
	result = computer_reverse_hard_compare_move ((ComputerReverseHard*) self, (PossibleMove*) a, (PossibleMove*) b);
	return result;
}

static void
computer_reverse_hard_real_sort_moves (ComputerReversi* base,
                                       GSList** moves)
{
	ComputerReverseHard * self;
	self = (ComputerReverseHard*) base;
	*moves = g_slist_sort_with_data (*moves, _computer_reverse_hard_compare_move_gcompare_data_func, self);
}

static inline gint
computer_reverse_hard_compare_move (ComputerReverseHard* self,
                                    PossibleMove* a,
                                    PossibleMove* b)
{
	PossibleMove _tmp0_;
	PossibleMove _tmp1_;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	_tmp0_ = (PossibleMove) (*b);
	_tmp1_ = (PossibleMove) (*a);
	result = computer_reverse_hard_calculate_move_heuristic (self, &_tmp0_) - computer_reverse_hard_calculate_move_heuristic (self, &_tmp1_);
	return result;
}

static inline gint
computer_reverse_hard_calculate_move_heuristic (ComputerReverseHard* self,
                                                PossibleMove* move)
{
	gint comparator = 0;
	PossibleMove _tmp0_;
	PossibleMove _tmp1_;
	PossibleMove _tmp2_;
	PossibleMove _tmp3_;
	PossibleMove _tmp4_;
	PossibleMove _tmp5_;
	PossibleMove _tmp6_;
	PossibleMove _tmp7_;
	PossibleMove _tmp8_;
	PossibleMove _tmp9_;
	PossibleMove _tmp10_;
	PossibleMove _tmp11_;
	PossibleMove _tmp12_;
	PossibleMove _tmp13_;
	PossibleMove _tmp14_;
	PossibleMove _tmp15_;
	PossibleMove _tmp16_;
	PossibleMove _tmp17_;
	PossibleMove _tmp18_;
	PossibleMove _tmp19_;
	PossibleMove _tmp20_;
	PossibleMove _tmp21_;
	PossibleMove _tmp22_;
	PossibleMove _tmp23_;
	gint16* _tmp24_;
	gint _tmp24__length1;
	gint _tmp24__length2;
	PossibleMove _tmp25_;
	PossibleMove _tmp26_;
	gint16 _tmp27_;
	guint8* _tmp28_;
	gint _tmp28__length1;
	gint _tmp28__length2;
	PossibleMove _tmp29_;
	PossibleMove _tmp30_;
	guint8 _tmp31_;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	g_return_val_if_fail (move != NULL, -1);
	comparator = 0;
	_tmp0_ = *move;
	_tmp1_ = *move;
	_tmp2_ = *move;
	computer_reverse_hard_calculate_dir_heuristic (self, &comparator, _tmp0_.x, _tmp1_.y, (gint8) 0, (gint8) -1, _tmp2_.n_tiles_n);
	_tmp3_ = *move;
	_tmp4_ = *move;
	_tmp5_ = *move;
	computer_reverse_hard_calculate_dir_heuristic (self, &comparator, _tmp3_.x, _tmp4_.y, (gint8) 1, (gint8) -1, _tmp5_.n_tiles_ne);
	_tmp6_ = *move;
	_tmp7_ = *move;
	_tmp8_ = *move;
	computer_reverse_hard_calculate_dir_heuristic (self, &comparator, _tmp6_.x, _tmp7_.y, (gint8) 1, (gint8) 0, _tmp8_.n_tiles_e);
	_tmp9_ = *move;
	_tmp10_ = *move;
	_tmp11_ = *move;
	computer_reverse_hard_calculate_dir_heuristic (self, &comparator, _tmp9_.x, _tmp10_.y, (gint8) 1, (gint8) 1, _tmp11_.n_tiles_se);
	_tmp12_ = *move;
	_tmp13_ = *move;
	_tmp14_ = *move;
	computer_reverse_hard_calculate_dir_heuristic (self, &comparator, _tmp12_.x, _tmp13_.y, (gint8) 0, (gint8) 1, _tmp14_.n_tiles_s);
	_tmp15_ = *move;
	_tmp16_ = *move;
	_tmp17_ = *move;
	computer_reverse_hard_calculate_dir_heuristic (self, &comparator, _tmp15_.x, _tmp16_.y, (gint8) -1, (gint8) 1, _tmp17_.n_tiles_so);
	_tmp18_ = *move;
	_tmp19_ = *move;
	_tmp20_ = *move;
	computer_reverse_hard_calculate_dir_heuristic (self, &comparator, _tmp18_.x, _tmp19_.y, (gint8) -1, (gint8) 0, _tmp20_.n_tiles_o);
	_tmp21_ = *move;
	_tmp22_ = *move;
	_tmp23_ = *move;
	computer_reverse_hard_calculate_dir_heuristic (self, &comparator, _tmp21_.x, _tmp22_.y, (gint8) -1, (gint8) -1, _tmp23_.n_tiles_no);
	_tmp24_ = self->priv->heuristic;
	_tmp24__length1 = self->priv->heuristic_length1;
	_tmp24__length2 = self->priv->heuristic_length2;
	_tmp25_ = *move;
	_tmp26_ = *move;
	_tmp27_ = _tmp24_[(_tmp25_.x * _tmp24__length2) + _tmp26_.y];
	_tmp28_ = ((ComputerReversi*) self)->neighbor_tiles;
	_tmp28__length1 = ((ComputerReversi*) self)->neighbor_tiles_length1;
	_tmp28__length2 = ((ComputerReversi*) self)->neighbor_tiles_length2;
	_tmp29_ = *move;
	_tmp30_ = *move;
	_tmp31_ = _tmp28_[(_tmp29_.x * _tmp28__length2) + _tmp30_.y];
	result = ((2 * comparator) + ((gint) _tmp27_)) + (8 * ((gint) _tmp31_));
	return result;
}

static inline void
computer_reverse_hard_calculate_dir_heuristic (ComputerReverseHard* self,
                                               gint* comparator,
                                               guint8 x,
                                               guint8 y,
                                               gint8 x_step,
                                               gint8 y_step,
                                               guint8 count)
{
	g_return_if_fail (self != NULL);
	{
		gboolean _tmp0_ = FALSE;
		_tmp0_ = TRUE;
		while (TRUE) {
			gint16* _tmp2_;
			gint _tmp2__length1;
			gint _tmp2__length2;
			gint16 _tmp3_;
			if (!_tmp0_) {
				guint8 _tmp1_;
				_tmp1_ = count;
				count = _tmp1_ - 1;
			}
			_tmp0_ = FALSE;
			if (!(((gint) count) > 0)) {
				break;
			}
			_tmp2_ = self->priv->heuristic;
			_tmp2__length1 = self->priv->heuristic_length1;
			_tmp2__length2 = self->priv->heuristic_length2;
			_tmp3_ = _tmp2_[((((gint8) x) + (((gint8) count) * x_step)) * _tmp2__length2) + (((gint8) y) + (((gint8) count) * y_step))];
			*comparator = (*comparator) + ((gint) _tmp3_);
		}
	}
}

static gint16
computer_reverse_hard_real_end_of_game (ComputerReversi* base,
                                        GameStateStruct* g)
{
	ComputerReverseHard * self;
	gint16 _tmp0_ = 0;
	GameStateStruct _tmp1_;
	GameStateStruct _tmp2_;
	gint16 result;
	self = (ComputerReverseHard*) base;
	g_return_val_if_fail (g != NULL, -1);
	_tmp1_ = *g;
	_tmp2_ = *g;
	if (_tmp1_.n_current_tiles < _tmp2_.n_opponent_tiles) {
		GameStateStruct _tmp3_;
		_tmp3_ = *g;
		_tmp0_ = COMPUTER_REVERSI_POSITIVE_INFINITY - ((gint16) _tmp3_.n_current_tiles);
	} else {
		GameStateStruct _tmp4_;
		_tmp4_ = *g;
		_tmp0_ = COMPUTER_REVERSI_NEGATIVE_INFINITY + ((gint16) _tmp4_.n_opponent_tiles);
	}
	result = _tmp0_;
	return result;
}

static gint16
computer_reverse_hard_real_calculate_heuristic (ComputerReversi* base,
                                                GameStateStruct* g)
{
	ComputerReverseHard * self;
	GameStateStruct _tmp0_;
	gboolean _tmp1_;
	gint16 _tmp2_;
	gint16 result;
	self = (ComputerReverseHard*) base;
	g_return_val_if_fail (g != NULL, -1);
	_tmp0_ = *g;
	_tmp1_ = self->priv->_even_depth;
	_tmp2_ = computer_reverse_hard_eval_heuristic (&_tmp0_, &self->priv->heuristic, (gint*) (&self->priv->heuristic_length1), (gint*) (&self->priv->heuristic_length2), _tmp1_);
	result = _tmp2_;
	return result;
}

static inline gint16
computer_reverse_hard_eval_heuristic (GameStateStruct* g,
                                      gint16** heuristic,
                                      gint* heuristic_length1,
                                      gint* heuristic_length2,
                                      gboolean even_depth)
{
	guint8 size = 0U;
	GameStateStruct _tmp0_;
	gint16 count = 0;
	GameStateStruct _tmp6_;
	GameStateStruct _tmp7_;
	GameStateStruct _tmp8_;
	GameStateStruct _tmp9_;
	GameStateStruct _tmp10_;
	GameStateStruct _tmp11_;
	gint16 result;
	g_return_val_if_fail (g != NULL, -1);
	_tmp0_ = *g;
	size = _tmp0_.size;
	count = (gint16) 0;
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				if (!_tmp1_) {
					guint8 _tmp2_;
					_tmp2_ = x;
					x = _tmp2_ + 1;
				}
				_tmp1_ = FALSE;
				if (!(x < size)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp3_ = FALSE;
						_tmp3_ = TRUE;
						while (TRUE) {
							gint16 a = 0;
							gint16 tile_heuristic = 0;
							gint16 _tmp5_;
							if (!_tmp3_) {
								guint8 _tmp4_;
								_tmp4_ = y;
								y = _tmp4_ + 1;
							}
							_tmp3_ = FALSE;
							if (!(y < size)) {
								break;
							}
							a = (gint16) game_state_struct_get_empty_neighbors (g, x, y);
							if (((gint) a) == 0) {
								a = (gint16) 6;
							}
							_tmp5_ = (*heuristic)[(x * (*heuristic_length2)) + y];
							tile_heuristic = (gint16) (_tmp5_ + (8 * a));
							if (game_state_struct_is_empty_tile (g, x, y)) {
								if (even_depth) {
									count -= (gint16) (tile_heuristic / 2);
								} else {
									count += (gint16) (tile_heuristic / 2);
								}
							} else {
								if (game_state_struct_is_current_color (g, x, y)) {
									count += tile_heuristic;
								} else {
									count -= tile_heuristic;
								}
							}
						}
					}
				}
			}
		}
	}
	_tmp6_ = *g;
	computer_reverse_hard_mainline_penalty (&_tmp6_, COMPUTER_REVERSE_HARD_border_penalty, &count, MAIN_LINE_TOP);
	_tmp7_ = *g;
	computer_reverse_hard_mainline_penalty (&_tmp7_, COMPUTER_REVERSE_HARD_border_penalty, &count, MAIN_LINE_LEFT);
	_tmp8_ = *g;
	computer_reverse_hard_mainline_penalty (&_tmp8_, COMPUTER_REVERSE_HARD_border_penalty, &count, MAIN_LINE_RIGHT);
	_tmp9_ = *g;
	computer_reverse_hard_mainline_penalty (&_tmp9_, COMPUTER_REVERSE_HARD_border_penalty, &count, MAIN_LINE_BOTTOM);
	_tmp10_ = *g;
	computer_reverse_hard_mainline_penalty (&_tmp10_, COMPUTER_REVERSE_HARD_corner_penalty, &count, MAIN_LINE_TOPLEFT);
	_tmp11_ = *g;
	computer_reverse_hard_mainline_penalty (&_tmp11_, COMPUTER_REVERSE_HARD_corner_penalty, &count, MAIN_LINE_TOPRIGHT);
	result = count;
	return result;
}

static void
computer_reverse_hard_mainline_penalty (GameStateStruct* g,
                                        gint16 penalty,
                                        gint16* count,
                                        MainLine mainline_id)
{
	Player* mainline = NULL;
	gint _tmp0_ = 0;
	Player* _tmp1_;
	gint mainline_length1;
	gint _mainline_size_;
	gboolean _tmp2_ = FALSE;
	Player* _tmp3_;
	gint _tmp3__length1;
	Player _tmp4_;
	GameStateStruct _tmp5_;
	gboolean _tmp18_ = FALSE;
	Player* _tmp19_;
	gint _tmp19__length1;
	GameStateStruct _tmp20_;
	Player _tmp21_;
	GameStateStruct _tmp22_;
	g_return_if_fail (g != NULL);
	_tmp1_ = game_state_struct_get_mainline (g, mainline_id, &_tmp0_);
	mainline = _tmp1_;
	mainline_length1 = _tmp0_;
	_mainline_size_ = mainline_length1;
	_tmp3_ = mainline;
	_tmp3__length1 = mainline_length1;
	_tmp4_ = _tmp3_[1];
	_tmp5_ = *g;
	if (_tmp4_ == _tmp5_.current_color) {
		Player* _tmp6_;
		gint _tmp6__length1;
		Player _tmp7_;
		_tmp6_ = mainline;
		_tmp6__length1 = mainline_length1;
		_tmp7_ = _tmp6_[0];
		_tmp2_ = _tmp7_ == PLAYER_NONE;
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		guint8 i = 0U;
		GameStateStruct _tmp14_;
		i = (guint8) 1;
		{
			gboolean _tmp8_ = FALSE;
			_tmp8_ = TRUE;
			while (TRUE) {
				guint8 _tmp12_;
				GameStateStruct _tmp13_;
				if (!_tmp8_) {
					Player* _tmp9_;
					gint _tmp9__length1;
					Player _tmp10_;
					GameStateStruct _tmp11_;
					_tmp9_ = mainline;
					_tmp9__length1 = mainline_length1;
					_tmp10_ = _tmp9_[i];
					_tmp11_ = *g;
					if (!(_tmp10_ == _tmp11_.current_color)) {
						break;
					}
				}
				_tmp8_ = FALSE;
				_tmp12_ = i;
				i = _tmp12_ + 1;
				_tmp13_ = *g;
				if (((gint) i) == (_tmp13_.size - 2)) {
					break;
				}
			}
		}
		_tmp14_ = *g;
		if (((gint) i) != (_tmp14_.size - 2)) {
			Player* _tmp15_;
			gint _tmp15__length1;
			Player _tmp16_;
			GameStateStruct _tmp17_;
			*count = (*count) + penalty;
			_tmp15_ = mainline;
			_tmp15__length1 = mainline_length1;
			_tmp16_ = _tmp15_[i + 1];
			_tmp17_ = *g;
			if (_tmp16_ == _tmp17_.current_color) {
				*count = (*count) + penalty;
			}
		}
	}
	_tmp19_ = mainline;
	_tmp19__length1 = mainline_length1;
	_tmp20_ = *g;
	_tmp21_ = _tmp19_[_tmp20_.size - 2];
	_tmp22_ = *g;
	if (_tmp21_ == _tmp22_.current_color) {
		Player* _tmp23_;
		gint _tmp23__length1;
		GameStateStruct _tmp24_;
		Player _tmp25_;
		_tmp23_ = mainline;
		_tmp23__length1 = mainline_length1;
		_tmp24_ = *g;
		_tmp25_ = _tmp23_[_tmp24_.size - 1];
		_tmp18_ = _tmp25_ == PLAYER_NONE;
	} else {
		_tmp18_ = FALSE;
	}
	if (_tmp18_) {
		guint8 i = 0U;
		GameStateStruct _tmp33_;
		i = (guint8) 1;
		{
			gboolean _tmp26_ = FALSE;
			_tmp26_ = TRUE;
			while (TRUE) {
				guint8 _tmp31_;
				GameStateStruct _tmp32_;
				if (!_tmp26_) {
					Player* _tmp27_;
					gint _tmp27__length1;
					GameStateStruct _tmp28_;
					Player _tmp29_;
					GameStateStruct _tmp30_;
					_tmp27_ = mainline;
					_tmp27__length1 = mainline_length1;
					_tmp28_ = *g;
					_tmp29_ = _tmp27_[(_tmp28_.size - 1) - i];
					_tmp30_ = *g;
					if (!(_tmp29_ == _tmp30_.current_color)) {
						break;
					}
				}
				_tmp26_ = FALSE;
				_tmp31_ = i;
				i = _tmp31_ + 1;
				_tmp32_ = *g;
				if (((gint) i) == (_tmp32_.size - 2)) {
					break;
				}
			}
		}
		_tmp33_ = *g;
		if (((gint) i) != (_tmp33_.size - 2)) {
			Player* _tmp34_;
			gint _tmp34__length1;
			GameStateStruct _tmp35_;
			Player _tmp36_;
			GameStateStruct _tmp37_;
			*count = (*count) + penalty;
			_tmp34_ = mainline;
			_tmp34__length1 = mainline_length1;
			_tmp35_ = *g;
			_tmp36_ = _tmp34_[(_tmp35_.size - 2) - i];
			_tmp37_ = *g;
			if (_tmp36_ == _tmp37_.current_color) {
				*count = (*count) + penalty;
			}
		}
	}
	mainline = (g_free (mainline), NULL);
}

static gint16*
_vala_array_dup1 (gint16* self,
                  gssize length)
{
	if (length > 0) {
		return g_memdup2 (self, length * sizeof (gint16));
	}
	return NULL;
}

static void
computer_reverse_hard_init_heuristic (guint8 size,
                                      gboolean fixed_heuristic,
                                      gint16** heuristic,
                                      gint* heuristic_length1,
                                      gint* heuristic_length2)
{
	gint16* _vala_heuristic = NULL;
	gint _vala_heuristic_length1 = 0;
	gint _vala_heuristic_length2 = 0;
	gint16* _heuristic = NULL;
	gint _heuristic_length1 = 0;
	gint _heuristic_length2 = 0;
	gint16* _tmp4_;
	_vala_return_if_fail (((gint) size) >= 4, "size >= 4");
	if (((gint) size) == 8) {
		gint16* _tmp0_;
		gint _tmp0__length1;
		gint _tmp0__length2;
		_tmp0_ = _vala_array_dup1 (heuristic_8, G_N_ELEMENTS (heuristic_8) * G_N_ELEMENTS (heuristic_8[0]));
		_tmp0__length1 = G_N_ELEMENTS (heuristic_8);
		_tmp0__length2 = G_N_ELEMENTS (heuristic_8[0]);
		_heuristic = (g_free (_heuristic), NULL);
		_heuristic = _tmp0_;
		_heuristic_length1 = _tmp0__length1;
		_heuristic_length2 = _tmp0__length2;
	} else {
		gint16* _tmp1_ = NULL;
		gint _tmp2_ = 0;
		gint _tmp3_ = 0;
		computer_reverse_hard_create_heuristic (size, &_tmp1_, &_tmp2_, &_tmp3_);
		_heuristic = (g_free (_heuristic), NULL);
		_heuristic = _tmp1_;
		_heuristic_length1 = _tmp2_;
		_heuristic_length2 = _tmp3_;
	}
	_tmp4_ = g_new0 (gint16, size * size);
	_vala_heuristic = (g_free (_vala_heuristic), NULL);
	_vala_heuristic = _tmp4_;
	_vala_heuristic_length1 = size;
	_vala_heuristic_length2 = size;
	{
		guint8 i = 0U;
		i = (guint8) 0;
		{
			gboolean _tmp5_ = FALSE;
			_tmp5_ = TRUE;
			while (TRUE) {
				if (!_tmp5_) {
					guint8 _tmp6_;
					_tmp6_ = i;
					i = _tmp6_ + 1;
				}
				_tmp5_ = FALSE;
				if (!(i < size)) {
					break;
				}
				{
					guint8 j = 0U;
					j = (guint8) 0;
					{
						gboolean _tmp7_ = FALSE;
						_tmp7_ = TRUE;
						while (TRUE) {
							gint16* _tmp9_;
							gint _tmp9__length1;
							gint _tmp9__length2;
							gint16* _tmp10_;
							gint _tmp10__length1;
							gint _tmp10__length2;
							gint16 _tmp11_;
							if (!_tmp7_) {
								guint8 _tmp8_;
								_tmp8_ = j;
								j = _tmp8_ + 1;
							}
							_tmp7_ = FALSE;
							if (!(j < size)) {
								break;
							}
							_tmp9_ = _vala_heuristic;
							_tmp9__length1 = _vala_heuristic_length1;
							_tmp9__length2 = _vala_heuristic_length2;
							_tmp10_ = _heuristic;
							_tmp10__length1 = _heuristic_length1;
							_tmp10__length2 = _heuristic_length2;
							_tmp11_ = _tmp10_[(i * _tmp10__length2) + j];
							_tmp9_[(i * _tmp9__length2) + j] = (gint16) ((-1.7) * (_tmp11_ + 112));
						}
					}
				}
			}
		}
	}
	if (fixed_heuristic) {
		_heuristic = (g_free (_heuristic), NULL);
		if (heuristic) {
			*heuristic = _vala_heuristic;
		} else {
			_vala_heuristic = (g_free (_vala_heuristic), NULL);
		}
		if (heuristic_length1) {
			*heuristic_length1 = _vala_heuristic_length1;
		}
		if (heuristic_length2) {
			*heuristic_length2 = _vala_heuristic_length2;
		}
		return;
	}
	{
		guint8 i = 0U;
		i = (guint8) 0;
		{
			gboolean _tmp12_ = FALSE;
			_tmp12_ = TRUE;
			while (TRUE) {
				gint _tmp14_ = 0;
				gint16* _tmp15_;
				gint _tmp15__length1;
				gint _tmp15__length2;
				guint8 x = 0U;
				guint8 y = 0U;
				gboolean minus = FALSE;
				gint _tmp16_ = 0;
				gint16* _tmp17_;
				gint _tmp17__length1;
				gint _tmp17__length2;
				gint _tmp18_ = 0;
				gint16* _tmp19_;
				gint _tmp19__length1;
				gint _tmp19__length2;
				if (!_tmp12_) {
					guint8 _tmp13_;
					_tmp13_ = i;
					i = _tmp13_ + 1;
				}
				_tmp12_ = FALSE;
				if (!(((gint) i) < 5)) {
					break;
				}
				if (g_random_boolean ()) {
					_tmp14_ = -1;
				} else {
					_tmp14_ = 1;
				}
				_tmp15_ = _vala_heuristic;
				_tmp15__length1 = _vala_heuristic_length1;
				_tmp15__length2 = _vala_heuristic_length2;
				_tmp15_[(g_random_int_range ((gint32) 0, (gint32) size) * _tmp15__length2) + g_random_int_range ((gint32) 0, (gint32) size)] += (gint16) _tmp14_;
				x = (guint8) g_random_int_range ((gint32) 0, (gint32) size);
				y = (guint8) g_random_int_range ((gint32) 0, (gint32) size);
				minus = g_random_boolean ();
				if (minus) {
					_tmp16_ = -1;
				} else {
					_tmp16_ = 1;
				}
				_tmp17_ = _vala_heuristic;
				_tmp17__length1 = _vala_heuristic_length1;
				_tmp17__length2 = _vala_heuristic_length2;
				_tmp17_[(x * _tmp17__length2) + y] += (gint16) _tmp16_;
				if (minus) {
					_tmp18_ = -1;
				} else {
					_tmp18_ = 1;
				}
				_tmp19_ = _vala_heuristic;
				_tmp19__length1 = _vala_heuristic_length1;
				_tmp19__length2 = _vala_heuristic_length2;
				_tmp19_[(((size - 1) - x) * _tmp19__length2) + ((size - 1) - y)] += (gint16) _tmp18_;
			}
		}
	}
	_heuristic = (g_free (_heuristic), NULL);
	if (heuristic) {
		*heuristic = _vala_heuristic;
	} else {
		_vala_heuristic = (g_free (_vala_heuristic), NULL);
	}
	if (heuristic_length1) {
		*heuristic_length1 = _vala_heuristic_length1;
	}
	if (heuristic_length2) {
		*heuristic_length2 = _vala_heuristic_length2;
	}
}

static void
computer_reverse_hard_create_heuristic (guint8 size,
                                        gint16** heuristic,
                                        gint* heuristic_length1,
                                        gint* heuristic_length2)
{
	gint16* _vala_heuristic = NULL;
	gint _vala_heuristic_length1 = 0;
	gint _vala_heuristic_length2 = 0;
	gint16* _tmp0_;
	guint8 tmp1 = 0U;
	gint16* _tmp6_;
	gint _tmp6__length1;
	gint _tmp6__length2;
	gint16* _tmp7_;
	gint _tmp7__length1;
	gint _tmp7__length2;
	gint16* _tmp8_;
	gint _tmp8__length1;
	gint _tmp8__length2;
	gint16* _tmp9_;
	gint _tmp9__length1;
	gint _tmp9__length2;
	_vala_return_if_fail (((gint) size) >= 4, "size >= 4");
	_tmp0_ = g_new0 (gint16, size * size);
	_vala_heuristic = (g_free (_vala_heuristic), NULL);
	_vala_heuristic = _tmp0_;
	_vala_heuristic_length1 = size;
	_vala_heuristic_length2 = size;
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				if (!_tmp1_) {
					guint8 _tmp2_;
					_tmp2_ = x;
					x = _tmp2_ + 1;
				}
				_tmp1_ = FALSE;
				if (!(x < size)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp3_ = FALSE;
						_tmp3_ = TRUE;
						while (TRUE) {
							gint16* _tmp5_;
							gint _tmp5__length1;
							gint _tmp5__length2;
							if (!_tmp3_) {
								guint8 _tmp4_;
								_tmp4_ = y;
								y = _tmp4_ + 1;
							}
							_tmp3_ = FALSE;
							if (!(y < size)) {
								break;
							}
							_tmp5_ = _vala_heuristic;
							_tmp5__length1 = _vala_heuristic_length1;
							_tmp5__length2 = _vala_heuristic_length2;
							_tmp5_[(x * _tmp5__length2) + y] = (gint16) 0;
						}
					}
				}
			}
		}
	}
	tmp1 = (guint8) (size - 1);
	_tmp6_ = _vala_heuristic;
	_tmp6__length1 = _vala_heuristic_length1;
	_tmp6__length2 = _vala_heuristic_length2;
	_tmp6_[(0 * _tmp6__length2) + 0] = (gint16) 110;
	_tmp7_ = _vala_heuristic;
	_tmp7__length1 = _vala_heuristic_length1;
	_tmp7__length2 = _vala_heuristic_length2;
	_tmp7_[(0 * _tmp7__length2) + tmp1] = (gint16) 110;
	_tmp8_ = _vala_heuristic;
	_tmp8__length1 = _vala_heuristic_length1;
	_tmp8__length2 = _vala_heuristic_length2;
	_tmp8_[(tmp1 * _tmp8__length2) + tmp1] = (gint16) 110;
	_tmp9_ = _vala_heuristic;
	_tmp9__length1 = _vala_heuristic_length1;
	_tmp9__length2 = _vala_heuristic_length2;
	_tmp9_[(tmp1 * _tmp9__length2) + 0] = (gint16) 110;
	if (((gint) size) >= 6) {
		guint8 tmp2 = 0U;
		gint16* _tmp10_;
		gint _tmp10__length1;
		gint _tmp10__length2;
		gint16* _tmp11_;
		gint _tmp11__length1;
		gint _tmp11__length2;
		gint16* _tmp12_;
		gint _tmp12__length1;
		gint _tmp12__length2;
		gint16* _tmp13_;
		gint _tmp13__length1;
		gint _tmp13__length2;
		gint16* _tmp14_;
		gint _tmp14__length1;
		gint _tmp14__length2;
		gint16* _tmp15_;
		gint _tmp15__length1;
		gint _tmp15__length2;
		gint16* _tmp16_;
		gint _tmp16__length1;
		gint _tmp16__length2;
		gint16* _tmp17_;
		gint _tmp17__length1;
		gint _tmp17__length2;
		gint16* _tmp18_;
		gint _tmp18__length1;
		gint _tmp18__length2;
		gint16* _tmp19_;
		gint _tmp19__length1;
		gint _tmp19__length2;
		gint16* _tmp20_;
		gint _tmp20__length1;
		gint _tmp20__length2;
		gint16* _tmp21_;
		gint _tmp21__length1;
		gint _tmp21__length2;
		tmp2 = (guint8) (size - 2);
		_tmp10_ = _vala_heuristic;
		_tmp10__length1 = _vala_heuristic_length1;
		_tmp10__length2 = _vala_heuristic_length2;
		_tmp10_[(0 * _tmp10__length2) + 1] = (gint16) 35;
		_tmp11_ = _vala_heuristic;
		_tmp11__length1 = _vala_heuristic_length1;
		_tmp11__length2 = _vala_heuristic_length2;
		_tmp11_[(0 * _tmp11__length2) + tmp2] = (gint16) 35;
		_tmp12_ = _vala_heuristic;
		_tmp12__length1 = _vala_heuristic_length1;
		_tmp12__length2 = _vala_heuristic_length2;
		_tmp12_[(tmp1 * _tmp12__length2) + 1] = (gint16) 35;
		_tmp13_ = _vala_heuristic;
		_tmp13__length1 = _vala_heuristic_length1;
		_tmp13__length2 = _vala_heuristic_length2;
		_tmp13_[(tmp1 * _tmp13__length2) + tmp2] = (gint16) 35;
		_tmp14_ = _vala_heuristic;
		_tmp14__length1 = _vala_heuristic_length1;
		_tmp14__length2 = _vala_heuristic_length2;
		_tmp14_[(1 * _tmp14__length2) + 0] = (gint16) 35;
		_tmp15_ = _vala_heuristic;
		_tmp15__length1 = _vala_heuristic_length1;
		_tmp15__length2 = _vala_heuristic_length2;
		_tmp15_[(1 * _tmp15__length2) + tmp1] = (gint16) 35;
		_tmp16_ = _vala_heuristic;
		_tmp16__length1 = _vala_heuristic_length1;
		_tmp16__length2 = _vala_heuristic_length2;
		_tmp16_[(tmp2 * _tmp16__length2) + 0] = (gint16) 35;
		_tmp17_ = _vala_heuristic;
		_tmp17__length1 = _vala_heuristic_length1;
		_tmp17__length2 = _vala_heuristic_length2;
		_tmp17_[(tmp2 * _tmp17__length2) + tmp1] = (gint16) 35;
		_tmp18_ = _vala_heuristic;
		_tmp18__length1 = _vala_heuristic_length1;
		_tmp18__length2 = _vala_heuristic_length2;
		_tmp18_[(1 * _tmp18__length2) + 1] = (gint16) 15;
		_tmp19_ = _vala_heuristic;
		_tmp19__length1 = _vala_heuristic_length1;
		_tmp19__length2 = _vala_heuristic_length2;
		_tmp19_[(1 * _tmp19__length2) + tmp2] = (gint16) 15;
		_tmp20_ = _vala_heuristic;
		_tmp20__length1 = _vala_heuristic_length1;
		_tmp20__length2 = _vala_heuristic_length2;
		_tmp20_[(tmp2 * _tmp20__length2) + tmp2] = (gint16) 15;
		_tmp21_ = _vala_heuristic;
		_tmp21__length1 = _vala_heuristic_length1;
		_tmp21__length2 = _vala_heuristic_length2;
		_tmp21_[(tmp2 * _tmp21__length2) + 1] = (gint16) 15;
	}
	if (heuristic) {
		*heuristic = _vala_heuristic;
	} else {
		_vala_heuristic = (g_free (_vala_heuristic), NULL);
	}
	if (heuristic_length1) {
		*heuristic_length1 = _vala_heuristic_length1;
	}
	if (heuristic_length2) {
		*heuristic_length2 = _vala_heuristic_length2;
	}
}

static gboolean
computer_reverse_hard_get_even_depth (ComputerReverseHard* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_even_depth;
	return result;
}

static void
computer_reverse_hard_set_even_depth (ComputerReverseHard* self,
                                      gboolean value)
{
	g_return_if_fail (self != NULL);
	self->priv->_even_depth = value;
}

static gboolean
computer_reverse_hard_get_fixed_heuristic (ComputerReverseHard* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_fixed_heuristic;
	return result;
}

static void
computer_reverse_hard_set_fixed_heuristic (ComputerReverseHard* self,
                                           gboolean value)
{
	g_return_if_fail (self != NULL);
	self->priv->_fixed_heuristic = value;
}

static GObject *
computer_reverse_hard_constructor (GType type,
                                   guint n_construct_properties,
                                   GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	ComputerReverseHard * self;
	guint8 _tmp0_;
	guint8 _tmp1_;
	gboolean _tmp2_;
	gint16* _tmp3_ = NULL;
	gint _tmp4_ = 0;
	gint _tmp5_ = 0;
	parent_class = G_OBJECT_CLASS (computer_reverse_hard_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_COMPUTER_REVERSE_HARD, ComputerReverseHard);
	_tmp0_ = computer_reversi_get_size ((ComputerReversi*) self);
	_tmp1_ = _tmp0_;
	_tmp2_ = self->priv->_fixed_heuristic;
	computer_reverse_hard_init_heuristic (_tmp1_, _tmp2_, &_tmp3_, &_tmp4_, &_tmp5_);
	self->priv->heuristic = (g_free (self->priv->heuristic), NULL);
	self->priv->heuristic = _tmp3_;
	self->priv->heuristic_length1 = _tmp4_;
	self->priv->heuristic_length2 = _tmp5_;
	return obj;
}

static void
computer_reverse_hard_class_init (ComputerReverseHardClass * klass,
                                  gpointer klass_data)
{
	computer_reverse_hard_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &ComputerReverseHard_private_offset);
	((ComputerReversiClass *) klass)->sort_moves = (void (*) (ComputerReversi*, GSList**)) computer_reverse_hard_real_sort_moves;
	((ComputerReversiClass *) klass)->end_of_game = (gint16 (*) (ComputerReversi*, GameStateStruct*)) computer_reverse_hard_real_end_of_game;
	((ComputerReversiClass *) klass)->calculate_heuristic = (gint16 (*) (ComputerReversi*, GameStateStruct*)) computer_reverse_hard_real_calculate_heuristic;
	G_OBJECT_CLASS (klass)->get_property = _vala_computer_reverse_hard_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_computer_reverse_hard_set_property;
	G_OBJECT_CLASS (klass)->constructor = computer_reverse_hard_constructor;
	G_OBJECT_CLASS (klass)->finalize = computer_reverse_hard_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), COMPUTER_REVERSE_HARD_EVEN_DEPTH_PROPERTY, computer_reverse_hard_properties[COMPUTER_REVERSE_HARD_EVEN_DEPTH_PROPERTY] = g_param_spec_boolean ("even-depth", "even-depth", "even-depth", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), COMPUTER_REVERSE_HARD_FIXED_HEURISTIC_PROPERTY, computer_reverse_hard_properties[COMPUTER_REVERSE_HARD_FIXED_HEURISTIC_PROPERTY] = g_param_spec_boolean ("fixed-heuristic", "fixed-heuristic", "fixed-heuristic", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY));
}

static void
computer_reverse_hard_instance_init (ComputerReverseHard * self,
                                     gpointer klass)
{
	self->priv = computer_reverse_hard_get_instance_private (self);
}

static void
computer_reverse_hard_finalize (GObject * obj)
{
	ComputerReverseHard * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_COMPUTER_REVERSE_HARD, ComputerReverseHard);
	self->priv->heuristic = (g_free (self->priv->heuristic), NULL);
	G_OBJECT_CLASS (computer_reverse_hard_parent_class)->finalize (obj);
}

 G_GNUC_NO_INLINE static GType
computer_reverse_hard_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ComputerReverseHardClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) computer_reverse_hard_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ComputerReverseHard), 0, (GInstanceInitFunc) computer_reverse_hard_instance_init, NULL };
	GType computer_reverse_hard_type_id;
	computer_reverse_hard_type_id = g_type_register_static (TYPE_COMPUTER_REVERSI, "ComputerReverseHard", &g_define_type_info, G_TYPE_FLAG_NONE);
	ComputerReverseHard_private_offset = g_type_add_instance_private (computer_reverse_hard_type_id, sizeof (ComputerReverseHardPrivate));
	return computer_reverse_hard_type_id;
}

GType
computer_reverse_hard_get_type (void)
{
	static gsize computer_reverse_hard_type_id__once = 0;
	if (g_once_init_enter (&computer_reverse_hard_type_id__once)) {
		GType computer_reverse_hard_type_id;
		computer_reverse_hard_type_id = computer_reverse_hard_get_type_once ();
		g_once_init_leave (&computer_reverse_hard_type_id__once, computer_reverse_hard_type_id);
	}
	return computer_reverse_hard_type_id__once;
}

static void
_vala_computer_reverse_hard_get_property (GObject * object,
                                          guint property_id,
                                          GValue * value,
                                          GParamSpec * pspec)
{
	ComputerReverseHard * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_COMPUTER_REVERSE_HARD, ComputerReverseHard);
	switch (property_id) {
		case COMPUTER_REVERSE_HARD_EVEN_DEPTH_PROPERTY:
		g_value_set_boolean (value, computer_reverse_hard_get_even_depth (self));
		break;
		case COMPUTER_REVERSE_HARD_FIXED_HEURISTIC_PROPERTY:
		g_value_set_boolean (value, computer_reverse_hard_get_fixed_heuristic (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_computer_reverse_hard_set_property (GObject * object,
                                          guint property_id,
                                          const GValue * value,
                                          GParamSpec * pspec)
{
	ComputerReverseHard * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_COMPUTER_REVERSE_HARD, ComputerReverseHard);
	switch (property_id) {
		case COMPUTER_REVERSE_HARD_EVEN_DEPTH_PROPERTY:
		computer_reverse_hard_set_even_depth (self, g_value_get_boolean (value));
		break;
		case COMPUTER_REVERSE_HARD_FIXED_HEURISTIC_PROPERTY:
		computer_reverse_hard_set_fixed_heuristic (self, g_value_get_boolean (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

ComputerReversiEasy*
computer_reversi_easy_construct (GType object_type,
                                 Game* game)
{
	ComputerReversiEasy * self = NULL;
	g_return_val_if_fail (game != NULL, NULL);
	self = (ComputerReversiEasy*) g_object_new (object_type, "game", game, "initial-depth", 2, NULL);
	return self;
}

ComputerReversiEasy*
computer_reversi_easy_new (Game* game)
{
	return computer_reversi_easy_construct (TYPE_COMPUTER_REVERSI_EASY, game);
}

static gint
_computer_reversi_easy_compare_move_gcompare_func (gconstpointer a,
                                                   gconstpointer b)
{
	gint result;
	result = computer_reversi_easy_compare_move ((PossibleMove*) a, (PossibleMove*) b);
	return result;
}

static void
computer_reversi_easy_real_sort_moves (ComputerReversi* base,
                                       GSList** moves)
{
	ComputerReversiEasy * self;
	self = (ComputerReversiEasy*) base;
	*moves = g_slist_sort (*moves, _computer_reversi_easy_compare_move_gcompare_func);
}

static inline gint
computer_reversi_easy_compare_move (PossibleMove* a,
                                    PossibleMove* b)
{
	gint _tmp0_ = 0;
	gint result;
	if (((PossibleMove) (*a)).n_tiles >= ((PossibleMove) (*b)).n_tiles) {
		_tmp0_ = -1;
	} else {
		_tmp0_ = 1;
	}
	result = _tmp0_;
	return result;
}

static gint16
computer_reversi_easy_real_end_of_game (ComputerReversi* base,
                                        GameStateStruct* g)
{
	ComputerReversiEasy * self;
	gint16 _tmp0_ = 0;
	GameStateStruct _tmp1_;
	GameStateStruct _tmp2_;
	gint16 result;
	self = (ComputerReversiEasy*) base;
	g_return_val_if_fail (g != NULL, -1);
	_tmp1_ = *g;
	_tmp2_ = *g;
	if (_tmp1_.n_current_tiles > _tmp2_.n_opponent_tiles) {
		GameStateStruct _tmp3_;
		_tmp3_ = *g;
		_tmp0_ = COMPUTER_REVERSI_POSITIVE_INFINITY - ((gint16) _tmp3_.n_opponent_tiles);
	} else {
		GameStateStruct _tmp4_;
		_tmp4_ = *g;
		_tmp0_ = COMPUTER_REVERSI_NEGATIVE_INFINITY + ((gint16) _tmp4_.n_current_tiles);
	}
	result = _tmp0_;
	return result;
}

static gint16
computer_reversi_easy_real_calculate_heuristic (ComputerReversi* base,
                                                GameStateStruct* g)
{
	ComputerReversiEasy * self;
	GameStateStruct _tmp0_;
	GameStateStruct _tmp1_;
	gint16 result;
	self = (ComputerReversiEasy*) base;
	g_return_val_if_fail (g != NULL, -1);
	_tmp0_ = *g;
	_tmp1_ = *g;
	result = ((gint16) _tmp0_.n_opponent_tiles) - ((gint16) _tmp1_.n_current_tiles);
	return result;
}

static void
computer_reversi_easy_class_init (ComputerReversiEasyClass * klass,
                                  gpointer klass_data)
{
	computer_reversi_easy_parent_class = g_type_class_peek_parent (klass);
	((ComputerReversiClass *) klass)->sort_moves = (void (*) (ComputerReversi*, GSList**)) computer_reversi_easy_real_sort_moves;
	((ComputerReversiClass *) klass)->end_of_game = (gint16 (*) (ComputerReversi*, GameStateStruct*)) computer_reversi_easy_real_end_of_game;
	((ComputerReversiClass *) klass)->calculate_heuristic = (gint16 (*) (ComputerReversi*, GameStateStruct*)) computer_reversi_easy_real_calculate_heuristic;
}

static void
computer_reversi_easy_instance_init (ComputerReversiEasy * self,
                                     gpointer klass)
{
}

 G_GNUC_NO_INLINE static GType
computer_reversi_easy_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ComputerReversiEasyClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) computer_reversi_easy_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ComputerReversiEasy), 0, (GInstanceInitFunc) computer_reversi_easy_instance_init, NULL };
	GType computer_reversi_easy_type_id;
	computer_reversi_easy_type_id = g_type_register_static (TYPE_COMPUTER_REVERSI, "ComputerReversiEasy", &g_define_type_info, G_TYPE_FLAG_NONE);
	return computer_reversi_easy_type_id;
}

GType
computer_reversi_easy_get_type (void)
{
	static gsize computer_reversi_easy_type_id__once = 0;
	if (g_once_init_enter (&computer_reversi_easy_type_id__once)) {
		GType computer_reversi_easy_type_id;
		computer_reversi_easy_type_id = computer_reversi_easy_get_type_once ();
		g_once_init_leave (&computer_reversi_easy_type_id__once, computer_reversi_easy_type_id);
	}
	return computer_reversi_easy_type_id__once;
}

static inline gpointer
computer_reversi_hard_get_instance_private (ComputerReversiHard* self)
{
	return G_STRUCT_MEMBER_P (self, ComputerReversiHard_private_offset);
}

ComputerReversiHard*
computer_reversi_hard_construct (GType object_type,
                                 Game* game,
                                 guint8 initial_depth,
                                 gboolean fixed_heuristic)
{
	ComputerReversiHard * self = NULL;
	g_return_val_if_fail (game != NULL, NULL);
	self = (ComputerReversiHard*) g_object_new (object_type, "game", game, "even-depth", (initial_depth % 2) == 0, "initial-depth", initial_depth, "fixed-heuristic", fixed_heuristic, NULL);
	return self;
}

ComputerReversiHard*
computer_reversi_hard_new (Game* game,
                           guint8 initial_depth,
                           gboolean fixed_heuristic)
{
	return computer_reversi_hard_construct (TYPE_COMPUTER_REVERSI_HARD, game, initial_depth, fixed_heuristic);
}

static gint
_computer_reversi_hard_compare_move_gcompare_data_func (gconstpointer a,
                                                        gconstpointer b,
                                                        gpointer self)
{
	gint result;
	result = computer_reversi_hard_compare_move ((ComputerReversiHard*) self, (PossibleMove*) a, (PossibleMove*) b);
	return result;
}

static void
computer_reversi_hard_real_sort_moves (ComputerReversi* base,
                                       GSList** moves)
{
	ComputerReversiHard * self;
	self = (ComputerReversiHard*) base;
	*moves = g_slist_sort_with_data (*moves, _computer_reversi_hard_compare_move_gcompare_data_func, self);
}

static inline gint
computer_reversi_hard_compare_move (ComputerReversiHard* self,
                                    PossibleMove* a,
                                    PossibleMove* b)
{
	PossibleMove _tmp0_;
	PossibleMove _tmp1_;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	_tmp0_ = (PossibleMove) (*b);
	_tmp1_ = (PossibleMove) (*a);
	result = computer_reversi_hard_calculate_move_heuristic (self, &_tmp0_) - computer_reversi_hard_calculate_move_heuristic (self, &_tmp1_);
	return result;
}

static inline gint
computer_reversi_hard_calculate_move_heuristic (ComputerReversiHard* self,
                                                PossibleMove* move)
{
	gint comparator = 0;
	PossibleMove _tmp0_;
	PossibleMove _tmp1_;
	PossibleMove _tmp2_;
	PossibleMove _tmp3_;
	PossibleMove _tmp4_;
	PossibleMove _tmp5_;
	PossibleMove _tmp6_;
	PossibleMove _tmp7_;
	PossibleMove _tmp8_;
	PossibleMove _tmp9_;
	PossibleMove _tmp10_;
	PossibleMove _tmp11_;
	PossibleMove _tmp12_;
	PossibleMove _tmp13_;
	PossibleMove _tmp14_;
	PossibleMove _tmp15_;
	PossibleMove _tmp16_;
	PossibleMove _tmp17_;
	PossibleMove _tmp18_;
	PossibleMove _tmp19_;
	PossibleMove _tmp20_;
	PossibleMove _tmp21_;
	PossibleMove _tmp22_;
	PossibleMove _tmp23_;
	gint16* _tmp24_;
	gint _tmp24__length1;
	gint _tmp24__length2;
	PossibleMove _tmp25_;
	PossibleMove _tmp26_;
	gint16 _tmp27_;
	guint8* _tmp28_;
	gint _tmp28__length1;
	gint _tmp28__length2;
	PossibleMove _tmp29_;
	PossibleMove _tmp30_;
	guint8 _tmp31_;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	g_return_val_if_fail (move != NULL, -1);
	comparator = 0;
	_tmp0_ = *move;
	_tmp1_ = *move;
	_tmp2_ = *move;
	computer_reversi_hard_calculate_dir_heuristic (self, &comparator, _tmp0_.x, _tmp1_.y, (gint8) 0, (gint8) -1, _tmp2_.n_tiles_n);
	_tmp3_ = *move;
	_tmp4_ = *move;
	_tmp5_ = *move;
	computer_reversi_hard_calculate_dir_heuristic (self, &comparator, _tmp3_.x, _tmp4_.y, (gint8) 1, (gint8) -1, _tmp5_.n_tiles_ne);
	_tmp6_ = *move;
	_tmp7_ = *move;
	_tmp8_ = *move;
	computer_reversi_hard_calculate_dir_heuristic (self, &comparator, _tmp6_.x, _tmp7_.y, (gint8) 1, (gint8) 0, _tmp8_.n_tiles_e);
	_tmp9_ = *move;
	_tmp10_ = *move;
	_tmp11_ = *move;
	computer_reversi_hard_calculate_dir_heuristic (self, &comparator, _tmp9_.x, _tmp10_.y, (gint8) 1, (gint8) 1, _tmp11_.n_tiles_se);
	_tmp12_ = *move;
	_tmp13_ = *move;
	_tmp14_ = *move;
	computer_reversi_hard_calculate_dir_heuristic (self, &comparator, _tmp12_.x, _tmp13_.y, (gint8) 0, (gint8) 1, _tmp14_.n_tiles_s);
	_tmp15_ = *move;
	_tmp16_ = *move;
	_tmp17_ = *move;
	computer_reversi_hard_calculate_dir_heuristic (self, &comparator, _tmp15_.x, _tmp16_.y, (gint8) -1, (gint8) 1, _tmp17_.n_tiles_so);
	_tmp18_ = *move;
	_tmp19_ = *move;
	_tmp20_ = *move;
	computer_reversi_hard_calculate_dir_heuristic (self, &comparator, _tmp18_.x, _tmp19_.y, (gint8) -1, (gint8) 0, _tmp20_.n_tiles_o);
	_tmp21_ = *move;
	_tmp22_ = *move;
	_tmp23_ = *move;
	computer_reversi_hard_calculate_dir_heuristic (self, &comparator, _tmp21_.x, _tmp22_.y, (gint8) -1, (gint8) -1, _tmp23_.n_tiles_no);
	_tmp24_ = self->priv->heuristic;
	_tmp24__length1 = self->priv->heuristic_length1;
	_tmp24__length2 = self->priv->heuristic_length2;
	_tmp25_ = *move;
	_tmp26_ = *move;
	_tmp27_ = _tmp24_[(_tmp25_.x * _tmp24__length2) + _tmp26_.y];
	_tmp28_ = ((ComputerReversi*) self)->neighbor_tiles;
	_tmp28__length1 = ((ComputerReversi*) self)->neighbor_tiles_length1;
	_tmp28__length2 = ((ComputerReversi*) self)->neighbor_tiles_length2;
	_tmp29_ = *move;
	_tmp30_ = *move;
	_tmp31_ = _tmp28_[(_tmp29_.x * _tmp28__length2) + _tmp30_.y];
	result = ((2 * comparator) + ((gint) _tmp27_)) - (8 * ((gint) _tmp31_));
	return result;
}

static inline void
computer_reversi_hard_calculate_dir_heuristic (ComputerReversiHard* self,
                                               gint* comparator,
                                               guint8 x,
                                               guint8 y,
                                               gint8 x_step,
                                               gint8 y_step,
                                               guint8 count)
{
	g_return_if_fail (self != NULL);
	{
		gboolean _tmp0_ = FALSE;
		_tmp0_ = TRUE;
		while (TRUE) {
			gint16* _tmp2_;
			gint _tmp2__length1;
			gint _tmp2__length2;
			gint16 _tmp3_;
			if (!_tmp0_) {
				guint8 _tmp1_;
				_tmp1_ = count;
				count = _tmp1_ - 1;
			}
			_tmp0_ = FALSE;
			if (!(((gint) count) > 0)) {
				break;
			}
			_tmp2_ = self->priv->heuristic;
			_tmp2__length1 = self->priv->heuristic_length1;
			_tmp2__length2 = self->priv->heuristic_length2;
			_tmp3_ = _tmp2_[((((gint8) x) + (((gint8) count) * x_step)) * _tmp2__length2) + (((gint8) y) + (((gint8) count) * y_step))];
			*comparator = (*comparator) + ((gint) _tmp3_);
		}
	}
}

static gint16
computer_reversi_hard_real_end_of_game (ComputerReversi* base,
                                        GameStateStruct* g)
{
	ComputerReversiHard * self;
	gint16 _tmp0_ = 0;
	GameStateStruct _tmp1_;
	GameStateStruct _tmp2_;
	gint16 result;
	self = (ComputerReversiHard*) base;
	g_return_val_if_fail (g != NULL, -1);
	_tmp1_ = *g;
	_tmp2_ = *g;
	if (_tmp1_.n_current_tiles > _tmp2_.n_opponent_tiles) {
		GameStateStruct _tmp3_;
		_tmp3_ = *g;
		_tmp0_ = COMPUTER_REVERSI_POSITIVE_INFINITY - ((gint16) _tmp3_.n_opponent_tiles);
	} else {
		GameStateStruct _tmp4_;
		_tmp4_ = *g;
		_tmp0_ = COMPUTER_REVERSI_NEGATIVE_INFINITY + ((gint16) _tmp4_.n_current_tiles);
	}
	result = _tmp0_;
	return result;
}

static gint16
computer_reversi_hard_real_calculate_heuristic (ComputerReversi* base,
                                                GameStateStruct* g)
{
	ComputerReversiHard * self;
	GameStateStruct _tmp0_;
	gboolean _tmp1_;
	gint16 _tmp2_;
	gint16 result;
	self = (ComputerReversiHard*) base;
	g_return_val_if_fail (g != NULL, -1);
	_tmp0_ = *g;
	_tmp1_ = self->priv->_even_depth;
	_tmp2_ = computer_reversi_hard_eval_heuristic (&_tmp0_, &self->priv->heuristic, (gint*) (&self->priv->heuristic_length1), (gint*) (&self->priv->heuristic_length2), _tmp1_);
	result = _tmp2_;
	return result;
}

static inline gint16
computer_reversi_hard_eval_heuristic (GameStateStruct* g,
                                      gint16** heuristic,
                                      gint* heuristic_length1,
                                      gint* heuristic_length2,
                                      gboolean even_depth)
{
	guint8 size = 0U;
	GameStateStruct _tmp0_;
	gint16 count = 0;
	GameStateStruct _tmp6_;
	GameStateStruct _tmp7_;
	GameStateStruct _tmp8_;
	GameStateStruct _tmp9_;
	GameStateStruct _tmp10_;
	GameStateStruct _tmp11_;
	gint16 result;
	g_return_val_if_fail (g != NULL, -1);
	_tmp0_ = *g;
	size = _tmp0_.size;
	count = (gint16) 0;
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				if (!_tmp1_) {
					guint8 _tmp2_;
					_tmp2_ = x;
					x = _tmp2_ + 1;
				}
				_tmp1_ = FALSE;
				if (!(x < size)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp3_ = FALSE;
						_tmp3_ = TRUE;
						while (TRUE) {
							gint16 a = 0;
							gint16 tile_heuristic = 0;
							gint16 _tmp5_;
							if (!_tmp3_) {
								guint8 _tmp4_;
								_tmp4_ = y;
								y = _tmp4_ + 1;
							}
							_tmp3_ = FALSE;
							if (!(y < size)) {
								break;
							}
							a = (gint16) game_state_struct_get_empty_neighbors (g, x, y);
							if (((gint) a) == 0) {
								a = (gint16) -6;
							}
							_tmp5_ = (*heuristic)[(x * (*heuristic_length2)) + y];
							tile_heuristic = (gint16) (_tmp5_ - (8 * a));
							if (game_state_struct_is_empty_tile (g, x, y)) {
								if (even_depth) {
									count -= (gint16) (tile_heuristic / 2);
								} else {
									count += (gint16) (tile_heuristic / 2);
								}
							} else {
								if (game_state_struct_is_current_color (g, x, y)) {
									count += tile_heuristic;
								} else {
									count -= tile_heuristic;
								}
							}
						}
					}
				}
			}
		}
	}
	_tmp6_ = *g;
	computer_reversi_hard_mainline_penalty (&_tmp6_, COMPUTER_REVERSI_HARD_border_penalty, &count, MAIN_LINE_TOP);
	_tmp7_ = *g;
	computer_reversi_hard_mainline_penalty (&_tmp7_, COMPUTER_REVERSI_HARD_border_penalty, &count, MAIN_LINE_LEFT);
	_tmp8_ = *g;
	computer_reversi_hard_mainline_penalty (&_tmp8_, COMPUTER_REVERSI_HARD_border_penalty, &count, MAIN_LINE_RIGHT);
	_tmp9_ = *g;
	computer_reversi_hard_mainline_penalty (&_tmp9_, COMPUTER_REVERSI_HARD_border_penalty, &count, MAIN_LINE_BOTTOM);
	_tmp10_ = *g;
	computer_reversi_hard_mainline_penalty (&_tmp10_, COMPUTER_REVERSI_HARD_corner_penalty, &count, MAIN_LINE_TOPLEFT);
	_tmp11_ = *g;
	computer_reversi_hard_mainline_penalty (&_tmp11_, COMPUTER_REVERSI_HARD_corner_penalty, &count, MAIN_LINE_TOPRIGHT);
	result = count;
	return result;
}

static void
computer_reversi_hard_mainline_penalty (GameStateStruct* g,
                                        gint16 penalty,
                                        gint16* count,
                                        MainLine mainline_id)
{
	Player* mainline = NULL;
	gint _tmp0_ = 0;
	Player* _tmp1_;
	gint mainline_length1;
	gint _mainline_size_;
	gboolean _tmp2_ = FALSE;
	Player* _tmp3_;
	gint _tmp3__length1;
	Player _tmp4_;
	GameStateStruct _tmp5_;
	gboolean _tmp34_ = FALSE;
	Player* _tmp35_;
	gint _tmp35__length1;
	GameStateStruct _tmp36_;
	Player _tmp37_;
	GameStateStruct _tmp38_;
	g_return_if_fail (g != NULL);
	_tmp1_ = game_state_struct_get_mainline (g, mainline_id, &_tmp0_);
	mainline = _tmp1_;
	mainline_length1 = _tmp0_;
	_mainline_size_ = mainline_length1;
	_tmp3_ = mainline;
	_tmp3__length1 = mainline_length1;
	_tmp4_ = _tmp3_[1];
	_tmp5_ = *g;
	if (_tmp4_ == _tmp5_.current_color) {
		Player* _tmp6_;
		gint _tmp6__length1;
		Player _tmp7_;
		_tmp6_ = mainline;
		_tmp6__length1 = mainline_length1;
		_tmp7_ = _tmp6_[0];
		_tmp2_ = _tmp7_ == PLAYER_NONE;
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		guint8 i = 0U;
		GameStateStruct _tmp14_;
		i = (guint8) 1;
		{
			gboolean _tmp8_ = FALSE;
			_tmp8_ = TRUE;
			while (TRUE) {
				guint8 _tmp12_;
				GameStateStruct _tmp13_;
				if (!_tmp8_) {
					Player* _tmp9_;
					gint _tmp9__length1;
					Player _tmp10_;
					GameStateStruct _tmp11_;
					_tmp9_ = mainline;
					_tmp9__length1 = mainline_length1;
					_tmp10_ = _tmp9_[i];
					_tmp11_ = *g;
					if (!(_tmp10_ == _tmp11_.current_color)) {
						break;
					}
				}
				_tmp8_ = FALSE;
				_tmp12_ = i;
				i = _tmp12_ + 1;
				_tmp13_ = *g;
				if (((gint) i) == (_tmp13_.size - 2)) {
					break;
				}
			}
		}
		_tmp14_ = *g;
		if (((gint) i) != (_tmp14_.size - 2)) {
			Player* _tmp15_;
			gint _tmp15__length1;
			Player _tmp16_;
			GameStateStruct _tmp17_;
			*count = (*count) - penalty;
			_tmp15_ = mainline;
			_tmp15__length1 = mainline_length1;
			_tmp16_ = _tmp15_[i + 1];
			_tmp17_ = *g;
			if (_tmp16_ == _tmp17_.current_color) {
				*count = (*count) - penalty;
			}
		}
	} else {
		gboolean _tmp18_ = FALSE;
		Player* _tmp19_;
		gint _tmp19__length1;
		Player _tmp20_;
		GameStateStruct _tmp21_;
		_tmp19_ = mainline;
		_tmp19__length1 = mainline_length1;
		_tmp20_ = _tmp19_[1];
		_tmp21_ = *g;
		if (_tmp20_ == _tmp21_.opponent_color) {
			Player* _tmp22_;
			gint _tmp22__length1;
			Player _tmp23_;
			_tmp22_ = mainline;
			_tmp22__length1 = mainline_length1;
			_tmp23_ = _tmp22_[0];
			_tmp18_ = _tmp23_ == PLAYER_NONE;
		} else {
			_tmp18_ = FALSE;
		}
		if (_tmp18_) {
			guint8 i = 0U;
			GameStateStruct _tmp30_;
			i = (guint8) 1;
			{
				gboolean _tmp24_ = FALSE;
				_tmp24_ = TRUE;
				while (TRUE) {
					guint8 _tmp28_;
					GameStateStruct _tmp29_;
					if (!_tmp24_) {
						Player* _tmp25_;
						gint _tmp25__length1;
						Player _tmp26_;
						GameStateStruct _tmp27_;
						_tmp25_ = mainline;
						_tmp25__length1 = mainline_length1;
						_tmp26_ = _tmp25_[i];
						_tmp27_ = *g;
						if (!(_tmp26_ == _tmp27_.opponent_color)) {
							break;
						}
					}
					_tmp24_ = FALSE;
					_tmp28_ = i;
					i = _tmp28_ + 1;
					_tmp29_ = *g;
					if (((gint) i) == (_tmp29_.size - 2)) {
						break;
					}
				}
			}
			_tmp30_ = *g;
			if (((gint) i) != (_tmp30_.size - 2)) {
				Player* _tmp31_;
				gint _tmp31__length1;
				Player _tmp32_;
				GameStateStruct _tmp33_;
				*count = (*count) + penalty;
				_tmp31_ = mainline;
				_tmp31__length1 = mainline_length1;
				_tmp32_ = _tmp31_[i + 1];
				_tmp33_ = *g;
				if (_tmp32_ == _tmp33_.opponent_color) {
					*count = (*count) + penalty;
				}
			}
		}
	}
	_tmp35_ = mainline;
	_tmp35__length1 = mainline_length1;
	_tmp36_ = *g;
	_tmp37_ = _tmp35_[_tmp36_.size - 2];
	_tmp38_ = *g;
	if (_tmp37_ == _tmp38_.current_color) {
		Player* _tmp39_;
		gint _tmp39__length1;
		GameStateStruct _tmp40_;
		Player _tmp41_;
		_tmp39_ = mainline;
		_tmp39__length1 = mainline_length1;
		_tmp40_ = *g;
		_tmp41_ = _tmp39_[_tmp40_.size - 1];
		_tmp34_ = _tmp41_ == PLAYER_NONE;
	} else {
		_tmp34_ = FALSE;
	}
	if (_tmp34_) {
		guint8 i = 0U;
		GameStateStruct _tmp49_;
		i = (guint8) 1;
		{
			gboolean _tmp42_ = FALSE;
			_tmp42_ = TRUE;
			while (TRUE) {
				guint8 _tmp47_;
				GameStateStruct _tmp48_;
				if (!_tmp42_) {
					Player* _tmp43_;
					gint _tmp43__length1;
					GameStateStruct _tmp44_;
					Player _tmp45_;
					GameStateStruct _tmp46_;
					_tmp43_ = mainline;
					_tmp43__length1 = mainline_length1;
					_tmp44_ = *g;
					_tmp45_ = _tmp43_[(_tmp44_.size - 1) - i];
					_tmp46_ = *g;
					if (!(_tmp45_ == _tmp46_.current_color)) {
						break;
					}
				}
				_tmp42_ = FALSE;
				_tmp47_ = i;
				i = _tmp47_ + 1;
				_tmp48_ = *g;
				if (((gint) i) == (_tmp48_.size - 2)) {
					break;
				}
			}
		}
		_tmp49_ = *g;
		if (((gint) i) != (_tmp49_.size - 2)) {
			Player* _tmp50_;
			gint _tmp50__length1;
			GameStateStruct _tmp51_;
			Player _tmp52_;
			GameStateStruct _tmp53_;
			*count = (*count) - penalty;
			_tmp50_ = mainline;
			_tmp50__length1 = mainline_length1;
			_tmp51_ = *g;
			_tmp52_ = _tmp50_[(_tmp51_.size - 2) - i];
			_tmp53_ = *g;
			if (_tmp52_ == _tmp53_.current_color) {
				*count = (*count) - penalty;
			}
		}
	} else {
		gboolean _tmp54_ = FALSE;
		Player* _tmp55_;
		gint _tmp55__length1;
		GameStateStruct _tmp56_;
		Player _tmp57_;
		GameStateStruct _tmp58_;
		_tmp55_ = mainline;
		_tmp55__length1 = mainline_length1;
		_tmp56_ = *g;
		_tmp57_ = _tmp55_[_tmp56_.size - 2];
		_tmp58_ = *g;
		if (_tmp57_ == _tmp58_.opponent_color) {
			Player* _tmp59_;
			gint _tmp59__length1;
			GameStateStruct _tmp60_;
			Player _tmp61_;
			_tmp59_ = mainline;
			_tmp59__length1 = mainline_length1;
			_tmp60_ = *g;
			_tmp61_ = _tmp59_[_tmp60_.size - 1];
			_tmp54_ = _tmp61_ == PLAYER_NONE;
		} else {
			_tmp54_ = FALSE;
		}
		if (_tmp54_) {
			guint8 i = 0U;
			GameStateStruct _tmp69_;
			i = (guint8) 1;
			{
				gboolean _tmp62_ = FALSE;
				_tmp62_ = TRUE;
				while (TRUE) {
					guint8 _tmp67_;
					GameStateStruct _tmp68_;
					if (!_tmp62_) {
						Player* _tmp63_;
						gint _tmp63__length1;
						GameStateStruct _tmp64_;
						Player _tmp65_;
						GameStateStruct _tmp66_;
						_tmp63_ = mainline;
						_tmp63__length1 = mainline_length1;
						_tmp64_ = *g;
						_tmp65_ = _tmp63_[(_tmp64_.size - 1) - i];
						_tmp66_ = *g;
						if (!(_tmp65_ == _tmp66_.opponent_color)) {
							break;
						}
					}
					_tmp62_ = FALSE;
					_tmp67_ = i;
					i = _tmp67_ + 1;
					_tmp68_ = *g;
					if (((gint) i) == (_tmp68_.size - 2)) {
						break;
					}
				}
			}
			_tmp69_ = *g;
			if (((gint) i) != (_tmp69_.size - 2)) {
				Player* _tmp70_;
				gint _tmp70__length1;
				GameStateStruct _tmp71_;
				Player _tmp72_;
				GameStateStruct _tmp73_;
				*count = (*count) + penalty;
				_tmp70_ = mainline;
				_tmp70__length1 = mainline_length1;
				_tmp71_ = *g;
				_tmp72_ = _tmp70_[(_tmp71_.size - 2) - i];
				_tmp73_ = *g;
				if (_tmp72_ == _tmp73_.opponent_color) {
					*count = (*count) + penalty;
				}
			}
		}
	}
	mainline = (g_free (mainline), NULL);
}

static gint16*
_vala_array_dup2 (gint16* self,
                  gssize length)
{
	if (length > 0) {
		return g_memdup2 (self, length * sizeof (gint16));
	}
	return NULL;
}

static inline void
computer_reversi_hard_init_heuristic (guint8 size,
                                      gboolean fixed_heuristic,
                                      gint16** heuristic,
                                      gint* heuristic_length1,
                                      gint* heuristic_length2)
{
	gint16* _vala_heuristic = NULL;
	gint _vala_heuristic_length1 = 0;
	gint _vala_heuristic_length2 = 0;
	_vala_return_if_fail (((gint) size) >= 4, "size >= 4");
	if (((gint) size) == 8) {
		gint16* _tmp0_;
		gint _tmp0__length1;
		gint _tmp0__length2;
		_tmp0_ = _vala_array_dup2 (heuristic_8, G_N_ELEMENTS (heuristic_8) * G_N_ELEMENTS (heuristic_8[0]));
		_tmp0__length1 = G_N_ELEMENTS (heuristic_8);
		_tmp0__length2 = G_N_ELEMENTS (heuristic_8[0]);
		_vala_heuristic = (g_free (_vala_heuristic), NULL);
		_vala_heuristic = _tmp0_;
		_vala_heuristic_length1 = _tmp0__length1;
		_vala_heuristic_length2 = _tmp0__length2;
	} else {
		gint16* _tmp1_ = NULL;
		gint _tmp2_ = 0;
		gint _tmp3_ = 0;
		computer_reversi_hard_create_heuristic (size, &_tmp1_, &_tmp2_, &_tmp3_);
		_vala_heuristic = (g_free (_vala_heuristic), NULL);
		_vala_heuristic = _tmp1_;
		_vala_heuristic_length1 = _tmp2_;
		_vala_heuristic_length2 = _tmp3_;
	}
	if (fixed_heuristic) {
		if (heuristic) {
			*heuristic = _vala_heuristic;
		} else {
			_vala_heuristic = (g_free (_vala_heuristic), NULL);
		}
		if (heuristic_length1) {
			*heuristic_length1 = _vala_heuristic_length1;
		}
		if (heuristic_length2) {
			*heuristic_length2 = _vala_heuristic_length2;
		}
		return;
	}
	{
		guint8 i = 0U;
		i = (guint8) 0;
		{
			gboolean _tmp4_ = FALSE;
			_tmp4_ = TRUE;
			while (TRUE) {
				gint _tmp6_ = 0;
				gint16* _tmp7_;
				gint _tmp7__length1;
				gint _tmp7__length2;
				guint8 x = 0U;
				guint8 y = 0U;
				gboolean minus = FALSE;
				gint _tmp8_ = 0;
				gint16* _tmp9_;
				gint _tmp9__length1;
				gint _tmp9__length2;
				gint _tmp10_ = 0;
				gint16* _tmp11_;
				gint _tmp11__length1;
				gint _tmp11__length2;
				if (!_tmp4_) {
					guint8 _tmp5_;
					_tmp5_ = i;
					i = _tmp5_ + 1;
				}
				_tmp4_ = FALSE;
				if (!(((gint) i) < 5)) {
					break;
				}
				if (g_random_boolean ()) {
					_tmp6_ = -1;
				} else {
					_tmp6_ = 1;
				}
				_tmp7_ = _vala_heuristic;
				_tmp7__length1 = _vala_heuristic_length1;
				_tmp7__length2 = _vala_heuristic_length2;
				_tmp7_[(g_random_int_range ((gint32) 0, (gint32) size) * _tmp7__length2) + g_random_int_range ((gint32) 0, (gint32) size)] += (gint16) _tmp6_;
				x = (guint8) g_random_int_range ((gint32) 0, (gint32) size);
				y = (guint8) g_random_int_range ((gint32) 0, (gint32) size);
				minus = g_random_boolean ();
				if (minus) {
					_tmp8_ = -1;
				} else {
					_tmp8_ = 1;
				}
				_tmp9_ = _vala_heuristic;
				_tmp9__length1 = _vala_heuristic_length1;
				_tmp9__length2 = _vala_heuristic_length2;
				_tmp9_[(x * _tmp9__length2) + y] += (gint16) _tmp8_;
				if (minus) {
					_tmp10_ = -1;
				} else {
					_tmp10_ = 1;
				}
				_tmp11_ = _vala_heuristic;
				_tmp11__length1 = _vala_heuristic_length1;
				_tmp11__length2 = _vala_heuristic_length2;
				_tmp11_[(((size - 1) - x) * _tmp11__length2) + ((size - 1) - y)] += (gint16) _tmp10_;
			}
		}
	}
	if (heuristic) {
		*heuristic = _vala_heuristic;
	} else {
		_vala_heuristic = (g_free (_vala_heuristic), NULL);
	}
	if (heuristic_length1) {
		*heuristic_length1 = _vala_heuristic_length1;
	}
	if (heuristic_length2) {
		*heuristic_length2 = _vala_heuristic_length2;
	}
}

static void
computer_reversi_hard_create_heuristic (guint8 size,
                                        gint16** heuristic,
                                        gint* heuristic_length1,
                                        gint* heuristic_length2)
{
	gint16* _vala_heuristic = NULL;
	gint _vala_heuristic_length1 = 0;
	gint _vala_heuristic_length2 = 0;
	gint16* _tmp0_;
	guint8 tmp1 = 0U;
	gint16* _tmp6_;
	gint _tmp6__length1;
	gint _tmp6__length2;
	gint16* _tmp7_;
	gint _tmp7__length1;
	gint _tmp7__length2;
	gint16* _tmp8_;
	gint _tmp8__length1;
	gint _tmp8__length2;
	gint16* _tmp9_;
	gint _tmp9__length1;
	gint _tmp9__length2;
	_vala_return_if_fail (((gint) size) >= 4, "size >= 4");
	_tmp0_ = g_new0 (gint16, size * size);
	_vala_heuristic = (g_free (_vala_heuristic), NULL);
	_vala_heuristic = _tmp0_;
	_vala_heuristic_length1 = size;
	_vala_heuristic_length2 = size;
	{
		guint8 x = 0U;
		x = (guint8) 0;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				if (!_tmp1_) {
					guint8 _tmp2_;
					_tmp2_ = x;
					x = _tmp2_ + 1;
				}
				_tmp1_ = FALSE;
				if (!(x < size)) {
					break;
				}
				{
					guint8 y = 0U;
					y = (guint8) 0;
					{
						gboolean _tmp3_ = FALSE;
						_tmp3_ = TRUE;
						while (TRUE) {
							gint16* _tmp5_;
							gint _tmp5__length1;
							gint _tmp5__length2;
							if (!_tmp3_) {
								guint8 _tmp4_;
								_tmp4_ = y;
								y = _tmp4_ + 1;
							}
							_tmp3_ = FALSE;
							if (!(y < size)) {
								break;
							}
							_tmp5_ = _vala_heuristic;
							_tmp5__length1 = _vala_heuristic_length1;
							_tmp5__length2 = _vala_heuristic_length2;
							_tmp5_[(x * _tmp5__length2) + y] = (gint16) 0;
						}
					}
				}
			}
		}
	}
	tmp1 = (guint8) (size - 1);
	_tmp6_ = _vala_heuristic;
	_tmp6__length1 = _vala_heuristic_length1;
	_tmp6__length2 = _vala_heuristic_length2;
	_tmp6_[(0 * _tmp6__length2) + 0] = (gint16) 110;
	_tmp7_ = _vala_heuristic;
	_tmp7__length1 = _vala_heuristic_length1;
	_tmp7__length2 = _vala_heuristic_length2;
	_tmp7_[(0 * _tmp7__length2) + tmp1] = (gint16) 110;
	_tmp8_ = _vala_heuristic;
	_tmp8__length1 = _vala_heuristic_length1;
	_tmp8__length2 = _vala_heuristic_length2;
	_tmp8_[(tmp1 * _tmp8__length2) + tmp1] = (gint16) 110;
	_tmp9_ = _vala_heuristic;
	_tmp9__length1 = _vala_heuristic_length1;
	_tmp9__length2 = _vala_heuristic_length2;
	_tmp9_[(tmp1 * _tmp9__length2) + 0] = (gint16) 110;
	if (((gint) size) >= 6) {
		guint8 tmp2 = 0U;
		gint16* _tmp10_;
		gint _tmp10__length1;
		gint _tmp10__length2;
		gint16* _tmp11_;
		gint _tmp11__length1;
		gint _tmp11__length2;
		gint16* _tmp12_;
		gint _tmp12__length1;
		gint _tmp12__length2;
		gint16* _tmp13_;
		gint _tmp13__length1;
		gint _tmp13__length2;
		gint16* _tmp14_;
		gint _tmp14__length1;
		gint _tmp14__length2;
		gint16* _tmp15_;
		gint _tmp15__length1;
		gint _tmp15__length2;
		gint16* _tmp16_;
		gint _tmp16__length1;
		gint _tmp16__length2;
		gint16* _tmp17_;
		gint _tmp17__length1;
		gint _tmp17__length2;
		gint16* _tmp18_;
		gint _tmp18__length1;
		gint _tmp18__length2;
		gint16* _tmp19_;
		gint _tmp19__length1;
		gint _tmp19__length2;
		gint16* _tmp20_;
		gint _tmp20__length1;
		gint _tmp20__length2;
		gint16* _tmp21_;
		gint _tmp21__length1;
		gint _tmp21__length2;
		tmp2 = (guint8) (size - 2);
		_tmp10_ = _vala_heuristic;
		_tmp10__length1 = _vala_heuristic_length1;
		_tmp10__length2 = _vala_heuristic_length2;
		_tmp10_[(0 * _tmp10__length2) + 1] = (gint16) 35;
		_tmp11_ = _vala_heuristic;
		_tmp11__length1 = _vala_heuristic_length1;
		_tmp11__length2 = _vala_heuristic_length2;
		_tmp11_[(0 * _tmp11__length2) + tmp2] = (gint16) 35;
		_tmp12_ = _vala_heuristic;
		_tmp12__length1 = _vala_heuristic_length1;
		_tmp12__length2 = _vala_heuristic_length2;
		_tmp12_[(tmp1 * _tmp12__length2) + 1] = (gint16) 35;
		_tmp13_ = _vala_heuristic;
		_tmp13__length1 = _vala_heuristic_length1;
		_tmp13__length2 = _vala_heuristic_length2;
		_tmp13_[(tmp1 * _tmp13__length2) + tmp2] = (gint16) 35;
		_tmp14_ = _vala_heuristic;
		_tmp14__length1 = _vala_heuristic_length1;
		_tmp14__length2 = _vala_heuristic_length2;
		_tmp14_[(1 * _tmp14__length2) + 0] = (gint16) 35;
		_tmp15_ = _vala_heuristic;
		_tmp15__length1 = _vala_heuristic_length1;
		_tmp15__length2 = _vala_heuristic_length2;
		_tmp15_[(1 * _tmp15__length2) + tmp1] = (gint16) 35;
		_tmp16_ = _vala_heuristic;
		_tmp16__length1 = _vala_heuristic_length1;
		_tmp16__length2 = _vala_heuristic_length2;
		_tmp16_[(tmp2 * _tmp16__length2) + 0] = (gint16) 35;
		_tmp17_ = _vala_heuristic;
		_tmp17__length1 = _vala_heuristic_length1;
		_tmp17__length2 = _vala_heuristic_length2;
		_tmp17_[(tmp2 * _tmp17__length2) + tmp1] = (gint16) 35;
		_tmp18_ = _vala_heuristic;
		_tmp18__length1 = _vala_heuristic_length1;
		_tmp18__length2 = _vala_heuristic_length2;
		_tmp18_[(1 * _tmp18__length2) + 1] = (gint16) 15;
		_tmp19_ = _vala_heuristic;
		_tmp19__length1 = _vala_heuristic_length1;
		_tmp19__length2 = _vala_heuristic_length2;
		_tmp19_[(1 * _tmp19__length2) + tmp2] = (gint16) 15;
		_tmp20_ = _vala_heuristic;
		_tmp20__length1 = _vala_heuristic_length1;
		_tmp20__length2 = _vala_heuristic_length2;
		_tmp20_[(tmp2 * _tmp20__length2) + tmp2] = (gint16) 15;
		_tmp21_ = _vala_heuristic;
		_tmp21__length1 = _vala_heuristic_length1;
		_tmp21__length2 = _vala_heuristic_length2;
		_tmp21_[(tmp2 * _tmp21__length2) + 1] = (gint16) 15;
	}
	if (heuristic) {
		*heuristic = _vala_heuristic;
	} else {
		_vala_heuristic = (g_free (_vala_heuristic), NULL);
	}
	if (heuristic_length1) {
		*heuristic_length1 = _vala_heuristic_length1;
	}
	if (heuristic_length2) {
		*heuristic_length2 = _vala_heuristic_length2;
	}
}

static gboolean
computer_reversi_hard_get_even_depth (ComputerReversiHard* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_even_depth;
	return result;
}

static void
computer_reversi_hard_set_even_depth (ComputerReversiHard* self,
                                      gboolean value)
{
	g_return_if_fail (self != NULL);
	self->priv->_even_depth = value;
}

static gboolean
computer_reversi_hard_get_fixed_heuristic (ComputerReversiHard* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_fixed_heuristic;
	return result;
}

static void
computer_reversi_hard_set_fixed_heuristic (ComputerReversiHard* self,
                                           gboolean value)
{
	g_return_if_fail (self != NULL);
	self->priv->_fixed_heuristic = value;
}

static GObject *
computer_reversi_hard_constructor (GType type,
                                   guint n_construct_properties,
                                   GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	ComputerReversiHard * self;
	guint8 _tmp0_;
	guint8 _tmp1_;
	gboolean _tmp2_;
	gint16* _tmp3_ = NULL;
	gint _tmp4_ = 0;
	gint _tmp5_ = 0;
	parent_class = G_OBJECT_CLASS (computer_reversi_hard_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_COMPUTER_REVERSI_HARD, ComputerReversiHard);
	_tmp0_ = computer_reversi_get_size ((ComputerReversi*) self);
	_tmp1_ = _tmp0_;
	_tmp2_ = self->priv->_fixed_heuristic;
	computer_reversi_hard_init_heuristic (_tmp1_, _tmp2_, &_tmp3_, &_tmp4_, &_tmp5_);
	self->priv->heuristic = (g_free (self->priv->heuristic), NULL);
	self->priv->heuristic = _tmp3_;
	self->priv->heuristic_length1 = _tmp4_;
	self->priv->heuristic_length2 = _tmp5_;
	return obj;
}

static void
computer_reversi_hard_class_init (ComputerReversiHardClass * klass,
                                  gpointer klass_data)
{
	computer_reversi_hard_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &ComputerReversiHard_private_offset);
	((ComputerReversiClass *) klass)->sort_moves = (void (*) (ComputerReversi*, GSList**)) computer_reversi_hard_real_sort_moves;
	((ComputerReversiClass *) klass)->end_of_game = (gint16 (*) (ComputerReversi*, GameStateStruct*)) computer_reversi_hard_real_end_of_game;
	((ComputerReversiClass *) klass)->calculate_heuristic = (gint16 (*) (ComputerReversi*, GameStateStruct*)) computer_reversi_hard_real_calculate_heuristic;
	G_OBJECT_CLASS (klass)->get_property = _vala_computer_reversi_hard_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_computer_reversi_hard_set_property;
	G_OBJECT_CLASS (klass)->constructor = computer_reversi_hard_constructor;
	G_OBJECT_CLASS (klass)->finalize = computer_reversi_hard_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), COMPUTER_REVERSI_HARD_EVEN_DEPTH_PROPERTY, computer_reversi_hard_properties[COMPUTER_REVERSI_HARD_EVEN_DEPTH_PROPERTY] = g_param_spec_boolean ("even-depth", "even-depth", "even-depth", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), COMPUTER_REVERSI_HARD_FIXED_HEURISTIC_PROPERTY, computer_reversi_hard_properties[COMPUTER_REVERSI_HARD_FIXED_HEURISTIC_PROPERTY] = g_param_spec_boolean ("fixed-heuristic", "fixed-heuristic", "fixed-heuristic", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY));
}

static void
computer_reversi_hard_instance_init (ComputerReversiHard * self,
                                     gpointer klass)
{
	self->priv = computer_reversi_hard_get_instance_private (self);
}

static void
computer_reversi_hard_finalize (GObject * obj)
{
	ComputerReversiHard * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_COMPUTER_REVERSI_HARD, ComputerReversiHard);
	self->priv->heuristic = (g_free (self->priv->heuristic), NULL);
	G_OBJECT_CLASS (computer_reversi_hard_parent_class)->finalize (obj);
}

 G_GNUC_NO_INLINE static GType
computer_reversi_hard_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ComputerReversiHardClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) computer_reversi_hard_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ComputerReversiHard), 0, (GInstanceInitFunc) computer_reversi_hard_instance_init, NULL };
	GType computer_reversi_hard_type_id;
	computer_reversi_hard_type_id = g_type_register_static (TYPE_COMPUTER_REVERSI, "ComputerReversiHard", &g_define_type_info, G_TYPE_FLAG_NONE);
	ComputerReversiHard_private_offset = g_type_add_instance_private (computer_reversi_hard_type_id, sizeof (ComputerReversiHardPrivate));
	return computer_reversi_hard_type_id;
}

GType
computer_reversi_hard_get_type (void)
{
	static gsize computer_reversi_hard_type_id__once = 0;
	if (g_once_init_enter (&computer_reversi_hard_type_id__once)) {
		GType computer_reversi_hard_type_id;
		computer_reversi_hard_type_id = computer_reversi_hard_get_type_once ();
		g_once_init_leave (&computer_reversi_hard_type_id__once, computer_reversi_hard_type_id);
	}
	return computer_reversi_hard_type_id__once;
}

static void
_vala_computer_reversi_hard_get_property (GObject * object,
                                          guint property_id,
                                          GValue * value,
                                          GParamSpec * pspec)
{
	ComputerReversiHard * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_COMPUTER_REVERSI_HARD, ComputerReversiHard);
	switch (property_id) {
		case COMPUTER_REVERSI_HARD_EVEN_DEPTH_PROPERTY:
		g_value_set_boolean (value, computer_reversi_hard_get_even_depth (self));
		break;
		case COMPUTER_REVERSI_HARD_FIXED_HEURISTIC_PROPERTY:
		g_value_set_boolean (value, computer_reversi_hard_get_fixed_heuristic (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_computer_reversi_hard_set_property (GObject * object,
                                          guint property_id,
                                          const GValue * value,
                                          GParamSpec * pspec)
{
	ComputerReversiHard * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_COMPUTER_REVERSI_HARD, ComputerReversiHard);
	switch (property_id) {
		case COMPUTER_REVERSI_HARD_EVEN_DEPTH_PROPERTY:
		computer_reversi_hard_set_even_depth (self, g_value_get_boolean (value));
		break;
		case COMPUTER_REVERSI_HARD_FIXED_HEURISTIC_PROPERTY:
		computer_reversi_hard_set_fixed_heuristic (self, g_value_get_boolean (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static inline gpointer
computer_reversi_get_instance_private (ComputerReversi* self)
{
	return G_STRUCT_MEMBER_P (self, ComputerReversi_private_offset);
}

static void
computer_reversi_real_complete_move (ComputerPlayer* base,
                                     PossibleMove* chosen_move)
{
	ComputerReversi * self;
	Game* _tmp0_;
	PossibleMove _tmp1_;
	PossibleMove _tmp2_;
	self = (ComputerReversi*) base;
	g_return_if_fail (chosen_move != NULL);
	_tmp0_ = self->priv->_game;
	_tmp1_ = *chosen_move;
	_tmp2_ = *chosen_move;
	if (!game_place_tile (_tmp0_, _tmp1_.x, _tmp2_.y)) {
		PossibleMove _tmp3_;
		gchar* _tmp4_;
		gchar* _tmp5_;
		PossibleMove _tmp6_;
		gchar* _tmp7_;
		gchar* _tmp8_;
		Game* _tmp9_;
		gchar* _tmp10_;
		gchar* _tmp11_;
		gchar* _tmp12_;
		gchar* _tmp13_;
		PossibleMove random_move = {0};
		Game* _tmp14_;
		GameStateObject* _tmp15_;
		GameStateObject* _tmp16_;
		GameStateStruct _tmp17_ = {0};
		GameStateStruct _tmp18_;
		PossibleMove _tmp19_ = {0};
		Game* _tmp20_;
		PossibleMove _tmp21_;
		PossibleMove _tmp22_;
		_tmp3_ = *chosen_move;
		_tmp4_ = g_strdup_printf ("%hhu", _tmp3_.x);
		_tmp5_ = _tmp4_;
		_tmp6_ = *chosen_move;
		_tmp7_ = g_strdup_printf ("%hhu", _tmp6_.y);
		_tmp8_ = _tmp7_;
		_tmp9_ = self->priv->_game;
		_tmp10_ = game_to_string (_tmp9_);
		_tmp11_ = _tmp10_;
		_tmp12_ = g_strconcat ("Computer chose an invalid move: ", _tmp5_, ",", _tmp8_, "\n", _tmp11_, NULL);
		_tmp13_ = _tmp12_;
		g_critical ("computer-reversi.vala:617: %s", _tmp13_);
		_g_free0 (_tmp13_);
		_g_free0 (_tmp11_);
		_g_free0 (_tmp8_);
		_g_free0 (_tmp5_);
		_tmp14_ = self->priv->_game;
		_tmp15_ = game_get_current_state (_tmp14_);
		_tmp16_ = _tmp15_;
		game_state_object_get_game_state_struct (_tmp16_, &_tmp17_);
		_tmp18_ = _tmp17_;
		computer_reversi_random_select (&_tmp18_, &_tmp19_);
		random_move = _tmp19_;
		_tmp20_ = self->priv->_game;
		_tmp21_ = random_move;
		_tmp22_ = random_move;
		if (!game_place_tile (_tmp20_, _tmp21_.x, _tmp22_.y)) {
			PossibleMove _tmp23_;
			gchar* _tmp24_;
			gchar* _tmp25_;
			PossibleMove _tmp26_;
			gchar* _tmp27_;
			gchar* _tmp28_;
			Game* _tmp29_;
			gchar* _tmp30_;
			gchar* _tmp31_;
			gchar* _tmp32_;
			gchar* _tmp33_;
			_tmp23_ = random_move;
			_tmp24_ = g_strdup_printf ("%hhu", _tmp23_.x);
			_tmp25_ = _tmp24_;
			_tmp26_ = random_move;
			_tmp27_ = g_strdup_printf ("%hhu", _tmp26_.y);
			_tmp28_ = _tmp27_;
			_tmp29_ = self->priv->_game;
			_tmp30_ = game_to_string (_tmp29_);
			_tmp31_ = _tmp30_;
			_tmp32_ = g_strconcat ("Computer chose an invalid move for the second time: ", _tmp25_, ",", _tmp28_, "\n", _tmp31_, NULL);
			_tmp33_ = _tmp32_;
			g_critical ("computer-reversi.vala:624: %s", _tmp33_);
			_g_free0 (_tmp33_);
			_g_free0 (_tmp31_);
			_g_free0 (_tmp28_);
			_g_free0 (_tmp25_);
			g_assert_not_reached ();
		}
	}
}

static void
_possible_move_free0_ (gpointer var)
{
	(var == NULL) ? NULL : (var = (possible_move_free (var), NULL));
}

static inline void
_g_slist_free__possible_move_free0_ (GSList* self)
{
	g_slist_free_full (self, (GDestroyNotify) _possible_move_free0_);
}

static void
computer_reversi_random_select (GameStateStruct* g,
                                PossibleMove* random_move)
{
	PossibleMove _vala_random_move = {0};
	GSList* moves = NULL;
	GSList* _tmp0_ = NULL;
	gconstpointer _tmp1_;
	g_return_if_fail (g != NULL);
	game_state_struct_get_possible_moves (g, &_tmp0_);
	(moves == NULL) ? NULL : (moves = (_g_slist_free__possible_move_free0_ (moves), NULL));
	moves = _tmp0_;
	_tmp1_ = g_slist_nth_data (moves, (guint) g_random_int_range ((gint32) 0, (gint32) g_slist_length (moves)));
	_vala_random_move = (PossibleMove) (*((PossibleMove*) _tmp1_));
	(moves == NULL) ? NULL : (moves = (_g_slist_free__possible_move_free0_ (moves), NULL));
	if (random_move) {
		*random_move = _vala_random_move;
	}
}

static void
computer_reversi_real_run_search (ComputerPlayer* base,
                                  PossibleMove* best_move)
{
	ComputerReversi * self;
	PossibleMove _vala_best_move = {0};
	GameStateStruct g = {0};
	Game* _tmp0_;
	GameStateObject* _tmp1_;
	GameStateObject* _tmp2_;
	GameStateStruct _tmp3_ = {0};
	GameStateStruct _tmp4_;
	GameStateStruct _tmp5_;
	GameStateStruct _tmp6_ = {0};
	GameStateStruct _tmp7_;
	guint8 _tmp8_;
	gint16 a = 0;
	GSList* moves = NULL;
	Game* _tmp26_;
	GSList* _tmp27_ = NULL;
	GSList* _tmp28_;
	self = (ComputerReversi*) base;
	_tmp0_ = self->priv->_game;
	_tmp1_ = game_get_current_state (_tmp0_);
	_tmp2_ = _tmp1_;
	game_state_object_get_game_state_struct (_tmp2_, &_tmp3_);
	_tmp4_ = _tmp3_;
	_tmp5_ = _tmp4_;
	game_state_struct_copy (&_tmp5_, &_tmp6_);
	g = _tmp6_;
	_tmp7_ = g;
	_tmp8_ = self->priv->_move_randomly;
	if (_tmp7_.n_tiles < _tmp8_) {
		gboolean _tmp9_ = FALSE;
		guint8 _tmp10_;
		_tmp10_ = self->priv->_size;
		if (((gint) _tmp10_) != 8) {
			_tmp9_ = TRUE;
		} else {
			Game* _tmp11_;
			gboolean _tmp12_;
			gboolean _tmp13_;
			_tmp11_ = self->priv->_game;
			_tmp12_ = game_get_reverse (_tmp11_);
			_tmp13_ = _tmp12_;
			_tmp9_ = _tmp13_;
		}
		if (_tmp9_) {
			GameStateStruct _tmp14_;
			PossibleMove _tmp15_ = {0};
			_tmp14_ = g;
			computer_reversi_random_select (&_tmp14_, &_tmp15_);
			_vala_best_move = _tmp15_;
		} else {
			{
				gboolean _tmp16_ = FALSE;
				_tmp16_ = TRUE;
				while (TRUE) {
					GameStateStruct _tmp24_;
					PossibleMove _tmp25_ = {0};
					if (!_tmp16_) {
						gboolean _tmp17_ = FALSE;
						gboolean _tmp18_ = FALSE;
						PossibleMove _tmp19_;
						_tmp19_ = _vala_best_move;
						if (((gint) _tmp19_.x) == 1) {
							_tmp18_ = TRUE;
						} else {
							PossibleMove _tmp20_;
							_tmp20_ = _vala_best_move;
							_tmp18_ = ((gint) _tmp20_.x) == 6;
						}
						if (_tmp18_) {
							gboolean _tmp21_ = FALSE;
							PossibleMove _tmp22_;
							_tmp22_ = _vala_best_move;
							if (((gint) _tmp22_.y) == 1) {
								_tmp21_ = TRUE;
							} else {
								PossibleMove _tmp23_;
								_tmp23_ = _vala_best_move;
								_tmp21_ = ((gint) _tmp23_.y) == 6;
							}
							_tmp17_ = _tmp21_;
						} else {
							_tmp17_ = FALSE;
						}
						if (!_tmp17_) {
							break;
						}
					}
					_tmp16_ = FALSE;
					_tmp24_ = g;
					computer_reversi_random_select (&_tmp24_, &_tmp25_);
					_vala_best_move = _tmp25_;
				}
			}
		}
		game_state_struct_destroy (&g);
		if (best_move) {
			*best_move = _vala_best_move;
		}
		return;
	}
	possible_move_init (&_vala_best_move, (guint8) 0, (guint8) 0);
	a = COMPUTER_REVERSI_LESS_THAN_NEGATIVE_INFINITY;
	_tmp26_ = self->priv->_game;
	game_get_possible_moves (_tmp26_, &_tmp27_);
	(moves == NULL) ? NULL : (moves = (_g_slist_free__possible_move_free0_ (moves), NULL));
	moves = _tmp27_;
	computer_reversi_sort_moves (self, &moves);
	_tmp28_ = moves;
	{
		GSList* move_collection = NULL;
		GSList* move_it = NULL;
		move_collection = _tmp28_;
		for (move_it = move_collection; move_it != NULL; move_it = move_it->next) {
			PossibleMove* move = NULL;
			move = (PossibleMove*) move_it->data;
			{
				GameStateStruct _g = {0};
				GameStateStruct _tmp29_;
				PossibleMove* _tmp30_;
				PossibleMove _tmp31_;
				gint16 a_new = 0;
				GameStateStruct _tmp32_;
				guint8 _tmp33_;
				gboolean _tmp35_;
				gboolean _tmp36_;
				_tmp29_ = g;
				_tmp30_ = move;
				_tmp31_ = (PossibleMove) (*_tmp30_);
				game_state_struct_init_copy_and_move (&_g, &_tmp29_, &_tmp31_);
				_tmp32_ = _g;
				_tmp33_ = self->priv->_initial_depth;
				a_new = (gint16) (-1 * computer_reversi_search (self, &_tmp32_, _tmp33_, COMPUTER_REVERSI_NEGATIVE_INFINITY, -a));
				if (a_new > a) {
					PossibleMove* _tmp34_;
					a = a_new;
					_tmp34_ = move;
					_vala_best_move = (PossibleMove) (*_tmp34_);
				}
				_tmp35_ = computer_player_get_move_pending ((ComputerPlayer*) self);
				_tmp36_ = _tmp35_;
				if (!_tmp36_) {
					game_state_struct_destroy (&_g);
					(moves == NULL) ? NULL : (moves = (_g_slist_free__possible_move_free0_ (moves), NULL));
					game_state_struct_destroy (&g);
					if (best_move) {
						*best_move = _vala_best_move;
					}
					return;
				}
				game_state_struct_destroy (&_g);
			}
		}
	}
	(moves == NULL) ? NULL : (moves = (_g_slist_free__possible_move_free0_ (moves), NULL));
	game_state_struct_destroy (&g);
	if (best_move) {
		*best_move = _vala_best_move;
	}
}

static gint16
computer_reversi_search (ComputerReversi* self,
                         GameStateStruct* g,
                         guint8 depth,
                         gint16 a,
                         gint16 b)
{
	GameStateStruct _tmp0_;
	GameStateStruct _tmp3_;
	gint16 result;
	g_return_val_if_fail (self != NULL, -1);
	g_return_val_if_fail (g != NULL, -1);
	_tmp0_ = *g;
	if (_tmp0_.is_complete) {
		GameStateStruct _tmp1_;
		_tmp1_ = *g;
		result = computer_reversi_end_of_game (self, &_tmp1_);
		return result;
	}
	if (((gint) depth) == 0) {
		GameStateStruct _tmp2_;
		_tmp2_ = *g;
		result = computer_reversi_calculate_heuristic (self, &_tmp2_);
		return result;
	}
	_tmp3_ = *g;
	if (_tmp3_.current_player_can_move) {
		GSList* moves = NULL;
		GSList* _tmp4_ = NULL;
		GSList* _tmp5_;
		game_state_struct_get_possible_moves (g, &_tmp4_);
		(moves == NULL) ? NULL : (moves = (_g_slist_free__possible_move_free0_ (moves), NULL));
		moves = _tmp4_;
		computer_reversi_sort_moves (self, &moves);
		_tmp5_ = moves;
		{
			GSList* move_collection = NULL;
			GSList* move_it = NULL;
			move_collection = _tmp5_;
			for (move_it = move_collection; move_it != NULL; move_it = move_it->next) {
				PossibleMove* move = NULL;
				move = (PossibleMove*) move_it->data;
				{
					GameStateStruct _g = {0};
					GameStateStruct _tmp6_;
					PossibleMove* _tmp7_;
					PossibleMove _tmp8_;
					gint16 a_new = 0;
					GameStateStruct _tmp9_;
					_tmp6_ = *g;
					_tmp7_ = move;
					_tmp8_ = (PossibleMove) (*_tmp7_);
					game_state_struct_init_copy_and_move (&_g, &_tmp6_, &_tmp8_);
					_tmp9_ = _g;
					a_new = (gint16) (-1 * computer_reversi_search (self, &_tmp9_, (guint8) (depth - 1), -b, -a));
					if (a_new > a) {
						a = a_new;
					}
					if (b <= a) {
						game_state_struct_destroy (&_g);
						break;
					}
					game_state_struct_destroy (&_g);
				}
			}
		}
		(moves == NULL) ? NULL : (moves = (_g_slist_free__possible_move_free0_ (moves), NULL));
	} else {
		GameStateStruct _g = {0};
		GameStateStruct _tmp10_;
		gint16 a_new = 0;
		GameStateStruct _tmp11_;
		_tmp10_ = *g;
		game_state_struct_init_copy_and_pass (&_g, &_tmp10_);
		_tmp11_ = _g;
		a_new = (gint16) (-1 * computer_reversi_search (self, &_tmp11_, (guint8) (depth - 1), -b, -a));
		if (a_new > a) {
			a = a_new;
		}
		game_state_struct_destroy (&_g);
	}
	result = a;
	return result;
}

static gint16
computer_reversi_real_calculate_heuristic (ComputerReversi* self,
                                           GameStateStruct* g)
{
	gint16 _tmp0_ = 0;
	g_critical ("Type `%s' does not implement abstract method `computer_reversi_calculate_heuristic'", g_type_name (G_TYPE_FROM_INSTANCE (self)));
	return _tmp0_;
}

gint16
computer_reversi_calculate_heuristic (ComputerReversi* self,
                                      GameStateStruct* g)
{
	ComputerReversiClass* _klass_;
	g_return_val_if_fail (self != NULL, -1);
	_klass_ = COMPUTER_REVERSI_GET_CLASS (self);
	if (_klass_->calculate_heuristic) {
		return _klass_->calculate_heuristic (self, g);
	}
	return -1;
}

static gint16
computer_reversi_real_end_of_game (ComputerReversi* self,
                                   GameStateStruct* g)
{
	gint16 _tmp0_ = 0;
	g_critical ("Type `%s' does not implement abstract method `computer_reversi_end_of_game'", g_type_name (G_TYPE_FROM_INSTANCE (self)));
	return _tmp0_;
}

gint16
computer_reversi_end_of_game (ComputerReversi* self,
                              GameStateStruct* g)
{
	ComputerReversiClass* _klass_;
	g_return_val_if_fail (self != NULL, -1);
	_klass_ = COMPUTER_REVERSI_GET_CLASS (self);
	if (_klass_->end_of_game) {
		return _klass_->end_of_game (self, g);
	}
	return -1;
}

static void
computer_reversi_real_sort_moves (ComputerReversi* self,
                                  GSList** moves)
{
	g_critical ("Type `%s' does not implement abstract method `computer_reversi_sort_moves'", g_type_name (G_TYPE_FROM_INSTANCE (self)));
	return;
}

void
computer_reversi_sort_moves (ComputerReversi* self,
                             GSList** moves)
{
	ComputerReversiClass* _klass_;
	g_return_if_fail (self != NULL);
	_klass_ = COMPUTER_REVERSI_GET_CLASS (self);
	if (_klass_->sort_moves) {
		_klass_->sort_moves (self, moves);
	}
}

ComputerReversi*
computer_reversi_construct (GType object_type)
{
	ComputerReversi * self = NULL;
	self = (ComputerReversi*) computer_player_construct (object_type);
	return self;
}

static Game*
computer_reversi_get_game (ComputerReversi* self)
{
	Game* result;
	Game* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_game;
	result = _tmp0_;
	return result;
}

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

static void
computer_reversi_set_game (ComputerReversi* self,
                           Game* value)
{
	Game* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = _g_object_ref0 (value);
	_g_object_unref0 (self->priv->_game);
	self->priv->_game = _tmp0_;
}

static guint8
computer_reversi_get_initial_depth (ComputerReversi* self)
{
	guint8 result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_initial_depth;
	return result;
}

static void
computer_reversi_set_initial_depth (ComputerReversi* self,
                                    guint8 value)
{
	g_return_if_fail (self != NULL);
	self->priv->_initial_depth = value;
}

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

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

guint8
computer_reversi_get_move_randomly (ComputerReversi* self)
{
	guint8 result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_move_randomly;
	return result;
}

static void
computer_reversi_set_move_randomly (ComputerReversi* self,
                                    guint8 value)
{
	g_return_if_fail (self != NULL);
	self->priv->_move_randomly = value;
}

static GObject *
computer_reversi_constructor (GType type,
                              guint n_construct_properties,
                              GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	ComputerReversi * self;
	Game* _tmp0_;
	guint8 _tmp1_;
	guint8 _tmp2_;
	gint _tmp3_ = 0;
	guint8 _tmp4_;
	Game* _tmp5_;
	guint8 _tmp6_;
	guint8 _tmp7_;
	Game* _tmp8_;
	gint _tmp9_ = 0;
	gint _tmp10_ = 0;
	guint8* _tmp11_;
	parent_class = G_OBJECT_CLASS (computer_reversi_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_COMPUTER_REVERSI, ComputerReversi);
	_tmp0_ = self->priv->_game;
	_tmp1_ = game_get_size (_tmp0_);
	_tmp2_ = _tmp1_;
	computer_reversi_set_size (self, _tmp2_);
	_tmp4_ = self->priv->_size;
	if (((gint) _tmp4_) < 6) {
		_tmp3_ = 2;
	} else {
		_tmp3_ = 4;
	}
	_tmp5_ = self->priv->_game;
	_tmp6_ = game_get_initial_number_of_tiles (_tmp5_);
	_tmp7_ = _tmp6_;
	computer_reversi_set_move_randomly (self, (guint8) (_tmp7_ + _tmp3_));
	_tmp8_ = self->priv->_game;
	_tmp11_ = game_copy_neighbor_tiles (_tmp8_, &_tmp9_, &_tmp10_);
	self->neighbor_tiles = (g_free (self->neighbor_tiles), NULL);
	self->neighbor_tiles = _tmp11_;
	self->neighbor_tiles_length1 = _tmp9_;
	self->neighbor_tiles_length2 = _tmp10_;
	return obj;
}

static void
computer_reversi_class_init (ComputerReversiClass * klass,
                             gpointer klass_data)
{
	computer_reversi_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &ComputerReversi_private_offset);
	((ComputerPlayerClass *) klass)->complete_move = (void (*) (ComputerPlayer*, PossibleMove*)) computer_reversi_real_complete_move;
	((ComputerPlayerClass *) klass)->run_search = (void (*) (ComputerPlayer*, PossibleMove*)) computer_reversi_real_run_search;
	((ComputerReversiClass *) klass)->calculate_heuristic = (gint16 (*) (ComputerReversi*, GameStateStruct*)) computer_reversi_real_calculate_heuristic;
	((ComputerReversiClass *) klass)->end_of_game = (gint16 (*) (ComputerReversi*, GameStateStruct*)) computer_reversi_real_end_of_game;
	((ComputerReversiClass *) klass)->sort_moves = (void (*) (ComputerReversi*, GSList**)) computer_reversi_real_sort_moves;
	G_OBJECT_CLASS (klass)->get_property = _vala_computer_reversi_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_computer_reversi_set_property;
	G_OBJECT_CLASS (klass)->constructor = computer_reversi_constructor;
	G_OBJECT_CLASS (klass)->finalize = computer_reversi_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), COMPUTER_REVERSI_GAME_PROPERTY, computer_reversi_properties[COMPUTER_REVERSI_GAME_PROPERTY] = g_param_spec_object ("game", "game", "game", TYPE_GAME, G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), COMPUTER_REVERSI_INITIAL_DEPTH_PROPERTY, computer_reversi_properties[COMPUTER_REVERSI_INITIAL_DEPTH_PROPERTY] = g_param_spec_uchar ("initial-depth", "initial-depth", "initial-depth", 0, G_MAXUINT8, 0, G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), COMPUTER_REVERSI_SIZE_PROPERTY, computer_reversi_properties[COMPUTER_REVERSI_SIZE_PROPERTY] = g_param_spec_uchar ("size", "size", "size", 0, G_MAXUINT8, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), COMPUTER_REVERSI_MOVE_RANDOMLY_PROPERTY, computer_reversi_properties[COMPUTER_REVERSI_MOVE_RANDOMLY_PROPERTY] = g_param_spec_uchar ("move-randomly", "move-randomly", "move-randomly", 0, G_MAXUINT8, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY));
}

static void
computer_reversi_instance_init (ComputerReversi * self,
                                gpointer klass)
{
	self->priv = computer_reversi_get_instance_private (self);
}

static void
computer_reversi_finalize (GObject * obj)
{
	ComputerReversi * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_COMPUTER_REVERSI, ComputerReversi);
	_g_object_unref0 (self->priv->_game);
	self->neighbor_tiles = (g_free (self->neighbor_tiles), NULL);
	G_OBJECT_CLASS (computer_reversi_parent_class)->finalize (obj);
}

 G_GNUC_NO_INLINE static GType
computer_reversi_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ComputerReversiClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) computer_reversi_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ComputerReversi), 0, (GInstanceInitFunc) computer_reversi_instance_init, NULL };
	GType computer_reversi_type_id;
	computer_reversi_type_id = g_type_register_static (TYPE_COMPUTER_PLAYER, "ComputerReversi", &g_define_type_info, G_TYPE_FLAG_ABSTRACT);
	ComputerReversi_private_offset = g_type_add_instance_private (computer_reversi_type_id, sizeof (ComputerReversiPrivate));
	return computer_reversi_type_id;
}

GType
computer_reversi_get_type (void)
{
	static gsize computer_reversi_type_id__once = 0;
	if (g_once_init_enter (&computer_reversi_type_id__once)) {
		GType computer_reversi_type_id;
		computer_reversi_type_id = computer_reversi_get_type_once ();
		g_once_init_leave (&computer_reversi_type_id__once, computer_reversi_type_id);
	}
	return computer_reversi_type_id__once;
}

static void
_vala_computer_reversi_get_property (GObject * object,
                                     guint property_id,
                                     GValue * value,
                                     GParamSpec * pspec)
{
	ComputerReversi * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_COMPUTER_REVERSI, ComputerReversi);
	switch (property_id) {
		case COMPUTER_REVERSI_GAME_PROPERTY:
		g_value_set_object (value, computer_reversi_get_game (self));
		break;
		case COMPUTER_REVERSI_INITIAL_DEPTH_PROPERTY:
		g_value_set_uchar (value, computer_reversi_get_initial_depth (self));
		break;
		case COMPUTER_REVERSI_SIZE_PROPERTY:
		g_value_set_uchar (value, computer_reversi_get_size (self));
		break;
		case COMPUTER_REVERSI_MOVE_RANDOMLY_PROPERTY:
		g_value_set_uchar (value, computer_reversi_get_move_randomly (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_computer_reversi_set_property (GObject * object,
                                     guint property_id,
                                     const GValue * value,
                                     GParamSpec * pspec)
{
	ComputerReversi * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_COMPUTER_REVERSI, ComputerReversi);
	switch (property_id) {
		case COMPUTER_REVERSI_GAME_PROPERTY:
		computer_reversi_set_game (self, g_value_get_object (value));
		break;
		case COMPUTER_REVERSI_INITIAL_DEPTH_PROPERTY:
		computer_reversi_set_initial_depth (self, g_value_get_uchar (value));
		break;
		case COMPUTER_REVERSI_SIZE_PROPERTY:
		computer_reversi_set_size (self, g_value_get_uchar (value));
		break;
		case COMPUTER_REVERSI_MOVE_RANDOMLY_PROPERTY:
		computer_reversi_set_move_randomly (self, g_value_get_uchar (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

